[AArch64] Support vrecp<esx> neon intrinsics in RTL.
[official-gcc.git] / gcc / config / aarch64 / aarch64.md
blob05974e3fb0ff832fc5b3eb47c30e5aab7c5f3b5a
1 ;; Machine description for AArch64 architecture.
2 ;; Copyright (C) 2009-2013 Free Software Foundation, Inc.
3 ;; Contributed by ARM Ltd.
4 ;;
5 ;; This file is part of GCC.
6 ;;
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
12 ;; GCC is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 ;; General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;; Register numbers
22 (define_constants
23   [
24     (R0_REGNUM          0)
25     (R1_REGNUM          1)
26     (R2_REGNUM          2)
27     (R3_REGNUM          3)
28     (R4_REGNUM          4)
29     (R5_REGNUM          5)
30     (R6_REGNUM          6)
31     (R7_REGNUM          7)
32     (R8_REGNUM          8)
33     (R9_REGNUM          9)
34     (R10_REGNUM         10)
35     (R11_REGNUM         11)
36     (R12_REGNUM         12)
37     (R13_REGNUM         13)
38     (R14_REGNUM         14)
39     (R15_REGNUM         15)
40     (R16_REGNUM         16)
41     (IP0_REGNUM         16)
42     (R17_REGNUM         17)
43     (IP1_REGNUM         17)
44     (R18_REGNUM         18)
45     (R19_REGNUM         19)
46     (R20_REGNUM         20)
47     (R21_REGNUM         21)
48     (R22_REGNUM         22)
49     (R23_REGNUM         23)
50     (R24_REGNUM         24)
51     (R25_REGNUM         25)
52     (R26_REGNUM         26)
53     (R27_REGNUM         27)
54     (R28_REGNUM         28)
55     (R29_REGNUM         29)
56     (R30_REGNUM         30)
57     (LR_REGNUM          30)
58     (SP_REGNUM          31)
59     (V0_REGNUM          32)
60     (V15_REGNUM         47)
61     (V31_REGNUM         63)
62     (SFP_REGNUM         64)
63     (AP_REGNUM          65)
64     (CC_REGNUM          66)
65   ]
68 (define_c_enum "unspec" [
69     UNSPEC_CASESI
70     UNSPEC_CLS
71     UNSPEC_FRECPE
72     UNSPEC_FRECPS
73     UNSPEC_FRECPX
74     UNSPEC_FRINTA
75     UNSPEC_FRINTI
76     UNSPEC_FRINTM
77     UNSPEC_FRINTP
78     UNSPEC_FRINTX
79     UNSPEC_FRINTZ
80     UNSPEC_GOTSMALLPIC
81     UNSPEC_GOTSMALLTLS
82     UNSPEC_LD2
83     UNSPEC_LD3
84     UNSPEC_LD4
85     UNSPEC_MB
86     UNSPEC_NOP
87     UNSPEC_PRLG_STK
88     UNSPEC_RBIT
89     UNSPEC_ST2
90     UNSPEC_ST3
91     UNSPEC_ST4
92     UNSPEC_TLS
93     UNSPEC_TLSDESC
94     UNSPEC_VSTRUCTDUMMY
97 (define_c_enum "unspecv" [
98     UNSPECV_EH_RETURN           ; Represent EH_RETURN
99   ]
102 ;; If further include files are added the defintion of MD_INCLUDES
103 ;; must be updated.
105 (include "constraints.md")
106 (include "predicates.md")
107 (include "iterators.md")
109 ;; -------------------------------------------------------------------
110 ;; Instruction types and attributes
111 ;; -------------------------------------------------------------------
113 ;; Main data types used by the insntructions
115 (define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
116   (const_string "unknown"))
118 (define_attr "mode2" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
119   (const_string "unknown"))
121 ; The "v8type" attribute is used to for fine grained classification of
122 ; AArch64 instructions.  This table briefly explains the meaning of each type.
124 ; adc              add/subtract with carry.
125 ; adcs             add/subtract with carry (setting condition flags).
126 ; adr              calculate address.
127 ; alu              simple alu instruction (no memory or fp regs access).
128 ; alu_ext          simple alu instruction (sign/zero-extended register).
129 ; alu_shift        simple alu instruction, with a source operand shifted by a constant.
130 ; alus             simple alu instruction (setting condition flags).
131 ; alus_ext         simple alu instruction (sign/zero-extended register, setting condition flags).
132 ; alus_shift       simple alu instruction, with a source operand shifted by a constant (setting condition flags).
133 ; bfm              bitfield move operation.
134 ; branch           branch.
135 ; call             subroutine call.
136 ; ccmp             conditional compare.
137 ; clz              count leading zeros/sign bits.
138 ; csel             conditional select.
139 ; dmb              data memory barrier.
140 ; extend           sign/zero-extend (specialised bitfield move).
141 ; extr             extract register-sized bitfield encoding.
142 ; fpsimd_load      load single floating point / simd scalar register from memory.
143 ; fpsimd_load2     load pair of floating point / simd scalar registers from memory.
144 ; fpsimd_store     store single floating point / simd scalar register to memory.
145 ; fpsimd_store2    store pair floating point / simd scalar registers to memory.
146 ; fadd             floating point add/sub.
147 ; fccmp            floating point conditional compare.
148 ; fcmp             floating point comparison.
149 ; fconst           floating point load immediate.
150 ; fcsel            floating point conditional select.
151 ; fcvt             floating point convert (float to float).
152 ; fcvtf2i          floating point convert (float to integer).
153 ; fcvti2f          floating point convert (integer to float).
154 ; fdiv             floating point division operation.
155 ; ffarith          floating point abs, neg or cpy.
156 ; fmadd            floating point multiply-add/sub.
157 ; fminmax          floating point min/max.
158 ; fmov             floating point move (float to float).
159 ; fmovf2i          floating point move (float to integer).
160 ; fmovi2f          floating point move (integer to float).
161 ; fmul             floating point multiply.
162 ; frint            floating point round to integral.
163 ; fsqrt            floating point square root.
164 ; load_acq         load-acquire.
165 ; load             load single general register from memory
166 ; load2            load pair of general registers from memory
167 ; logic            logical operation (register).
168 ; logic_imm        and/or/xor operation (immediate).
169 ; logic_shift      logical operation with shift.
170 ; logics           logical operation (register, setting condition flags).
171 ; logics_imm       and/or/xor operation (immediate, setting condition flags).
172 ; logics_shift     logical operation with shift (setting condition flags).
173 ; madd             integer multiply-add/sub.
174 ; maddl            widening integer multiply-add/sub.
175 ; misc             miscellaneous - any type that doesn't fit into the rest.
176 ; move             integer move operation.
177 ; move2            double integer move operation.
178 ; movk             move 16-bit immediate with keep.
179 ; movz             move 16-bit immmediate with zero/one.
180 ; mrs              system/special register move.
181 ; mulh             64x64 to 128-bit multiply (high part).
182 ; mull             widening multiply.
183 ; mult             integer multiply instruction.
184 ; prefetch         memory prefetch.
185 ; rbit             reverse bits.
186 ; rev              reverse bytes.
187 ; sdiv             integer division operation (signed).
188 ; shift            variable shift operation.
189 ; shift_imm        immediate shift operation (specialised bitfield move).
190 ; store_rel        store-release.
191 ; store            store single general register to memory.
192 ; store2           store pair of general registers to memory.
193 ; udiv             integer division operation (unsigned).
195 (define_attr "v8type"
196    "adc,\
197    adcs,\
198    adr,\
199    alu,\
200    alu_ext,\
201    alu_shift,\
202    alus,\
203    alus_ext,\
204    alus_shift,\
205    bfm,\
206    branch,\
207    call,\
208    ccmp,\
209    clz,\
210    csel,\
211    dmb,\
212    div,\
213    div64,\
214    extend,\
215    extr,\
216    fpsimd_load,\
217    fpsimd_load2,\
218    fpsimd_store2,\
219    fpsimd_store,\
220    fadd,\
221    fccmp,\
222    fcvt,\
223    fcvtf2i,\
224    fcvti2f,\
225    fcmp,\
226    fconst,\
227    fcsel,\
228    fdiv,\
229    ffarith,\
230    fmadd,\
231    fminmax,\
232    fmov,\
233    fmovf2i,\
234    fmovi2f,\
235    fmul,\
236    frecpe,\
237    frecps,\
238    frecpx,\
239    frint,\
240    fsqrt,\
241    load_acq,\
242    load1,\
243    load2,\
244    logic,\
245    logic_imm,\
246    logic_shift,\
247    logics,\
248    logics_imm,\
249    logics_shift,\
250    madd,\
251    maddl,\
252    misc,\
253    move,\
254    move2,\
255    movk,\
256    movz,\
257    mrs,\
258    mulh,\
259    mull,\
260    mult,\
261    prefetch,\
262    rbit,\
263    rev,\
264    sdiv,\
265    shift,\
266    shift_imm,\
267    store_rel,\
268    store1,\
269    store2,\
270    udiv"
271   (const_string "alu"))
274 ; The "type" attribute is used by the AArch32 backend.  Below is a mapping
275 ; from "v8type" to "type".
277 (define_attr "type"
278   "alu,alu_shift,block,branch,call,f_2_r,f_cvt,f_flag,f_loads,
279    f_loadd,f_stored,f_stores,faddd,fadds,fcmpd,fcmps,fconstd,fconsts,
280    fcpys,fdivd,fdivs,ffarithd,ffariths,fmacd,fmacs,fmuld,fmuls,load_byte,
281    load1,load2,mult,r_2_f,store1,store2"
282   (cond [
283           (eq_attr "v8type" "alu_shift,alus_shift,logic_shift,logics_shift") (const_string "alu_shift")
284           (eq_attr "v8type" "branch") (const_string "branch")
285           (eq_attr "v8type" "call") (const_string "call")
286           (eq_attr "v8type" "fmovf2i") (const_string "f_2_r")
287           (eq_attr "v8type" "fcvt,fcvtf2i,fcvti2f") (const_string "f_cvt")
288           (and (eq_attr "v8type" "fpsimd_load") (eq_attr "mode" "SF")) (const_string "f_loads")
289           (and (eq_attr "v8type" "fpsimd_load") (eq_attr "mode" "DF")) (const_string "f_loadd")
290           (and (eq_attr "v8type" "fpsimd_store") (eq_attr "mode" "SF")) (const_string "f_stores")
291           (and (eq_attr "v8type" "fpsimd_store") (eq_attr "mode" "DF")) (const_string "f_stored")
292           (and (eq_attr "v8type" "fadd,fminmax") (eq_attr "mode" "DF")) (const_string "faddd")
293           (and (eq_attr "v8type" "fadd,fminmax") (eq_attr "mode" "SF")) (const_string "fadds")
294           (and (eq_attr "v8type" "fcmp,fccmp") (eq_attr "mode" "DF")) (const_string "fcmpd")
295           (and (eq_attr "v8type" "fcmp,fccmp") (eq_attr "mode" "SF")) (const_string "fcmps")
296           (and (eq_attr "v8type" "fconst") (eq_attr "mode" "DF")) (const_string "fconstd")
297           (and (eq_attr "v8type" "fconst") (eq_attr "mode" "SF")) (const_string "fconsts")
298           (and (eq_attr "v8type" "fdiv,fsqrt") (eq_attr "mode" "DF")) (const_string "fdivd")
299           (and (eq_attr "v8type" "fdiv,fsqrt") (eq_attr "mode" "SF")) (const_string "fdivs")
300           (and (eq_attr "v8type" "ffarith") (eq_attr "mode" "DF")) (const_string "ffarithd")
301           (and (eq_attr "v8type" "ffarith") (eq_attr "mode" "SF")) (const_string "ffariths")
302           (and (eq_attr "v8type" "fmadd") (eq_attr "mode" "DF")) (const_string "fmacd")
303           (and (eq_attr "v8type" "fmadd") (eq_attr "mode" "SF")) (const_string "fmacs")
304           (and (eq_attr "v8type" "fmul") (eq_attr "mode" "DF")) (const_string "fmuld")
305           (and (eq_attr "v8type" "fmul") (eq_attr "mode" "SF")) (const_string "fmuls")
306           (and (eq_attr "v8type" "load1") (eq_attr "mode" "QI,HI")) (const_string "load_byte")
307           (and (eq_attr "v8type" "load1") (eq_attr "mode" "SI,DI,TI")) (const_string "load1")
308           (eq_attr "v8type" "load2") (const_string "load2")
309           (and (eq_attr "v8type" "mulh,mult,mull,madd,sdiv,udiv") (eq_attr "mode" "SI")) (const_string "mult")
310           (eq_attr "v8type" "fmovi2f") (const_string "r_2_f")
311           (eq_attr "v8type" "store1") (const_string "store1")
312           (eq_attr "v8type" "store2") (const_string "store2")
313   ]
314   (const_string "alu")))
316 ;; Attribute that specifies whether or not the instruction touches fp
317 ;; registers.
318 (define_attr "fp" "no,yes" (const_string "no"))
320 ;; Attribute that specifies whether or not the instruction touches simd
321 ;; registers.
322 (define_attr "simd" "no,yes" (const_string "no"))
324 (define_attr "length" ""
325   (const_int 4))
327 ;; Attribute that controls whether an alternative is enabled or not.
328 ;; Currently it is only used to disable alternatives which touch fp or simd
329 ;; registers when -mgeneral-regs-only is specified.
330 (define_attr "enabled" "no,yes"
331   (cond [(ior
332         (and (eq_attr "fp" "yes")
333              (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
334         (and (eq_attr "simd" "yes")
335              (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
336              (const_string "no")
337         ] (const_string "yes")))
339 ;; -------------------------------------------------------------------
340 ;; Pipeline descriptions and scheduling
341 ;; -------------------------------------------------------------------
343 ;; Processor types.
344 (include "aarch64-tune.md")
346 ;; Scheduling
347 (include "aarch64-generic.md")
348 (include "large.md")
349 (include "small.md")
351 ;; -------------------------------------------------------------------
352 ;; Jumps and other miscellaneous insns
353 ;; -------------------------------------------------------------------
355 (define_insn "indirect_jump"
356   [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
357   ""
358   "br\\t%0"
359   [(set_attr "v8type" "branch")]
362 (define_insn "jump"
363   [(set (pc) (label_ref (match_operand 0 "" "")))]
364   ""
365   "b\\t%l0"
366   [(set_attr "v8type" "branch")]
369 (define_expand "cbranch<mode>4"
370   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
371                             [(match_operand:GPI 1 "register_operand" "")
372                              (match_operand:GPI 2 "aarch64_plus_operand" "")])
373                            (label_ref (match_operand 3 "" ""))
374                            (pc)))]
375   ""
376   "
377   operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
378                                          operands[2]);
379   operands[2] = const0_rtx;
380   "
383 (define_expand "cbranch<mode>4"
384   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
385                             [(match_operand:GPF 1 "register_operand" "")
386                              (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
387                            (label_ref (match_operand 3 "" ""))
388                            (pc)))]
389   ""
390   "
391   operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
392                                          operands[2]);
393   operands[2] = const0_rtx;
394   "
397 (define_insn "*condjump"
398   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
399                             [(match_operand 1 "cc_register" "") (const_int 0)])
400                            (label_ref (match_operand 2 "" ""))
401                            (pc)))]
402   ""
403   "b%m0\\t%l2"
404   [(set_attr "v8type" "branch")]
407 (define_expand "casesi"
408   [(match_operand:SI 0 "register_operand" "")   ; Index
409    (match_operand:SI 1 "const_int_operand" "")  ; Lower bound
410    (match_operand:SI 2 "const_int_operand" "")  ; Total range
411    (match_operand:DI 3 "" "")                   ; Table label
412    (match_operand:DI 4 "" "")]                  ; Out of range label
413   ""
414   {
415     if (operands[1] != const0_rtx)
416       {
417         rtx reg = gen_reg_rtx (SImode);
419         /* Canonical RTL says that if you have:
421            (minus (X) (CONST))
423            then this should be emitted as:
425            (plus (X) (-CONST))
427            The use of trunc_int_for_mode ensures that the resulting
428            constant can be represented in SImode, this is important
429            for the corner case where operand[1] is INT_MIN.  */
431         operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
433         if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
434               (operands[1], SImode))
435           operands[1] = force_reg (SImode, operands[1]);
436         emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
437         operands[0] = reg;
438       }
440     if (!aarch64_plus_operand (operands[2], SImode))
441       operands[2] = force_reg (SImode, operands[2]);
442     emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
443                                                  const0_rtx),
444                                     operands[0], operands[2], operands[4]));
446     operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
447     emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
448                                          operands[3]));
449     DONE;
450   }
453 (define_insn "casesi_dispatch"
454   [(parallel
455     [(set (pc)
456           (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
457                            (match_operand:SI 1 "register_operand" "r")]
458                         UNSPEC_CASESI)))
459      (clobber (reg:CC CC_REGNUM))
460      (clobber (match_scratch:DI 3 "=r"))
461      (clobber (match_scratch:DI 4 "=r"))
462      (use (label_ref (match_operand 2 "" "")))])]
463   ""
464   "*
465   return aarch64_output_casesi (operands);
466   "
467   [(set_attr "length" "16")
468    (set_attr "v8type" "branch")]
471 (define_insn "nop"
472   [(unspec[(const_int 0)] UNSPEC_NOP)]
473   ""
474   "nop"
475   [(set_attr "v8type" "misc")]
478 (define_expand "prologue"
479   [(clobber (const_int 0))]
480   ""
481   "
482   aarch64_expand_prologue ();
483   DONE;
484   "
487 (define_expand "epilogue"
488   [(clobber (const_int 0))]
489   ""
490   "
491   aarch64_expand_epilogue (false);
492   DONE;
493   "
496 (define_expand "sibcall_epilogue"
497   [(clobber (const_int 0))]
498   ""
499   "
500   aarch64_expand_epilogue (true);
501   DONE;
502   "
505 (define_insn "*do_return"
506   [(return)]
507   ""
508   "ret"
509   [(set_attr "v8type" "branch")]
512 (define_insn "eh_return"
513   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
514     UNSPECV_EH_RETURN)]
515   ""
516   "#"
517   [(set_attr "v8type" "branch")]
520 (define_split
521   [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
522     UNSPECV_EH_RETURN)]
523   "reload_completed"
524   [(set (match_dup 1) (match_dup 0))]
525   {
526     operands[1] = aarch64_final_eh_return_addr ();
527   }
530 (define_insn "*cb<optab><mode>1"
531   [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
532                                 (const_int 0))
533                            (label_ref (match_operand 1 "" ""))
534                            (pc)))]
535   ""
536   "<cbz>\\t%<w>0, %l1"
537   [(set_attr "v8type" "branch")]
540 (define_insn "*tb<optab><mode>1"
541   [(set (pc) (if_then_else
542               (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
543                                     (const_int 1)
544                                     (match_operand 1 "const_int_operand" "n"))
545                    (const_int 0))
546              (label_ref (match_operand 2 "" ""))
547              (pc)))
548    (clobber (match_scratch:DI 3 "=r"))]
549   ""
550   "*
551   if (get_attr_length (insn) == 8)
552     return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
553   return \"<tbz>\\t%<w>0, %1, %l2\";
554   "
555   [(set_attr "v8type" "branch")
556    (set_attr "mode" "<MODE>")
557    (set (attr "length")
558         (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
559                            (lt (minus (match_dup 2) (pc)) (const_int 32764)))
560                       (const_int 4)
561                       (const_int 8)))]
564 (define_insn "*cb<optab><mode>1"
565   [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
566                                  (const_int 0))
567                            (label_ref (match_operand 1 "" ""))
568                            (pc)))
569    (clobber (match_scratch:DI 2 "=r"))]
570   ""
571   "*
572   if (get_attr_length (insn) == 8)
573     return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
574   return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
575   "
576   [(set_attr "v8type" "branch")
577    (set_attr "mode" "<MODE>")
578    (set (attr "length")
579         (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
580                            (lt (minus (match_dup 1) (pc)) (const_int 32764)))
581                       (const_int 4)
582                       (const_int 8)))]
585 ;; -------------------------------------------------------------------
586 ;; Subroutine calls and sibcalls
587 ;; -------------------------------------------------------------------
589 (define_expand "call"
590   [(parallel [(call (match_operand 0 "memory_operand" "")
591                     (match_operand 1 "general_operand" ""))
592               (use (match_operand 2 "" ""))
593               (clobber (reg:DI LR_REGNUM))])]
594   ""
595   "
596   {
597     rtx callee;
599     /* In an untyped call, we can get NULL for operand 2.  */
600     if (operands[2] == NULL)
601       operands[2] = const0_rtx;
603     /* Decide if we should generate indirect calls by loading the
604        64-bit address of the callee into a register before performing
605        the branch-and-link.  */
606     callee = XEXP (operands[0], 0);
607     if (GET_CODE (callee) == SYMBOL_REF
608         ? aarch64_is_long_call_p (callee)
609         : !REG_P (callee))
610       XEXP (operands[0], 0) = force_reg (Pmode, callee);
611   }"
614 (define_insn "*call_reg"
615   [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
616          (match_operand 1 "" ""))
617    (use (match_operand 2 "" ""))
618    (clobber (reg:DI LR_REGNUM))]
619   ""
620   "blr\\t%0"
621   [(set_attr "v8type" "call")]
624 (define_insn "*call_symbol"
625   [(call (mem:DI (match_operand:DI 0 "" ""))
626          (match_operand 1 "" ""))
627    (use (match_operand 2 "" ""))
628    (clobber (reg:DI LR_REGNUM))]
629   "GET_CODE (operands[0]) == SYMBOL_REF
630    && !aarch64_is_long_call_p (operands[0])"
631   "bl\\t%a0"
632   [(set_attr "v8type" "call")]
635 (define_expand "call_value"
636   [(parallel [(set (match_operand 0 "" "")
637                    (call (match_operand 1 "memory_operand" "")
638                          (match_operand 2 "general_operand" "")))
639               (use (match_operand 3 "" ""))
640               (clobber (reg:DI LR_REGNUM))])]
641   ""
642   "
643   {
644     rtx callee;
646     /* In an untyped call, we can get NULL for operand 3.  */
647     if (operands[3] == NULL)
648       operands[3] = const0_rtx;
650     /* Decide if we should generate indirect calls by loading the
651        64-bit address of the callee into a register before performing
652        the branch-and-link.  */
653     callee = XEXP (operands[1], 0);
654     if (GET_CODE (callee) == SYMBOL_REF
655         ? aarch64_is_long_call_p (callee)
656         : !REG_P (callee))
657       XEXP (operands[1], 0) = force_reg (Pmode, callee);
658   }"
661 (define_insn "*call_value_reg"
662   [(set (match_operand 0 "" "")
663         (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
664                       (match_operand 2 "" "")))
665    (use (match_operand 3 "" ""))
666    (clobber (reg:DI LR_REGNUM))]
667   ""
668   "blr\\t%1"
669   [(set_attr "v8type" "call")]
672 (define_insn "*call_value_symbol"
673   [(set (match_operand 0 "" "")
674         (call (mem:DI (match_operand:DI 1 "" ""))
675               (match_operand 2 "" "")))
676    (use (match_operand 3 "" ""))
677    (clobber (reg:DI LR_REGNUM))]
678   "GET_CODE (operands[1]) == SYMBOL_REF
679    && !aarch64_is_long_call_p (operands[1])"
680   "bl\\t%a1"
681   [(set_attr "v8type" "call")]
684 (define_expand "sibcall"
685   [(parallel [(call (match_operand 0 "memory_operand" "")
686                     (match_operand 1 "general_operand" ""))
687               (return)
688               (use (match_operand 2 "" ""))])]
689   ""
690   {
691     if (operands[2] == NULL_RTX)
692       operands[2] = const0_rtx;
693   }
696 (define_expand "sibcall_value"
697   [(parallel [(set (match_operand 0 "" "")
698                    (call (match_operand 1 "memory_operand" "")
699                          (match_operand 2 "general_operand" "")))
700               (return)
701               (use (match_operand 3 "" ""))])]
702   ""
703   {
704     if (operands[3] == NULL_RTX)
705       operands[3] = const0_rtx;
706   }
709 (define_insn "*sibcall_insn"
710   [(call (mem:DI (match_operand:DI 0 "" "X"))
711          (match_operand 1 "" ""))
712    (return)
713    (use (match_operand 2 "" ""))]
714   "GET_CODE (operands[0]) == SYMBOL_REF"
715   "b\\t%a0"
716   [(set_attr "v8type" "branch")]
719 (define_insn "*sibcall_value_insn"
720   [(set (match_operand 0 "" "")
721         (call (mem:DI (match_operand 1 "" "X"))
722               (match_operand 2 "" "")))
723    (return)
724    (use (match_operand 3 "" ""))]
725   "GET_CODE (operands[1]) == SYMBOL_REF"
726   "b\\t%a1"
727   [(set_attr "v8type" "branch")]
730 ;; Call subroutine returning any type.
732 (define_expand "untyped_call"
733   [(parallel [(call (match_operand 0 "")
734                     (const_int 0))
735               (match_operand 1 "")
736               (match_operand 2 "")])]
737   ""
739   int i;
741   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
743   for (i = 0; i < XVECLEN (operands[2], 0); i++)
744     {
745       rtx set = XVECEXP (operands[2], 0, i);
746       emit_move_insn (SET_DEST (set), SET_SRC (set));
747     }
749   /* The optimizer does not know that the call sets the function value
750      registers we stored in the result block.  We avoid problems by
751      claiming that all hard registers are used and clobbered at this
752      point.  */
753   emit_insn (gen_blockage ());
754   DONE;
757 ;; -------------------------------------------------------------------
758 ;; Moves
759 ;; -------------------------------------------------------------------
761 (define_expand "mov<mode>"
762   [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
763         (match_operand:SHORT 1 "general_operand" ""))]
764   ""
765   "
766     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
767       operands[1] = force_reg (<MODE>mode, operands[1]);
768   "
771 (define_insn "*mov<mode>_aarch64"
772   [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r,   *w,r,*w, m, m, r,*w,*w")
773         (match_operand:SHORT 1 "general_operand"      " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
774   "(register_operand (operands[0], <MODE>mode)
775     || aarch64_reg_or_zero (operands[1], <MODE>mode))"
776   "@
777    mov\\t%w0, %w1
778    mov\\t%w0, %1
779    movi\\t%0.<Vallxd>, %1
780    ldr<size>\\t%w0, %1
781    ldr\\t%<size>0, %1
782    str<size>\\t%w1, %0
783    str\\t%<size>1, %0
784    umov\\t%w0, %1.<v>[0]
785    dup\\t%0.<Vallxd>, %w1
786    dup\\t%0, %1.<v>[0]"
787   [(set_attr "v8type" "move,alu,alu,load1,load1,store1,store1,*,*,*")
788    (set_attr "simd_type" "*,*,simd_move_imm,*,*,*,*,simd_movgp,simd_dupgp,simd_dup")
789    (set_attr "mode" "<MODE>")
790    (set_attr "simd_mode" "<MODE>")]
793 (define_expand "mov<mode>"
794   [(set (match_operand:GPI 0 "nonimmediate_operand" "")
795         (match_operand:GPI 1 "general_operand" ""))]
796   ""
797   "
798     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
799       operands[1] = force_reg (<MODE>mode, operands[1]);
801     if (CONSTANT_P (operands[1]))
802       {
803         aarch64_expand_mov_immediate (operands[0], operands[1]);
804         DONE;
805       }
806   "
809 (define_insn "*movsi_aarch64"
810   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m, *w, r,*w")
811         (match_operand:SI 1 "aarch64_mov_operand"     " r,M,m,rZ,rZ,*w,*w"))]
812   "(register_operand (operands[0], SImode)
813     || aarch64_reg_or_zero (operands[1], SImode))"
814   "@
815    mov\\t%w0, %w1
816    mov\\t%w0, %1
817    ldr\\t%w0, %1
818    str\\t%w1, %0
819    fmov\\t%s0, %w1
820    fmov\\t%w0, %s1
821    fmov\\t%s0, %s1"
822   [(set_attr "v8type" "move,alu,load1,store1,fmov,fmov,fmov")
823    (set_attr "mode" "SI")
824    (set_attr "fp" "*,*,*,*,yes,yes,yes")]
827 (define_insn "*movdi_aarch64"
828   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,m, r,  r,  *w, r,*w,w")
829         (match_operand:DI 1 "aarch64_mov_operand"  " r,r,k,N,m,rZ,Usa,Ush,rZ,*w,*w,Dd"))]
830   "(register_operand (operands[0], DImode)
831     || aarch64_reg_or_zero (operands[1], DImode))"
832   "@
833    mov\\t%x0, %x1
834    mov\\t%0, %x1
835    mov\\t%x0, %1
836    mov\\t%x0, %1
837    ldr\\t%x0, %1
838    str\\t%x1, %0
839    adr\\t%x0, %a1
840    adrp\\t%x0, %A1
841    fmov\\t%d0, %x1
842    fmov\\t%x0, %d1
843    fmov\\t%d0, %d1
844    movi\\t%d0, %1"
845   [(set_attr "v8type" "move,move,move,alu,load1,store1,adr,adr,fmov,fmov,fmov,fmov")
846    (set_attr "mode" "DI")
847    (set_attr "fp" "*,*,*,*,*,*,*,*,yes,yes,yes,yes")]
850 (define_insn "insv_imm<mode>"
851   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
852                           (const_int 16)
853                           (match_operand:GPI 1 "const_int_operand" "n"))
854         (match_operand:GPI 2 "const_int_operand" "n"))]
855   "INTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
856    && INTVAL (operands[1]) % 16 == 0
857    && UINTVAL (operands[2]) <= 0xffff"
858   "movk\\t%<w>0, %X2, lsl %1"
859   [(set_attr "v8type" "movk")
860    (set_attr "mode" "<MODE>")]
863 (define_expand "movti"
864   [(set (match_operand:TI 0 "nonimmediate_operand" "")
865         (match_operand:TI 1 "general_operand" ""))]
866   ""
867   "
868     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
869       operands[1] = force_reg (TImode, operands[1]);
870   "
873 (define_insn "*movti_aarch64"
874   [(set (match_operand:TI 0
875          "nonimmediate_operand"  "=r, *w,r ,*w,r  ,Ump,Ump,*w,m")
876         (match_operand:TI 1
877          "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r  ,Z  , m,*w"))]
878   "(register_operand (operands[0], TImode)
879     || aarch64_reg_or_zero (operands[1], TImode))"
880   "@
881    #
882    #
883    #
884    orr\\t%0.16b, %1.16b, %1.16b
885    ldp\\t%0, %H0, %1
886    stp\\t%1, %H1, %0
887    stp\\txzr, xzr, %0
888    ldr\\t%q0, %1
889    str\\t%q1, %0"
890   [(set_attr "v8type" "move2,fmovi2f,fmovf2i,*, \
891                        load2,store2,store2,fpsimd_load,fpsimd_store")
892    (set_attr "simd_type" "*,*,*,simd_move,*,*,*,*,*")
893    (set_attr "mode" "DI,DI,DI,TI,DI,DI,DI,TI,TI")
894    (set_attr "length" "8,8,8,4,4,4,4,4,4")
895    (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")
896    (set_attr "simd" "*,*,*,yes,*,*,*,*,*")])
898 ;; Split a TImode register-register or register-immediate move into
899 ;; its component DImode pieces, taking care to handle overlapping
900 ;; source and dest registers.
901 (define_split
902    [(set (match_operand:TI 0 "register_operand" "")
903          (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
904   "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
905   [(const_int 0)]
907   aarch64_split_128bit_move (operands[0], operands[1]);
908   DONE;
911 (define_expand "mov<mode>"
912   [(set (match_operand:GPF 0 "nonimmediate_operand" "")
913         (match_operand:GPF 1 "general_operand" ""))]
914   ""
915   "
916     if (!TARGET_FLOAT)
917      {
918         sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
919         FAIL;
920      }
922     if (GET_CODE (operands[0]) == MEM)
923       operands[1] = force_reg (<MODE>mode, operands[1]);
924   "
927 (define_insn "*movsf_aarch64"
928   [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w  ,w,m,r,m ,r")
929         (match_operand:SF 1 "general_operand"      "?rY, w,w,Ufc,m,w,m,rY,r"))]
930   "TARGET_FLOAT && (register_operand (operands[0], SFmode)
931     || register_operand (operands[1], SFmode))"
932   "@
933    fmov\\t%s0, %w1
934    fmov\\t%w0, %s1
935    fmov\\t%s0, %s1
936    fmov\\t%s0, %1
937    ldr\\t%s0, %1
938    str\\t%s1, %0
939    ldr\\t%w0, %1
940    str\\t%w1, %0
941    mov\\t%w0, %w1"
942   [(set_attr "v8type" "fmovi2f,fmovf2i,\
943                        fmov,fconst,fpsimd_load,\
944                        fpsimd_store,fpsimd_load,fpsimd_store,fmov")
945    (set_attr "mode" "SF")]
948 (define_insn "*movdf_aarch64"
949   [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w  ,w,m,r,m ,r")
950         (match_operand:DF 1 "general_operand"      "?rY, w,w,Ufc,m,w,m,rY,r"))]
951   "TARGET_FLOAT && (register_operand (operands[0], DFmode)
952     || register_operand (operands[1], DFmode))"
953   "@
954    fmov\\t%d0, %x1
955    fmov\\t%x0, %d1
956    fmov\\t%d0, %d1
957    fmov\\t%d0, %1
958    ldr\\t%d0, %1
959    str\\t%d1, %0
960    ldr\\t%x0, %1
961    str\\t%x1, %0
962    mov\\t%x0, %x1"
963   [(set_attr "v8type" "fmovi2f,fmovf2i,\
964                        fmov,fconst,fpsimd_load,\
965                        fpsimd_store,fpsimd_load,fpsimd_store,move")
966    (set_attr "mode" "DF")]
969 (define_expand "movtf"
970   [(set (match_operand:TF 0 "nonimmediate_operand" "")
971         (match_operand:TF 1 "general_operand" ""))]
972   ""
973   "
974     if (!TARGET_FLOAT)
975      {
976         sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
977         FAIL;
978      }
980     if (GET_CODE (operands[0]) == MEM)
981       operands[1] = force_reg (TFmode, operands[1]);
982   "
985 (define_insn "*movtf_aarch64"
986   [(set (match_operand:TF 0
987          "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
988         (match_operand:TF 1
989          "general_operand"      " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
990   "TARGET_FLOAT && (register_operand (operands[0], TFmode)
991     || register_operand (operands[1], TFmode))"
992   "@
993    orr\\t%0.16b, %1.16b, %1.16b
994    mov\\t%0, %1\;mov\\t%H0, %H1
995    fmov\\t%d0, %Q1\;fmov\\t%0.d[1], %R1
996    fmov\\t%Q0, %d1\;fmov\\t%R0, %1.d[1]
997    movi\\t%0.2d, #0
998    fmov\\t%s0, wzr
999    ldr\\t%q0, %1
1000    str\\t%q1, %0
1001    ldp\\t%0, %H0, %1
1002    stp\\t%1, %H1, %0"
1003   [(set_attr "v8type" "logic,move2,fmovi2f,fmovf2i,fconst,fconst,fpsimd_load,fpsimd_store,fpsimd_load2,fpsimd_store2")
1004    (set_attr "mode" "DF,DF,DF,DF,DF,DF,TF,TF,DF,DF")
1005    (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
1006    (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
1007    (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
1010 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1011 ;; fairly lax checking on the second memory operation.
1012 (define_insn "load_pair<mode>"
1013   [(set (match_operand:GPI 0 "register_operand" "=r")
1014         (match_operand:GPI 1 "aarch64_mem_pair_operand" "Ump"))
1015    (set (match_operand:GPI 2 "register_operand" "=r")
1016         (match_operand:GPI 3 "memory_operand" "m"))]
1017   "rtx_equal_p (XEXP (operands[3], 0),
1018                 plus_constant (Pmode,
1019                                XEXP (operands[1], 0),
1020                                GET_MODE_SIZE (<MODE>mode)))"
1021   "ldp\\t%<w>0, %<w>2, %1"
1022   [(set_attr "v8type" "load2")
1023    (set_attr "mode" "<MODE>")]
1026 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1027 ;; fairly lax checking on the second memory operation.
1028 (define_insn "store_pair<mode>"
1029   [(set (match_operand:GPI 0 "aarch64_mem_pair_operand" "=Ump")
1030         (match_operand:GPI 1 "register_operand" "r"))
1031    (set (match_operand:GPI 2 "memory_operand" "=m")
1032         (match_operand:GPI 3 "register_operand" "r"))]
1033   "rtx_equal_p (XEXP (operands[2], 0),
1034                 plus_constant (Pmode,
1035                                XEXP (operands[0], 0),
1036                                GET_MODE_SIZE (<MODE>mode)))"
1037   "stp\\t%<w>1, %<w>3, %0"
1038   [(set_attr "v8type" "store2")
1039    (set_attr "mode" "<MODE>")]
1042 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1043 ;; fairly lax checking on the second memory operation.
1044 (define_insn "load_pair<mode>"
1045   [(set (match_operand:GPF 0 "register_operand" "=w")
1046         (match_operand:GPF 1 "aarch64_mem_pair_operand" "Ump"))
1047    (set (match_operand:GPF 2 "register_operand" "=w")
1048         (match_operand:GPF 3 "memory_operand" "m"))]
1049   "rtx_equal_p (XEXP (operands[3], 0),
1050                 plus_constant (Pmode,
1051                                XEXP (operands[1], 0),
1052                                GET_MODE_SIZE (<MODE>mode)))"
1053   "ldp\\t%<w>0, %<w>2, %1"
1054   [(set_attr "v8type" "fpsimd_load2")
1055    (set_attr "mode" "<MODE>")]
1058 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1059 ;; fairly lax checking on the second memory operation.
1060 (define_insn "store_pair<mode>"
1061   [(set (match_operand:GPF 0 "aarch64_mem_pair_operand" "=Ump")
1062         (match_operand:GPF 1 "register_operand" "w"))
1063    (set (match_operand:GPF 2 "memory_operand" "=m")
1064         (match_operand:GPF 3 "register_operand" "w"))]
1065   "rtx_equal_p (XEXP (operands[2], 0),
1066                 plus_constant (Pmode,
1067                                XEXP (operands[0], 0),
1068                                GET_MODE_SIZE (<MODE>mode)))"
1069   "stp\\t%<w>1, %<w>3, %0"
1070   [(set_attr "v8type" "fpsimd_load2")
1071    (set_attr "mode" "<MODE>")]
1074 ;; Load pair with writeback.  This is primarily used in function epilogues
1075 ;; when restoring [fp,lr]
1076 (define_insn "loadwb_pair<GPI:mode>_<PTR:mode>"
1077   [(parallel
1078     [(set (match_operand:PTR 0 "register_operand" "=k")
1079           (plus:PTR (match_operand:PTR 1 "register_operand" "0")
1080                   (match_operand:PTR 4 "const_int_operand" "n")))
1081      (set (match_operand:GPI 2 "register_operand" "=r")
1082           (mem:GPI (plus:PTR (match_dup 1)
1083                    (match_dup 4))))
1084      (set (match_operand:GPI 3 "register_operand" "=r")
1085           (mem:GPI (plus:PTR (match_dup 1)
1086                    (match_operand:PTR 5 "const_int_operand" "n"))))])]
1087   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1088   "ldp\\t%<w>2, %<w>3, [%1], %4"
1089   [(set_attr "v8type" "load2")
1090    (set_attr "mode" "<GPI:MODE>")]
1093 ;; Store pair with writeback.  This is primarily used in function prologues
1094 ;; when saving [fp,lr]
1095 (define_insn "storewb_pair<GPI:mode>_<PTR:mode>"
1096   [(parallel
1097     [(set (match_operand:PTR 0 "register_operand" "=&k")
1098           (plus:PTR (match_operand:PTR 1 "register_operand" "0")
1099                   (match_operand:PTR 4 "const_int_operand" "n")))
1100      (set (mem:GPI (plus:PTR (match_dup 0)
1101                    (match_dup 4)))
1102           (match_operand:GPI 2 "register_operand" "r"))
1103      (set (mem:GPI (plus:PTR (match_dup 0)
1104                    (match_operand:PTR 5 "const_int_operand" "n")))
1105           (match_operand:GPI 3 "register_operand" "r"))])]
1106   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1107   "stp\\t%<w>2, %<w>3, [%0, %4]!"
1108   [(set_attr "v8type" "store2")
1109    (set_attr "mode" "<GPI:MODE>")]
1112 ;; -------------------------------------------------------------------
1113 ;; Sign/Zero extension
1114 ;; -------------------------------------------------------------------
1116 (define_expand "<optab>sidi2"
1117   [(set (match_operand:DI 0 "register_operand")
1118         (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1119   ""
1122 (define_insn "*extendsidi2_aarch64"
1123   [(set (match_operand:DI 0 "register_operand" "=r,r")
1124         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1125   ""
1126   "@
1127    sxtw\t%0, %w1
1128    ldrsw\t%0, %1"
1129   [(set_attr "v8type" "extend,load1")
1130    (set_attr "mode" "DI")]
1133 (define_insn "*zero_extendsidi2_aarch64"
1134   [(set (match_operand:DI 0 "register_operand" "=r,r")
1135         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1136   ""
1137   "@
1138    uxtw\t%0, %w1
1139    ldr\t%w0, %1"
1140   [(set_attr "v8type" "extend,load1")
1141    (set_attr "mode" "DI")]
1144 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1145   [(set (match_operand:GPI 0 "register_operand")
1146         (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1147   ""
1150 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1151   [(set (match_operand:GPI 0 "register_operand" "=r,r")
1152         (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1153   ""
1154   "@
1155    sxt<SHORT:size>\t%<GPI:w>0, %w1
1156    ldrs<SHORT:size>\t%<GPI:w>0, %1"
1157   [(set_attr "v8type" "extend,load1")
1158    (set_attr "mode" "<GPI:MODE>")]
1161 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1162   [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1163         (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1164   ""
1165   "@
1166    uxt<SHORT:size>\t%<GPI:w>0, %w1
1167    ldr<SHORT:size>\t%w0, %1
1168    ldr\t%<SHORT:size>0, %1"
1169   [(set_attr "v8type" "extend,load1,load1")
1170    (set_attr "mode" "<GPI:MODE>")]
1173 (define_expand "<optab>qihi2"
1174   [(set (match_operand:HI 0 "register_operand")
1175         (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1176   ""
1179 (define_insn "*<optab>qihi2_aarch64"
1180   [(set (match_operand:HI 0 "register_operand" "=r,r")
1181         (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1182   ""
1183   "@
1184    <su>xtb\t%w0, %w1
1185    <ldrxt>b\t%w0, %1"
1186   [(set_attr "v8type" "extend,load1")
1187    (set_attr "mode" "HI")]
1190 ;; -------------------------------------------------------------------
1191 ;; Simple arithmetic
1192 ;; -------------------------------------------------------------------
1194 (define_expand "add<mode>3"
1195   [(set
1196     (match_operand:GPI 0 "register_operand" "")
1197     (plus:GPI (match_operand:GPI 1 "register_operand" "")
1198               (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1199   ""
1200   "
1201   if (! aarch64_plus_operand (operands[2], VOIDmode))
1202     {
1203       rtx subtarget = ((optimize && can_create_pseudo_p ())
1204                        ? gen_reg_rtx (<MODE>mode) : operands[0]);
1205       HOST_WIDE_INT imm = INTVAL (operands[2]);
1207       if (imm < 0)
1208         imm = -(-imm & ~0xfff);
1209       else
1210         imm &= ~0xfff;
1212       emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1213       operands[1] = subtarget;
1214       operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1215     }
1216   "
1219 (define_insn "*addsi3_aarch64"
1220   [(set
1221     (match_operand:SI 0 "register_operand" "=rk,rk,rk")
1222     (plus:SI
1223      (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1224      (match_operand:SI 2 "aarch64_plus_operand" "I,r,J")))]
1225   ""
1226   "@
1227   add\\t%w0, %w1, %2
1228   add\\t%w0, %w1, %w2
1229   sub\\t%w0, %w1, #%n2"
1230   [(set_attr "v8type" "alu")
1231    (set_attr "mode" "SI")]
1234 ;; zero_extend version of above
1235 (define_insn "*addsi3_aarch64_uxtw"
1236   [(set
1237     (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1238     (zero_extend:DI
1239      (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1240               (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1241   ""
1242   "@
1243   add\\t%w0, %w1, %2
1244   add\\t%w0, %w1, %w2
1245   sub\\t%w0, %w1, #%n2"
1246   [(set_attr "v8type" "alu")
1247    (set_attr "mode" "SI")]
1250 (define_insn "*adddi3_aarch64"
1251   [(set
1252     (match_operand:DI 0 "register_operand" "=rk,rk,rk,!w")
1253     (plus:DI
1254      (match_operand:DI 1 "register_operand" "%rk,rk,rk,!w")
1255      (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,!w")))]
1256   ""
1257   "@
1258   add\\t%x0, %x1, %2
1259   add\\t%x0, %x1, %x2
1260   sub\\t%x0, %x1, #%n2
1261   add\\t%d0, %d1, %d2"
1262   [(set_attr "v8type" "alu")
1263    (set_attr "mode" "DI")
1264    (set_attr "simd" "*,*,*,yes")]
1267 (define_insn "*add<mode>3_compare0"
1268   [(set (reg:CC_NZ CC_REGNUM)
1269         (compare:CC_NZ
1270          (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r")
1271                    (match_operand:GPI 2 "aarch64_plus_operand" "rI,J"))
1272          (const_int 0)))
1273    (set (match_operand:GPI 0 "register_operand" "=r,r")
1274         (plus:GPI (match_dup 1) (match_dup 2)))]
1275   ""
1276   "@
1277   adds\\t%<w>0, %<w>1, %<w>2
1278   subs\\t%<w>0, %<w>1, #%n2"
1279   [(set_attr "v8type" "alus")
1280    (set_attr "mode" "<MODE>")]
1283 ;; zero_extend version of above
1284 (define_insn "*addsi3_compare0_uxtw"
1285   [(set (reg:CC_NZ CC_REGNUM)
1286         (compare:CC_NZ
1287          (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
1288                   (match_operand:SI 2 "aarch64_plus_operand" "rI,J"))
1289          (const_int 0)))
1290    (set (match_operand:DI 0 "register_operand" "=r,r")
1291         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1292   ""
1293   "@
1294   adds\\t%w0, %w1, %w2
1295   subs\\t%w0, %w1, #%n2"
1296   [(set_attr "v8type" "alus")
1297    (set_attr "mode" "SI")]
1300 (define_insn "*adds_mul_imm_<mode>"
1301   [(set (reg:CC_NZ CC_REGNUM)
1302         (compare:CC_NZ
1303          (plus:GPI (mult:GPI
1304                     (match_operand:GPI 1 "register_operand" "r")
1305                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1306                    (match_operand:GPI 3 "register_operand" "rk"))
1307          (const_int 0)))
1308    (set (match_operand:GPI 0 "register_operand" "=r")
1309         (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1310                   (match_dup 3)))]
1311   ""
1312   "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1313   [(set_attr "v8type" "alus_shift")
1314    (set_attr "mode" "<MODE>")]
1317 (define_insn "*subs_mul_imm_<mode>"
1318   [(set (reg:CC_NZ CC_REGNUM)
1319         (compare:CC_NZ
1320          (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
1321                     (mult:GPI
1322                      (match_operand:GPI 2 "register_operand" "r")
1323                      (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1324          (const_int 0)))
1325    (set (match_operand:GPI 0 "register_operand" "=r")
1326         (minus:GPI (match_dup 1)
1327                    (mult:GPI (match_dup 2) (match_dup 3))))]
1328   ""
1329   "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1330   [(set_attr "v8type" "alus_shift")
1331    (set_attr "mode" "<MODE>")]
1334 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1335   [(set (reg:CC_NZ CC_REGNUM)
1336         (compare:CC_NZ
1337          (plus:GPI
1338           (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1339           (match_operand:GPI 2 "register_operand" "r"))
1340         (const_int 0)))
1341    (set (match_operand:GPI 0 "register_operand" "=r")
1342         (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1343   ""
1344   "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1345   [(set_attr "v8type" "alus_ext")
1346    (set_attr "mode" "<GPI:MODE>")]
1349 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1350   [(set (reg:CC_NZ CC_REGNUM)
1351         (compare:CC_NZ
1352          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1353                     (ANY_EXTEND:GPI
1354                      (match_operand:ALLX 2 "register_operand" "r")))
1355         (const_int 0)))
1356    (set (match_operand:GPI 0 "register_operand" "=r")
1357         (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1358   ""
1359   "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1360   [(set_attr "v8type" "alus_ext")
1361    (set_attr "mode" "<GPI:MODE>")]
1364 (define_insn "*adds_<optab><mode>_multp2"
1365   [(set (reg:CC_NZ CC_REGNUM)
1366         (compare:CC_NZ
1367          (plus:GPI (ANY_EXTRACT:GPI
1368                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1369                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1370                     (match_operand 3 "const_int_operand" "n")
1371                     (const_int 0))
1372                    (match_operand:GPI 4 "register_operand" "r"))
1373         (const_int 0)))
1374    (set (match_operand:GPI 0 "register_operand" "=r")
1375         (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1376                                    (match_dup 3)
1377                                    (const_int 0))
1378                   (match_dup 4)))]
1379   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1380   "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1381   [(set_attr "v8type" "alus_ext")
1382    (set_attr "mode" "<MODE>")]
1385 (define_insn "*subs_<optab><mode>_multp2"
1386   [(set (reg:CC_NZ CC_REGNUM)
1387         (compare:CC_NZ
1388          (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1389                     (ANY_EXTRACT:GPI
1390                      (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1391                                (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1392                      (match_operand 3 "const_int_operand" "n")
1393                      (const_int 0)))
1394         (const_int 0)))
1395    (set (match_operand:GPI 0 "register_operand" "=r")
1396         (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1397                                   (mult:GPI (match_dup 1) (match_dup 2))
1398                                   (match_dup 3)
1399                                   (const_int 0))))]
1400   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1401   "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1402   [(set_attr "v8type" "alus_ext")
1403    (set_attr "mode" "<MODE>")]
1406 (define_insn "*add<mode>3nr_compare0"
1407   [(set (reg:CC_NZ CC_REGNUM)
1408         (compare:CC_NZ
1409          (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r")
1410                    (match_operand:GPI 1 "aarch64_plus_operand" "rI,J"))
1411          (const_int 0)))]
1412   ""
1413   "@
1414   cmn\\t%<w>0, %<w>1
1415   cmp\\t%<w>0, #%n1"
1416   [(set_attr "v8type" "alus")
1417    (set_attr "mode" "<MODE>")]
1420 (define_insn "*compare_neg<mode>"
1421   [(set (reg:CC CC_REGNUM)
1422         (compare:CC
1423          (match_operand:GPI 0 "register_operand" "r")
1424          (neg:GPI (match_operand:GPI 1 "register_operand" "r"))))]
1425   ""
1426   "cmn\\t%<w>0, %<w>1"
1427   [(set_attr "v8type" "alus")
1428    (set_attr "mode" "<MODE>")]
1431 (define_insn "*add_<shift>_<mode>"
1432   [(set (match_operand:GPI 0 "register_operand" "=rk")
1433         (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1434                               (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1435                   (match_operand:GPI 3 "register_operand" "r")))]
1436   ""
1437   "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1438   [(set_attr "v8type" "alu_shift")
1439    (set_attr "mode" "<MODE>")]
1442 ;; zero_extend version of above
1443 (define_insn "*add_<shift>_si_uxtw"
1444   [(set (match_operand:DI 0 "register_operand" "=rk")
1445         (zero_extend:DI
1446          (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1447                              (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1448                   (match_operand:SI 3 "register_operand" "r"))))]
1449   ""
1450   "add\\t%w0, %w3, %w1, <shift> %2"
1451   [(set_attr "v8type" "alu_shift")
1452    (set_attr "mode" "SI")]
1455 (define_insn "*add_mul_imm_<mode>"
1456   [(set (match_operand:GPI 0 "register_operand" "=rk")
1457         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1458                             (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1459                   (match_operand:GPI 3 "register_operand" "r")))]
1460   ""
1461   "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1462   [(set_attr "v8type" "alu_shift")
1463    (set_attr "mode" "<MODE>")]
1466 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1467   [(set (match_operand:GPI 0 "register_operand" "=rk")
1468         (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1469                   (match_operand:GPI 2 "register_operand" "r")))]
1470   ""
1471   "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1472   [(set_attr "v8type" "alu_ext")
1473    (set_attr "mode" "<GPI:MODE>")]
1476 ;; zero_extend version of above
1477 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1478   [(set (match_operand:DI 0 "register_operand" "=rk")
1479         (zero_extend:DI
1480          (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1481                   (match_operand:GPI 2 "register_operand" "r"))))]
1482   ""
1483   "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1484   [(set_attr "v8type" "alu_ext")
1485    (set_attr "mode" "SI")]
1488 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1489   [(set (match_operand:GPI 0 "register_operand" "=rk")
1490         (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1491                                (match_operand:ALLX 1 "register_operand" "r"))
1492                               (match_operand 2 "aarch64_imm3" "Ui3"))
1493                   (match_operand:GPI 3 "register_operand" "r")))]
1494   ""
1495   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1496   [(set_attr "v8type" "alu_ext")
1497    (set_attr "mode" "<GPI:MODE>")]
1500 ;; zero_extend version of above
1501 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1502   [(set (match_operand:DI 0 "register_operand" "=rk")
1503         (zero_extend:DI
1504          (plus:SI (ashift:SI (ANY_EXTEND:SI
1505                               (match_operand:SHORT 1 "register_operand" "r"))
1506                              (match_operand 2 "aarch64_imm3" "Ui3"))
1507                   (match_operand:SI 3 "register_operand" "r"))))]
1508   ""
1509   "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1510   [(set_attr "v8type" "alu_ext")
1511    (set_attr "mode" "SI")]
1514 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1515   [(set (match_operand:GPI 0 "register_operand" "=rk")
1516         (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1517                              (match_operand:ALLX 1 "register_operand" "r"))
1518                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1519                   (match_operand:GPI 3 "register_operand" "r")))]
1520   ""
1521   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1522   [(set_attr "v8type" "alu_ext")
1523    (set_attr "mode" "<GPI:MODE>")]
1526 ;; zero_extend version of above
1527 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1528   [(set (match_operand:DI 0 "register_operand" "=rk")
1529         (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1530                              (match_operand:SHORT 1 "register_operand" "r"))
1531                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1532                   (match_operand:SI 3 "register_operand" "r"))))]
1533   ""
1534   "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1535   [(set_attr "v8type" "alu_ext")
1536    (set_attr "mode" "SI")]
1539 (define_insn "*add_<optab><mode>_multp2"
1540   [(set (match_operand:GPI 0 "register_operand" "=rk")
1541         (plus:GPI (ANY_EXTRACT:GPI
1542                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1543                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1544                    (match_operand 3 "const_int_operand" "n")
1545                    (const_int 0))
1546                   (match_operand:GPI 4 "register_operand" "r")))]
1547   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1548   "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1549   [(set_attr "v8type" "alu_ext")
1550    (set_attr "mode" "<MODE>")]
1553 ;; zero_extend version of above
1554 (define_insn "*add_<optab>si_multp2_uxtw"
1555   [(set (match_operand:DI 0 "register_operand" "=rk")
1556         (zero_extend:DI
1557          (plus:SI (ANY_EXTRACT:SI
1558                    (mult:SI (match_operand:SI 1 "register_operand" "r")
1559                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1560                    (match_operand 3 "const_int_operand" "n")
1561                    (const_int 0))
1562                   (match_operand:SI 4 "register_operand" "r"))))]
1563   "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1564   "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1565   [(set_attr "v8type" "alu_ext")
1566    (set_attr "mode" "SI")]
1569 (define_insn "*add<mode>3_carryin"
1570   [(set
1571     (match_operand:GPI 0 "register_operand" "=r")
1572     (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1573               (plus:GPI
1574                 (match_operand:GPI 1 "register_operand" "r")
1575                 (match_operand:GPI 2 "register_operand" "r"))))]
1576    ""
1577    "adc\\t%<w>0, %<w>1, %<w>2"
1578   [(set_attr "v8type" "adc")
1579    (set_attr "mode" "<MODE>")]
1582 ;; zero_extend version of above
1583 (define_insn "*addsi3_carryin_uxtw"
1584   [(set
1585     (match_operand:DI 0 "register_operand" "=r")
1586     (zero_extend:DI
1587      (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1588               (plus:SI
1589                (match_operand:SI 1 "register_operand" "r")
1590                (match_operand:SI 2 "register_operand" "r")))))]
1591    ""
1592    "adc\\t%w0, %w1, %w2"
1593   [(set_attr "v8type" "adc")
1594    (set_attr "mode" "SI")]
1597 (define_insn "*add<mode>3_carryin_alt1"
1598   [(set
1599     (match_operand:GPI 0 "register_operand" "=r")
1600     (plus:GPI (plus:GPI
1601                 (match_operand:GPI 1 "register_operand" "r")
1602                 (match_operand:GPI 2 "register_operand" "r"))
1603               (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1604    ""
1605    "adc\\t%<w>0, %<w>1, %<w>2"
1606   [(set_attr "v8type" "adc")
1607    (set_attr "mode" "<MODE>")]
1610 ;; zero_extend version of above
1611 (define_insn "*addsi3_carryin_alt1_uxtw"
1612   [(set
1613     (match_operand:DI 0 "register_operand" "=r")
1614     (zero_extend:DI
1615      (plus:SI (plus:SI
1616                (match_operand:SI 1 "register_operand" "r")
1617                (match_operand:SI 2 "register_operand" "r"))
1618               (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1619    ""
1620    "adc\\t%w0, %w1, %w2"
1621   [(set_attr "v8type" "adc")
1622    (set_attr "mode" "SI")]
1625 (define_insn "*add<mode>3_carryin_alt2"
1626   [(set
1627     (match_operand:GPI 0 "register_operand" "=r")
1628     (plus:GPI (plus:GPI
1629                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1630                 (match_operand:GPI 1 "register_operand" "r"))
1631               (match_operand:GPI 2 "register_operand" "r")))]
1632    ""
1633    "adc\\t%<w>0, %<w>1, %<w>2"
1634   [(set_attr "v8type" "adc")
1635    (set_attr "mode" "<MODE>")]
1638 ;; zero_extend version of above
1639 (define_insn "*addsi3_carryin_alt2_uxtw"
1640   [(set
1641     (match_operand:DI 0 "register_operand" "=r")
1642     (zero_extend:DI
1643      (plus:SI (plus:SI
1644                (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1645                (match_operand:SI 1 "register_operand" "r"))
1646               (match_operand:SI 2 "register_operand" "r"))))]
1647    ""
1648    "adc\\t%w0, %w1, %w2"
1649   [(set_attr "v8type" "adc")
1650    (set_attr "mode" "SI")]
1653 (define_insn "*add<mode>3_carryin_alt3"
1654   [(set
1655     (match_operand:GPI 0 "register_operand" "=r")
1656     (plus:GPI (plus:GPI
1657                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1658                 (match_operand:GPI 2 "register_operand" "r"))
1659               (match_operand:GPI 1 "register_operand" "r")))]
1660    ""
1661    "adc\\t%<w>0, %<w>1, %<w>2"
1662   [(set_attr "v8type" "adc")
1663    (set_attr "mode" "<MODE>")]
1666 ;; zero_extend version of above
1667 (define_insn "*addsi3_carryin_alt3_uxtw"
1668   [(set
1669     (match_operand:DI 0 "register_operand" "=r")
1670     (zero_extend:DI
1671      (plus:SI (plus:SI
1672                (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1673                (match_operand:SI 2 "register_operand" "r"))
1674               (match_operand:SI 1 "register_operand" "r"))))]
1675    ""
1676    "adc\\t%w0, %w1, %w2"
1677   [(set_attr "v8type" "adc")
1678    (set_attr "mode" "SI")]
1681 (define_insn "*add_uxt<mode>_multp2"
1682   [(set (match_operand:GPI 0 "register_operand" "=rk")
1683         (plus:GPI (and:GPI
1684                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1685                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1686                    (match_operand 3 "const_int_operand" "n"))
1687                   (match_operand:GPI 4 "register_operand" "r")))]
1688   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1689   "*
1690   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1691                                            INTVAL (operands[3])));
1692   return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1693   [(set_attr "v8type" "alu_ext")
1694    (set_attr "mode" "<MODE>")]
1697 ;; zero_extend version of above
1698 (define_insn "*add_uxtsi_multp2_uxtw"
1699   [(set (match_operand:DI 0 "register_operand" "=rk")
1700         (zero_extend:DI
1701          (plus:SI (and:SI
1702                    (mult:SI (match_operand:SI 1 "register_operand" "r")
1703                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1704                    (match_operand 3 "const_int_operand" "n"))
1705                   (match_operand:SI 4 "register_operand" "r"))))]
1706   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1707   "*
1708   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1709                                            INTVAL (operands[3])));
1710   return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1711   [(set_attr "v8type" "alu_ext")
1712    (set_attr "mode" "SI")]
1715 (define_insn "subsi3"
1716   [(set (match_operand:SI 0 "register_operand" "=rk")
1717         (minus:SI (match_operand:SI 1 "register_operand" "r")
1718                    (match_operand:SI 2 "register_operand" "r")))]
1719   ""
1720   "sub\\t%w0, %w1, %w2"
1721   [(set_attr "v8type" "alu")
1722    (set_attr "mode" "SI")]
1725 ;; zero_extend version of above
1726 (define_insn "*subsi3_uxtw"
1727   [(set (match_operand:DI 0 "register_operand" "=rk")
1728         (zero_extend:DI
1729          (minus:SI (match_operand:SI 1 "register_operand" "r")
1730                    (match_operand:SI 2 "register_operand" "r"))))]
1731   ""
1732   "sub\\t%w0, %w1, %w2"
1733   [(set_attr "v8type" "alu")
1734    (set_attr "mode" "SI")]
1737 (define_insn "subdi3"
1738   [(set (match_operand:DI 0 "register_operand" "=rk,!w")
1739         (minus:DI (match_operand:DI 1 "register_operand" "r,!w")
1740                    (match_operand:DI 2 "register_operand" "r,!w")))]
1741   ""
1742   "@
1743    sub\\t%x0, %x1, %x2
1744    sub\\t%d0, %d1, %d2"
1745   [(set_attr "v8type" "alu")
1746    (set_attr "mode" "DI")
1747    (set_attr "simd" "*,yes")]
1751 (define_insn "*sub<mode>3_compare0"
1752   [(set (reg:CC_NZ CC_REGNUM)
1753         (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1754                                   (match_operand:GPI 2 "register_operand" "r"))
1755                        (const_int 0)))
1756    (set (match_operand:GPI 0 "register_operand" "=r")
1757         (minus:GPI (match_dup 1) (match_dup 2)))]
1758   ""
1759   "subs\\t%<w>0, %<w>1, %<w>2"
1760   [(set_attr "v8type" "alus")
1761    (set_attr "mode" "<MODE>")]
1764 ;; zero_extend version of above
1765 (define_insn "*subsi3_compare0_uxtw"
1766   [(set (reg:CC_NZ CC_REGNUM)
1767         (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1768                                  (match_operand:SI 2 "register_operand" "r"))
1769                        (const_int 0)))
1770    (set (match_operand:DI 0 "register_operand" "=r")
1771         (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1772   ""
1773   "subs\\t%w0, %w1, %w2"
1774   [(set_attr "v8type" "alus")
1775    (set_attr "mode" "SI")]
1778 (define_insn "*sub_<shift>_<mode>"
1779   [(set (match_operand:GPI 0 "register_operand" "=rk")
1780         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1781                    (ASHIFT:GPI
1782                     (match_operand:GPI 1 "register_operand" "r")
1783                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1784   ""
1785   "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1786   [(set_attr "v8type" "alu_shift")
1787    (set_attr "mode" "<MODE>")]
1790 ;; zero_extend version of above
1791 (define_insn "*sub_<shift>_si_uxtw"
1792   [(set (match_operand:DI 0 "register_operand" "=rk")
1793         (zero_extend:DI
1794          (minus:SI (match_operand:SI 3 "register_operand" "r")
1795                    (ASHIFT:SI
1796                     (match_operand:SI 1 "register_operand" "r")
1797                     (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1798   ""
1799   "sub\\t%w0, %w3, %w1, <shift> %2"
1800   [(set_attr "v8type" "alu_shift")
1801    (set_attr "mode" "SI")]
1804 (define_insn "*sub_mul_imm_<mode>"
1805   [(set (match_operand:GPI 0 "register_operand" "=rk")
1806         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1807                    (mult:GPI
1808                     (match_operand:GPI 1 "register_operand" "r")
1809                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1810   ""
1811   "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1812   [(set_attr "v8type" "alu_shift")
1813    (set_attr "mode" "<MODE>")]
1816 ;; zero_extend version of above
1817 (define_insn "*sub_mul_imm_si_uxtw"
1818   [(set (match_operand:DI 0 "register_operand" "=rk")
1819         (zero_extend:DI
1820          (minus:SI (match_operand:SI 3 "register_operand" "r")
1821                    (mult:SI
1822                     (match_operand:SI 1 "register_operand" "r")
1823                     (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
1824   ""
1825   "sub\\t%w0, %w3, %w1, lsl %p2"
1826   [(set_attr "v8type" "alu_shift")
1827    (set_attr "mode" "SI")]
1830 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
1831   [(set (match_operand:GPI 0 "register_operand" "=rk")
1832         (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1833                    (ANY_EXTEND:GPI
1834                     (match_operand:ALLX 2 "register_operand" "r"))))]
1835   ""
1836   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1837   [(set_attr "v8type" "alu_ext")
1838    (set_attr "mode" "<GPI:MODE>")]
1841 ;; zero_extend version of above
1842 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
1843   [(set (match_operand:DI 0 "register_operand" "=rk")
1844         (zero_extend:DI
1845          (minus:SI (match_operand:SI 1 "register_operand" "r")
1846                    (ANY_EXTEND:SI
1847                     (match_operand:SHORT 2 "register_operand" "r")))))]
1848   ""
1849   "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
1850   [(set_attr "v8type" "alu_ext")
1851    (set_attr "mode" "SI")]
1854 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
1855   [(set (match_operand:GPI 0 "register_operand" "=rk")
1856         (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1857                    (ashift:GPI (ANY_EXTEND:GPI
1858                                 (match_operand:ALLX 2 "register_operand" "r"))
1859                                (match_operand 3 "aarch64_imm3" "Ui3"))))]
1860   ""
1861   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1862   [(set_attr "v8type" "alu_ext")
1863    (set_attr "mode" "<GPI:MODE>")]
1866 ;; zero_extend version of above
1867 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
1868   [(set (match_operand:DI 0 "register_operand" "=rk")
1869         (zero_extend:DI
1870          (minus:SI (match_operand:SI 1 "register_operand" "r")
1871                    (ashift:SI (ANY_EXTEND:SI
1872                                (match_operand:SHORT 2 "register_operand" "r"))
1873                               (match_operand 3 "aarch64_imm3" "Ui3")))))]
1874   ""
1875   "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
1876   [(set_attr "v8type" "alu_ext")
1877    (set_attr "mode" "SI")]
1880 (define_insn "*sub_<optab><mode>_multp2"
1881   [(set (match_operand:GPI 0 "register_operand" "=rk")
1882         (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1883                    (ANY_EXTRACT:GPI
1884                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1885                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1886                     (match_operand 3 "const_int_operand" "n")
1887                     (const_int 0))))]
1888   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1889   "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1890   [(set_attr "v8type" "alu_ext")
1891    (set_attr "mode" "<MODE>")]
1894 ;; zero_extend version of above
1895 (define_insn "*sub_<optab>si_multp2_uxtw"
1896   [(set (match_operand:DI 0 "register_operand" "=rk")
1897         (zero_extend:DI
1898          (minus:SI (match_operand:SI 4 "register_operand" "r")
1899                    (ANY_EXTRACT:SI
1900                     (mult:SI (match_operand:SI 1 "register_operand" "r")
1901                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1902                     (match_operand 3 "const_int_operand" "n")
1903                     (const_int 0)))))]
1904   "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1905   "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1906   [(set_attr "v8type" "alu_ext")
1907    (set_attr "mode" "SI")]
1910 (define_insn "*sub<mode>3_carryin"
1911   [(set
1912     (match_operand:GPI 0 "register_operand" "=r")
1913     (minus:GPI (minus:GPI
1914                 (match_operand:GPI 1 "register_operand" "r")
1915                 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
1916                (match_operand:GPI 2 "register_operand" "r")))]
1917    ""
1918    "sbc\\t%<w>0, %<w>1, %<w>2"
1919   [(set_attr "v8type" "adc")
1920    (set_attr "mode" "<MODE>")]
1923 ;; zero_extend version of the above
1924 (define_insn "*subsi3_carryin_uxtw"
1925   [(set
1926     (match_operand:DI 0 "register_operand" "=r")
1927     (zero_extend:DI
1928      (minus:SI (minus:SI
1929                 (match_operand:SI 1 "register_operand" "r")
1930                 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
1931                (match_operand:SI 2 "register_operand" "r"))))]
1932    ""
1933    "sbc\\t%w0, %w1, %w2"
1934   [(set_attr "v8type" "adc")
1935    (set_attr "mode" "SI")]
1938 (define_insn "*sub_uxt<mode>_multp2"
1939   [(set (match_operand:GPI 0 "register_operand" "=rk")
1940         (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1941                    (and:GPI
1942                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1943                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1944                     (match_operand 3 "const_int_operand" "n"))))]
1945   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1946   "*
1947   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1948                                            INTVAL (operands[3])));
1949   return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1950   [(set_attr "v8type" "alu_ext")
1951    (set_attr "mode" "<MODE>")]
1954 ;; zero_extend version of above
1955 (define_insn "*sub_uxtsi_multp2_uxtw"
1956   [(set (match_operand:DI 0 "register_operand" "=rk")
1957         (zero_extend:DI
1958          (minus:SI (match_operand:SI 4 "register_operand" "r")
1959                    (and:SI
1960                     (mult:SI (match_operand:SI 1 "register_operand" "r")
1961                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1962                     (match_operand 3 "const_int_operand" "n")))))]
1963   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1964   "*
1965   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1966                                            INTVAL (operands[3])));
1967   return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
1968   [(set_attr "v8type" "alu_ext")
1969    (set_attr "mode" "SI")]
1972 (define_insn "neg<mode>2"
1973   [(set (match_operand:GPI 0 "register_operand" "=r")
1974         (neg:GPI (match_operand:GPI 1 "register_operand" "r")))]
1975   ""
1976   "neg\\t%<w>0, %<w>1"
1977   [(set_attr "v8type" "alu")
1978    (set_attr "mode" "<MODE>")]
1981 ;; zero_extend version of above
1982 (define_insn "*negsi2_uxtw"
1983   [(set (match_operand:DI 0 "register_operand" "=r")
1984         (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
1985   ""
1986   "neg\\t%w0, %w1"
1987   [(set_attr "v8type" "alu")
1988    (set_attr "mode" "SI")]
1991 (define_insn "*neg<mode>2_compare0"
1992   [(set (reg:CC_NZ CC_REGNUM)
1993         (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
1994                        (const_int 0)))
1995    (set (match_operand:GPI 0 "register_operand" "=r")
1996         (neg:GPI (match_dup 1)))]
1997   ""
1998   "negs\\t%<w>0, %<w>1"
1999   [(set_attr "v8type" "alus")
2000    (set_attr "mode" "<MODE>")]
2003 ;; zero_extend version of above
2004 (define_insn "*negsi2_compare0_uxtw"
2005   [(set (reg:CC_NZ CC_REGNUM)
2006         (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
2007                        (const_int 0)))
2008    (set (match_operand:DI 0 "register_operand" "=r")
2009         (zero_extend:DI (neg:SI (match_dup 1))))]
2010   ""
2011   "negs\\t%w0, %w1"
2012   [(set_attr "v8type" "alus")
2013    (set_attr "mode" "SI")]
2016 (define_insn "*neg_<shift><mode>3_compare0"
2017   [(set (reg:CC_NZ CC_REGNUM)
2018         (compare:CC_NZ
2019          (neg:GPI (ASHIFT:GPI
2020                    (match_operand:GPI 1 "register_operand" "r")
2021                    (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2022          (const_int 0)))
2023    (set (match_operand:GPI 0 "register_operand" "=r")
2024         (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2025   ""
2026   "negs\\t%<w>0, %<w>1, <shift> %2"
2027   [(set_attr "v8type" "alus_shift")
2028    (set_attr "mode" "<MODE>")]
2031 (define_insn "*neg_<shift>_<mode>2"
2032   [(set (match_operand:GPI 0 "register_operand" "=r")
2033         (neg:GPI (ASHIFT:GPI
2034                   (match_operand:GPI 1 "register_operand" "r")
2035                   (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2036   ""
2037   "neg\\t%<w>0, %<w>1, <shift> %2"
2038   [(set_attr "v8type" "alu_shift")
2039    (set_attr "mode" "<MODE>")]
2042 ;; zero_extend version of above
2043 (define_insn "*neg_<shift>_si2_uxtw"
2044   [(set (match_operand:DI 0 "register_operand" "=r")
2045         (zero_extend:DI
2046          (neg:SI (ASHIFT:SI
2047                   (match_operand:SI 1 "register_operand" "r")
2048                   (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2049   ""
2050   "neg\\t%w0, %w1, <shift> %2"
2051   [(set_attr "v8type" "alu_shift")
2052    (set_attr "mode" "SI")]
2055 (define_insn "*neg_mul_imm_<mode>2"
2056   [(set (match_operand:GPI 0 "register_operand" "=r")
2057         (neg:GPI (mult:GPI
2058                   (match_operand:GPI 1 "register_operand" "r")
2059                   (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2060   ""
2061   "neg\\t%<w>0, %<w>1, lsl %p2"
2062   [(set_attr "v8type" "alu_shift")
2063    (set_attr "mode" "<MODE>")]
2066 ;; zero_extend version of above
2067 (define_insn "*neg_mul_imm_si2_uxtw"
2068   [(set (match_operand:DI 0 "register_operand" "=r")
2069         (zero_extend:DI
2070          (neg:SI (mult:SI
2071                   (match_operand:SI 1 "register_operand" "r")
2072                   (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2073   ""
2074   "neg\\t%w0, %w1, lsl %p2"
2075   [(set_attr "v8type" "alu_shift")
2076    (set_attr "mode" "SI")]
2079 (define_insn "mul<mode>3"
2080   [(set (match_operand:GPI 0 "register_operand" "=r")
2081         (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2082                   (match_operand:GPI 2 "register_operand" "r")))]
2083   ""
2084   "mul\\t%<w>0, %<w>1, %<w>2"
2085   [(set_attr "v8type" "mult")
2086    (set_attr "mode" "<MODE>")]
2089 ;; zero_extend version of above
2090 (define_insn "*mulsi3_uxtw"
2091   [(set (match_operand:DI 0 "register_operand" "=r")
2092         (zero_extend:DI
2093          (mult:SI (match_operand:SI 1 "register_operand" "r")
2094                   (match_operand:SI 2 "register_operand" "r"))))]
2095   ""
2096   "mul\\t%w0, %w1, %w2"
2097   [(set_attr "v8type" "mult")
2098    (set_attr "mode" "SI")]
2101 (define_insn "*madd<mode>"
2102   [(set (match_operand:GPI 0 "register_operand" "=r")
2103         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2104                             (match_operand:GPI 2 "register_operand" "r"))
2105                   (match_operand:GPI 3 "register_operand" "r")))]
2106   ""
2107   "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2108   [(set_attr "v8type" "madd")
2109    (set_attr "mode" "<MODE>")]
2112 ;; zero_extend version of above
2113 (define_insn "*maddsi_uxtw"
2114   [(set (match_operand:DI 0 "register_operand" "=r")
2115         (zero_extend:DI
2116          (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2117                            (match_operand:SI 2 "register_operand" "r"))
2118                   (match_operand:SI 3 "register_operand" "r"))))]
2119   ""
2120   "madd\\t%w0, %w1, %w2, %w3"
2121   [(set_attr "v8type" "madd")
2122    (set_attr "mode" "SI")]
2125 (define_insn "*msub<mode>"
2126   [(set (match_operand:GPI 0 "register_operand" "=r")
2127         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2128                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2129                              (match_operand:GPI 2 "register_operand" "r"))))]
2131   ""
2132   "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2133   [(set_attr "v8type" "madd")
2134    (set_attr "mode" "<MODE>")]
2137 ;; zero_extend version of above
2138 (define_insn "*msubsi_uxtw"
2139   [(set (match_operand:DI 0 "register_operand" "=r")
2140         (zero_extend:DI
2141          (minus:SI (match_operand:SI 3 "register_operand" "r")
2142                    (mult:SI (match_operand:SI 1 "register_operand" "r")
2143                             (match_operand:SI 2 "register_operand" "r")))))]
2145   ""
2146   "msub\\t%w0, %w1, %w2, %w3"
2147   [(set_attr "v8type" "madd")
2148    (set_attr "mode" "SI")]
2151 (define_insn "*mul<mode>_neg"
2152   [(set (match_operand:GPI 0 "register_operand" "=r")
2153         (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2154                   (match_operand:GPI 2 "register_operand" "r")))]
2156   ""
2157   "mneg\\t%<w>0, %<w>1, %<w>2"
2158   [(set_attr "v8type" "mult")
2159    (set_attr "mode" "<MODE>")]
2162 ;; zero_extend version of above
2163 (define_insn "*mulsi_neg_uxtw"
2164   [(set (match_operand:DI 0 "register_operand" "=r")
2165         (zero_extend:DI
2166          (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2167                   (match_operand:SI 2 "register_operand" "r"))))]
2169   ""
2170   "mneg\\t%w0, %w1, %w2"
2171   [(set_attr "v8type" "mult")
2172    (set_attr "mode" "SI")]
2175 (define_insn "<su_optab>mulsidi3"
2176   [(set (match_operand:DI 0 "register_operand" "=r")
2177         (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2178                  (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2179   ""
2180   "<su>mull\\t%0, %w1, %w2"
2181   [(set_attr "v8type" "mull")
2182    (set_attr "mode" "DI")]
2185 (define_insn "<su_optab>maddsidi4"
2186   [(set (match_operand:DI 0 "register_operand" "=r")
2187         (plus:DI (mult:DI
2188                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2189                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2190                  (match_operand:DI 3 "register_operand" "r")))]
2191   ""
2192   "<su>maddl\\t%0, %w1, %w2, %3"
2193   [(set_attr "v8type" "maddl")
2194    (set_attr "mode" "DI")]
2197 (define_insn "<su_optab>msubsidi4"
2198   [(set (match_operand:DI 0 "register_operand" "=r")
2199         (minus:DI
2200          (match_operand:DI 3 "register_operand" "r")
2201          (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2202                   (ANY_EXTEND:DI
2203                    (match_operand:SI 2 "register_operand" "r")))))]
2204   ""
2205   "<su>msubl\\t%0, %w1, %w2, %3"
2206   [(set_attr "v8type" "maddl")
2207    (set_attr "mode" "DI")]
2210 (define_insn "*<su_optab>mulsidi_neg"
2211   [(set (match_operand:DI 0 "register_operand" "=r")
2212         (mult:DI (neg:DI
2213                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2214                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2215   ""
2216   "<su>mnegl\\t%0, %w1, %w2"
2217   [(set_attr "v8type" "mull")
2218    (set_attr "mode" "DI")]
2221 (define_insn "<su>muldi3_highpart"
2222   [(set (match_operand:DI 0 "register_operand" "=r")
2223         (truncate:DI
2224          (lshiftrt:TI
2225           (mult:TI
2226            (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2227            (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2228           (const_int 64))))]
2229   ""
2230   "<su>mulh\\t%0, %1, %2"
2231   [(set_attr "v8type" "mulh")
2232    (set_attr "mode" "DI")]
2235 (define_insn "<su_optab>div<mode>3"
2236   [(set (match_operand:GPI 0 "register_operand" "=r")
2237         (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2238                      (match_operand:GPI 2 "register_operand" "r")))]
2239   ""
2240   "<su>div\\t%<w>0, %<w>1, %<w>2"
2241   [(set_attr "v8type" "<su>div")
2242    (set_attr "mode" "<MODE>")]
2245 ;; zero_extend version of above
2246 (define_insn "*<su_optab>divsi3_uxtw"
2247   [(set (match_operand:DI 0 "register_operand" "=r")
2248         (zero_extend:DI
2249          (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2250                      (match_operand:SI 2 "register_operand" "r"))))]
2251   ""
2252   "<su>div\\t%w0, %w1, %w2"
2253   [(set_attr "v8type" "<su>div")
2254    (set_attr "mode" "SI")]
2257 ;; -------------------------------------------------------------------
2258 ;; Comparison insns
2259 ;; -------------------------------------------------------------------
2261 (define_insn "*cmp<mode>"
2262   [(set (reg:CC CC_REGNUM)
2263         (compare:CC (match_operand:GPI 0 "register_operand" "r,r")
2264                     (match_operand:GPI 1 "aarch64_plus_operand" "rI,J")))]
2265   ""
2266   "@
2267    cmp\\t%<w>0, %<w>1
2268    cmn\\t%<w>0, #%n1"
2269   [(set_attr "v8type" "alus")
2270    (set_attr "mode" "<MODE>")]
2273 (define_insn "*cmp<mode>"
2274   [(set (reg:CCFP CC_REGNUM)
2275         (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2276                       (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2277    "TARGET_FLOAT"
2278    "@
2279     fcmp\\t%<s>0, #0.0
2280     fcmp\\t%<s>0, %<s>1"
2281   [(set_attr "v8type" "fcmp")
2282    (set_attr "mode" "<MODE>")]
2285 (define_insn "*cmpe<mode>"
2286   [(set (reg:CCFPE CC_REGNUM)
2287         (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2288                        (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2289    "TARGET_FLOAT"
2290    "@
2291     fcmpe\\t%<s>0, #0.0
2292     fcmpe\\t%<s>0, %<s>1"
2293   [(set_attr "v8type" "fcmp")
2294    (set_attr "mode" "<MODE>")]
2297 (define_insn "*cmp_swp_<shift>_reg<mode>"
2298   [(set (reg:CC_SWP CC_REGNUM)
2299         (compare:CC_SWP (ASHIFT:GPI
2300                          (match_operand:GPI 0 "register_operand" "r")
2301                          (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2302                         (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2303   ""
2304   "cmp\\t%<w>2, %<w>0, <shift> %1"
2305   [(set_attr "v8type" "alus_shift")
2306    (set_attr "mode" "<MODE>")]
2309 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2310   [(set (reg:CC_SWP CC_REGNUM)
2311         (compare:CC_SWP (ANY_EXTEND:GPI
2312                          (match_operand:ALLX 0 "register_operand" "r"))
2313                         (match_operand:GPI 1 "register_operand" "r")))]
2314   ""
2315   "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2316   [(set_attr "v8type" "alus_ext")
2317    (set_attr "mode" "<GPI:MODE>")]
2321 ;; -------------------------------------------------------------------
2322 ;; Store-flag and conditional select insns
2323 ;; -------------------------------------------------------------------
2325 (define_expand "cstore<mode>4"
2326   [(set (match_operand:SI 0 "register_operand" "")
2327         (match_operator:SI 1 "aarch64_comparison_operator"
2328          [(match_operand:GPI 2 "register_operand" "")
2329           (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2330   ""
2331   "
2332   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2333                                       operands[3]);
2334   operands[3] = const0_rtx;
2335   "
2338 (define_expand "cstore<mode>4"
2339   [(set (match_operand:SI 0 "register_operand" "")
2340         (match_operator:SI 1 "aarch64_comparison_operator"
2341          [(match_operand:GPF 2 "register_operand" "")
2342           (match_operand:GPF 3 "register_operand" "")]))]
2343   ""
2344   "
2345   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2346                                       operands[3]);
2347   operands[3] = const0_rtx;
2348   "
2351 (define_insn "*cstore<mode>_insn"
2352   [(set (match_operand:ALLI 0 "register_operand" "=r")
2353         (match_operator:ALLI 1 "aarch64_comparison_operator"
2354          [(match_operand 2 "cc_register" "") (const_int 0)]))]
2355   ""
2356   "cset\\t%<w>0, %m1"
2357   [(set_attr "v8type" "csel")
2358    (set_attr "mode" "<MODE>")]
2361 ;; zero_extend version of the above
2362 (define_insn "*cstoresi_insn_uxtw"
2363   [(set (match_operand:DI 0 "register_operand" "=r")
2364         (zero_extend:DI
2365          (match_operator:SI 1 "aarch64_comparison_operator"
2366           [(match_operand 2 "cc_register" "") (const_int 0)])))]
2367   ""
2368   "cset\\t%w0, %m1"
2369   [(set_attr "v8type" "csel")
2370    (set_attr "mode" "SI")]
2373 (define_insn "*cstore<mode>_neg"
2374   [(set (match_operand:ALLI 0 "register_operand" "=r")
2375         (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2376                   [(match_operand 2 "cc_register" "") (const_int 0)])))]
2377   ""
2378   "csetm\\t%<w>0, %m1"
2379   [(set_attr "v8type" "csel")
2380    (set_attr "mode" "<MODE>")]
2383 ;; zero_extend version of the above
2384 (define_insn "*cstoresi_neg_uxtw"
2385   [(set (match_operand:DI 0 "register_operand" "=r")
2386         (zero_extend:DI
2387          (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2388                   [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2389   ""
2390   "csetm\\t%w0, %m1"
2391   [(set_attr "v8type" "csel")
2392    (set_attr "mode" "SI")]
2395 (define_expand "cmov<mode>6"
2396   [(set (match_operand:GPI 0 "register_operand" "")
2397         (if_then_else:GPI
2398          (match_operator 1 "aarch64_comparison_operator"
2399           [(match_operand:GPI 2 "register_operand" "")
2400            (match_operand:GPI 3 "aarch64_plus_operand" "")])
2401          (match_operand:GPI 4 "register_operand" "")
2402          (match_operand:GPI 5 "register_operand" "")))]
2403   ""
2404   "
2405   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2406                                       operands[3]);
2407   operands[3] = const0_rtx;
2408   "
2411 (define_expand "cmov<mode>6"
2412   [(set (match_operand:GPF 0 "register_operand" "")
2413         (if_then_else:GPF
2414          (match_operator 1 "aarch64_comparison_operator"
2415           [(match_operand:GPF 2 "register_operand" "")
2416            (match_operand:GPF 3 "register_operand" "")])
2417          (match_operand:GPF 4 "register_operand" "")
2418          (match_operand:GPF 5 "register_operand" "")))]
2419   ""
2420   "
2421   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2422                                       operands[3]);
2423   operands[3] = const0_rtx;
2424   "
2427 (define_insn "*cmov<mode>_insn"
2428   [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2429         (if_then_else:ALLI
2430          (match_operator 1 "aarch64_comparison_operator"
2431           [(match_operand 2 "cc_register" "") (const_int 0)])
2432          (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2433          (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2434   "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2435      || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2436   ;; Final two alternatives should be unreachable, but included for completeness
2437   "@
2438    csel\\t%<w>0, %<w>3, %<w>4, %m1
2439    csinv\\t%<w>0, %<w>3, <w>zr, %m1
2440    csinv\\t%<w>0, %<w>4, <w>zr, %M1
2441    csinc\\t%<w>0, %<w>3, <w>zr, %m1
2442    csinc\\t%<w>0, %<w>4, <w>zr, %M1
2443    mov\\t%<w>0, -1
2444    mov\\t%<w>0, 1"
2445   [(set_attr "v8type" "csel")
2446    (set_attr "mode" "<MODE>")]
2449 ;; zero_extend version of above
2450 (define_insn "*cmovsi_insn_uxtw"
2451   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2452         (zero_extend:DI
2453          (if_then_else:SI
2454           (match_operator 1 "aarch64_comparison_operator"
2455            [(match_operand 2 "cc_register" "") (const_int 0)])
2456           (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2457           (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2458   "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2459      || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2460   ;; Final two alternatives should be unreachable, but included for completeness
2461   "@
2462    csel\\t%w0, %w3, %w4, %m1
2463    csinv\\t%w0, %w3, wzr, %m1
2464    csinv\\t%w0, %w4, wzr, %M1
2465    csinc\\t%w0, %w3, wzr, %m1
2466    csinc\\t%w0, %w4, wzr, %M1
2467    mov\\t%w0, -1
2468    mov\\t%w0, 1"
2469   [(set_attr "v8type" "csel")
2470    (set_attr "mode" "SI")]
2473 (define_insn "*cmov<mode>_insn"
2474   [(set (match_operand:GPF 0 "register_operand" "=w")
2475         (if_then_else:GPF
2476          (match_operator 1 "aarch64_comparison_operator"
2477           [(match_operand 2 "cc_register" "") (const_int 0)])
2478          (match_operand:GPF 3 "register_operand" "w")
2479          (match_operand:GPF 4 "register_operand" "w")))]
2480   "TARGET_FLOAT"
2481   "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2482   [(set_attr "v8type" "fcsel")
2483    (set_attr "mode" "<MODE>")]
2486 (define_expand "mov<mode>cc"
2487   [(set (match_operand:ALLI 0 "register_operand" "")
2488         (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2489                            (match_operand:ALLI 2 "register_operand" "")
2490                            (match_operand:ALLI 3 "register_operand" "")))]
2491   ""
2492   {
2493     rtx ccreg;
2494     enum rtx_code code = GET_CODE (operands[1]);
2496     if (code == UNEQ || code == LTGT)
2497       FAIL;
2499     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2500                                   XEXP (operands[1], 1));
2501     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2502   }
2505 (define_expand "mov<GPF:mode><GPI:mode>cc"
2506   [(set (match_operand:GPI 0 "register_operand" "")
2507         (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2508                           (match_operand:GPF 2 "register_operand" "")
2509                           (match_operand:GPF 3 "register_operand" "")))]
2510   ""
2511   {
2512     rtx ccreg;
2513     enum rtx_code code = GET_CODE (operands[1]);
2515     if (code == UNEQ || code == LTGT)
2516       FAIL;
2518     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2519                                   XEXP (operands[1], 1));
2520     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2521   }
2524 (define_insn "*csinc2<mode>_insn"
2525   [(set (match_operand:GPI 0 "register_operand" "=r")
2526         (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator"
2527                   [(match_operand:CC 3 "cc_register" "") (const_int 0)])
2528                  (match_operand:GPI 1 "register_operand" "r")))]
2529   ""
2530   "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2531   [(set_attr "v8type" "csel")
2532    (set_attr "mode" "<MODE>")])
2534 (define_insn "csinc3<mode>_insn"
2535   [(set (match_operand:GPI 0 "register_operand" "=r")
2536         (if_then_else:GPI
2537           (match_operator:GPI 1 "aarch64_comparison_operator"
2538            [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2539           (plus:GPI (match_operand:GPI 3 "register_operand" "r")
2540                     (const_int 1))
2541           (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2542   ""
2543   "csinc\\t%<w>0, %<w>4, %<w>3, %M1"
2544   [(set_attr "v8type" "csel")
2545    (set_attr "mode" "<MODE>")]
2548 (define_insn "*csinv3<mode>_insn"
2549   [(set (match_operand:GPI 0 "register_operand" "=r")
2550         (if_then_else:GPI
2551           (match_operator:GPI 1 "aarch64_comparison_operator"
2552            [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2553           (not:GPI (match_operand:GPI 3 "register_operand" "r"))
2554           (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2555   ""
2556   "csinv\\t%<w>0, %<w>4, %<w>3, %M1"
2557   [(set_attr "v8type" "csel")
2558    (set_attr "mode" "<MODE>")])
2560 (define_insn "*csneg3<mode>_insn"
2561   [(set (match_operand:GPI 0 "register_operand" "=r")
2562         (if_then_else:GPI
2563           (match_operator:GPI 1 "aarch64_comparison_operator"
2564            [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2565           (neg:GPI (match_operand:GPI 3 "register_operand" "r"))
2566           (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2567   ""
2568   "csneg\\t%<w>0, %<w>4, %<w>3, %M1"
2569   [(set_attr "v8type" "csel")
2570    (set_attr "mode" "<MODE>")])
2572 ;; -------------------------------------------------------------------
2573 ;; Logical operations
2574 ;; -------------------------------------------------------------------
2576 (define_insn "<optab><mode>3"
2577   [(set (match_operand:GPI 0 "register_operand" "=r,rk")
2578         (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2579                      (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
2580   ""
2581   "<logical>\\t%<w>0, %<w>1, %<w>2"
2582   [(set_attr "v8type" "logic,logic_imm")
2583    (set_attr "mode" "<MODE>")])
2585 ;; zero_extend version of above
2586 (define_insn "*<optab>si3_uxtw"
2587   [(set (match_operand:DI 0 "register_operand" "=r,rk")
2588         (zero_extend:DI
2589          (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2590                      (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2591   ""
2592   "<logical>\\t%w0, %w1, %w2"
2593   [(set_attr "v8type" "logic,logic_imm")
2594    (set_attr "mode" "SI")])
2596 (define_insn "*and<mode>3_compare0"
2597   [(set (reg:CC_NZ CC_REGNUM)
2598         (compare:CC_NZ
2599          (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2600                   (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2601          (const_int 0)))
2602    (set (match_operand:GPI 0 "register_operand" "=r,r")
2603         (and:GPI (match_dup 1) (match_dup 2)))]
2604   ""
2605   "ands\\t%<w>0, %<w>1, %<w>2"
2606   [(set_attr "v8type" "logics,logics_imm")
2607    (set_attr "mode" "<MODE>")]
2610 ;; zero_extend version of above
2611 (define_insn "*andsi3_compare0_uxtw"
2612   [(set (reg:CC_NZ CC_REGNUM)
2613         (compare:CC_NZ
2614          (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2615                  (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2616          (const_int 0)))
2617    (set (match_operand:DI 0 "register_operand" "=r,r")
2618         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2619   ""
2620   "ands\\t%w0, %w1, %w2"
2621   [(set_attr "v8type" "logics,logics_imm")
2622    (set_attr "mode" "SI")]
2625 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2626   [(set (reg:CC_NZ CC_REGNUM)
2627         (compare:CC_NZ
2628          (and:GPI (SHIFT:GPI
2629                    (match_operand:GPI 1 "register_operand" "r")
2630                    (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2631                   (match_operand:GPI 3 "register_operand" "r"))
2632          (const_int 0)))
2633    (set (match_operand:GPI 0 "register_operand" "=r")
2634         (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2635   ""
2636   "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2637   [(set_attr "v8type" "logics_shift")
2638    (set_attr "mode" "<MODE>")]
2641 ;; zero_extend version of above
2642 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2643   [(set (reg:CC_NZ CC_REGNUM)
2644         (compare:CC_NZ
2645          (and:SI (SHIFT:SI
2646                   (match_operand:SI 1 "register_operand" "r")
2647                   (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2648                  (match_operand:SI 3 "register_operand" "r"))
2649          (const_int 0)))
2650    (set (match_operand:DI 0 "register_operand" "=r")
2651         (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2652                                 (match_dup 3))))]
2653   ""
2654   "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2655   [(set_attr "v8type" "logics_shift")
2656    (set_attr "mode" "SI")]
2659 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2660   [(set (match_operand:GPI 0 "register_operand" "=r")
2661         (LOGICAL:GPI (SHIFT:GPI
2662                       (match_operand:GPI 1 "register_operand" "r")
2663                       (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2664                      (match_operand:GPI 3 "register_operand" "r")))]
2665   ""
2666   "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2667   [(set_attr "v8type" "logic_shift")
2668    (set_attr "mode" "<MODE>")])
2670 ;; zero_extend version of above
2671 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
2672   [(set (match_operand:DI 0 "register_operand" "=r")
2673         (zero_extend:DI
2674          (LOGICAL:SI (SHIFT:SI
2675                       (match_operand:SI 1 "register_operand" "r")
2676                       (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2677                      (match_operand:SI 3 "register_operand" "r"))))]
2678   ""
2679   "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2680   [(set_attr "v8type" "logic_shift")
2681    (set_attr "mode" "SI")])
2683 (define_insn "one_cmpl<mode>2"
2684   [(set (match_operand:GPI 0 "register_operand" "=r")
2685         (not:GPI (match_operand:GPI 1 "register_operand" "r")))]
2686   ""
2687   "mvn\\t%<w>0, %<w>1"
2688   [(set_attr "v8type" "logic")
2689    (set_attr "mode" "<MODE>")])
2691 (define_insn "*one_cmpl_<optab><mode>2"
2692   [(set (match_operand:GPI 0 "register_operand" "=r")
2693         (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
2694                             (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2695   ""
2696   "mvn\\t%<w>0, %<w>1, <shift> %2"
2697   [(set_attr "v8type" "logic_shift")
2698    (set_attr "mode" "<MODE>")])
2700 (define_insn "*<LOGICAL:optab>_one_cmpl<mode>3"
2701   [(set (match_operand:GPI 0 "register_operand" "=r")
2702         (LOGICAL:GPI (not:GPI
2703                       (match_operand:GPI 1 "register_operand" "r"))
2704                      (match_operand:GPI 2 "register_operand" "r")))]
2705   ""
2706   "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1"
2707   [(set_attr "v8type" "logic")
2708    (set_attr "mode" "<MODE>")])
2710 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
2711   [(set (match_operand:GPI 0 "register_operand" "=r")
2712         (LOGICAL:GPI (not:GPI
2713                       (SHIFT:GPI
2714                        (match_operand:GPI 1 "register_operand" "r")
2715                        (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2716                      (match_operand:GPI 3 "register_operand" "r")))]
2717   ""
2718   "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2719   [(set_attr "v8type" "logic_shift")
2720    (set_attr "mode" "<MODE>")])
2722 (define_insn "clz<mode>2"
2723   [(set (match_operand:GPI 0 "register_operand" "=r")
2724         (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
2725   ""
2726   "clz\\t%<w>0, %<w>1"
2727   [(set_attr "v8type" "clz")
2728    (set_attr "mode" "<MODE>")])
2730 (define_expand "ffs<mode>2"
2731   [(match_operand:GPI 0 "register_operand")
2732    (match_operand:GPI 1 "register_operand")]
2733   ""
2734   {
2735     rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
2736     rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
2738     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2739     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2740     emit_insn (gen_csinc3<mode>_insn (operands[0], x, ccreg, operands[0], const0_rtx));
2741     DONE;
2742   }
2745 (define_insn "clrsb<mode>2"
2746   [(set (match_operand:GPI 0 "register_operand" "=r")
2747         (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_CLS))]
2748   ""
2749   "cls\\t%<w>0, %<w>1"
2750   [(set_attr "v8type" "clz")
2751    (set_attr "mode" "<MODE>")])
2753 (define_insn "rbit<mode>2"
2754   [(set (match_operand:GPI 0 "register_operand" "=r")
2755         (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
2756   ""
2757   "rbit\\t%<w>0, %<w>1"
2758   [(set_attr "v8type" "rbit")
2759    (set_attr "mode" "<MODE>")])
2761 (define_expand "ctz<mode>2"
2762   [(match_operand:GPI 0 "register_operand")
2763    (match_operand:GPI 1 "register_operand")]
2764   ""
2765   {
2766     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2767     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2768     DONE;
2769   }
2772 (define_insn "*and<mode>3nr_compare0"
2773   [(set (reg:CC_NZ CC_REGNUM)
2774         (compare:CC_NZ
2775          (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
2776                   (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
2777          (const_int 0)))]
2778   ""
2779   "tst\\t%<w>0, %<w>1"
2780   [(set_attr "v8type" "logics")
2781    (set_attr "mode" "<MODE>")])
2783 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
2784   [(set (reg:CC_NZ CC_REGNUM)
2785         (compare:CC_NZ
2786          (and:GPI (SHIFT:GPI
2787                    (match_operand:GPI 0 "register_operand" "r")
2788                    (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2789                   (match_operand:GPI 2 "register_operand" "r"))
2790         (const_int 0)))]
2791   ""
2792   "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
2793   [(set_attr "v8type" "logics_shift")
2794    (set_attr "mode" "<MODE>")])
2796 ;; -------------------------------------------------------------------
2797 ;; Shifts
2798 ;; -------------------------------------------------------------------
2800 (define_expand "<optab><mode>3"
2801   [(set (match_operand:GPI 0 "register_operand")
2802         (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
2803                     (match_operand:QI 2 "nonmemory_operand")))]
2804   ""
2805   {
2806     if (CONST_INT_P (operands[2]))
2807       {
2808         operands[2] = GEN_INT (INTVAL (operands[2])
2809                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2811         if (operands[2] == const0_rtx)
2812           {
2813             emit_insn (gen_mov<mode> (operands[0], operands[1]));
2814             DONE;
2815           }
2816       }
2817   }
2820 (define_expand "ashl<mode>3"
2821   [(set (match_operand:SHORT 0 "register_operand")
2822         (ashift:SHORT (match_operand:SHORT 1 "register_operand")
2823                       (match_operand:QI 2 "nonmemory_operand")))]
2824   ""
2825   {
2826     if (CONST_INT_P (operands[2]))
2827       {
2828         operands[2] = GEN_INT (INTVAL (operands[2])
2829                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2831         if (operands[2] == const0_rtx)
2832           {
2833             emit_insn (gen_mov<mode> (operands[0], operands[1]));
2834             DONE;
2835           }
2836       }
2837   }
2840 (define_expand "rotr<mode>3"
2841   [(set (match_operand:GPI 0 "register_operand")
2842         (rotatert:GPI (match_operand:GPI 1 "register_operand")
2843                       (match_operand:QI 2 "nonmemory_operand")))]
2844   ""
2845   {
2846     if (CONST_INT_P (operands[2]))
2847       {
2848         operands[2] = GEN_INT (INTVAL (operands[2])
2849                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2851         if (operands[2] == const0_rtx)
2852           {
2853             emit_insn (gen_mov<mode> (operands[0], operands[1]));
2854             DONE;
2855           }
2856       }
2857   }
2860 (define_expand "rotl<mode>3"
2861   [(set (match_operand:GPI 0 "register_operand")
2862         (rotatert:GPI (match_operand:GPI 1 "register_operand")
2863                       (match_operand:QI 2 "nonmemory_operand")))]
2864   ""
2865   {
2866     /* (SZ - cnt) % SZ == -cnt % SZ */
2867     if (CONST_INT_P (operands[2]))
2868       {
2869         operands[2] = GEN_INT ((-INTVAL (operands[2]))
2870                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2871         if (operands[2] == const0_rtx)
2872           {
2873             emit_insn (gen_mov<mode> (operands[0], operands[1]));
2874             DONE;
2875           }
2876       }
2877     else
2878       operands[2] = expand_simple_unop (QImode, NEG, operands[2],
2879                                         NULL_RTX, 1);
2880   }
2883 (define_insn "*<optab><mode>3_insn"
2884   [(set (match_operand:GPI 0 "register_operand" "=r")
2885         (SHIFT:GPI
2886          (match_operand:GPI 1 "register_operand" "r")
2887          (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
2888   ""
2889   "<shift>\\t%<w>0, %<w>1, %<w>2"
2890   [(set_attr "v8type" "shift")
2891    (set_attr "mode" "<MODE>")]
2894 ;; zero_extend version of above
2895 (define_insn "*<optab>si3_insn_uxtw"
2896   [(set (match_operand:DI 0 "register_operand" "=r")
2897         (zero_extend:DI (SHIFT:SI
2898          (match_operand:SI 1 "register_operand" "r")
2899          (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
2900   ""
2901   "<shift>\\t%w0, %w1, %w2"
2902   [(set_attr "v8type" "shift")
2903    (set_attr "mode" "SI")]
2906 (define_insn "*ashl<mode>3_insn"
2907   [(set (match_operand:SHORT 0 "register_operand" "=r")
2908         (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
2909                       (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
2910   ""
2911   "lsl\\t%<w>0, %<w>1, %<w>2"
2912   [(set_attr "v8type" "shift")
2913    (set_attr "mode" "<MODE>")]
2916 (define_insn "*<optab><mode>3_insn"
2917   [(set (match_operand:SHORT 0 "register_operand" "=r")
2918         (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
2919                       (match_operand 2 "const_int_operand" "n")))]
2920   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
2922   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
2923   return "<bfshift>\t%w0, %w1, %2, %3";
2925   [(set_attr "v8type" "bfm")
2926    (set_attr "mode" "<MODE>")]
2929 (define_insn "*extr<mode>5_insn"
2930   [(set (match_operand:GPI 0 "register_operand" "=r")
2931         (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
2932                              (match_operand 3 "const_int_operand" "n"))
2933                  (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
2934                                (match_operand 4 "const_int_operand" "n"))))]
2935   "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
2936    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
2937   "extr\\t%<w>0, %<w>1, %<w>2, %4"
2938   [(set_attr "v8type" "shift")
2939    (set_attr "mode" "<MODE>")]
2942 ;; zero_extend version of the above
2943 (define_insn "*extrsi5_insn_uxtw"
2944   [(set (match_operand:DI 0 "register_operand" "=r")
2945         (zero_extend:DI
2946          (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
2947                             (match_operand 3 "const_int_operand" "n"))
2948                  (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
2949                               (match_operand 4 "const_int_operand" "n")))))]
2950   "UINTVAL (operands[3]) < 32 &&
2951    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
2952   "extr\\t%w0, %w1, %w2, %4"
2953   [(set_attr "v8type" "shift")
2954    (set_attr "mode" "SI")]
2957 (define_insn "*ror<mode>3_insn"
2958   [(set (match_operand:GPI 0 "register_operand" "=r")
2959         (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
2960                     (match_operand 2 "const_int_operand" "n")))]
2961   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
2963   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
2964   return "ror\\t%<w>0, %<w>1, %3";
2966   [(set_attr "v8type" "shift")
2967    (set_attr "mode" "<MODE>")]
2970 ;; zero_extend version of the above
2971 (define_insn "*rorsi3_insn_uxtw"
2972   [(set (match_operand:DI 0 "register_operand" "=r")
2973         (zero_extend:DI
2974          (rotate:SI (match_operand:SI 1 "register_operand" "r")
2975                     (match_operand 2 "const_int_operand" "n"))))]
2976   "UINTVAL (operands[2]) < 32"
2978   operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
2979   return "ror\\t%w0, %w1, %3";
2981   [(set_attr "v8type" "shift")
2982    (set_attr "mode" "SI")]
2985 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
2986   [(set (match_operand:GPI 0 "register_operand" "=r")
2987         (ANY_EXTEND:GPI
2988          (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
2989                        (match_operand 2 "const_int_operand" "n"))))]
2990   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
2992   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
2993   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
2995   [(set_attr "v8type" "bfm")
2996    (set_attr "mode" "<GPI:MODE>")]
2999 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3000   [(set (match_operand:GPI 0 "register_operand" "=r")
3001         (zero_extend:GPI
3002          (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3003                          (match_operand 2 "const_int_operand" "n"))))]
3004   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3006   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3007   return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3009   [(set_attr "v8type" "bfm")
3010    (set_attr "mode" "<GPI:MODE>")]
3013 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3014   [(set (match_operand:GPI 0 "register_operand" "=r")
3015         (sign_extend:GPI
3016          (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3017                          (match_operand 2 "const_int_operand" "n"))))]
3018   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3020   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3021   return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3023   [(set_attr "v8type" "bfm")
3024    (set_attr "mode" "<GPI:MODE>")]
3027 ;; -------------------------------------------------------------------
3028 ;; Bitfields
3029 ;; -------------------------------------------------------------------
3031 (define_expand "<optab>"
3032   [(set (match_operand:DI 0 "register_operand" "=r")
3033         (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3034                         (match_operand 2 "const_int_operand" "n")
3035                         (match_operand 3 "const_int_operand" "n")))]
3036   ""
3037   ""
3040 (define_insn "*<optab><mode>"
3041   [(set (match_operand:GPI 0 "register_operand" "=r")
3042         (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3043                          (match_operand 2 "const_int_operand" "n")
3044                          (match_operand 3 "const_int_operand" "n")))]
3045   ""
3046   "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3047   [(set_attr "v8type" "bfm")
3048    (set_attr "mode" "<MODE>")]
3051 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3052   [(set (match_operand:GPI 0 "register_operand" "=r")
3053         (ashift:GPI (ANY_EXTEND:GPI
3054                      (match_operand:ALLX 1 "register_operand" "r"))
3055                     (match_operand 2 "const_int_operand" "n")))]
3056   "UINTVAL (operands[2]) < <GPI:sizen>"
3058   operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3059               ? GEN_INT (<ALLX:sizen>)
3060               : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3061   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3063   [(set_attr "v8type" "bfm")
3064    (set_attr "mode" "<GPI:MODE>")]
3067 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3069 (define_insn "*andim_ashift<mode>_bfiz"
3070   [(set (match_operand:GPI 0 "register_operand" "=r")
3071         (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3072                              (match_operand 2 "const_int_operand" "n"))
3073                  (match_operand 3 "const_int_operand" "n")))]
3074   "exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3075    && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3076   "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3077   [(set_attr "v8type" "bfm")
3078    (set_attr "mode" "<MODE>")]
3081 (define_insn "bswap<mode>2"
3082   [(set (match_operand:GPI 0 "register_operand" "=r")
3083         (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3084   ""
3085   "rev\\t%<w>0, %<w>1"
3086   [(set_attr "v8type" "rev")
3087    (set_attr "mode" "<MODE>")]
3090 (define_insn "bswaphi2"
3091   [(set (match_operand:HI 0 "register_operand" "=r")
3092         (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3093   ""
3094   "rev16\\t%w0, %w1"
3095   [(set_attr "v8type" "rev")
3096    (set_attr "mode" "HI")]
3099 ;; zero_extend version of above
3100 (define_insn "*bswapsi2_uxtw"
3101   [(set (match_operand:DI 0 "register_operand" "=r")
3102         (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3103   ""
3104   "rev\\t%w0, %w1"
3105   [(set_attr "v8type" "rev")
3106    (set_attr "mode" "SI")]
3109 ;; -------------------------------------------------------------------
3110 ;; Floating-point intrinsics
3111 ;; -------------------------------------------------------------------
3113 ;; frint floating-point round to integral standard patterns.
3114 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round.
3116 (define_insn "<frint_pattern><mode>2"
3117   [(set (match_operand:GPF 0 "register_operand" "=w")
3118         (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3119          FRINT))]
3120   "TARGET_FLOAT"
3121   "frint<frint_suffix>\\t%<s>0, %<s>1"
3122   [(set_attr "v8type" "frint")
3123    (set_attr "mode" "<MODE>")]
3126 ;; frcvt floating-point round to integer and convert standard patterns.
3127 ;; Expands to lbtrunc, lceil, lfloor, lround.
3128 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3129   [(set (match_operand:GPI 0 "register_operand" "=r")
3130         (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3131                       FCVT)))]
3132   "TARGET_FLOAT"
3133   "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3134   [(set_attr "v8type" "fcvtf2i")
3135    (set_attr "mode" "<GPF:MODE>")
3136    (set_attr "mode2" "<GPI:MODE>")]
3139 ;; fma - no throw
3141 (define_insn "fma<mode>4"
3142   [(set (match_operand:GPF 0 "register_operand" "=w")
3143         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3144                  (match_operand:GPF 2 "register_operand" "w")
3145                  (match_operand:GPF 3 "register_operand" "w")))]
3146   "TARGET_FLOAT"
3147   "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3148   [(set_attr "v8type" "fmadd")
3149    (set_attr "mode" "<MODE>")]
3152 (define_insn "fnma<mode>4"
3153   [(set (match_operand:GPF 0 "register_operand" "=w")
3154         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3155                  (match_operand:GPF 2 "register_operand" "w")
3156                  (match_operand:GPF 3 "register_operand" "w")))]
3157   "TARGET_FLOAT"
3158   "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3159   [(set_attr "v8type" "fmadd")
3160    (set_attr "mode" "<MODE>")]
3163 (define_insn "fms<mode>4"
3164   [(set (match_operand:GPF 0 "register_operand" "=w")
3165         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3166                  (match_operand:GPF 2 "register_operand" "w")
3167                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3168   "TARGET_FLOAT"
3169   "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3170   [(set_attr "v8type" "fmadd")
3171    (set_attr "mode" "<MODE>")]
3174 (define_insn "fnms<mode>4"
3175   [(set (match_operand:GPF 0 "register_operand" "=w")
3176         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3177                  (match_operand:GPF 2 "register_operand" "w")
3178                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3179   "TARGET_FLOAT"
3180   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3181   [(set_attr "v8type" "fmadd")
3182    (set_attr "mode" "<MODE>")]
3185 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3186 (define_insn "*fnmadd<mode>4"
3187   [(set (match_operand:GPF 0 "register_operand" "=w")
3188         (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3189                           (match_operand:GPF 2 "register_operand" "w")
3190                           (match_operand:GPF 3 "register_operand" "w"))))]
3191   "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3192   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3193   [(set_attr "v8type" "fmadd")
3194    (set_attr "mode" "<MODE>")]
3197 ;; -------------------------------------------------------------------
3198 ;; Floating-point conversions
3199 ;; -------------------------------------------------------------------
3201 (define_insn "extendsfdf2"
3202   [(set (match_operand:DF 0 "register_operand" "=w")
3203         (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3204   "TARGET_FLOAT"
3205   "fcvt\\t%d0, %s1"
3206   [(set_attr "v8type" "fcvt")
3207    (set_attr "mode" "DF")
3208    (set_attr "mode2" "SF")]
3211 (define_insn "truncdfsf2"
3212   [(set (match_operand:SF 0 "register_operand" "=w")
3213         (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3214   "TARGET_FLOAT"
3215   "fcvt\\t%s0, %d1"
3216   [(set_attr "v8type" "fcvt")
3217    (set_attr "mode" "SF")
3218    (set_attr "mode2" "DF")]
3221 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3222   [(set (match_operand:GPI 0 "register_operand" "=r")
3223         (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3224   "TARGET_FLOAT"
3225   "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3226   [(set_attr "v8type" "fcvtf2i")
3227    (set_attr "mode" "<GPF:MODE>")
3228    (set_attr "mode2" "<GPI:MODE>")]
3231 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3232   [(set (match_operand:GPI 0 "register_operand" "=r")
3233         (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3234   "TARGET_FLOAT"
3235   "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3236   [(set_attr "v8type" "fcvtf2i")
3237    (set_attr "mode" "<GPF:MODE>")
3238    (set_attr "mode2" "<GPI:MODE>")]
3241 (define_insn "float<GPI:mode><GPF:mode>2"
3242   [(set (match_operand:GPF 0 "register_operand" "=w")
3243         (float:GPF (match_operand:GPI 1 "register_operand" "r")))]
3244   "TARGET_FLOAT"
3245   "scvtf\\t%<GPF:s>0, %<GPI:w>1"
3246   [(set_attr "v8type" "fcvti2f")
3247    (set_attr "mode" "<GPF:MODE>")
3248    (set_attr "mode2" "<GPI:MODE>")]
3251 (define_insn "floatuns<GPI:mode><GPF:mode>2"
3252   [(set (match_operand:GPF 0 "register_operand" "=w")
3253         (unsigned_float:GPF (match_operand:GPI 1 "register_operand" "r")))]
3254   "TARGET_FLOAT"
3255   "ucvtf\\t%<GPF:s>0, %<GPI:w>1"
3256   [(set_attr "v8type" "fcvt")
3257    (set_attr "mode" "<GPF:MODE>")
3258    (set_attr "mode2" "<GPI:MODE>")]
3261 ;; -------------------------------------------------------------------
3262 ;; Floating-point arithmetic
3263 ;; -------------------------------------------------------------------
3265 (define_insn "add<mode>3"
3266   [(set (match_operand:GPF 0 "register_operand" "=w")
3267         (plus:GPF
3268          (match_operand:GPF 1 "register_operand" "w")
3269          (match_operand:GPF 2 "register_operand" "w")))]
3270   "TARGET_FLOAT"
3271   "fadd\\t%<s>0, %<s>1, %<s>2"
3272   [(set_attr "v8type" "fadd")
3273    (set_attr "mode" "<MODE>")]
3276 (define_insn "sub<mode>3"
3277   [(set (match_operand:GPF 0 "register_operand" "=w")
3278         (minus:GPF
3279          (match_operand:GPF 1 "register_operand" "w")
3280          (match_operand:GPF 2 "register_operand" "w")))]
3281   "TARGET_FLOAT"
3282   "fsub\\t%<s>0, %<s>1, %<s>2"
3283   [(set_attr "v8type" "fadd")
3284    (set_attr "mode" "<MODE>")]
3287 (define_insn "mul<mode>3"
3288   [(set (match_operand:GPF 0 "register_operand" "=w")
3289         (mult:GPF
3290          (match_operand:GPF 1 "register_operand" "w")
3291          (match_operand:GPF 2 "register_operand" "w")))]
3292   "TARGET_FLOAT"
3293   "fmul\\t%<s>0, %<s>1, %<s>2"
3294   [(set_attr "v8type" "fmul")
3295    (set_attr "mode" "<MODE>")]
3298 (define_insn "*fnmul<mode>3"
3299   [(set (match_operand:GPF 0 "register_operand" "=w")
3300         (mult:GPF
3301                  (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3302                  (match_operand:GPF 2 "register_operand" "w")))]
3303   "TARGET_FLOAT"
3304   "fnmul\\t%<s>0, %<s>1, %<s>2"
3305   [(set_attr "v8type" "fmul")
3306    (set_attr "mode" "<MODE>")]
3309 (define_insn "div<mode>3"
3310   [(set (match_operand:GPF 0 "register_operand" "=w")
3311         (div:GPF
3312          (match_operand:GPF 1 "register_operand" "w")
3313          (match_operand:GPF 2 "register_operand" "w")))]
3314   "TARGET_FLOAT"
3315   "fdiv\\t%<s>0, %<s>1, %<s>2"
3316   [(set_attr "v8type" "fdiv")
3317    (set_attr "mode" "<MODE>")]
3320 (define_insn "neg<mode>2"
3321   [(set (match_operand:GPF 0 "register_operand" "=w")
3322         (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
3323   "TARGET_FLOAT"
3324   "fneg\\t%<s>0, %<s>1"
3325   [(set_attr "v8type" "ffarith")
3326    (set_attr "mode" "<MODE>")]
3329 (define_insn "sqrt<mode>2"
3330   [(set (match_operand:GPF 0 "register_operand" "=w")
3331         (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
3332   "TARGET_FLOAT"
3333   "fsqrt\\t%<s>0, %<s>1"
3334   [(set_attr "v8type" "fsqrt")
3335    (set_attr "mode" "<MODE>")]
3338 (define_insn "abs<mode>2"
3339   [(set (match_operand:GPF 0 "register_operand" "=w")
3340         (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
3341   "TARGET_FLOAT"
3342   "fabs\\t%<s>0, %<s>1"
3343   [(set_attr "v8type" "ffarith")
3344    (set_attr "mode" "<MODE>")]
3347 ;; Given that smax/smin do not specify the result when either input is NaN,
3348 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
3349 ;; for smin.
3351 (define_insn "smax<mode>3"
3352   [(set (match_operand:GPF 0 "register_operand" "=w")
3353         (smax:GPF (match_operand:GPF 1 "register_operand" "w")
3354                   (match_operand:GPF 2 "register_operand" "w")))]
3355   "TARGET_FLOAT"
3356   "fmaxnm\\t%<s>0, %<s>1, %<s>2"
3357   [(set_attr "v8type" "fminmax")
3358    (set_attr "mode" "<MODE>")]
3361 (define_insn "smin<mode>3"
3362   [(set (match_operand:GPF 0 "register_operand" "=w")
3363         (smin:GPF (match_operand:GPF 1 "register_operand" "w")
3364                   (match_operand:GPF 2 "register_operand" "w")))]
3365   "TARGET_FLOAT"
3366   "fminnm\\t%<s>0, %<s>1, %<s>2"
3367   [(set_attr "v8type" "fminmax")
3368    (set_attr "mode" "<MODE>")]
3371 (define_insn "aarch64_frecp<FRECP:frecp_suffix><mode>"
3372   [(set (match_operand:GPF 0 "register_operand" "=w")
3373         (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3374                     FRECP))]
3375   "TARGET_FLOAT"
3376   "frecp<FRECP:frecp_suffix>\\t%<s>0, %<s>1"
3377   [(set_attr "v8type" "frecp<FRECP:frecp_suffix>")
3378    (set_attr "mode" "<MODE>")]
3381 (define_insn "aarch64_frecps<mode>"
3382   [(set (match_operand:GPF 0 "register_operand" "=w")
3383         (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")
3384                      (match_operand:GPF 2 "register_operand" "w")]
3385                     UNSPEC_FRECPS))]
3386   "TARGET_FLOAT"
3387   "frecps\\t%<s>0, %<s>1, %<s>2"
3388   [(set_attr "v8type" "frecps")
3389    (set_attr "mode" "<MODE>")]
3392 ;; -------------------------------------------------------------------
3393 ;; Reload support
3394 ;; -------------------------------------------------------------------
3396 ;; Reload SP+imm where imm cannot be handled by a single ADD instruction.  
3397 ;; Must load imm into a scratch register and copy SP to the dest reg before
3398 ;; adding, since SP cannot be used as a source register in an ADD
3399 ;; instruction.
3400 (define_expand "reload_sp_immediate"
3401   [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
3402                    (match_operand:DI 1 "" ""))
3403              (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
3404   ""
3405   {
3406     rtx sp = XEXP (operands[1], 0);
3407     rtx val = XEXP (operands[1], 1);
3408     unsigned regno = REGNO (operands[2]);
3409     rtx scratch = operands[1];
3410     gcc_assert (GET_CODE (operands[1]) == PLUS);
3411     gcc_assert (sp == stack_pointer_rtx);
3412     gcc_assert (CONST_INT_P (val));
3414     /* It is possible that one of the registers we got for operands[2]
3415        might coincide with that of operands[0] (which is why we made
3416        it TImode).  Pick the other one to use as our scratch.  */
3417     if (regno == REGNO (operands[0]))
3418       regno++;
3419     scratch = gen_rtx_REG (DImode, regno);
3421     emit_move_insn (scratch, val);
3422     emit_move_insn (operands[0], sp);
3423     emit_insn (gen_adddi3 (operands[0], operands[0], scratch));
3424     DONE;
3425   }
3428 (define_expand "aarch64_reload_mov<mode>"
3429   [(set (match_operand:TX 0 "register_operand" "=w")
3430         (match_operand:TX 1 "register_operand" "w"))
3431    (clobber (match_operand:DI 2 "register_operand" "=&r"))
3432   ]
3433   ""
3434   {
3435     rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
3436     rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
3437     gen_aarch64_movtilow_tilow (op0, op1);
3438     gen_aarch64_movdi_tihigh (operands[2], op1);
3439     gen_aarch64_movtihigh_di (op0, operands[2]);
3440     DONE;
3441   }
3444 ;; The following secondary reload helpers patterns are invoked
3445 ;; after or during reload as we don't want these patterns to start
3446 ;; kicking in during the combiner.
3448 (define_insn "aarch64_movdi_tilow"
3449   [(set (match_operand:DI 0 "register_operand" "=r")
3450         (truncate:DI (match_operand:TI 1 "register_operand" "w")))]
3451   "reload_completed || reload_in_progress"
3452   "fmov\\t%x0, %d1"
3453   [(set_attr "v8type" "fmovf2i")
3454    (set_attr "mode"   "DI")
3455    (set_attr "length" "4")
3456   ])
3458 (define_insn "aarch64_movdi_tihigh"
3459   [(set (match_operand:DI 0 "register_operand" "=r")
3460         (truncate:DI
3461           (lshiftrt:TI (match_operand:TI 1 "register_operand" "w")
3462                        (const_int 64))))]
3463   "reload_completed || reload_in_progress"
3464   "fmov\\t%x0, %1.d[1]"
3465   [(set_attr "v8type" "fmovf2i")
3466    (set_attr "mode"   "DI")
3467    (set_attr "length" "4")
3468   ])
3470 (define_insn "aarch64_movtihigh_di"
3471   [(set (zero_extract:TI (match_operand:TI 0 "register_operand" "+w")
3472                          (const_int 64) (const_int 64))
3473         (zero_extend:TI (match_operand:DI 1 "register_operand" "r")))]
3474   "reload_completed || reload_in_progress"
3475   "fmov\\t%0.d[1], %x1"
3477   [(set_attr "v8type" "fmovi2f")
3478    (set_attr "mode"   "DI")
3479    (set_attr "length" "4")
3480   ])
3482 (define_insn "aarch64_movtilow_di"
3483   [(set (match_operand:TI 0 "register_operand" "=w")
3484         (zero_extend:TI (match_operand:DI 1 "register_operand" "r")))]
3485   "reload_completed || reload_in_progress"
3486   "fmov\\t%d0, %x1"
3488   [(set_attr "v8type" "fmovi2f")
3489    (set_attr "mode"   "DI")
3490    (set_attr "length" "4")
3491   ])
3493 (define_insn "aarch64_movtilow_tilow"
3494   [(set (match_operand:TI 0 "register_operand" "=w")
3495         (zero_extend:TI 
3496           (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
3497   "reload_completed || reload_in_progress"
3498   "fmov\\t%d0, %d1"
3500   [(set_attr "v8type" "fmovi2f")
3501    (set_attr "mode"   "DI")
3502    (set_attr "length" "4")
3503   ])
3505 ;; There is a deliberate reason why the parameters of high and lo_sum's
3506 ;; don't have modes for ADRP and ADD instructions.  This is to allow high
3507 ;; and lo_sum's to be used with the labels defining the jump tables in
3508 ;; rodata section.
3510 (define_insn "add_losym"
3511   [(set (match_operand:DI 0 "register_operand" "=r")
3512         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
3513                    (match_operand 2 "aarch64_valid_symref" "S")))]
3514   ""
3515   "add\\t%0, %1, :lo12:%a2"
3516   [(set_attr "v8type" "alu")
3517    (set_attr "mode" "DI")]
3521 (define_insn "ldr_got_small"
3522   [(set (match_operand:DI 0 "register_operand" "=r")
3523         (unspec:DI [(mem:DI (lo_sum:DI
3524                               (match_operand:DI 1 "register_operand" "r")
3525                               (match_operand:DI 2 "aarch64_valid_symref" "S")))]
3526                    UNSPEC_GOTSMALLPIC))]
3527   ""
3528   "ldr\\t%0, [%1, #:got_lo12:%a2]"
3529   [(set_attr "v8type" "load1")
3530    (set_attr "mode" "DI")]
3533 (define_insn "aarch64_load_tp_hard"
3534   [(set (match_operand:DI 0 "register_operand" "=r")
3535         (unspec:DI [(const_int 0)] UNSPEC_TLS))]
3536   ""
3537   "mrs\\t%0, tpidr_el0"
3538   [(set_attr "v8type" "mrs")
3539    (set_attr "mode" "DI")]
3542 ;; The TLS ABI specifically requires that the compiler does not schedule
3543 ;; instructions in the TLS stubs, in order to enable linker relaxation.
3544 ;; Therefore we treat the stubs as an atomic sequence.
3545 (define_expand "tlsgd_small"
3546  [(parallel [(set (match_operand 0 "register_operand" "")
3547                   (call (mem:DI (match_dup 2)) (const_int 1)))
3548              (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
3549              (clobber (reg:DI LR_REGNUM))])]
3550  ""
3552   operands[2] = aarch64_tls_get_addr ();
3555 (define_insn "*tlsgd_small"
3556   [(set (match_operand 0 "register_operand" "")
3557         (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
3558    (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
3559    (clobber (reg:DI LR_REGNUM))
3560   ]
3561   ""
3562   "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
3563   [(set_attr "v8type" "call")
3564    (set_attr "length" "16")])
3566 (define_insn "tlsie_small"
3567   [(set (match_operand:DI 0 "register_operand" "=r")
3568         (unspec:DI [(match_operand:DI 1 "aarch64_tls_ie_symref" "S")]
3569                    UNSPEC_GOTSMALLTLS))]
3570   ""
3571   "adrp\\t%0, %A1\;ldr\\t%0, [%0, #%L1]"
3572   [(set_attr "v8type" "load1")
3573    (set_attr "mode" "DI")
3574    (set_attr "length" "8")]
3577 (define_insn "tlsle_small"
3578   [(set (match_operand:DI 0 "register_operand" "=r")
3579         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
3580                    (match_operand:DI 2 "aarch64_tls_le_symref" "S")]
3581                    UNSPEC_GOTSMALLTLS))]
3582   ""
3583   "add\\t%0, %1, #%G2\;add\\t%0, %0, #%L2"
3584   [(set_attr "v8type" "alu")
3585    (set_attr "mode" "DI")
3586    (set_attr "length" "8")]
3589 (define_insn "tlsdesc_small"
3590   [(set (reg:DI R0_REGNUM)
3591         (unspec:DI [(match_operand:DI 0 "aarch64_valid_symref" "S")]
3592                    UNSPEC_TLSDESC))
3593    (clobber (reg:DI LR_REGNUM))
3594    (clobber (match_scratch:DI 1 "=r"))]
3595   "TARGET_TLS_DESC"
3596   "adrp\\tx0, %A0\;ldr\\t%1, [x0, #%L0]\;add\\tx0, x0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
3597   [(set_attr "v8type" "call")
3598    (set_attr "length" "16")])
3600 (define_insn "stack_tie"
3601   [(set (mem:BLK (scratch))
3602         (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
3603                      (match_operand:DI 1 "register_operand" "rk")]
3604                     UNSPEC_PRLG_STK))]
3605   ""
3606   ""
3607   [(set_attr "length" "0")]
3610 ;; Named pattern for expanding thread pointer reference.
3611 (define_expand "get_thread_pointerdi"
3612   [(match_operand:DI 0 "register_operand" "=r")]
3613   ""
3615   rtx tmp = aarch64_load_tp (operands[0]);
3616   if (tmp != operands[0])
3617     emit_move_insn (operands[0], tmp);
3618   DONE;
3621 ;; AdvSIMD Stuff
3622 (include "aarch64-simd.md")
3624 ;; Atomic Operations
3625 (include "atomics.md")