[AArch64] [Neon types 2/10] Update Current type attributes to new Neon Types.
[official-gcc.git] / gcc / config / aarch64 / aarch64.md
blob01664665e7d309f2cf2076bdc3ca6e0825612cea
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_FRINTN
78     UNSPEC_FRINTP
79     UNSPEC_FRINTX
80     UNSPEC_FRINTZ
81     UNSPEC_GOTSMALLPIC
82     UNSPEC_GOTSMALLTLS
83     UNSPEC_GOTTINYPIC
84     UNSPEC_LD2
85     UNSPEC_LD3
86     UNSPEC_LD4
87     UNSPEC_MB
88     UNSPEC_NOP
89     UNSPEC_PRLG_STK
90     UNSPEC_RBIT
91     UNSPEC_SISD_NEG
92     UNSPEC_SISD_SSHL
93     UNSPEC_SISD_USHL
94     UNSPEC_SSHL_2S
95     UNSPEC_ST2
96     UNSPEC_ST3
97     UNSPEC_ST4
98     UNSPEC_TLS
99     UNSPEC_TLSDESC
100     UNSPEC_USHL_2S
101     UNSPEC_VSTRUCTDUMMY
104 (define_c_enum "unspecv" [
105     UNSPECV_EH_RETURN           ; Represent EH_RETURN
106   ]
109 ;; If further include files are added the defintion of MD_INCLUDES
110 ;; must be updated.
112 (include "constraints.md")
113 (include "predicates.md")
114 (include "iterators.md")
116 ;; -------------------------------------------------------------------
117 ;; Instruction types and attributes
118 ;; -------------------------------------------------------------------
120 ;; Main data types used by the insntructions
122 (define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
123   (const_string "unknown"))
125 (define_attr "mode2" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
126   (const_string "unknown"))
128 ; The "v8type" attribute is used to for fine grained classification of
129 ; AArch64 instructions.  This table briefly explains the meaning of each type.
131 ; adc              add/subtract with carry.
132 ; adcs             add/subtract with carry (setting condition flags).
133 ; adr              calculate address.
134 ; alu              simple alu instruction (no memory or fp regs access).
135 ; alu_ext          simple alu instruction (sign/zero-extended register).
136 ; alu_shift        simple alu instruction, with a source operand shifted by a constant.
137 ; alus             simple alu instruction (setting condition flags).
138 ; alus_ext         simple alu instruction (sign/zero-extended register, setting condition flags).
139 ; alus_shift       simple alu instruction, with a source operand shifted by a constant (setting condition flags).
140 ; bfm              bitfield move operation.
141 ; branch           branch.
142 ; call             subroutine call.
143 ; ccmp             conditional compare.
144 ; clz              count leading zeros/sign bits.
145 ; csel             conditional select.
146 ; dmb              data memory barrier.
147 ; extend           sign/zero-extend (specialised bitfield move).
148 ; extr             extract register-sized bitfield encoding.
149 ; fpsimd_load      load single floating point / simd scalar register from memory.
150 ; fpsimd_load2     load pair of floating point / simd scalar registers from memory.
151 ; fpsimd_store     store single floating point / simd scalar register to memory.
152 ; fpsimd_store2    store pair floating point / simd scalar registers to memory.
153 ; fadd             floating point add/sub.
154 ; fccmp            floating point conditional compare.
155 ; fcmp             floating point comparison.
156 ; fconst           floating point load immediate.
157 ; fcsel            floating point conditional select.
158 ; fcvt             floating point convert (float to float).
159 ; fcvtf2i          floating point convert (float to integer).
160 ; fcvti2f          floating point convert (integer to float).
161 ; fdiv             floating point division operation.
162 ; ffarith          floating point abs, neg or cpy.
163 ; fmadd            floating point multiply-add/sub.
164 ; fminmax          floating point min/max.
165 ; fmov             floating point move (float to float).
166 ; fmovf2i          floating point move (float to integer).
167 ; fmovi2f          floating point move (integer to float).
168 ; fmul             floating point multiply.
169 ; frint            floating point round to integral.
170 ; fsqrt            floating point square root.
171 ; load_acq         load-acquire.
172 ; load             load single general register from memory
173 ; load2            load pair of general registers from memory
174 ; logic            logical operation (register).
175 ; logic_imm        and/or/xor operation (immediate).
176 ; logic_shift      logical operation with shift.
177 ; logics           logical operation (register, setting condition flags).
178 ; logics_imm       and/or/xor operation (immediate, setting condition flags).
179 ; logics_shift     logical operation with shift (setting condition flags).
180 ; madd             integer multiply-add/sub.
181 ; maddl            widening integer multiply-add/sub.
182 ; misc             miscellaneous - any type that doesn't fit into the rest.
183 ; move             integer move operation.
184 ; move2            double integer move operation.
185 ; movk             move 16-bit immediate with keep.
186 ; movz             move 16-bit immmediate with zero/one.
187 ; mrs              system/special register move.
188 ; mulh             64x64 to 128-bit multiply (high part).
189 ; mull             widening multiply.
190 ; mult             integer multiply instruction.
191 ; prefetch         memory prefetch.
192 ; rbit             reverse bits.
193 ; rev              reverse bytes.
194 ; sdiv             integer division operation (signed).
195 ; shift            variable shift operation.
196 ; shift_imm        immediate shift operation (specialised bitfield move).
197 ; store_rel        store-release.
198 ; store            store single general register to memory.
199 ; store2           store pair of general registers to memory.
200 ; udiv             integer division operation (unsigned).
202 (define_attr "v8type"
203    "adc,\
204    adcs,\
205    adr,\
206    alu,\
207    alu_ext,\
208    alu_shift,\
209    alus,\
210    alus_ext,\
211    alus_shift,\
212    bfm,\
213    branch,\
214    call,\
215    ccmp,\
216    clz,\
217    csel,\
218    dmb,\
219    div,\
220    div64,\
221    extend,\
222    extr,\
223    fpsimd_load,\
224    fpsimd_load2,\
225    fpsimd_store2,\
226    fpsimd_store,\
227    fadd,\
228    fccmp,\
229    fcvt,\
230    fcvtf2i,\
231    fcvti2f,\
232    fcmp,\
233    fconst,\
234    fcsel,\
235    fdiv,\
236    ffarith,\
237    fmadd,\
238    fminmax,\
239    fmov,\
240    fmovf2i,\
241    fmovi2f,\
242    fmul,\
243    frint,\
244    fsqrt,\
245    load_acq,\
246    load1,\
247    load2,\
248    logic,\
249    logic_imm,\
250    logic_shift,\
251    logics,\
252    logics_imm,\
253    logics_shift,\
254    madd,\
255    maddl,\
256    misc,\
257    move,\
258    move2,\
259    movk,\
260    movz,\
261    mrs,\
262    mulh,\
263    mull,\
264    mult,\
265    prefetch,\
266    rbit,\
267    rev,\
268    sdiv,\
269    shift,\
270    shift_imm,\
271    store_rel,\
272    store1,\
273    store2,\
274    udiv"
275   (const_string "alu"))
277 ; The "type" attribute is is included here from AArch32 backend to be able
278 ; to share pipeline descriptions.
279 (include "../arm/types.md")
281 ;; Attribute that specifies whether or not the instruction touches fp
282 ;; registers.
283 (define_attr "fp" "no,yes" (const_string "no"))
285 ;; Attribute that specifies whether or not the instruction touches simd
286 ;; registers.
287 (define_attr "simd" "no,yes" (const_string "no"))
289 (define_attr "length" ""
290   (const_int 4))
292 ;; Attribute that controls whether an alternative is enabled or not.
293 ;; Currently it is only used to disable alternatives which touch fp or simd
294 ;; registers when -mgeneral-regs-only is specified.
295 (define_attr "enabled" "no,yes"
296   (cond [(ior
297         (and (eq_attr "fp" "yes")
298              (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
299         (and (eq_attr "simd" "yes")
300              (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
301              (const_string "no")
302         ] (const_string "yes")))
304 ;; -------------------------------------------------------------------
305 ;; Pipeline descriptions and scheduling
306 ;; -------------------------------------------------------------------
308 ;; Processor types.
309 (include "aarch64-tune.md")
311 ;; True if the generic scheduling description should be used.
313 (define_attr "generic_sched" "yes,no"
314   (const (if_then_else
315           (eq_attr "tune" "large,small,cortexa53")
316           (const_string "no")
317           (const_string "yes"))))
319 ;; Scheduling
320 (include "aarch64-generic.md")
321 (include "large.md")
322 (include "small.md")
323 (include "../arm/cortex-a53.md")
325 ;; -------------------------------------------------------------------
326 ;; Jumps and other miscellaneous insns
327 ;; -------------------------------------------------------------------
329 (define_insn "indirect_jump"
330   [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
331   ""
332   "br\\t%0"
333   [(set_attr "v8type" "branch")
334    (set_attr "type" "branch")]
337 (define_insn "jump"
338   [(set (pc) (label_ref (match_operand 0 "" "")))]
339   ""
340   "b\\t%l0"
341   [(set_attr "v8type" "branch")
342    (set_attr "type" "branch")]
345 (define_expand "cbranch<mode>4"
346   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
347                             [(match_operand:GPI 1 "register_operand" "")
348                              (match_operand:GPI 2 "aarch64_plus_operand" "")])
349                            (label_ref (match_operand 3 "" ""))
350                            (pc)))]
351   ""
352   "
353   operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
354                                          operands[2]);
355   operands[2] = const0_rtx;
356   "
359 (define_expand "cbranch<mode>4"
360   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
361                             [(match_operand:GPF 1 "register_operand" "")
362                              (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
363                            (label_ref (match_operand 3 "" ""))
364                            (pc)))]
365   ""
366   "
367   operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
368                                          operands[2]);
369   operands[2] = const0_rtx;
370   "
373 (define_insn "*condjump"
374   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
375                             [(match_operand 1 "cc_register" "") (const_int 0)])
376                            (label_ref (match_operand 2 "" ""))
377                            (pc)))]
378   ""
379   "b%m0\\t%l2"
380   [(set_attr "v8type" "branch")
381    (set_attr "type" "branch")]
384 (define_expand "casesi"
385   [(match_operand:SI 0 "register_operand" "")   ; Index
386    (match_operand:SI 1 "const_int_operand" "")  ; Lower bound
387    (match_operand:SI 2 "const_int_operand" "")  ; Total range
388    (match_operand:DI 3 "" "")                   ; Table label
389    (match_operand:DI 4 "" "")]                  ; Out of range label
390   ""
391   {
392     if (operands[1] != const0_rtx)
393       {
394         rtx reg = gen_reg_rtx (SImode);
396         /* Canonical RTL says that if you have:
398            (minus (X) (CONST))
400            then this should be emitted as:
402            (plus (X) (-CONST))
404            The use of trunc_int_for_mode ensures that the resulting
405            constant can be represented in SImode, this is important
406            for the corner case where operand[1] is INT_MIN.  */
408         operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
410         if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
411               (operands[1], SImode))
412           operands[1] = force_reg (SImode, operands[1]);
413         emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
414         operands[0] = reg;
415       }
417     if (!aarch64_plus_operand (operands[2], SImode))
418       operands[2] = force_reg (SImode, operands[2]);
419     emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
420                                                  const0_rtx),
421                                     operands[0], operands[2], operands[4]));
423     operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
424     emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
425                                          operands[3]));
426     DONE;
427   }
430 (define_insn "casesi_dispatch"
431   [(parallel
432     [(set (pc)
433           (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
434                            (match_operand:SI 1 "register_operand" "r")]
435                         UNSPEC_CASESI)))
436      (clobber (reg:CC CC_REGNUM))
437      (clobber (match_scratch:DI 3 "=r"))
438      (clobber (match_scratch:DI 4 "=r"))
439      (use (label_ref (match_operand 2 "" "")))])]
440   ""
441   "*
442   return aarch64_output_casesi (operands);
443   "
444   [(set_attr "length" "16")
445    (set_attr "v8type" "branch")
446    (set_attr "type" "branch")]
449 (define_insn "nop"
450   [(unspec[(const_int 0)] UNSPEC_NOP)]
451   ""
452   "nop"
453   [(set_attr "v8type" "misc")]
456 (define_expand "prologue"
457   [(clobber (const_int 0))]
458   ""
459   "
460   aarch64_expand_prologue ();
461   DONE;
462   "
465 (define_expand "epilogue"
466   [(clobber (const_int 0))]
467   ""
468   "
469   aarch64_expand_epilogue (false);
470   DONE;
471   "
474 (define_expand "sibcall_epilogue"
475   [(clobber (const_int 0))]
476   ""
477   "
478   aarch64_expand_epilogue (true);
479   DONE;
480   "
483 (define_insn "*do_return"
484   [(return)]
485   ""
486   "ret"
487   [(set_attr "v8type" "branch")
488    (set_attr "type" "branch")]
491 (define_insn "eh_return"
492   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
493     UNSPECV_EH_RETURN)]
494   ""
495   "#"
496   [(set_attr "v8type" "branch")
497    (set_attr "type" "branch")]
501 (define_split
502   [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
503     UNSPECV_EH_RETURN)]
504   "reload_completed"
505   [(set (match_dup 1) (match_dup 0))]
506   {
507     operands[1] = aarch64_final_eh_return_addr ();
508   }
511 (define_insn "*cb<optab><mode>1"
512   [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
513                                 (const_int 0))
514                            (label_ref (match_operand 1 "" ""))
515                            (pc)))]
516   ""
517   "<cbz>\\t%<w>0, %l1"
518   [(set_attr "v8type" "branch")
519    (set_attr "type" "branch")]
523 (define_insn "*tb<optab><mode>1"
524   [(set (pc) (if_then_else
525               (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
526                                     (const_int 1)
527                                     (match_operand 1 "const_int_operand" "n"))
528                    (const_int 0))
529              (label_ref (match_operand 2 "" ""))
530              (pc)))
531    (clobber (match_scratch:DI 3 "=r"))]
532   ""
533   "*
534   if (get_attr_length (insn) == 8)
535     return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
536   return \"<tbz>\\t%<w>0, %1, %l2\";
537   "
538   [(set_attr "v8type" "branch")
539    (set_attr "type" "branch")
540    (set_attr "mode" "<MODE>")
541    (set (attr "length")
542         (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
543                            (lt (minus (match_dup 2) (pc)) (const_int 32764)))
544                       (const_int 4)
545                       (const_int 8)))]
548 (define_insn "*cb<optab><mode>1"
549   [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
550                                  (const_int 0))
551                            (label_ref (match_operand 1 "" ""))
552                            (pc)))
553    (clobber (match_scratch:DI 2 "=r"))]
554   ""
555   "*
556   if (get_attr_length (insn) == 8)
557     return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
558   return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
559   "
560   [(set_attr "v8type" "branch")
561    (set_attr "type" "branch")
562    (set_attr "mode" "<MODE>")
563    (set (attr "length")
564         (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
565                            (lt (minus (match_dup 1) (pc)) (const_int 32764)))
566                       (const_int 4)
567                       (const_int 8)))]
570 ;; -------------------------------------------------------------------
571 ;; Subroutine calls and sibcalls
572 ;; -------------------------------------------------------------------
574 (define_expand "call"
575   [(parallel [(call (match_operand 0 "memory_operand" "")
576                     (match_operand 1 "general_operand" ""))
577               (use (match_operand 2 "" ""))
578               (clobber (reg:DI LR_REGNUM))])]
579   ""
580   "
581   {
582     rtx callee;
584     /* In an untyped call, we can get NULL for operand 2.  */
585     if (operands[2] == NULL)
586       operands[2] = const0_rtx;
588     /* Decide if we should generate indirect calls by loading the
589        64-bit address of the callee into a register before performing
590        the branch-and-link.  */
591     callee = XEXP (operands[0], 0);
592     if (GET_CODE (callee) == SYMBOL_REF
593         ? aarch64_is_long_call_p (callee)
594         : !REG_P (callee))
595       XEXP (operands[0], 0) = force_reg (Pmode, callee);
596   }"
599 (define_insn "*call_reg"
600   [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
601          (match_operand 1 "" ""))
602    (use (match_operand 2 "" ""))
603    (clobber (reg:DI LR_REGNUM))]
604   ""
605   "blr\\t%0"
606   [(set_attr "v8type" "call")
607    (set_attr "type" "call")]
610 (define_insn "*call_symbol"
611   [(call (mem:DI (match_operand:DI 0 "" ""))
612          (match_operand 1 "" ""))
613    (use (match_operand 2 "" ""))
614    (clobber (reg:DI LR_REGNUM))]
615   "GET_CODE (operands[0]) == SYMBOL_REF
616    && !aarch64_is_long_call_p (operands[0])"
617   "bl\\t%a0"
618   [(set_attr "v8type" "call")
619    (set_attr "type" "call")]
622 (define_expand "call_value"
623   [(parallel [(set (match_operand 0 "" "")
624                    (call (match_operand 1 "memory_operand" "")
625                          (match_operand 2 "general_operand" "")))
626               (use (match_operand 3 "" ""))
627               (clobber (reg:DI LR_REGNUM))])]
628   ""
629   "
630   {
631     rtx callee;
633     /* In an untyped call, we can get NULL for operand 3.  */
634     if (operands[3] == NULL)
635       operands[3] = const0_rtx;
637     /* Decide if we should generate indirect calls by loading the
638        64-bit address of the callee into a register before performing
639        the branch-and-link.  */
640     callee = XEXP (operands[1], 0);
641     if (GET_CODE (callee) == SYMBOL_REF
642         ? aarch64_is_long_call_p (callee)
643         : !REG_P (callee))
644       XEXP (operands[1], 0) = force_reg (Pmode, callee);
645   }"
648 (define_insn "*call_value_reg"
649   [(set (match_operand 0 "" "")
650         (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
651                       (match_operand 2 "" "")))
652    (use (match_operand 3 "" ""))
653    (clobber (reg:DI LR_REGNUM))]
654   ""
655   "blr\\t%1"
656   [(set_attr "v8type" "call")
657    (set_attr "type" "call")]
661 (define_insn "*call_value_symbol"
662   [(set (match_operand 0 "" "")
663         (call (mem:DI (match_operand:DI 1 "" ""))
664               (match_operand 2 "" "")))
665    (use (match_operand 3 "" ""))
666    (clobber (reg:DI LR_REGNUM))]
667   "GET_CODE (operands[1]) == SYMBOL_REF
668    && !aarch64_is_long_call_p (operands[1])"
669   "bl\\t%a1"
670   [(set_attr "v8type" "call")
671    (set_attr "type" "call")]
674 (define_expand "sibcall"
675   [(parallel [(call (match_operand 0 "memory_operand" "")
676                     (match_operand 1 "general_operand" ""))
677               (return)
678               (use (match_operand 2 "" ""))])]
679   ""
680   {
681     if (operands[2] == NULL_RTX)
682       operands[2] = const0_rtx;
683   }
686 (define_expand "sibcall_value"
687   [(parallel [(set (match_operand 0 "" "")
688                    (call (match_operand 1 "memory_operand" "")
689                          (match_operand 2 "general_operand" "")))
690               (return)
691               (use (match_operand 3 "" ""))])]
692   ""
693   {
694     if (operands[3] == NULL_RTX)
695       operands[3] = const0_rtx;
696   }
699 (define_insn "*sibcall_insn"
700   [(call (mem:DI (match_operand:DI 0 "" "X"))
701          (match_operand 1 "" ""))
702    (return)
703    (use (match_operand 2 "" ""))]
704   "GET_CODE (operands[0]) == SYMBOL_REF"
705   "b\\t%a0"
706   [(set_attr "v8type" "branch")
707    (set_attr "type" "branch")]
711 (define_insn "*sibcall_value_insn"
712   [(set (match_operand 0 "" "")
713         (call (mem:DI (match_operand 1 "" "X"))
714               (match_operand 2 "" "")))
715    (return)
716    (use (match_operand 3 "" ""))]
717   "GET_CODE (operands[1]) == SYMBOL_REF"
718   "b\\t%a1"
719   [(set_attr "v8type" "branch")
720    (set_attr "type" "branch")]
723 ;; Call subroutine returning any type.
725 (define_expand "untyped_call"
726   [(parallel [(call (match_operand 0 "")
727                     (const_int 0))
728               (match_operand 1 "")
729               (match_operand 2 "")])]
730   ""
732   int i;
734   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
736   for (i = 0; i < XVECLEN (operands[2], 0); i++)
737     {
738       rtx set = XVECEXP (operands[2], 0, i);
739       emit_move_insn (SET_DEST (set), SET_SRC (set));
740     }
742   /* The optimizer does not know that the call sets the function value
743      registers we stored in the result block.  We avoid problems by
744      claiming that all hard registers are used and clobbered at this
745      point.  */
746   emit_insn (gen_blockage ());
747   DONE;
750 ;; -------------------------------------------------------------------
751 ;; Moves
752 ;; -------------------------------------------------------------------
754 (define_expand "mov<mode>"
755   [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
756         (match_operand:SHORT 1 "general_operand" ""))]
757   ""
758   "
759     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
760       operands[1] = force_reg (<MODE>mode, operands[1]);
761   "
764 (define_insn "*mov<mode>_aarch64"
765   [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r,   *w,r,*w, m, m, r,*w,*w")
766         (match_operand:SHORT 1 "general_operand"      " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
767   "(register_operand (operands[0], <MODE>mode)
768     || aarch64_reg_or_zero (operands[1], <MODE>mode))"
770    switch (which_alternative)
771      {
772      case 0:
773        return "mov\t%w0, %w1";
774      case 1:
775        return "mov\t%w0, %1";
776      case 2:
777        return aarch64_output_scalar_simd_mov_immediate (operands[1],
778                                                         <MODE>mode);
779      case 3:
780        return "ldr<size>\t%w0, %1";
781      case 4:
782        return "ldr\t%<size>0, %1";
783      case 5:
784        return "str<size>\t%w1, %0";
785      case 6:
786        return "str\t%<size>1, %0";
787      case 7:
788        return "umov\t%w0, %1.<v>[0]";
789      case 8:
790        return "dup\t%0.<Vallxd>, %w1";
791      case 9:
792        return "dup\t%0, %1.<v>[0]";
793      default:
794        gcc_unreachable ();
795      }
797   [(set_attr "v8type" "move,alu,alu,load1,load1,store1,store1,*,*,*")
798    (set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,*,*,*")
799    (set_attr "simd_type" "*,*,simd_move_imm,*,*,*,*,simd_movgp,simd_dupgp,simd_dup")
800    (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")
801    (set_attr "mode" "<MODE>")
802    (set_attr "simd_mode" "<MODE>")]
805 (define_expand "mov<mode>"
806   [(set (match_operand:GPI 0 "nonimmediate_operand" "")
807         (match_operand:GPI 1 "general_operand" ""))]
808   ""
809   "
810     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
811       operands[1] = force_reg (<MODE>mode, operands[1]);
813     if (CONSTANT_P (operands[1]))
814       {
815         aarch64_expand_mov_immediate (operands[0], operands[1]);
816         DONE;
817       }
818   "
821 (define_insn "*movsi_aarch64"
822   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m,  m,r,r  ,*w, r,*w")
823         (match_operand:SI 1 "aarch64_mov_operand"  " r,r,k,M,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
824   "(register_operand (operands[0], SImode)
825     || aarch64_reg_or_zero (operands[1], SImode))"
826   "@
827    mov\\t%w0, %w1
828    mov\\t%w0, %w1
829    mov\\t%w0, %w1
830    mov\\t%w0, %1
831    ldr\\t%w0, %1
832    ldr\\t%s0, %1
833    str\\t%w1, %0
834    str\\t%s1, %0
835    adr\\t%x0, %a1
836    adrp\\t%x0, %A1
837    fmov\\t%s0, %w1
838    fmov\\t%w0, %s1
839    fmov\\t%s0, %s1"
840   [(set_attr "v8type" "move,move,move,alu,load1,load1,store1,store1,adr,adr,fmov,fmov,fmov")
841    (set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
842                      adr,adr,fmov,fmov,fmov")
843    (set_attr "mode" "SI")
844    (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
847 (define_insn "*movdi_aarch64"
848   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m,  m,r,r,  *w, r,*w,w")
849         (match_operand:DI 1 "aarch64_mov_operand"  " r,r,k,N,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))]
850   "(register_operand (operands[0], DImode)
851     || aarch64_reg_or_zero (operands[1], DImode))"
852   "@
853    mov\\t%x0, %x1
854    mov\\t%0, %x1
855    mov\\t%x0, %1
856    mov\\t%x0, %1
857    ldr\\t%x0, %1
858    ldr\\t%d0, %1
859    str\\t%x1, %0
860    str\\t%d1, %0
861    adr\\t%x0, %a1
862    adrp\\t%x0, %A1
863    fmov\\t%d0, %x1
864    fmov\\t%x0, %d1
865    fmov\\t%d0, %d1
866    movi\\t%d0, %1"
867   [(set_attr "v8type" "move,move,move,alu,load1,load1,store1,store1,adr,adr,fmov,fmov,fmov,fmov")
868    (set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
869                      adr,adr,fmov,fmov,fmov,fmov")
870    (set_attr "mode" "DI")
871    (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
872    (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
875 (define_insn "insv_imm<mode>"
876   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
877                           (const_int 16)
878                           (match_operand:GPI 1 "const_int_operand" "n"))
879         (match_operand:GPI 2 "const_int_operand" "n"))]
880   "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
881    && UINTVAL (operands[1]) % 16 == 0"
882   "movk\\t%<w>0, %X2, lsl %1"
883   [(set_attr "v8type" "movk")
884    (set_attr "type" "mov_imm")
885    (set_attr "mode" "<MODE>")]
888 (define_expand "movti"
889   [(set (match_operand:TI 0 "nonimmediate_operand" "")
890         (match_operand:TI 1 "general_operand" ""))]
891   ""
892   "
893     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
894       operands[1] = force_reg (TImode, operands[1]);
895   "
898 (define_insn "*movti_aarch64"
899   [(set (match_operand:TI 0
900          "nonimmediate_operand"  "=r, *w,r ,*w,r  ,Ump,Ump,*w,m")
901         (match_operand:TI 1
902          "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r  ,Z  , m,*w"))]
903   "(register_operand (operands[0], TImode)
904     || aarch64_reg_or_zero (operands[1], TImode))"
905   "@
906    #
907    #
908    #
909    orr\\t%0.16b, %1.16b, %1.16b
910    ldp\\t%0, %H0, %1
911    stp\\t%1, %H1, %0
912    stp\\txzr, xzr, %0
913    ldr\\t%q0, %1
914    str\\t%q1, %0"
915   [(set_attr "v8type" "move2,fmovi2f,fmovf2i,*, \
916                        load2,store2,store2,fpsimd_load,fpsimd_store")
917    (set_attr "type" "multiple,f_mcr,f_mrc,*, \
918                              load2,store2,store2,f_loadd,f_stored")
919    (set_attr "simd_type" "*,*,*,simd_move,*,*,*,*,*")
920    (set_attr "mode" "DI,DI,DI,TI,DI,DI,DI,TI,TI")
921    (set_attr "length" "8,8,8,4,4,4,4,4,4")
922    (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")
923    (set_attr "simd" "*,*,*,yes,*,*,*,*,*")])
925 ;; Split a TImode register-register or register-immediate move into
926 ;; its component DImode pieces, taking care to handle overlapping
927 ;; source and dest registers.
928 (define_split
929    [(set (match_operand:TI 0 "register_operand" "")
930          (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
931   "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
932   [(const_int 0)]
934   aarch64_split_128bit_move (operands[0], operands[1]);
935   DONE;
938 (define_expand "mov<mode>"
939   [(set (match_operand:GPF 0 "nonimmediate_operand" "")
940         (match_operand:GPF 1 "general_operand" ""))]
941   ""
942   "
943     if (!TARGET_FLOAT)
944      {
945         sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
946         FAIL;
947      }
949     if (GET_CODE (operands[0]) == MEM)
950       operands[1] = force_reg (<MODE>mode, operands[1]);
951   "
954 (define_insn "*movsf_aarch64"
955   [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w  ,w,m,r,m ,r")
956         (match_operand:SF 1 "general_operand"      "?rY, w,w,Ufc,m,w,m,rY,r"))]
957   "TARGET_FLOAT && (register_operand (operands[0], SFmode)
958     || register_operand (operands[1], SFmode))"
959   "@
960    fmov\\t%s0, %w1
961    fmov\\t%w0, %s1
962    fmov\\t%s0, %s1
963    fmov\\t%s0, %1
964    ldr\\t%s0, %1
965    str\\t%s1, %0
966    ldr\\t%w0, %1
967    str\\t%w1, %0
968    mov\\t%w0, %w1"
969   [(set_attr "v8type" "fmovi2f,fmovf2i,\
970                        fmov,fconst,fpsimd_load,\
971                        fpsimd_store,fpsimd_load,fpsimd_store,fmov")
972    (set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
973                      f_loads,f_stores,f_loads,f_stores,fmov")
974    (set_attr "mode" "SF")]
977 (define_insn "*movdf_aarch64"
978   [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w  ,w,m,r,m ,r")
979         (match_operand:DF 1 "general_operand"      "?rY, w,w,Ufc,m,w,m,rY,r"))]
980   "TARGET_FLOAT && (register_operand (operands[0], DFmode)
981     || register_operand (operands[1], DFmode))"
982   "@
983    fmov\\t%d0, %x1
984    fmov\\t%x0, %d1
985    fmov\\t%d0, %d1
986    fmov\\t%d0, %1
987    ldr\\t%d0, %1
988    str\\t%d1, %0
989    ldr\\t%x0, %1
990    str\\t%x1, %0
991    mov\\t%x0, %x1"
992   [(set_attr "v8type" "fmovi2f,fmovf2i,\
993                        fmov,fconst,fpsimd_load,\
994                        fpsimd_store,fpsimd_load,fpsimd_store,move")
995    (set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
996                      f_loadd,f_stored,f_loadd,f_stored,mov_reg")
997    (set_attr "mode" "DF")]
1000 (define_expand "movtf"
1001   [(set (match_operand:TF 0 "nonimmediate_operand" "")
1002         (match_operand:TF 1 "general_operand" ""))]
1003   ""
1004   "
1005     if (!TARGET_FLOAT)
1006      {
1007         sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
1008         FAIL;
1009      }
1011     if (GET_CODE (operands[0]) == MEM)
1012       operands[1] = force_reg (TFmode, operands[1]);
1013   "
1016 (define_insn "*movtf_aarch64"
1017   [(set (match_operand:TF 0
1018          "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
1019         (match_operand:TF 1
1020          "general_operand"      " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
1021   "TARGET_FLOAT && (register_operand (operands[0], TFmode)
1022     || register_operand (operands[1], TFmode))"
1023   "@
1024    orr\\t%0.16b, %1.16b, %1.16b
1025    #
1026    #
1027    #
1028    movi\\t%0.2d, #0
1029    fmov\\t%s0, wzr
1030    ldr\\t%q0, %1
1031    str\\t%q1, %0
1032    ldp\\t%0, %H0, %1
1033    stp\\t%1, %H1, %0"
1034   [(set_attr "v8type" "logic,move2,fmovi2f,fmovf2i,fconst,fconst,fpsimd_load,fpsimd_store,fpsimd_load2,fpsimd_store2")
1035    (set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,fconstd,fconstd,\
1036                      f_loadd,f_stored,neon_load1_2reg,neon_store1_2reg")
1037    (set_attr "mode" "DF,DF,DF,DF,DF,DF,TF,TF,DF,DF")
1038    (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
1039    (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
1040    (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
1043 (define_split
1044    [(set (match_operand:TF 0 "register_operand" "")
1045          (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
1046   "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
1047   [(const_int 0)]
1048   {
1049     aarch64_split_128bit_move (operands[0], operands[1]);
1050     DONE;
1051   }
1054 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1055 ;; fairly lax checking on the second memory operation.
1056 (define_insn "load_pair<mode>"
1057   [(set (match_operand:GPI 0 "register_operand" "=r")
1058         (match_operand:GPI 1 "aarch64_mem_pair_operand" "Ump"))
1059    (set (match_operand:GPI 2 "register_operand" "=r")
1060         (match_operand:GPI 3 "memory_operand" "m"))]
1061   "rtx_equal_p (XEXP (operands[3], 0),
1062                 plus_constant (Pmode,
1063                                XEXP (operands[1], 0),
1064                                GET_MODE_SIZE (<MODE>mode)))"
1065   "ldp\\t%<w>0, %<w>2, %1"
1066   [(set_attr "v8type" "load2")
1067    (set_attr "type" "load2")
1068    (set_attr "mode" "<MODE>")]
1071 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1072 ;; fairly lax checking on the second memory operation.
1073 (define_insn "store_pair<mode>"
1074   [(set (match_operand:GPI 0 "aarch64_mem_pair_operand" "=Ump")
1075         (match_operand:GPI 1 "register_operand" "r"))
1076    (set (match_operand:GPI 2 "memory_operand" "=m")
1077         (match_operand:GPI 3 "register_operand" "r"))]
1078   "rtx_equal_p (XEXP (operands[2], 0),
1079                 plus_constant (Pmode,
1080                                XEXP (operands[0], 0),
1081                                GET_MODE_SIZE (<MODE>mode)))"
1082   "stp\\t%<w>1, %<w>3, %0"
1083   [(set_attr "v8type" "store2")
1084    (set_attr "type" "store2")
1085    (set_attr "mode" "<MODE>")]
1088 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1089 ;; fairly lax checking on the second memory operation.
1090 (define_insn "load_pair<mode>"
1091   [(set (match_operand:GPF 0 "register_operand" "=w")
1092         (match_operand:GPF 1 "aarch64_mem_pair_operand" "Ump"))
1093    (set (match_operand:GPF 2 "register_operand" "=w")
1094         (match_operand:GPF 3 "memory_operand" "m"))]
1095   "rtx_equal_p (XEXP (operands[3], 0),
1096                 plus_constant (Pmode,
1097                                XEXP (operands[1], 0),
1098                                GET_MODE_SIZE (<MODE>mode)))"
1099   "ldp\\t%<w>0, %<w>2, %1"
1100   [(set_attr "v8type" "fpsimd_load2")
1101    (set_attr "type" "neon_load1_2reg<q>")
1102    (set_attr "mode" "<MODE>")]
1105 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1106 ;; fairly lax checking on the second memory operation.
1107 (define_insn "store_pair<mode>"
1108   [(set (match_operand:GPF 0 "aarch64_mem_pair_operand" "=Ump")
1109         (match_operand:GPF 1 "register_operand" "w"))
1110    (set (match_operand:GPF 2 "memory_operand" "=m")
1111         (match_operand:GPF 3 "register_operand" "w"))]
1112   "rtx_equal_p (XEXP (operands[2], 0),
1113                 plus_constant (Pmode,
1114                                XEXP (operands[0], 0),
1115                                GET_MODE_SIZE (<MODE>mode)))"
1116   "stp\\t%<w>1, %<w>3, %0"
1117   [(set_attr "v8type" "fpsimd_store2")
1118    (set_attr "type" "neon_store1_2reg<q>")
1119    (set_attr "mode" "<MODE>")]
1122 ;; Load pair with writeback.  This is primarily used in function epilogues
1123 ;; when restoring [fp,lr]
1124 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
1125   [(parallel
1126     [(set (match_operand:P 0 "register_operand" "=k")
1127           (plus:P (match_operand:P 1 "register_operand" "0")
1128                   (match_operand:P 4 "const_int_operand" "n")))
1129      (set (match_operand:GPI 2 "register_operand" "=r")
1130           (mem:GPI (plus:P (match_dup 1)
1131                    (match_dup 4))))
1132      (set (match_operand:GPI 3 "register_operand" "=r")
1133           (mem:GPI (plus:P (match_dup 1)
1134                    (match_operand:P 5 "const_int_operand" "n"))))])]
1135   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1136   "ldp\\t%<w>2, %<w>3, [%1], %4"
1137   [(set_attr "v8type" "load2")
1138    (set_attr "type" "load2")
1139    (set_attr "mode" "<GPI:MODE>")]
1142 ;; Store pair with writeback.  This is primarily used in function prologues
1143 ;; when saving [fp,lr]
1144 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
1145   [(parallel
1146     [(set (match_operand:P 0 "register_operand" "=&k")
1147           (plus:P (match_operand:P 1 "register_operand" "0")
1148                   (match_operand:P 4 "const_int_operand" "n")))
1149      (set (mem:GPI (plus:P (match_dup 0)
1150                    (match_dup 4)))
1151           (match_operand:GPI 2 "register_operand" "r"))
1152      (set (mem:GPI (plus:P (match_dup 0)
1153                    (match_operand:P 5 "const_int_operand" "n")))
1154           (match_operand:GPI 3 "register_operand" "r"))])]
1155   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1156   "stp\\t%<w>2, %<w>3, [%0, %4]!"
1157   [(set_attr "v8type" "store2")
1158    (set_attr "type" "store2")
1159    (set_attr "mode" "<GPI:MODE>")]
1162 ;; -------------------------------------------------------------------
1163 ;; Sign/Zero extension
1164 ;; -------------------------------------------------------------------
1166 (define_expand "<optab>sidi2"
1167   [(set (match_operand:DI 0 "register_operand")
1168         (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1169   ""
1172 (define_insn "*extendsidi2_aarch64"
1173   [(set (match_operand:DI 0 "register_operand" "=r,r")
1174         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1175   ""
1176   "@
1177    sxtw\t%0, %w1
1178    ldrsw\t%0, %1"
1179   [(set_attr "v8type" "extend,load1")
1180    (set_attr "type" "extend,load1")
1181    (set_attr "mode" "DI")]
1184 (define_insn "*zero_extendsidi2_aarch64"
1185   [(set (match_operand:DI 0 "register_operand" "=r,r")
1186         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1187   ""
1188   "@
1189    uxtw\t%0, %w1
1190    ldr\t%w0, %1"
1191   [(set_attr "v8type" "extend,load1")
1192    (set_attr "type" "extend,load1")
1193    (set_attr "mode" "DI")]
1196 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1197   [(set (match_operand:GPI 0 "register_operand")
1198         (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1199   ""
1202 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1203   [(set (match_operand:GPI 0 "register_operand" "=r,r")
1204         (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1205   ""
1206   "@
1207    sxt<SHORT:size>\t%<GPI:w>0, %w1
1208    ldrs<SHORT:size>\t%<GPI:w>0, %1"
1209   [(set_attr "v8type" "extend,load1")
1210    (set_attr "type" "extend,load1")
1211    (set_attr "mode" "<GPI:MODE>")]
1214 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1215   [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1216         (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1217   ""
1218   "@
1219    uxt<SHORT:size>\t%<GPI:w>0, %w1
1220    ldr<SHORT:size>\t%w0, %1
1221    ldr\t%<SHORT:size>0, %1"
1222   [(set_attr "v8type" "extend,load1,load1")
1223    (set_attr "type" "extend,load1,load1")
1224    (set_attr "mode" "<GPI:MODE>")]
1227 (define_expand "<optab>qihi2"
1228   [(set (match_operand:HI 0 "register_operand")
1229         (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1230   ""
1233 (define_insn "*<optab>qihi2_aarch64"
1234   [(set (match_operand:HI 0 "register_operand" "=r,r")
1235         (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1236   ""
1237   "@
1238    <su>xtb\t%w0, %w1
1239    <ldrxt>b\t%w0, %1"
1240   [(set_attr "v8type" "extend,load1")
1241    (set_attr "type" "extend,load1")
1242    (set_attr "mode" "HI")]
1245 ;; -------------------------------------------------------------------
1246 ;; Simple arithmetic
1247 ;; -------------------------------------------------------------------
1249 (define_expand "add<mode>3"
1250   [(set
1251     (match_operand:GPI 0 "register_operand" "")
1252     (plus:GPI (match_operand:GPI 1 "register_operand" "")
1253               (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1254   ""
1255   "
1256   if (! aarch64_plus_operand (operands[2], VOIDmode))
1257     {
1258       rtx subtarget = ((optimize && can_create_pseudo_p ())
1259                        ? gen_reg_rtx (<MODE>mode) : operands[0]);
1260       HOST_WIDE_INT imm = INTVAL (operands[2]);
1262       if (imm < 0)
1263         imm = -(-imm & ~0xfff);
1264       else
1265         imm &= ~0xfff;
1267       emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1268       operands[1] = subtarget;
1269       operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1270     }
1271   "
1274 (define_insn "*addsi3_aarch64"
1275   [(set
1276     (match_operand:SI 0 "register_operand" "=rk,rk,rk")
1277     (plus:SI
1278      (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1279      (match_operand:SI 2 "aarch64_plus_operand" "I,r,J")))]
1280   ""
1281   "@
1282   add\\t%w0, %w1, %2
1283   add\\t%w0, %w1, %w2
1284   sub\\t%w0, %w1, #%n2"
1285   [(set_attr "v8type" "alu")
1286    (set_attr "type" "alu_imm,alu_reg,alu_imm")
1287    (set_attr "mode" "SI")]
1290 ;; zero_extend version of above
1291 (define_insn "*addsi3_aarch64_uxtw"
1292   [(set
1293     (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1294     (zero_extend:DI
1295      (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1296               (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1297   ""
1298   "@
1299   add\\t%w0, %w1, %2
1300   add\\t%w0, %w1, %w2
1301   sub\\t%w0, %w1, #%n2"
1302   [(set_attr "v8type" "alu")
1303    (set_attr "type" "alu_imm,alu_reg,alu_imm")
1304    (set_attr "mode" "SI")]
1307 (define_insn "*adddi3_aarch64"
1308   [(set
1309     (match_operand:DI 0 "register_operand" "=rk,rk,rk,!w")
1310     (plus:DI
1311      (match_operand:DI 1 "register_operand" "%rk,rk,rk,!w")
1312      (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,!w")))]
1313   ""
1314   "@
1315   add\\t%x0, %x1, %2
1316   add\\t%x0, %x1, %x2
1317   sub\\t%x0, %x1, #%n2
1318   add\\t%d0, %d1, %d2"
1319   [(set_attr "v8type" "alu")
1320    (set_attr "type" "alu_imm,alu_reg,alu_imm,alu_reg")
1321    (set_attr "mode" "DI")
1322    (set_attr "simd" "*,*,*,yes")]
1325 (define_insn "*add<mode>3_compare0"
1326   [(set (reg:CC_NZ CC_REGNUM)
1327         (compare:CC_NZ
1328          (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1329                    (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1330          (const_int 0)))
1331    (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1332         (plus:GPI (match_dup 1) (match_dup 2)))]
1333   ""
1334   "@
1335   adds\\t%<w>0, %<w>1, %<w>2
1336   adds\\t%<w>0, %<w>1, %<w>2
1337   subs\\t%<w>0, %<w>1, #%n2"
1338   [(set_attr "v8type" "alus")
1339    (set_attr "type" "alus_reg,alus_imm,alus_imm")
1340    (set_attr "mode" "<MODE>")]
1343 ;; zero_extend version of above
1344 (define_insn "*addsi3_compare0_uxtw"
1345   [(set (reg:CC_NZ CC_REGNUM)
1346         (compare:CC_NZ
1347          (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1348                   (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1349          (const_int 0)))
1350    (set (match_operand:DI 0 "register_operand" "=r,r,r")
1351         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1352   ""
1353   "@
1354   adds\\t%w0, %w1, %w2
1355   adds\\t%w0, %w1, %w2
1356   subs\\t%w0, %w1, #%n2"
1357   [(set_attr "v8type" "alus")
1358    (set_attr "type" "alus_reg,alus_imm,alus_imm")
1359    (set_attr "mode" "SI")]
1362 (define_insn "*adds_mul_imm_<mode>"
1363   [(set (reg:CC_NZ CC_REGNUM)
1364         (compare:CC_NZ
1365          (plus:GPI (mult:GPI
1366                     (match_operand:GPI 1 "register_operand" "r")
1367                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1368                    (match_operand:GPI 3 "register_operand" "r"))
1369          (const_int 0)))
1370    (set (match_operand:GPI 0 "register_operand" "=r")
1371         (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1372                   (match_dup 3)))]
1373   ""
1374   "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1375   [(set_attr "v8type" "alus_shift")
1376    (set_attr "type" "alus_shift_imm")
1377    (set_attr "mode" "<MODE>")]
1380 (define_insn "*subs_mul_imm_<mode>"
1381   [(set (reg:CC_NZ CC_REGNUM)
1382         (compare:CC_NZ
1383          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1384                     (mult:GPI
1385                      (match_operand:GPI 2 "register_operand" "r")
1386                      (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1387          (const_int 0)))
1388    (set (match_operand:GPI 0 "register_operand" "=r")
1389         (minus:GPI (match_dup 1)
1390                    (mult:GPI (match_dup 2) (match_dup 3))))]
1391   ""
1392   "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1393   [(set_attr "v8type" "alus_shift")
1394    (set_attr "type" "alus_shift_imm")
1395    (set_attr "mode" "<MODE>")]
1398 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1399   [(set (reg:CC_NZ CC_REGNUM)
1400         (compare:CC_NZ
1401          (plus:GPI
1402           (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1403           (match_operand:GPI 2 "register_operand" "r"))
1404         (const_int 0)))
1405    (set (match_operand:GPI 0 "register_operand" "=r")
1406         (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1407   ""
1408   "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1409   [(set_attr "v8type" "alus_ext")
1410    (set_attr "type" "alus_ext")
1411    (set_attr "mode" "<GPI:MODE>")]
1414 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1415   [(set (reg:CC_NZ CC_REGNUM)
1416         (compare:CC_NZ
1417          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1418                     (ANY_EXTEND:GPI
1419                      (match_operand:ALLX 2 "register_operand" "r")))
1420         (const_int 0)))
1421    (set (match_operand:GPI 0 "register_operand" "=r")
1422         (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1423   ""
1424   "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1425   [(set_attr "v8type" "alus_ext")
1426    (set_attr "type" "alus_ext")
1427    (set_attr "mode" "<GPI:MODE>")]
1430 (define_insn "*adds_<optab><mode>_multp2"
1431   [(set (reg:CC_NZ CC_REGNUM)
1432         (compare:CC_NZ
1433          (plus:GPI (ANY_EXTRACT:GPI
1434                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1435                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1436                     (match_operand 3 "const_int_operand" "n")
1437                     (const_int 0))
1438                    (match_operand:GPI 4 "register_operand" "r"))
1439         (const_int 0)))
1440    (set (match_operand:GPI 0 "register_operand" "=r")
1441         (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1442                                    (match_dup 3)
1443                                    (const_int 0))
1444                   (match_dup 4)))]
1445   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1446   "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1447   [(set_attr "v8type" "alus_ext")
1448    (set_attr "type" "alus_ext")
1449    (set_attr "mode" "<MODE>")]
1452 (define_insn "*subs_<optab><mode>_multp2"
1453   [(set (reg:CC_NZ CC_REGNUM)
1454         (compare:CC_NZ
1455          (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1456                     (ANY_EXTRACT:GPI
1457                      (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1458                                (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1459                      (match_operand 3 "const_int_operand" "n")
1460                      (const_int 0)))
1461         (const_int 0)))
1462    (set (match_operand:GPI 0 "register_operand" "=r")
1463         (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1464                                   (mult:GPI (match_dup 1) (match_dup 2))
1465                                   (match_dup 3)
1466                                   (const_int 0))))]
1467   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1468   "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1469   [(set_attr "v8type" "alus_ext")
1470    (set_attr "type" "alus_ext")
1471    (set_attr "mode" "<MODE>")]
1474 (define_insn "*add<mode>3nr_compare0"
1475   [(set (reg:CC_NZ CC_REGNUM)
1476         (compare:CC_NZ
1477          (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1478                    (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1479          (const_int 0)))]
1480   ""
1481   "@
1482   cmn\\t%<w>0, %<w>1
1483   cmn\\t%<w>0, %<w>1
1484   cmp\\t%<w>0, #%n1"
1485   [(set_attr "v8type" "alus")
1486    (set_attr "type" "alus_reg,alus_imm,alus_imm")
1487    (set_attr "mode" "<MODE>")]
1490 (define_insn "*compare_neg<mode>"
1491   [(set (reg:CC_SWP CC_REGNUM)
1492         (compare:CC_SWP
1493          (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1494          (match_operand:GPI 1 "register_operand" "r")))]
1495   ""
1496   "cmn\\t%<w>1, %<w>0"
1497   [(set_attr "v8type" "alus")
1498    (set_attr "type" "alus_reg")
1499    (set_attr "mode" "<MODE>")]
1502 (define_insn "*add_<shift>_<mode>"
1503   [(set (match_operand:GPI 0 "register_operand" "=r")
1504         (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1505                               (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1506                   (match_operand:GPI 3 "register_operand" "r")))]
1507   ""
1508   "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1509   [(set_attr "v8type" "alu_shift")
1510    (set_attr "type" "alu_shift_imm")
1511    (set_attr "mode" "<MODE>")]
1514 ;; zero_extend version of above
1515 (define_insn "*add_<shift>_si_uxtw"
1516   [(set (match_operand:DI 0 "register_operand" "=r")
1517         (zero_extend:DI
1518          (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1519                              (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1520                   (match_operand:SI 3 "register_operand" "r"))))]
1521   ""
1522   "add\\t%w0, %w3, %w1, <shift> %2"
1523   [(set_attr "v8type" "alu_shift")
1524    (set_attr "type" "alu_shift_imm")
1525    (set_attr "mode" "SI")]
1528 (define_insn "*add_mul_imm_<mode>"
1529   [(set (match_operand:GPI 0 "register_operand" "=r")
1530         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1531                             (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1532                   (match_operand:GPI 3 "register_operand" "r")))]
1533   ""
1534   "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1535   [(set_attr "v8type" "alu_shift")
1536    (set_attr "type" "alu_shift_imm")
1537    (set_attr "mode" "<MODE>")]
1540 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1541   [(set (match_operand:GPI 0 "register_operand" "=rk")
1542         (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1543                   (match_operand:GPI 2 "register_operand" "r")))]
1544   ""
1545   "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1546   [(set_attr "v8type" "alu_ext")
1547    (set_attr "type" "alu_ext")
1548    (set_attr "mode" "<GPI:MODE>")]
1551 ;; zero_extend version of above
1552 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1553   [(set (match_operand:DI 0 "register_operand" "=rk")
1554         (zero_extend:DI
1555          (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1556                   (match_operand:GPI 2 "register_operand" "r"))))]
1557   ""
1558   "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1559   [(set_attr "v8type" "alu_ext")
1560    (set_attr "type" "alu_ext")
1561    (set_attr "mode" "SI")]
1564 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1565   [(set (match_operand:GPI 0 "register_operand" "=rk")
1566         (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1567                                (match_operand:ALLX 1 "register_operand" "r"))
1568                               (match_operand 2 "aarch64_imm3" "Ui3"))
1569                   (match_operand:GPI 3 "register_operand" "r")))]
1570   ""
1571   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1572   [(set_attr "v8type" "alu_ext")
1573    (set_attr "type" "alu_ext")
1574    (set_attr "mode" "<GPI:MODE>")]
1577 ;; zero_extend version of above
1578 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1579   [(set (match_operand:DI 0 "register_operand" "=rk")
1580         (zero_extend:DI
1581          (plus:SI (ashift:SI (ANY_EXTEND:SI
1582                               (match_operand:SHORT 1 "register_operand" "r"))
1583                              (match_operand 2 "aarch64_imm3" "Ui3"))
1584                   (match_operand:SI 3 "register_operand" "r"))))]
1585   ""
1586   "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1587   [(set_attr "v8type" "alu_ext")
1588    (set_attr "type" "alu_ext")
1589    (set_attr "mode" "SI")]
1592 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1593   [(set (match_operand:GPI 0 "register_operand" "=rk")
1594         (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1595                              (match_operand:ALLX 1 "register_operand" "r"))
1596                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1597                   (match_operand:GPI 3 "register_operand" "r")))]
1598   ""
1599   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1600   [(set_attr "v8type" "alu_ext")
1601    (set_attr "type" "alu_ext")
1602    (set_attr "mode" "<GPI:MODE>")]
1605 ;; zero_extend version of above
1606 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1607   [(set (match_operand:DI 0 "register_operand" "=rk")
1608         (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1609                              (match_operand:SHORT 1 "register_operand" "r"))
1610                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1611                   (match_operand:SI 3 "register_operand" "r"))))]
1612   ""
1613   "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1614   [(set_attr "v8type" "alu_ext")
1615    (set_attr "type" "alu_ext")
1616    (set_attr "mode" "SI")]
1619 (define_insn "*add_<optab><mode>_multp2"
1620   [(set (match_operand:GPI 0 "register_operand" "=rk")
1621         (plus:GPI (ANY_EXTRACT:GPI
1622                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1623                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1624                    (match_operand 3 "const_int_operand" "n")
1625                    (const_int 0))
1626                   (match_operand:GPI 4 "register_operand" "r")))]
1627   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1628   "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1629   [(set_attr "v8type" "alu_ext")
1630    (set_attr "type" "alu_ext")
1631    (set_attr "mode" "<MODE>")]
1634 ;; zero_extend version of above
1635 (define_insn "*add_<optab>si_multp2_uxtw"
1636   [(set (match_operand:DI 0 "register_operand" "=rk")
1637         (zero_extend:DI
1638          (plus:SI (ANY_EXTRACT:SI
1639                    (mult:SI (match_operand:SI 1 "register_operand" "r")
1640                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1641                    (match_operand 3 "const_int_operand" "n")
1642                    (const_int 0))
1643                   (match_operand:SI 4 "register_operand" "r"))))]
1644   "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1645   "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1646   [(set_attr "v8type" "alu_ext")
1647    (set_attr "type" "alu_ext")
1648    (set_attr "mode" "SI")]
1651 (define_insn "*add<mode>3_carryin"
1652   [(set
1653     (match_operand:GPI 0 "register_operand" "=r")
1654     (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1655               (plus:GPI
1656                 (match_operand:GPI 1 "register_operand" "r")
1657                 (match_operand:GPI 2 "register_operand" "r"))))]
1658    ""
1659    "adc\\t%<w>0, %<w>1, %<w>2"
1660   [(set_attr "v8type" "adc")
1661    (set_attr "type" "adc_reg")
1662    (set_attr "mode" "<MODE>")]
1665 ;; zero_extend version of above
1666 (define_insn "*addsi3_carryin_uxtw"
1667   [(set
1668     (match_operand:DI 0 "register_operand" "=r")
1669     (zero_extend:DI
1670      (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1671               (plus:SI
1672                (match_operand:SI 1 "register_operand" "r")
1673                (match_operand:SI 2 "register_operand" "r")))))]
1674    ""
1675    "adc\\t%w0, %w1, %w2"
1676   [(set_attr "v8type" "adc")
1677    (set_attr "type" "adc_reg")
1678    (set_attr "mode" "SI")]
1681 (define_insn "*add<mode>3_carryin_alt1"
1682   [(set
1683     (match_operand:GPI 0 "register_operand" "=r")
1684     (plus:GPI (plus:GPI
1685                 (match_operand:GPI 1 "register_operand" "r")
1686                 (match_operand:GPI 2 "register_operand" "r"))
1687               (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1688    ""
1689    "adc\\t%<w>0, %<w>1, %<w>2"
1690   [(set_attr "v8type" "adc")
1691    (set_attr "type" "adc_reg")
1692    (set_attr "mode" "<MODE>")]
1695 ;; zero_extend version of above
1696 (define_insn "*addsi3_carryin_alt1_uxtw"
1697   [(set
1698     (match_operand:DI 0 "register_operand" "=r")
1699     (zero_extend:DI
1700      (plus:SI (plus:SI
1701                (match_operand:SI 1 "register_operand" "r")
1702                (match_operand:SI 2 "register_operand" "r"))
1703               (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1704    ""
1705    "adc\\t%w0, %w1, %w2"
1706   [(set_attr "v8type" "adc")
1707    (set_attr "type" "adc_reg")
1708    (set_attr "mode" "SI")]
1711 (define_insn "*add<mode>3_carryin_alt2"
1712   [(set
1713     (match_operand:GPI 0 "register_operand" "=r")
1714     (plus:GPI (plus:GPI
1715                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1716                 (match_operand:GPI 1 "register_operand" "r"))
1717               (match_operand:GPI 2 "register_operand" "r")))]
1718    ""
1719    "adc\\t%<w>0, %<w>1, %<w>2"
1720   [(set_attr "v8type" "adc")
1721    (set_attr "type" "adc_reg")
1722    (set_attr "mode" "<MODE>")]
1725 ;; zero_extend version of above
1726 (define_insn "*addsi3_carryin_alt2_uxtw"
1727   [(set
1728     (match_operand:DI 0 "register_operand" "=r")
1729     (zero_extend:DI
1730      (plus:SI (plus:SI
1731                (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1732                (match_operand:SI 1 "register_operand" "r"))
1733               (match_operand:SI 2 "register_operand" "r"))))]
1734    ""
1735    "adc\\t%w0, %w1, %w2"
1736   [(set_attr "v8type" "adc")
1737    (set_attr "type" "adc_reg")
1738    (set_attr "mode" "SI")]
1741 (define_insn "*add<mode>3_carryin_alt3"
1742   [(set
1743     (match_operand:GPI 0 "register_operand" "=r")
1744     (plus:GPI (plus:GPI
1745                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1746                 (match_operand:GPI 2 "register_operand" "r"))
1747               (match_operand:GPI 1 "register_operand" "r")))]
1748    ""
1749    "adc\\t%<w>0, %<w>1, %<w>2"
1750   [(set_attr "v8type" "adc")
1751    (set_attr "type" "adc_reg")
1752    (set_attr "mode" "<MODE>")]
1755 ;; zero_extend version of above
1756 (define_insn "*addsi3_carryin_alt3_uxtw"
1757   [(set
1758     (match_operand:DI 0 "register_operand" "=r")
1759     (zero_extend:DI
1760      (plus:SI (plus:SI
1761                (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1762                (match_operand:SI 2 "register_operand" "r"))
1763               (match_operand:SI 1 "register_operand" "r"))))]
1764    ""
1765    "adc\\t%w0, %w1, %w2"
1766   [(set_attr "v8type" "adc")
1767    (set_attr "type" "adc_reg")
1768    (set_attr "mode" "SI")]
1771 (define_insn "*add_uxt<mode>_multp2"
1772   [(set (match_operand:GPI 0 "register_operand" "=rk")
1773         (plus:GPI (and:GPI
1774                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1775                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1776                    (match_operand 3 "const_int_operand" "n"))
1777                   (match_operand:GPI 4 "register_operand" "r")))]
1778   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1779   "*
1780   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1781                                            INTVAL (operands[3])));
1782   return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1783   [(set_attr "v8type" "alu_ext")
1784    (set_attr "type" "alu_ext")
1785    (set_attr "mode" "<MODE>")]
1788 ;; zero_extend version of above
1789 (define_insn "*add_uxtsi_multp2_uxtw"
1790   [(set (match_operand:DI 0 "register_operand" "=rk")
1791         (zero_extend:DI
1792          (plus:SI (and:SI
1793                    (mult:SI (match_operand:SI 1 "register_operand" "r")
1794                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1795                    (match_operand 3 "const_int_operand" "n"))
1796                   (match_operand:SI 4 "register_operand" "r"))))]
1797   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1798   "*
1799   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1800                                            INTVAL (operands[3])));
1801   return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1802   [(set_attr "v8type" "alu_ext")
1803    (set_attr "type" "alu_ext")
1804    (set_attr "mode" "SI")]
1807 (define_insn "subsi3"
1808   [(set (match_operand:SI 0 "register_operand" "=rk")
1809         (minus:SI (match_operand:SI 1 "register_operand" "r")
1810                    (match_operand:SI 2 "register_operand" "r")))]
1811   ""
1812   "sub\\t%w0, %w1, %w2"
1813   [(set_attr "v8type" "alu")
1814    (set_attr "type" "alu_reg")
1815    (set_attr "mode" "SI")]
1818 ;; zero_extend version of above
1819 (define_insn "*subsi3_uxtw"
1820   [(set (match_operand:DI 0 "register_operand" "=rk")
1821         (zero_extend:DI
1822          (minus:SI (match_operand:SI 1 "register_operand" "r")
1823                    (match_operand:SI 2 "register_operand" "r"))))]
1824   ""
1825   "sub\\t%w0, %w1, %w2"
1826   [(set_attr "v8type" "alu")
1827    (set_attr "type" "alu_reg")
1828    (set_attr "mode" "SI")]
1831 (define_insn "subdi3"
1832   [(set (match_operand:DI 0 "register_operand" "=rk,!w")
1833         (minus:DI (match_operand:DI 1 "register_operand" "r,!w")
1834                    (match_operand:DI 2 "register_operand" "r,!w")))]
1835   ""
1836   "@
1837    sub\\t%x0, %x1, %x2
1838    sub\\t%d0, %d1, %d2"
1839   [(set_attr "v8type" "alu")
1840    (set_attr "type" "alu_reg")
1841    (set_attr "mode" "DI")
1842    (set_attr "simd" "*,yes")]
1846 (define_insn "*sub<mode>3_compare0"
1847   [(set (reg:CC_NZ CC_REGNUM)
1848         (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1849                                   (match_operand:GPI 2 "register_operand" "r"))
1850                        (const_int 0)))
1851    (set (match_operand:GPI 0 "register_operand" "=r")
1852         (minus:GPI (match_dup 1) (match_dup 2)))]
1853   ""
1854   "subs\\t%<w>0, %<w>1, %<w>2"
1855   [(set_attr "v8type" "alus")
1856    (set_attr "type" "alus_reg")
1857    (set_attr "mode" "<MODE>")]
1860 ;; zero_extend version of above
1861 (define_insn "*subsi3_compare0_uxtw"
1862   [(set (reg:CC_NZ CC_REGNUM)
1863         (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1864                                  (match_operand:SI 2 "register_operand" "r"))
1865                        (const_int 0)))
1866    (set (match_operand:DI 0 "register_operand" "=r")
1867         (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1868   ""
1869   "subs\\t%w0, %w1, %w2"
1870   [(set_attr "v8type" "alus")
1871    (set_attr "type" "alus_reg")
1872    (set_attr "mode" "SI")]
1875 (define_insn "*sub_<shift>_<mode>"
1876   [(set (match_operand:GPI 0 "register_operand" "=r")
1877         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1878                    (ASHIFT:GPI
1879                     (match_operand:GPI 1 "register_operand" "r")
1880                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1881   ""
1882   "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1883   [(set_attr "v8type" "alu_shift")
1884    (set_attr "type" "alu_shift_imm")
1885    (set_attr "mode" "<MODE>")]
1888 ;; zero_extend version of above
1889 (define_insn "*sub_<shift>_si_uxtw"
1890   [(set (match_operand:DI 0 "register_operand" "=r")
1891         (zero_extend:DI
1892          (minus:SI (match_operand:SI 3 "register_operand" "r")
1893                    (ASHIFT:SI
1894                     (match_operand:SI 1 "register_operand" "r")
1895                     (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1896   ""
1897   "sub\\t%w0, %w3, %w1, <shift> %2"
1898   [(set_attr "v8type" "alu_shift")
1899    (set_attr "type" "alu_shift_imm")
1900    (set_attr "mode" "SI")]
1903 (define_insn "*sub_mul_imm_<mode>"
1904   [(set (match_operand:GPI 0 "register_operand" "=r")
1905         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1906                    (mult:GPI
1907                     (match_operand:GPI 1 "register_operand" "r")
1908                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1909   ""
1910   "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1911   [(set_attr "v8type" "alu_shift")
1912    (set_attr "type" "alu_shift_imm")
1913    (set_attr "mode" "<MODE>")]
1916 ;; zero_extend version of above
1917 (define_insn "*sub_mul_imm_si_uxtw"
1918   [(set (match_operand:DI 0 "register_operand" "=r")
1919         (zero_extend:DI
1920          (minus:SI (match_operand:SI 3 "register_operand" "r")
1921                    (mult:SI
1922                     (match_operand:SI 1 "register_operand" "r")
1923                     (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
1924   ""
1925   "sub\\t%w0, %w3, %w1, lsl %p2"
1926   [(set_attr "v8type" "alu_shift")
1927    (set_attr "type" "alu_shift_imm")
1928    (set_attr "mode" "SI")]
1931 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
1932   [(set (match_operand:GPI 0 "register_operand" "=rk")
1933         (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1934                    (ANY_EXTEND:GPI
1935                     (match_operand:ALLX 2 "register_operand" "r"))))]
1936   ""
1937   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1938   [(set_attr "v8type" "alu_ext")
1939    (set_attr "type" "alu_ext")
1940    (set_attr "mode" "<GPI:MODE>")]
1943 ;; zero_extend version of above
1944 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
1945   [(set (match_operand:DI 0 "register_operand" "=rk")
1946         (zero_extend:DI
1947          (minus:SI (match_operand:SI 1 "register_operand" "r")
1948                    (ANY_EXTEND:SI
1949                     (match_operand:SHORT 2 "register_operand" "r")))))]
1950   ""
1951   "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
1952   [(set_attr "v8type" "alu_ext")
1953    (set_attr "type" "alu_ext")
1954    (set_attr "mode" "SI")]
1957 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
1958   [(set (match_operand:GPI 0 "register_operand" "=rk")
1959         (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1960                    (ashift:GPI (ANY_EXTEND:GPI
1961                                 (match_operand:ALLX 2 "register_operand" "r"))
1962                                (match_operand 3 "aarch64_imm3" "Ui3"))))]
1963   ""
1964   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1965   [(set_attr "v8type" "alu_ext")
1966    (set_attr "type" "alu_ext")
1967    (set_attr "mode" "<GPI:MODE>")]
1970 ;; zero_extend version of above
1971 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
1972   [(set (match_operand:DI 0 "register_operand" "=rk")
1973         (zero_extend:DI
1974          (minus:SI (match_operand:SI 1 "register_operand" "r")
1975                    (ashift:SI (ANY_EXTEND:SI
1976                                (match_operand:SHORT 2 "register_operand" "r"))
1977                               (match_operand 3 "aarch64_imm3" "Ui3")))))]
1978   ""
1979   "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
1980   [(set_attr "v8type" "alu_ext")
1981    (set_attr "type" "alu_ext")
1982    (set_attr "mode" "SI")]
1985 (define_insn "*sub_<optab><mode>_multp2"
1986   [(set (match_operand:GPI 0 "register_operand" "=rk")
1987         (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1988                    (ANY_EXTRACT:GPI
1989                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1990                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1991                     (match_operand 3 "const_int_operand" "n")
1992                     (const_int 0))))]
1993   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1994   "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1995   [(set_attr "v8type" "alu_ext")
1996    (set_attr "type" "alu_ext")
1997    (set_attr "mode" "<MODE>")]
2000 ;; zero_extend version of above
2001 (define_insn "*sub_<optab>si_multp2_uxtw"
2002   [(set (match_operand:DI 0 "register_operand" "=rk")
2003         (zero_extend:DI
2004          (minus:SI (match_operand:SI 4 "register_operand" "r")
2005                    (ANY_EXTRACT:SI
2006                     (mult:SI (match_operand:SI 1 "register_operand" "r")
2007                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2008                     (match_operand 3 "const_int_operand" "n")
2009                     (const_int 0)))))]
2010   "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
2011   "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
2012   [(set_attr "v8type" "alu_ext")
2013    (set_attr "type" "alu_ext")
2014    (set_attr "mode" "SI")]
2017 (define_insn "*sub<mode>3_carryin"
2018   [(set
2019     (match_operand:GPI 0 "register_operand" "=r")
2020     (minus:GPI (minus:GPI
2021                 (match_operand:GPI 1 "register_operand" "r")
2022                 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2023                (match_operand:GPI 2 "register_operand" "r")))]
2024    ""
2025    "sbc\\t%<w>0, %<w>1, %<w>2"
2026   [(set_attr "v8type" "adc")
2027    (set_attr "type" "adc_reg")
2028    (set_attr "mode" "<MODE>")]
2031 ;; zero_extend version of the above
2032 (define_insn "*subsi3_carryin_uxtw"
2033   [(set
2034     (match_operand:DI 0 "register_operand" "=r")
2035     (zero_extend:DI
2036      (minus:SI (minus:SI
2037                 (match_operand:SI 1 "register_operand" "r")
2038                 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2039                (match_operand:SI 2 "register_operand" "r"))))]
2040    ""
2041    "sbc\\t%w0, %w1, %w2"
2042   [(set_attr "v8type" "adc")
2043    (set_attr "type" "adc_reg")
2044    (set_attr "mode" "SI")]
2047 (define_insn "*sub_uxt<mode>_multp2"
2048   [(set (match_operand:GPI 0 "register_operand" "=rk")
2049         (minus:GPI (match_operand:GPI 4 "register_operand" "r")
2050                    (and:GPI
2051                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2052                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2053                     (match_operand 3 "const_int_operand" "n"))))]
2054   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2055   "*
2056   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2057                                            INTVAL (operands[3])));
2058   return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
2059   [(set_attr "v8type" "alu_ext")
2060    (set_attr "type" "alu_ext")
2061    (set_attr "mode" "<MODE>")]
2064 ;; zero_extend version of above
2065 (define_insn "*sub_uxtsi_multp2_uxtw"
2066   [(set (match_operand:DI 0 "register_operand" "=rk")
2067         (zero_extend:DI
2068          (minus:SI (match_operand:SI 4 "register_operand" "r")
2069                    (and:SI
2070                     (mult:SI (match_operand:SI 1 "register_operand" "r")
2071                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2072                     (match_operand 3 "const_int_operand" "n")))))]
2073   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2074   "*
2075   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2076                                            INTVAL (operands[3])));
2077   return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
2078   [(set_attr "v8type" "alu_ext")
2079    (set_attr "type" "alu_ext")
2080    (set_attr "mode" "SI")]
2083 (define_insn_and_split "absdi2"
2084   [(set (match_operand:DI 0 "register_operand" "=r,w")
2085         (abs:DI (match_operand:DI 1 "register_operand" "r,w")))
2086    (clobber (match_scratch:DI 2 "=&r,X"))]
2087   ""
2088   "@
2089    #
2090    abs\\t%d0, %d1"
2091   "reload_completed
2092    && GP_REGNUM_P (REGNO (operands[0]))
2093    && GP_REGNUM_P (REGNO (operands[1]))"
2094   [(const_int 0)]
2095   {
2096     emit_insn (gen_rtx_SET (VOIDmode, operands[2],
2097                             gen_rtx_XOR (DImode,
2098                                          gen_rtx_ASHIFTRT (DImode,
2099                                                            operands[1],
2100                                                            GEN_INT (63)),
2101                                          operands[1])));
2102     emit_insn (gen_rtx_SET (VOIDmode,
2103                             operands[0],
2104                             gen_rtx_MINUS (DImode,
2105                                            operands[2],
2106                                            gen_rtx_ASHIFTRT (DImode,
2107                                                              operands[1],
2108                                                              GEN_INT (63)))));
2109     DONE;
2110   }
2111   [(set_attr "v8type" "alu")
2112    (set_attr "type" "alu_reg")
2113    (set_attr "mode" "DI")]
2116 (define_insn "neg<mode>2"
2117   [(set (match_operand:GPI 0 "register_operand" "=r,w")
2118         (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
2119   ""
2120   "@
2121    neg\\t%<w>0, %<w>1
2122    neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
2123   [(set_attr "v8type" "alu")
2124    (set_attr "type" "alu_reg")
2125    (set_attr "simd_type" "*,simd_negabs")
2126    (set_attr "simd" "*,yes")
2127    (set_attr "mode" "<MODE>")
2128    (set_attr "simd_mode" "<MODE>")]
2131 ;; zero_extend version of above
2132 (define_insn "*negsi2_uxtw"
2133   [(set (match_operand:DI 0 "register_operand" "=r")
2134         (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
2135   ""
2136   "neg\\t%w0, %w1"
2137   [(set_attr "v8type" "alu")
2138    (set_attr "type" "alu_reg")
2139    (set_attr "mode" "SI")]
2142 (define_insn "*ngc<mode>"
2143   [(set (match_operand:GPI 0 "register_operand" "=r")
2144         (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2145                    (match_operand:GPI 1 "register_operand" "r")))]
2146   ""
2147   "ngc\\t%<w>0, %<w>1"
2148   [(set_attr "v8type" "adc")
2149    (set_attr "type" "adc_reg")
2150    (set_attr "mode" "<MODE>")]
2153 (define_insn "*ngcsi_uxtw"
2154   [(set (match_operand:DI 0 "register_operand" "=r")
2155         (zero_extend:DI
2156          (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2157                    (match_operand:SI 1 "register_operand" "r"))))]
2158   ""
2159   "ngc\\t%w0, %w1"
2160   [(set_attr "v8type" "adc")
2161    (set_attr "type" "adc_reg")
2162    (set_attr "mode" "SI")]
2165 (define_insn "*neg<mode>2_compare0"
2166   [(set (reg:CC_NZ CC_REGNUM)
2167         (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2168                        (const_int 0)))
2169    (set (match_operand:GPI 0 "register_operand" "=r")
2170         (neg:GPI (match_dup 1)))]
2171   ""
2172   "negs\\t%<w>0, %<w>1"
2173   [(set_attr "v8type" "alus")
2174    (set_attr "type" "alus_reg")
2175    (set_attr "mode" "<MODE>")]
2178 ;; zero_extend version of above
2179 (define_insn "*negsi2_compare0_uxtw"
2180   [(set (reg:CC_NZ CC_REGNUM)
2181         (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
2182                        (const_int 0)))
2183    (set (match_operand:DI 0 "register_operand" "=r")
2184         (zero_extend:DI (neg:SI (match_dup 1))))]
2185   ""
2186   "negs\\t%w0, %w1"
2187   [(set_attr "v8type" "alus")
2188    (set_attr "type" "alus_reg")
2189    (set_attr "mode" "SI")]
2192 (define_insn "*neg_<shift><mode>3_compare0"
2193   [(set (reg:CC_NZ CC_REGNUM)
2194         (compare:CC_NZ
2195          (neg:GPI (ASHIFT:GPI
2196                    (match_operand:GPI 1 "register_operand" "r")
2197                    (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2198          (const_int 0)))
2199    (set (match_operand:GPI 0 "register_operand" "=r")
2200         (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2201   ""
2202   "negs\\t%<w>0, %<w>1, <shift> %2"
2203   [(set_attr "v8type" "alus_shift")
2204    (set_attr "type" "alus_shift_imm")
2205    (set_attr "mode" "<MODE>")]
2208 (define_insn "*neg_<shift>_<mode>2"
2209   [(set (match_operand:GPI 0 "register_operand" "=r")
2210         (neg:GPI (ASHIFT:GPI
2211                   (match_operand:GPI 1 "register_operand" "r")
2212                   (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2213   ""
2214   "neg\\t%<w>0, %<w>1, <shift> %2"
2215   [(set_attr "v8type" "alu_shift")
2216    (set_attr "type" "alu_shift_imm")
2217    (set_attr "mode" "<MODE>")]
2220 ;; zero_extend version of above
2221 (define_insn "*neg_<shift>_si2_uxtw"
2222   [(set (match_operand:DI 0 "register_operand" "=r")
2223         (zero_extend:DI
2224          (neg:SI (ASHIFT:SI
2225                   (match_operand:SI 1 "register_operand" "r")
2226                   (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2227   ""
2228   "neg\\t%w0, %w1, <shift> %2"
2229   [(set_attr "v8type" "alu_shift")
2230    (set_attr "type" "alu_shift_imm")
2231    (set_attr "mode" "SI")]
2234 (define_insn "*neg_mul_imm_<mode>2"
2235   [(set (match_operand:GPI 0 "register_operand" "=r")
2236         (neg:GPI (mult:GPI
2237                   (match_operand:GPI 1 "register_operand" "r")
2238                   (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2239   ""
2240   "neg\\t%<w>0, %<w>1, lsl %p2"
2241   [(set_attr "v8type" "alu_shift")
2242    (set_attr "type" "alu_shift_imm")
2243    (set_attr "mode" "<MODE>")]
2246 ;; zero_extend version of above
2247 (define_insn "*neg_mul_imm_si2_uxtw"
2248   [(set (match_operand:DI 0 "register_operand" "=r")
2249         (zero_extend:DI
2250          (neg:SI (mult:SI
2251                   (match_operand:SI 1 "register_operand" "r")
2252                   (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2253   ""
2254   "neg\\t%w0, %w1, lsl %p2"
2255   [(set_attr "v8type" "alu_shift")
2256    (set_attr "type" "alu_shift_imm")
2257    (set_attr "mode" "SI")]
2260 (define_insn "mul<mode>3"
2261   [(set (match_operand:GPI 0 "register_operand" "=r")
2262         (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2263                   (match_operand:GPI 2 "register_operand" "r")))]
2264   ""
2265   "mul\\t%<w>0, %<w>1, %<w>2"
2266   [(set_attr "v8type" "mult")
2267    (set_attr "type" "mul")
2268    (set_attr "mode" "<MODE>")]
2271 ;; zero_extend version of above
2272 (define_insn "*mulsi3_uxtw"
2273   [(set (match_operand:DI 0 "register_operand" "=r")
2274         (zero_extend:DI
2275          (mult:SI (match_operand:SI 1 "register_operand" "r")
2276                   (match_operand:SI 2 "register_operand" "r"))))]
2277   ""
2278   "mul\\t%w0, %w1, %w2"
2279   [(set_attr "v8type" "mult")
2280    (set_attr "type" "mul")
2281    (set_attr "mode" "SI")]
2284 (define_insn "*madd<mode>"
2285   [(set (match_operand:GPI 0 "register_operand" "=r")
2286         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2287                             (match_operand:GPI 2 "register_operand" "r"))
2288                   (match_operand:GPI 3 "register_operand" "r")))]
2289   ""
2290   "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2291   [(set_attr "v8type" "madd")
2292    (set_attr "type" "mla")
2293    (set_attr "mode" "<MODE>")]
2296 ;; zero_extend version of above
2297 (define_insn "*maddsi_uxtw"
2298   [(set (match_operand:DI 0 "register_operand" "=r")
2299         (zero_extend:DI
2300          (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2301                            (match_operand:SI 2 "register_operand" "r"))
2302                   (match_operand:SI 3 "register_operand" "r"))))]
2303   ""
2304   "madd\\t%w0, %w1, %w2, %w3"
2305   [(set_attr "v8type" "madd")
2306    (set_attr "type" "mla")
2307    (set_attr "mode" "SI")]
2310 (define_insn "*msub<mode>"
2311   [(set (match_operand:GPI 0 "register_operand" "=r")
2312         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2313                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2314                              (match_operand:GPI 2 "register_operand" "r"))))]
2316   ""
2317   "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2318   [(set_attr "v8type" "madd")
2319    (set_attr "type" "mla")
2320    (set_attr "mode" "<MODE>")]
2323 ;; zero_extend version of above
2324 (define_insn "*msubsi_uxtw"
2325   [(set (match_operand:DI 0 "register_operand" "=r")
2326         (zero_extend:DI
2327          (minus:SI (match_operand:SI 3 "register_operand" "r")
2328                    (mult:SI (match_operand:SI 1 "register_operand" "r")
2329                             (match_operand:SI 2 "register_operand" "r")))))]
2331   ""
2332   "msub\\t%w0, %w1, %w2, %w3"
2333   [(set_attr "v8type" "madd")
2334    (set_attr "type" "mla")
2335    (set_attr "mode" "SI")]
2338 (define_insn "*mul<mode>_neg"
2339   [(set (match_operand:GPI 0 "register_operand" "=r")
2340         (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2341                   (match_operand:GPI 2 "register_operand" "r")))]
2343   ""
2344   "mneg\\t%<w>0, %<w>1, %<w>2"
2345   [(set_attr "v8type" "mult")
2346    (set_attr "type" "mul")
2347    (set_attr "mode" "<MODE>")]
2350 ;; zero_extend version of above
2351 (define_insn "*mulsi_neg_uxtw"
2352   [(set (match_operand:DI 0 "register_operand" "=r")
2353         (zero_extend:DI
2354          (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2355                   (match_operand:SI 2 "register_operand" "r"))))]
2357   ""
2358   "mneg\\t%w0, %w1, %w2"
2359   [(set_attr "v8type" "mult")
2360    (set_attr "type" "mul")
2361    (set_attr "mode" "SI")]
2364 (define_insn "<su_optab>mulsidi3"
2365   [(set (match_operand:DI 0 "register_operand" "=r")
2366         (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2367                  (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2368   ""
2369   "<su>mull\\t%0, %w1, %w2"
2370   [(set_attr "v8type" "mull")
2371    (set_attr "type" "<su>mull")
2372    (set_attr "mode" "DI")]
2375 (define_insn "<su_optab>maddsidi4"
2376   [(set (match_operand:DI 0 "register_operand" "=r")
2377         (plus:DI (mult:DI
2378                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2379                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2380                  (match_operand:DI 3 "register_operand" "r")))]
2381   ""
2382   "<su>maddl\\t%0, %w1, %w2, %3"
2383   [(set_attr "v8type" "maddl")
2384    (set_attr "type" "<su>mlal")
2385    (set_attr "mode" "DI")]
2388 (define_insn "<su_optab>msubsidi4"
2389   [(set (match_operand:DI 0 "register_operand" "=r")
2390         (minus:DI
2391          (match_operand:DI 3 "register_operand" "r")
2392          (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2393                   (ANY_EXTEND:DI
2394                    (match_operand:SI 2 "register_operand" "r")))))]
2395   ""
2396   "<su>msubl\\t%0, %w1, %w2, %3"
2397   [(set_attr "v8type" "maddl")
2398    (set_attr "type" "<su>mlal")
2399    (set_attr "mode" "DI")]
2402 (define_insn "*<su_optab>mulsidi_neg"
2403   [(set (match_operand:DI 0 "register_operand" "=r")
2404         (mult:DI (neg:DI
2405                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2406                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2407   ""
2408   "<su>mnegl\\t%0, %w1, %w2"
2409   [(set_attr "v8type" "mull")
2410    (set_attr "type" "<su>mull")
2411    (set_attr "mode" "DI")]
2414 (define_insn "<su>muldi3_highpart"
2415   [(set (match_operand:DI 0 "register_operand" "=r")
2416         (truncate:DI
2417          (lshiftrt:TI
2418           (mult:TI
2419            (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2420            (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2421           (const_int 64))))]
2422   ""
2423   "<su>mulh\\t%0, %1, %2"
2424   [(set_attr "v8type" "mulh")
2425    (set_attr "type" "<su>mull")
2426    (set_attr "mode" "DI")]
2429 (define_insn "<su_optab>div<mode>3"
2430   [(set (match_operand:GPI 0 "register_operand" "=r")
2431         (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2432                      (match_operand:GPI 2 "register_operand" "r")))]
2433   ""
2434   "<su>div\\t%<w>0, %<w>1, %<w>2"
2435   [(set_attr "v8type" "<su>div")
2436    (set_attr "type" "<su>div")
2437    (set_attr "mode" "<MODE>")]
2440 ;; zero_extend version of above
2441 (define_insn "*<su_optab>divsi3_uxtw"
2442   [(set (match_operand:DI 0 "register_operand" "=r")
2443         (zero_extend:DI
2444          (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2445                      (match_operand:SI 2 "register_operand" "r"))))]
2446   ""
2447   "<su>div\\t%w0, %w1, %w2"
2448   [(set_attr "v8type" "<su>div")
2449    (set_attr "type" "<su>div")
2450    (set_attr "mode" "SI")]
2453 ;; -------------------------------------------------------------------
2454 ;; Comparison insns
2455 ;; -------------------------------------------------------------------
2457 (define_insn "*cmp<mode>"
2458   [(set (reg:CC CC_REGNUM)
2459         (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2460                     (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2461   ""
2462   "@
2463    cmp\\t%<w>0, %<w>1
2464    cmp\\t%<w>0, %<w>1
2465    cmn\\t%<w>0, #%n1"
2466   [(set_attr "v8type" "alus")
2467    (set_attr "type" "alus_reg,alus_imm,alus_imm")
2468    (set_attr "mode" "<MODE>")]
2471 (define_insn "*cmp<mode>"
2472   [(set (reg:CCFP CC_REGNUM)
2473         (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2474                       (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2475    "TARGET_FLOAT"
2476    "@
2477     fcmp\\t%<s>0, #0.0
2478     fcmp\\t%<s>0, %<s>1"
2479   [(set_attr "v8type" "fcmp")
2480    (set_attr "type" "fcmp<s>")
2481    (set_attr "mode" "<MODE>")]
2484 (define_insn "*cmpe<mode>"
2485   [(set (reg:CCFPE CC_REGNUM)
2486         (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2487                        (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2488    "TARGET_FLOAT"
2489    "@
2490     fcmpe\\t%<s>0, #0.0
2491     fcmpe\\t%<s>0, %<s>1"
2492   [(set_attr "v8type" "fcmp")
2493    (set_attr "type" "fcmp<s>")
2494    (set_attr "mode" "<MODE>")]
2497 (define_insn "*cmp_swp_<shift>_reg<mode>"
2498   [(set (reg:CC_SWP CC_REGNUM)
2499         (compare:CC_SWP (ASHIFT:GPI
2500                          (match_operand:GPI 0 "register_operand" "r")
2501                          (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2502                         (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2503   ""
2504   "cmp\\t%<w>2, %<w>0, <shift> %1"
2505   [(set_attr "v8type" "alus_shift")
2506    (set_attr "type" "alus_shift_imm")
2507    (set_attr "mode" "<MODE>")]
2510 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2511   [(set (reg:CC_SWP CC_REGNUM)
2512         (compare:CC_SWP (ANY_EXTEND:GPI
2513                          (match_operand:ALLX 0 "register_operand" "r"))
2514                         (match_operand:GPI 1 "register_operand" "r")))]
2515   ""
2516   "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2517   [(set_attr "v8type" "alus_ext")
2518    (set_attr "type" "alus_ext")
2519    (set_attr "mode" "<GPI:MODE>")]
2522 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2523   [(set (reg:CC_SWP CC_REGNUM)
2524         (compare:CC_SWP (ashift:GPI
2525                          (ANY_EXTEND:GPI
2526                           (match_operand:ALLX 0 "register_operand" "r"))
2527                          (match_operand 1 "aarch64_imm3" "Ui3"))
2528         (match_operand:GPI 2 "register_operand" "r")))]
2529   ""
2530   "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2531   [(set_attr "v8type" "alus_ext")
2532    (set_attr "type" "alus_ext")
2533    (set_attr "mode" "<GPI:MODE>")]
2536 ;; -------------------------------------------------------------------
2537 ;; Store-flag and conditional select insns
2538 ;; -------------------------------------------------------------------
2540 (define_expand "cstore<mode>4"
2541   [(set (match_operand:SI 0 "register_operand" "")
2542         (match_operator:SI 1 "aarch64_comparison_operator"
2543          [(match_operand:GPI 2 "register_operand" "")
2544           (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2545   ""
2546   "
2547   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2548                                       operands[3]);
2549   operands[3] = const0_rtx;
2550   "
2553 (define_expand "cstore<mode>4"
2554   [(set (match_operand:SI 0 "register_operand" "")
2555         (match_operator:SI 1 "aarch64_comparison_operator"
2556          [(match_operand:GPF 2 "register_operand" "")
2557           (match_operand:GPF 3 "register_operand" "")]))]
2558   ""
2559   "
2560   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2561                                       operands[3]);
2562   operands[3] = const0_rtx;
2563   "
2566 (define_insn "*cstore<mode>_insn"
2567   [(set (match_operand:ALLI 0 "register_operand" "=r")
2568         (match_operator:ALLI 1 "aarch64_comparison_operator"
2569          [(match_operand 2 "cc_register" "") (const_int 0)]))]
2570   ""
2571   "cset\\t%<w>0, %m1"
2572   [(set_attr "v8type" "csel")
2573    (set_attr "type" "csel")
2574    (set_attr "mode" "<MODE>")]
2577 ;; zero_extend version of the above
2578 (define_insn "*cstoresi_insn_uxtw"
2579   [(set (match_operand:DI 0 "register_operand" "=r")
2580         (zero_extend:DI
2581          (match_operator:SI 1 "aarch64_comparison_operator"
2582           [(match_operand 2 "cc_register" "") (const_int 0)])))]
2583   ""
2584   "cset\\t%w0, %m1"
2585   [(set_attr "v8type" "csel")
2586    (set_attr "type" "csel")
2587    (set_attr "mode" "SI")]
2590 (define_insn "cstore<mode>_neg"
2591   [(set (match_operand:ALLI 0 "register_operand" "=r")
2592         (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2593                   [(match_operand 2 "cc_register" "") (const_int 0)])))]
2594   ""
2595   "csetm\\t%<w>0, %m1"
2596   [(set_attr "v8type" "csel")
2597    (set_attr "type" "csel")
2598    (set_attr "mode" "<MODE>")]
2601 ;; zero_extend version of the above
2602 (define_insn "*cstoresi_neg_uxtw"
2603   [(set (match_operand:DI 0 "register_operand" "=r")
2604         (zero_extend:DI
2605          (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2606                   [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2607   ""
2608   "csetm\\t%w0, %m1"
2609   [(set_attr "v8type" "csel")
2610    (set_attr "type" "csel")
2611    (set_attr "mode" "SI")]
2614 (define_expand "cmov<mode>6"
2615   [(set (match_operand:GPI 0 "register_operand" "")
2616         (if_then_else:GPI
2617          (match_operator 1 "aarch64_comparison_operator"
2618           [(match_operand:GPI 2 "register_operand" "")
2619            (match_operand:GPI 3 "aarch64_plus_operand" "")])
2620          (match_operand:GPI 4 "register_operand" "")
2621          (match_operand:GPI 5 "register_operand" "")))]
2622   ""
2623   "
2624   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2625                                       operands[3]);
2626   operands[3] = const0_rtx;
2627   "
2630 (define_expand "cmov<mode>6"
2631   [(set (match_operand:GPF 0 "register_operand" "")
2632         (if_then_else:GPF
2633          (match_operator 1 "aarch64_comparison_operator"
2634           [(match_operand:GPF 2 "register_operand" "")
2635            (match_operand:GPF 3 "register_operand" "")])
2636          (match_operand:GPF 4 "register_operand" "")
2637          (match_operand:GPF 5 "register_operand" "")))]
2638   ""
2639   "
2640   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2641                                       operands[3]);
2642   operands[3] = const0_rtx;
2643   "
2646 (define_insn "*cmov<mode>_insn"
2647   [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2648         (if_then_else:ALLI
2649          (match_operator 1 "aarch64_comparison_operator"
2650           [(match_operand 2 "cc_register" "") (const_int 0)])
2651          (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2652          (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2653   "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2654      || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2655   ;; Final two alternatives should be unreachable, but included for completeness
2656   "@
2657    csel\\t%<w>0, %<w>3, %<w>4, %m1
2658    csinv\\t%<w>0, %<w>3, <w>zr, %m1
2659    csinv\\t%<w>0, %<w>4, <w>zr, %M1
2660    csinc\\t%<w>0, %<w>3, <w>zr, %m1
2661    csinc\\t%<w>0, %<w>4, <w>zr, %M1
2662    mov\\t%<w>0, -1
2663    mov\\t%<w>0, 1"
2664   [(set_attr "v8type" "csel")
2665    (set_attr "type" "csel")
2666    (set_attr "mode" "<MODE>")]
2669 ;; zero_extend version of above
2670 (define_insn "*cmovsi_insn_uxtw"
2671   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2672         (zero_extend:DI
2673          (if_then_else:SI
2674           (match_operator 1 "aarch64_comparison_operator"
2675            [(match_operand 2 "cc_register" "") (const_int 0)])
2676           (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2677           (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2678   "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2679      || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2680   ;; Final two alternatives should be unreachable, but included for completeness
2681   "@
2682    csel\\t%w0, %w3, %w4, %m1
2683    csinv\\t%w0, %w3, wzr, %m1
2684    csinv\\t%w0, %w4, wzr, %M1
2685    csinc\\t%w0, %w3, wzr, %m1
2686    csinc\\t%w0, %w4, wzr, %M1
2687    mov\\t%w0, -1
2688    mov\\t%w0, 1"
2689   [(set_attr "v8type" "csel")
2690    (set_attr "type" "csel")
2691    (set_attr "mode" "SI")]
2694 (define_insn "*cmov<mode>_insn"
2695   [(set (match_operand:GPF 0 "register_operand" "=w")
2696         (if_then_else:GPF
2697          (match_operator 1 "aarch64_comparison_operator"
2698           [(match_operand 2 "cc_register" "") (const_int 0)])
2699          (match_operand:GPF 3 "register_operand" "w")
2700          (match_operand:GPF 4 "register_operand" "w")))]
2701   "TARGET_FLOAT"
2702   "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2703   [(set_attr "v8type" "fcsel")
2704    (set_attr "type" "fcsel")
2705    (set_attr "mode" "<MODE>")]
2708 (define_expand "mov<mode>cc"
2709   [(set (match_operand:ALLI 0 "register_operand" "")
2710         (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2711                            (match_operand:ALLI 2 "register_operand" "")
2712                            (match_operand:ALLI 3 "register_operand" "")))]
2713   ""
2714   {
2715     rtx ccreg;
2716     enum rtx_code code = GET_CODE (operands[1]);
2718     if (code == UNEQ || code == LTGT)
2719       FAIL;
2721     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2722                                   XEXP (operands[1], 1));
2723     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2724   }
2727 (define_expand "mov<GPF:mode><GPI:mode>cc"
2728   [(set (match_operand:GPI 0 "register_operand" "")
2729         (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2730                           (match_operand:GPF 2 "register_operand" "")
2731                           (match_operand:GPF 3 "register_operand" "")))]
2732   ""
2733   {
2734     rtx ccreg;
2735     enum rtx_code code = GET_CODE (operands[1]);
2737     if (code == UNEQ || code == LTGT)
2738       FAIL;
2740     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2741                                   XEXP (operands[1], 1));
2742     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2743   }
2746 (define_insn "*csinc2<mode>_insn"
2747   [(set (match_operand:GPI 0 "register_operand" "=r")
2748         (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator"
2749                   [(match_operand:CC 3 "cc_register" "") (const_int 0)])
2750                  (match_operand:GPI 1 "register_operand" "r")))]
2751   ""
2752   "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2753   [(set_attr "v8type" "csel")
2754    (set_attr "type" "csel")
2755    (set_attr "mode" "<MODE>")])
2757 (define_insn "csinc3<mode>_insn"
2758   [(set (match_operand:GPI 0 "register_operand" "=r")
2759         (if_then_else:GPI
2760           (match_operator:GPI 1 "aarch64_comparison_operator"
2761            [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2762           (plus:GPI (match_operand:GPI 3 "register_operand" "r")
2763                     (const_int 1))
2764           (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2765   ""
2766   "csinc\\t%<w>0, %<w>4, %<w>3, %M1"
2767   [(set_attr "v8type" "csel")
2768    (set_attr "type" "csel")
2769    (set_attr "mode" "<MODE>")]
2772 (define_insn "*csinv3<mode>_insn"
2773   [(set (match_operand:GPI 0 "register_operand" "=r")
2774         (if_then_else:GPI
2775           (match_operator:GPI 1 "aarch64_comparison_operator"
2776            [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2777           (not:GPI (match_operand:GPI 3 "register_operand" "r"))
2778           (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2779   ""
2780   "csinv\\t%<w>0, %<w>4, %<w>3, %M1"
2781   [(set_attr "v8type" "csel")
2782    (set_attr "type" "csel")
2783    (set_attr "mode" "<MODE>")])
2785 (define_insn "*csneg3<mode>_insn"
2786   [(set (match_operand:GPI 0 "register_operand" "=r")
2787         (if_then_else:GPI
2788           (match_operator:GPI 1 "aarch64_comparison_operator"
2789            [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2790           (neg:GPI (match_operand:GPI 3 "register_operand" "r"))
2791           (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2792   ""
2793   "csneg\\t%<w>0, %<w>4, %<w>3, %M1"
2794   [(set_attr "v8type" "csel")
2795    (set_attr "type" "csel")
2796    (set_attr "mode" "<MODE>")])
2798 ;; -------------------------------------------------------------------
2799 ;; Logical operations
2800 ;; -------------------------------------------------------------------
2802 (define_insn "<optab><mode>3"
2803   [(set (match_operand:GPI 0 "register_operand" "=r,rk")
2804         (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2805                      (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
2806   ""
2807   "<logical>\\t%<w>0, %<w>1, %<w>2"
2808   [(set_attr "v8type" "logic,logic_imm")
2809    (set_attr "type" "logic_reg,logic_imm")
2810    (set_attr "mode" "<MODE>")])
2812 ;; zero_extend version of above
2813 (define_insn "*<optab>si3_uxtw"
2814   [(set (match_operand:DI 0 "register_operand" "=r,rk")
2815         (zero_extend:DI
2816          (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2817                      (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2818   ""
2819   "<logical>\\t%w0, %w1, %w2"
2820   [(set_attr "v8type" "logic,logic_imm")
2821    (set_attr "type" "logic_reg,logic_imm")
2822    (set_attr "mode" "SI")])
2824 (define_insn "*and<mode>3_compare0"
2825   [(set (reg:CC_NZ CC_REGNUM)
2826         (compare:CC_NZ
2827          (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2828                   (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2829          (const_int 0)))
2830    (set (match_operand:GPI 0 "register_operand" "=r,r")
2831         (and:GPI (match_dup 1) (match_dup 2)))]
2832   ""
2833   "ands\\t%<w>0, %<w>1, %<w>2"
2834   [(set_attr "v8type" "logics,logics_imm")
2835    (set_attr "type" "logics_reg,logics_imm")
2836    (set_attr "mode" "<MODE>")]
2839 ;; zero_extend version of above
2840 (define_insn "*andsi3_compare0_uxtw"
2841   [(set (reg:CC_NZ CC_REGNUM)
2842         (compare:CC_NZ
2843          (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2844                  (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2845          (const_int 0)))
2846    (set (match_operand:DI 0 "register_operand" "=r,r")
2847         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2848   ""
2849   "ands\\t%w0, %w1, %w2"
2850   [(set_attr "v8type" "logics,logics_imm")
2851    (set_attr "type" "logics_reg,logics_imm")
2852    (set_attr "mode" "SI")]
2855 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2856   [(set (reg:CC_NZ CC_REGNUM)
2857         (compare:CC_NZ
2858          (and:GPI (SHIFT:GPI
2859                    (match_operand:GPI 1 "register_operand" "r")
2860                    (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2861                   (match_operand:GPI 3 "register_operand" "r"))
2862          (const_int 0)))
2863    (set (match_operand:GPI 0 "register_operand" "=r")
2864         (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2865   ""
2866   "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2867   [(set_attr "v8type" "logics_shift")
2868    (set_attr "type" "logics_shift_imm")
2869    (set_attr "mode" "<MODE>")]
2872 ;; zero_extend version of above
2873 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2874   [(set (reg:CC_NZ CC_REGNUM)
2875         (compare:CC_NZ
2876          (and:SI (SHIFT:SI
2877                   (match_operand:SI 1 "register_operand" "r")
2878                   (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2879                  (match_operand:SI 3 "register_operand" "r"))
2880          (const_int 0)))
2881    (set (match_operand:DI 0 "register_operand" "=r")
2882         (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2883                                 (match_dup 3))))]
2884   ""
2885   "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2886   [(set_attr "v8type" "logics_shift")
2887    (set_attr "type" "logics_shift_imm")
2888    (set_attr "mode" "SI")]
2891 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2892   [(set (match_operand:GPI 0 "register_operand" "=r")
2893         (LOGICAL:GPI (SHIFT:GPI
2894                       (match_operand:GPI 1 "register_operand" "r")
2895                       (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2896                      (match_operand:GPI 3 "register_operand" "r")))]
2897   ""
2898   "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2899   [(set_attr "v8type" "logic_shift")
2900    (set_attr "type" "logic_shift_imm")
2901    (set_attr "mode" "<MODE>")])
2903 ;; zero_extend version of above
2904 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
2905   [(set (match_operand:DI 0 "register_operand" "=r")
2906         (zero_extend:DI
2907          (LOGICAL:SI (SHIFT:SI
2908                       (match_operand:SI 1 "register_operand" "r")
2909                       (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2910                      (match_operand:SI 3 "register_operand" "r"))))]
2911   ""
2912   "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2913   [(set_attr "v8type" "logic_shift")
2914    (set_attr "type" "logic_shift_imm")
2915    (set_attr "mode" "SI")])
2917 (define_insn "one_cmpl<mode>2"
2918   [(set (match_operand:GPI 0 "register_operand" "=r")
2919         (not:GPI (match_operand:GPI 1 "register_operand" "r")))]
2920   ""
2921   "mvn\\t%<w>0, %<w>1"
2922   [(set_attr "v8type" "logic")
2923    (set_attr "type" "logic_reg")
2924    (set_attr "mode" "<MODE>")])
2926 (define_insn "*one_cmpl_<optab><mode>2"
2927   [(set (match_operand:GPI 0 "register_operand" "=r")
2928         (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
2929                             (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2930   ""
2931   "mvn\\t%<w>0, %<w>1, <shift> %2"
2932   [(set_attr "v8type" "logic_shift")
2933    (set_attr "type" "logic_shift_imm")
2934    (set_attr "mode" "<MODE>")])
2936 (define_insn "*<LOGICAL:optab>_one_cmpl<mode>3"
2937   [(set (match_operand:GPI 0 "register_operand" "=r")
2938         (LOGICAL:GPI (not:GPI
2939                       (match_operand:GPI 1 "register_operand" "r"))
2940                      (match_operand:GPI 2 "register_operand" "r")))]
2941   ""
2942   "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1"
2943   [(set_attr "v8type" "logic")
2944    (set_attr "type" "logic_reg")
2945    (set_attr "mode" "<MODE>")])
2947 (define_insn "*and_one_cmpl<mode>3_compare0"
2948   [(set (reg:CC_NZ CC_REGNUM)
2949         (compare:CC_NZ
2950          (and:GPI (not:GPI
2951                    (match_operand:GPI 1 "register_operand" "r"))
2952                   (match_operand:GPI 2 "register_operand" "r"))
2953          (const_int 0)))
2954    (set (match_operand:GPI 0 "register_operand" "=r")
2955         (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
2956   ""
2957   "bics\\t%<w>0, %<w>2, %<w>1"
2958   [(set_attr "v8type" "logics")
2959    (set_attr "type" "logics_reg")
2960    (set_attr "mode" "<MODE>")])
2962 ;; zero_extend version of above
2963 (define_insn "*and_one_cmplsi3_compare0_uxtw"
2964   [(set (reg:CC_NZ CC_REGNUM)
2965         (compare:CC_NZ
2966          (and:SI (not:SI
2967                   (match_operand:SI 1 "register_operand" "r"))
2968                  (match_operand:SI 2 "register_operand" "r"))
2969          (const_int 0)))
2970    (set (match_operand:DI 0 "register_operand" "=r")
2971         (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
2972   ""
2973   "bics\\t%w0, %w2, %w1"
2974   [(set_attr "v8type" "logics")
2975    (set_attr "type" "logics_reg")
2976    (set_attr "mode" "SI")])
2978 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
2979   [(set (match_operand:GPI 0 "register_operand" "=r")
2980         (LOGICAL:GPI (not:GPI
2981                       (SHIFT:GPI
2982                        (match_operand:GPI 1 "register_operand" "r")
2983                        (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2984                      (match_operand:GPI 3 "register_operand" "r")))]
2985   ""
2986   "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2987   [(set_attr "v8type" "logic_shift")
2988    (set_attr "type" "logics_shift_imm")
2989    (set_attr "mode" "<MODE>")])
2991 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
2992   [(set (reg:CC_NZ CC_REGNUM)
2993         (compare:CC_NZ
2994          (and:GPI (not:GPI
2995                    (SHIFT:GPI
2996                     (match_operand:GPI 1 "register_operand" "r")
2997                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2998                   (match_operand:GPI 3 "register_operand" "r"))
2999          (const_int 0)))
3000    (set (match_operand:GPI 0 "register_operand" "=r")
3001         (and:GPI (not:GPI
3002                   (SHIFT:GPI
3003                    (match_dup 1) (match_dup 2))) (match_dup 3)))]
3004   ""
3005   "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3006   [(set_attr "v8type" "logics_shift")
3007    (set_attr "type" "logics_shift_imm")
3008    (set_attr "mode" "<MODE>")])
3010 ;; zero_extend version of above
3011 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
3012   [(set (reg:CC_NZ CC_REGNUM)
3013         (compare:CC_NZ
3014          (and:SI (not:SI
3015                   (SHIFT:SI
3016                    (match_operand:SI 1 "register_operand" "r")
3017                    (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
3018                  (match_operand:SI 3 "register_operand" "r"))
3019          (const_int 0)))
3020    (set (match_operand:DI 0 "register_operand" "=r")
3021         (zero_extend:DI (and:SI
3022                          (not:SI
3023                           (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
3024   ""
3025   "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3026   [(set_attr "v8type" "logics_shift")
3027    (set_attr "type" "logics_shift_imm")
3028    (set_attr "mode" "SI")])
3030 (define_insn "clz<mode>2"
3031   [(set (match_operand:GPI 0 "register_operand" "=r")
3032         (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
3033   ""
3034   "clz\\t%<w>0, %<w>1"
3035   [(set_attr "v8type" "clz")
3036    (set_attr "type" "clz")
3037    (set_attr "mode" "<MODE>")])
3039 (define_expand "ffs<mode>2"
3040   [(match_operand:GPI 0 "register_operand")
3041    (match_operand:GPI 1 "register_operand")]
3042   ""
3043   {
3044     rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
3045     rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
3047     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3048     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3049     emit_insn (gen_csinc3<mode>_insn (operands[0], x, ccreg, operands[0], const0_rtx));
3050     DONE;
3051   }
3054 (define_insn "clrsb<mode>2"
3055   [(set (match_operand:GPI 0 "register_operand" "=r")
3056         (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_CLS))]
3057   ""
3058   "cls\\t%<w>0, %<w>1"
3059   [(set_attr "v8type" "clz")
3060    (set_attr "type" "clz")
3061    (set_attr "mode" "<MODE>")])
3063 (define_insn "rbit<mode>2"
3064   [(set (match_operand:GPI 0 "register_operand" "=r")
3065         (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
3066   ""
3067   "rbit\\t%<w>0, %<w>1"
3068   [(set_attr "v8type" "rbit")
3069    (set_attr "type" "rbit")
3070    (set_attr "mode" "<MODE>")])
3072 (define_expand "ctz<mode>2"
3073   [(match_operand:GPI 0 "register_operand")
3074    (match_operand:GPI 1 "register_operand")]
3075   ""
3076   {
3077     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3078     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3079     DONE;
3080   }
3083 (define_insn "*and<mode>3nr_compare0"
3084   [(set (reg:CC_NZ CC_REGNUM)
3085         (compare:CC_NZ
3086          (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
3087                   (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
3088          (const_int 0)))]
3089   ""
3090   "tst\\t%<w>0, %<w>1"
3091   [(set_attr "v8type" "logics")
3092    (set_attr "type" "logics_reg")
3093    (set_attr "mode" "<MODE>")])
3095 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
3096   [(set (reg:CC_NZ CC_REGNUM)
3097         (compare:CC_NZ
3098          (and:GPI (SHIFT:GPI
3099                    (match_operand:GPI 0 "register_operand" "r")
3100                    (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
3101                   (match_operand:GPI 2 "register_operand" "r"))
3102         (const_int 0)))]
3103   ""
3104   "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
3105   [(set_attr "v8type" "logics_shift")
3106    (set_attr "type" "logics_shift_imm")
3107    (set_attr "mode" "<MODE>")])
3109 ;; -------------------------------------------------------------------
3110 ;; Shifts
3111 ;; -------------------------------------------------------------------
3113 (define_expand "<optab><mode>3"
3114   [(set (match_operand:GPI 0 "register_operand")
3115         (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
3116                     (match_operand:QI 2 "nonmemory_operand")))]
3117   ""
3118   {
3119     if (CONST_INT_P (operands[2]))
3120       {
3121         operands[2] = GEN_INT (INTVAL (operands[2])
3122                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3124         if (operands[2] == const0_rtx)
3125           {
3126             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3127             DONE;
3128           }
3129       }
3130   }
3133 (define_expand "ashl<mode>3"
3134   [(set (match_operand:SHORT 0 "register_operand")
3135         (ashift:SHORT (match_operand:SHORT 1 "register_operand")
3136                       (match_operand:QI 2 "nonmemory_operand")))]
3137   ""
3138   {
3139     if (CONST_INT_P (operands[2]))
3140       {
3141         operands[2] = GEN_INT (INTVAL (operands[2])
3142                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3144         if (operands[2] == const0_rtx)
3145           {
3146             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3147             DONE;
3148           }
3149       }
3150   }
3153 (define_expand "rotr<mode>3"
3154   [(set (match_operand:GPI 0 "register_operand")
3155         (rotatert:GPI (match_operand:GPI 1 "register_operand")
3156                       (match_operand:QI 2 "nonmemory_operand")))]
3157   ""
3158   {
3159     if (CONST_INT_P (operands[2]))
3160       {
3161         operands[2] = GEN_INT (INTVAL (operands[2])
3162                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3164         if (operands[2] == const0_rtx)
3165           {
3166             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3167             DONE;
3168           }
3169       }
3170   }
3173 (define_expand "rotl<mode>3"
3174   [(set (match_operand:GPI 0 "register_operand")
3175         (rotatert:GPI (match_operand:GPI 1 "register_operand")
3176                       (match_operand:QI 2 "nonmemory_operand")))]
3177   ""
3178   {
3179     /* (SZ - cnt) % SZ == -cnt % SZ */
3180     if (CONST_INT_P (operands[2]))
3181       {
3182         operands[2] = GEN_INT ((-INTVAL (operands[2]))
3183                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3184         if (operands[2] == const0_rtx)
3185           {
3186             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3187             DONE;
3188           }
3189       }
3190     else
3191       operands[2] = expand_simple_unop (QImode, NEG, operands[2],
3192                                         NULL_RTX, 1);
3193   }
3196 ;; Logical left shift using SISD or Integer instruction
3197 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
3198   [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3199         (ashift:GPI
3200           (match_operand:GPI 1 "register_operand" "w,w,r")
3201           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3202   ""
3203   "@
3204    shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3205    ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
3206    lsl\t%<w>0, %<w>1, %<w>2"
3207   [(set_attr "simd" "yes,yes,no")
3208    (set_attr "simd_type" "simd_shift_imm,simd_shift,*")
3209    (set_attr "simd_mode" "<MODE>,<MODE>,*")
3210    (set_attr "v8type" "*,*,shift")
3211    (set_attr "type" "*,*,shift_reg")
3212    (set_attr "mode" "*,*,<MODE>")]
3215 ;; Logical right shift using SISD or Integer instruction
3216 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3217   [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3218         (lshiftrt:GPI
3219           (match_operand:GPI 1 "register_operand" "w,w,r")
3220           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3221   ""
3222   "@
3223    ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3224    #
3225    lsr\t%<w>0, %<w>1, %<w>2"
3226   [(set_attr "simd" "yes,yes,no")
3227    (set_attr "simd_type" "simd_shift_imm,simd_shift,*")
3228    (set_attr "simd_mode" "<MODE>,<MODE>,*")
3229    (set_attr "v8type" "*,*,shift")
3230    (set_attr "type" "*,*,shift_reg")
3231    (set_attr "mode" "*,*,<MODE>")]
3234 (define_split
3235   [(set (match_operand:DI 0 "aarch64_simd_register")
3236         (lshiftrt:DI
3237            (match_operand:DI 1 "aarch64_simd_register")
3238            (match_operand:QI 2 "aarch64_simd_register")))]
3239   "TARGET_SIMD && reload_completed"
3240   [(set (match_dup 2)
3241         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3242    (set (match_dup 0)
3243         (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_USHL))]
3244   ""
3247 (define_split
3248   [(set (match_operand:SI 0 "aarch64_simd_register")
3249         (lshiftrt:SI
3250            (match_operand:SI 1 "aarch64_simd_register")
3251            (match_operand:QI 2 "aarch64_simd_register")))]
3252   "TARGET_SIMD && reload_completed"
3253   [(set (match_dup 2)
3254         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3255    (set (match_dup 0)
3256         (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_USHL_2S))]
3257   ""
3260 ;; Arithmetic right shift using SISD or Integer instruction
3261 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3262   [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3263         (ashiftrt:GPI
3264           (match_operand:GPI 1 "register_operand" "w,w,r")
3265           (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,rUs<cmode>")))]
3266   ""
3267   "@
3268    sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3269    #
3270    asr\t%<w>0, %<w>1, %<w>2"
3271   [(set_attr "simd" "yes,yes,no")
3272    (set_attr "simd_type" "simd_shift_imm,simd_shift,*")
3273    (set_attr "simd_mode" "<MODE>,<MODE>,*")
3274    (set_attr "v8type" "*,*,shift")
3275    (set_attr "type" "*,*,shift_reg")
3276    (set_attr "mode" "*,*,<MODE>")]
3279 (define_split
3280   [(set (match_operand:DI 0 "aarch64_simd_register")
3281         (ashiftrt:DI
3282            (match_operand:DI 1 "aarch64_simd_register")
3283            (match_operand:QI 2 "aarch64_simd_register")))]
3284   "TARGET_SIMD && reload_completed"
3285   [(set (match_dup 2)
3286         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3287    (set (match_dup 0)
3288         (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_SSHL))]
3289   ""
3292 (define_split
3293   [(set (match_operand:SI 0 "aarch64_simd_register")
3294         (ashiftrt:SI
3295            (match_operand:SI 1 "aarch64_simd_register")
3296            (match_operand:QI 2 "aarch64_simd_register")))]
3297   "TARGET_SIMD && reload_completed"
3298   [(set (match_dup 2)
3299         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3300    (set (match_dup 0)
3301         (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_SSHL_2S))]
3302   ""
3305 (define_insn "*aarch64_sisd_ushl"
3306   [(set (match_operand:DI 0 "register_operand" "=w")
3307         (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3308                     (match_operand:QI 2 "register_operand" "w")]
3309                    UNSPEC_SISD_USHL))]
3310   "TARGET_SIMD"
3311   "ushl\t%d0, %d1, %d2"
3312   [(set_attr "simd" "yes")
3313    (set_attr "simd_type" "simd_shift")
3314    (set_attr "simd_mode" "DI")]
3317 (define_insn "*aarch64_ushl_2s"
3318   [(set (match_operand:SI 0 "register_operand" "=w")
3319         (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3320                     (match_operand:QI 2 "register_operand" "w")]
3321                    UNSPEC_USHL_2S))]
3322   "TARGET_SIMD"
3323   "ushl\t%0.2s, %1.2s, %2.2s"
3324   [(set_attr "simd" "yes")
3325    (set_attr "simd_type" "simd_shift")
3326    (set_attr "simd_mode" "DI")]
3329 (define_insn "*aarch64_sisd_sshl"
3330   [(set (match_operand:DI 0 "register_operand" "=w")
3331         (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3332                     (match_operand:QI 2 "register_operand" "w")]
3333                    UNSPEC_SISD_SSHL))]
3334   "TARGET_SIMD"
3335   "sshl\t%d0, %d1, %d2"
3336   [(set_attr "simd" "yes")
3337    (set_attr "simd_type" "simd_shift")
3338    (set_attr "simd_mode" "DI")]
3341 (define_insn "*aarch64_sshl_2s"
3342   [(set (match_operand:SI 0 "register_operand" "=w")
3343         (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3344                     (match_operand:QI 2 "register_operand" "w")]
3345                    UNSPEC_SSHL_2S))]
3346   "TARGET_SIMD"
3347   "sshl\t%0.2s, %1.2s, %2.2s"
3348   [(set_attr "simd" "yes")
3349    (set_attr "simd_type" "simd_shift")
3350    (set_attr "simd_mode" "DI")]
3353 (define_insn "*aarch64_sisd_neg_qi"
3354   [(set (match_operand:QI 0 "register_operand" "=w")
3355         (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3356                    UNSPEC_SISD_NEG))]
3357   "TARGET_SIMD"
3358   "neg\t%d0, %d1"
3359   [(set_attr "simd" "yes")
3360    (set_attr "simd_type" "simd_negabs")
3361    (set_attr "simd_mode" "QI")]
3364 ;; Rotate right
3365 (define_insn "*ror<mode>3_insn"
3366   [(set (match_operand:GPI 0 "register_operand" "=r")
3367         (rotatert:GPI
3368           (match_operand:GPI 1 "register_operand" "r")
3369           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3370   ""
3371   "ror\\t%<w>0, %<w>1, %<w>2"
3372   [(set_attr "v8type" "shift")
3373    (set_attr "type" "shift_reg")
3374    (set_attr "mode" "<MODE>")]
3377 ;; zero_extend version of above
3378 (define_insn "*<optab>si3_insn_uxtw"
3379   [(set (match_operand:DI 0 "register_operand" "=r")
3380         (zero_extend:DI (SHIFT:SI
3381          (match_operand:SI 1 "register_operand" "r")
3382          (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3383   ""
3384   "<shift>\\t%w0, %w1, %w2"
3385   [(set_attr "v8type" "shift")
3386    (set_attr "type" "shift_reg")
3387    (set_attr "mode" "SI")]
3390 (define_insn "*ashl<mode>3_insn"
3391   [(set (match_operand:SHORT 0 "register_operand" "=r")
3392         (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3393                       (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
3394   ""
3395   "lsl\\t%<w>0, %<w>1, %<w>2"
3396   [(set_attr "v8type" "shift")
3397    (set_attr "type" "shift_reg")
3398    (set_attr "mode" "<MODE>")]
3401 (define_insn "*<optab><mode>3_insn"
3402   [(set (match_operand:SHORT 0 "register_operand" "=r")
3403         (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3404                       (match_operand 2 "const_int_operand" "n")))]
3405   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3407   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3408   return "<bfshift>\t%w0, %w1, %2, %3";
3410   [(set_attr "v8type" "bfm")
3411    (set_attr "type" "bfm")
3412    (set_attr "mode" "<MODE>")]
3415 (define_insn "*extr<mode>5_insn"
3416   [(set (match_operand:GPI 0 "register_operand" "=r")
3417         (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3418                              (match_operand 3 "const_int_operand" "n"))
3419                  (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3420                                (match_operand 4 "const_int_operand" "n"))))]
3421   "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3422    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3423   "extr\\t%<w>0, %<w>1, %<w>2, %4"
3424   [(set_attr "v8type" "shift")
3425    (set_attr "type" "shift_imm")
3426    (set_attr "mode" "<MODE>")]
3429 ;; zero_extend version of the above
3430 (define_insn "*extrsi5_insn_uxtw"
3431   [(set (match_operand:DI 0 "register_operand" "=r")
3432         (zero_extend:DI
3433          (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3434                             (match_operand 3 "const_int_operand" "n"))
3435                  (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3436                               (match_operand 4 "const_int_operand" "n")))))]
3437   "UINTVAL (operands[3]) < 32 &&
3438    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3439   "extr\\t%w0, %w1, %w2, %4"
3440   [(set_attr "v8type" "shift")
3441    (set_attr "type" "shift_imm")
3442    (set_attr "mode" "SI")]
3445 (define_insn "*ror<mode>3_insn"
3446   [(set (match_operand:GPI 0 "register_operand" "=r")
3447         (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3448                     (match_operand 2 "const_int_operand" "n")))]
3449   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3451   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3452   return "ror\\t%<w>0, %<w>1, %3";
3454   [(set_attr "v8type" "shift")
3455    (set_attr "type" "shift_imm")
3456    (set_attr "mode" "<MODE>")]
3459 ;; zero_extend version of the above
3460 (define_insn "*rorsi3_insn_uxtw"
3461   [(set (match_operand:DI 0 "register_operand" "=r")
3462         (zero_extend:DI
3463          (rotate:SI (match_operand:SI 1 "register_operand" "r")
3464                     (match_operand 2 "const_int_operand" "n"))))]
3465   "UINTVAL (operands[2]) < 32"
3467   operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3468   return "ror\\t%w0, %w1, %3";
3470   [(set_attr "v8type" "shift")
3471    (set_attr "type" "shift_imm")
3472    (set_attr "mode" "SI")]
3475 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3476   [(set (match_operand:GPI 0 "register_operand" "=r")
3477         (ANY_EXTEND:GPI
3478          (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3479                        (match_operand 2 "const_int_operand" "n"))))]
3480   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3482   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3483   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3485   [(set_attr "v8type" "bfm")
3486    (set_attr "type" "bfm")
3487    (set_attr "mode" "<GPI:MODE>")]
3490 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3491   [(set (match_operand:GPI 0 "register_operand" "=r")
3492         (zero_extend:GPI
3493          (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3494                          (match_operand 2 "const_int_operand" "n"))))]
3495   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3497   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3498   return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3500   [(set_attr "v8type" "bfm")
3501    (set_attr "type" "bfm")
3502    (set_attr "mode" "<GPI:MODE>")]
3505 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3506   [(set (match_operand:GPI 0 "register_operand" "=r")
3507         (sign_extend:GPI
3508          (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3509                          (match_operand 2 "const_int_operand" "n"))))]
3510   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3512   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3513   return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3515   [(set_attr "v8type" "bfm")
3516    (set_attr "type" "bfm")
3517    (set_attr "mode" "<GPI:MODE>")]
3520 ;; -------------------------------------------------------------------
3521 ;; Bitfields
3522 ;; -------------------------------------------------------------------
3524 (define_expand "<optab>"
3525   [(set (match_operand:DI 0 "register_operand" "=r")
3526         (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3527                         (match_operand 2 "const_int_operand" "n")
3528                         (match_operand 3 "const_int_operand" "n")))]
3529   ""
3530   ""
3533 (define_insn "*<optab><mode>"
3534   [(set (match_operand:GPI 0 "register_operand" "=r")
3535         (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3536                          (match_operand 2 "const_int_operand" "n")
3537                          (match_operand 3 "const_int_operand" "n")))]
3538   ""
3539   "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3540   [(set_attr "v8type" "bfm")
3541    (set_attr "type" "bfm")
3542    (set_attr "mode" "<MODE>")]
3545 ;; Bitfield Insert (insv)
3546 (define_expand "insv<mode>"
3547   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3548                           (match_operand 1 "const_int_operand")
3549                           (match_operand 2 "const_int_operand"))
3550         (match_operand:GPI 3 "general_operand"))]
3551   ""
3553   unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3554   unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3555   rtx value = operands[3];
3557   if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3558     FAIL;
3560   if (CONST_INT_P (value))
3561     {
3562       unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3564       /* Prefer AND/OR for inserting all zeros or all ones.  */
3565       if ((UINTVAL (value) & mask) == 0
3566            || (UINTVAL (value) & mask) == mask)
3567         FAIL;
3569       /* 16-bit aligned 16-bit wide insert is handled by insv_imm.  */
3570       if (width == 16 && (pos % 16) == 0)
3571         DONE;
3572     }
3573   operands[3] = force_reg (<MODE>mode, value);
3576 (define_insn "*insv_reg<mode>"
3577   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3578                           (match_operand 1 "const_int_operand" "n")
3579                           (match_operand 2 "const_int_operand" "n"))
3580         (match_operand:GPI 3 "register_operand" "r"))]
3581   "!(UINTVAL (operands[1]) == 0
3582      || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3583          > GET_MODE_BITSIZE (<MODE>mode)))"
3584   "bfi\\t%<w>0, %<w>3, %2, %1"
3585   [(set_attr "v8type" "bfm")
3586    (set_attr "type" "bfm")
3587    (set_attr "mode" "<MODE>")]
3590 (define_insn "*extr_insv_lower_reg<mode>"
3591   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3592                           (match_operand 1 "const_int_operand" "n")
3593                           (const_int 0))
3594         (zero_extract:GPI (match_operand:GPI 2 "register_operand" "+r")
3595                           (match_dup 1)
3596                           (match_operand 3 "const_int_operand" "n")))]
3597   "!(UINTVAL (operands[1]) == 0
3598      || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3599          > GET_MODE_BITSIZE (<MODE>mode)))"
3600   "bfxil\\t%<w>0, %<w>2, %3, %1"
3601   [(set_attr "v8type" "bfm")
3602    (set_attr "type" "bfm")
3603    (set_attr "mode" "<MODE>")]
3606 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3607   [(set (match_operand:GPI 0 "register_operand" "=r")
3608         (ashift:GPI (ANY_EXTEND:GPI
3609                      (match_operand:ALLX 1 "register_operand" "r"))
3610                     (match_operand 2 "const_int_operand" "n")))]
3611   "UINTVAL (operands[2]) < <GPI:sizen>"
3613   operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3614               ? GEN_INT (<ALLX:sizen>)
3615               : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3616   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3618   [(set_attr "v8type" "bfm")
3619    (set_attr "type" "bfm")
3620    (set_attr "mode" "<GPI:MODE>")]
3623 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3625 (define_insn "*andim_ashift<mode>_bfiz"
3626   [(set (match_operand:GPI 0 "register_operand" "=r")
3627         (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3628                              (match_operand 2 "const_int_operand" "n"))
3629                  (match_operand 3 "const_int_operand" "n")))]
3630   "exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3631    && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3632   "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3633   [(set_attr "v8type" "bfm")
3634    (set_attr "type" "bfm")
3635    (set_attr "mode" "<MODE>")]
3638 (define_insn "bswap<mode>2"
3639   [(set (match_operand:GPI 0 "register_operand" "=r")
3640         (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3641   ""
3642   "rev\\t%<w>0, %<w>1"
3643   [(set_attr "v8type" "rev")
3644    (set_attr "type" "rev")
3645    (set_attr "mode" "<MODE>")]
3648 (define_insn "bswaphi2"
3649   [(set (match_operand:HI 0 "register_operand" "=r")
3650         (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3651   ""
3652   "rev16\\t%w0, %w1"
3653   [(set_attr "v8type" "rev")
3654    (set_attr "type" "rev")
3655    (set_attr "mode" "HI")]
3658 ;; zero_extend version of above
3659 (define_insn "*bswapsi2_uxtw"
3660   [(set (match_operand:DI 0 "register_operand" "=r")
3661         (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3662   ""
3663   "rev\\t%w0, %w1"
3664   [(set_attr "v8type" "rev")
3665    (set_attr "type" "rev")
3666    (set_attr "mode" "SI")]
3669 ;; -------------------------------------------------------------------
3670 ;; Floating-point intrinsics
3671 ;; -------------------------------------------------------------------
3673 ;; frint floating-point round to integral standard patterns.
3674 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round.
3676 (define_insn "<frint_pattern><mode>2"
3677   [(set (match_operand:GPF 0 "register_operand" "=w")
3678         (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3679          FRINT))]
3680   "TARGET_FLOAT"
3681   "frint<frint_suffix>\\t%<s>0, %<s>1"
3682   [(set_attr "v8type" "frint")
3683    (set_attr "type" "f_rint<s>")
3684    (set_attr "mode" "<MODE>")]
3687 ;; frcvt floating-point round to integer and convert standard patterns.
3688 ;; Expands to lbtrunc, lceil, lfloor, lround.
3689 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3690   [(set (match_operand:GPI 0 "register_operand" "=r")
3691         (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3692                       FCVT)))]
3693   "TARGET_FLOAT"
3694   "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3695   [(set_attr "v8type" "fcvtf2i")
3696    (set_attr "type" "f_cvtf2i")
3697    (set_attr "mode" "<GPF:MODE>")
3698    (set_attr "mode2" "<GPI:MODE>")]
3701 ;; fma - no throw
3703 (define_insn "fma<mode>4"
3704   [(set (match_operand:GPF 0 "register_operand" "=w")
3705         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3706                  (match_operand:GPF 2 "register_operand" "w")
3707                  (match_operand:GPF 3 "register_operand" "w")))]
3708   "TARGET_FLOAT"
3709   "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3710   [(set_attr "v8type" "fmadd")
3711    (set_attr "type" "fmac<s>")
3712    (set_attr "mode" "<MODE>")]
3715 (define_insn "fnma<mode>4"
3716   [(set (match_operand:GPF 0 "register_operand" "=w")
3717         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3718                  (match_operand:GPF 2 "register_operand" "w")
3719                  (match_operand:GPF 3 "register_operand" "w")))]
3720   "TARGET_FLOAT"
3721   "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3722   [(set_attr "v8type" "fmadd")
3723    (set_attr "type" "fmac<s>")
3724    (set_attr "mode" "<MODE>")]
3727 (define_insn "fms<mode>4"
3728   [(set (match_operand:GPF 0 "register_operand" "=w")
3729         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3730                  (match_operand:GPF 2 "register_operand" "w")
3731                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3732   "TARGET_FLOAT"
3733   "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3734   [(set_attr "v8type" "fmadd")
3735    (set_attr "type" "fmac<s>")
3736    (set_attr "mode" "<MODE>")]
3739 (define_insn "fnms<mode>4"
3740   [(set (match_operand:GPF 0 "register_operand" "=w")
3741         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3742                  (match_operand:GPF 2 "register_operand" "w")
3743                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3744   "TARGET_FLOAT"
3745   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3746   [(set_attr "v8type" "fmadd")
3747    (set_attr "type" "fmac<s>")
3748    (set_attr "mode" "<MODE>")]
3751 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3752 (define_insn "*fnmadd<mode>4"
3753   [(set (match_operand:GPF 0 "register_operand" "=w")
3754         (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3755                           (match_operand:GPF 2 "register_operand" "w")
3756                           (match_operand:GPF 3 "register_operand" "w"))))]
3757   "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3758   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3759   [(set_attr "v8type" "fmadd")
3760    (set_attr "type" "fmac<s>")
3761    (set_attr "mode" "<MODE>")]
3764 ;; -------------------------------------------------------------------
3765 ;; Floating-point conversions
3766 ;; -------------------------------------------------------------------
3768 (define_insn "extendsfdf2"
3769   [(set (match_operand:DF 0 "register_operand" "=w")
3770         (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3771   "TARGET_FLOAT"
3772   "fcvt\\t%d0, %s1"
3773   [(set_attr "v8type" "fcvt")
3774    (set_attr "type" "f_cvt")
3775    (set_attr "mode" "DF")
3776    (set_attr "mode2" "SF")]
3779 (define_insn "truncdfsf2"
3780   [(set (match_operand:SF 0 "register_operand" "=w")
3781         (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3782   "TARGET_FLOAT"
3783   "fcvt\\t%s0, %d1"
3784   [(set_attr "v8type" "fcvt")
3785    (set_attr "type" "f_cvt")
3786    (set_attr "mode" "SF")
3787    (set_attr "mode2" "DF")]
3790 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3791   [(set (match_operand:GPI 0 "register_operand" "=r")
3792         (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3793   "TARGET_FLOAT"
3794   "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3795   [(set_attr "v8type" "fcvtf2i")
3796    (set_attr "type" "f_cvtf2i")
3797    (set_attr "mode" "<GPF:MODE>")
3798    (set_attr "mode2" "<GPI:MODE>")]
3801 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3802   [(set (match_operand:GPI 0 "register_operand" "=r")
3803         (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3804   "TARGET_FLOAT"
3805   "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3806   [(set_attr "v8type" "fcvtf2i")
3807    (set_attr "type" "f_cvtf2i")
3808    (set_attr "mode" "<GPF:MODE>")
3809    (set_attr "mode2" "<GPI:MODE>")]
3812 (define_insn "float<GPI:mode><GPF:mode>2"
3813   [(set (match_operand:GPF 0 "register_operand" "=w")
3814         (float:GPF (match_operand:GPI 1 "register_operand" "r")))]
3815   "TARGET_FLOAT"
3816   "scvtf\\t%<GPF:s>0, %<GPI:w>1"
3817   [(set_attr "v8type" "fcvti2f")
3818    (set_attr "type" "f_cvti2f")
3819    (set_attr "mode" "<GPF:MODE>")
3820    (set_attr "mode2" "<GPI:MODE>")]
3823 (define_insn "floatuns<GPI:mode><GPF:mode>2"
3824   [(set (match_operand:GPF 0 "register_operand" "=w")
3825         (unsigned_float:GPF (match_operand:GPI 1 "register_operand" "r")))]
3826   "TARGET_FLOAT"
3827   "ucvtf\\t%<GPF:s>0, %<GPI:w>1"
3828   [(set_attr "v8type" "fcvt")
3829    (set_attr "type" "f_cvt")
3830    (set_attr "mode" "<GPF:MODE>")
3831    (set_attr "mode2" "<GPI:MODE>")]
3834 ;; -------------------------------------------------------------------
3835 ;; Floating-point arithmetic
3836 ;; -------------------------------------------------------------------
3838 (define_insn "add<mode>3"
3839   [(set (match_operand:GPF 0 "register_operand" "=w")
3840         (plus:GPF
3841          (match_operand:GPF 1 "register_operand" "w")
3842          (match_operand:GPF 2 "register_operand" "w")))]
3843   "TARGET_FLOAT"
3844   "fadd\\t%<s>0, %<s>1, %<s>2"
3845   [(set_attr "v8type" "fadd")
3846    (set_attr "type" "fadd<s>")
3847    (set_attr "mode" "<MODE>")]
3850 (define_insn "sub<mode>3"
3851   [(set (match_operand:GPF 0 "register_operand" "=w")
3852         (minus:GPF
3853          (match_operand:GPF 1 "register_operand" "w")
3854          (match_operand:GPF 2 "register_operand" "w")))]
3855   "TARGET_FLOAT"
3856   "fsub\\t%<s>0, %<s>1, %<s>2"
3857   [(set_attr "v8type" "fadd")
3858    (set_attr "type" "fadd<s>")
3859    (set_attr "mode" "<MODE>")]
3862 (define_insn "mul<mode>3"
3863   [(set (match_operand:GPF 0 "register_operand" "=w")
3864         (mult:GPF
3865          (match_operand:GPF 1 "register_operand" "w")
3866          (match_operand:GPF 2 "register_operand" "w")))]
3867   "TARGET_FLOAT"
3868   "fmul\\t%<s>0, %<s>1, %<s>2"
3869   [(set_attr "v8type" "fmul")
3870    (set_attr "type" "fmul<s>")
3871    (set_attr "mode" "<MODE>")]
3874 (define_insn "*fnmul<mode>3"
3875   [(set (match_operand:GPF 0 "register_operand" "=w")
3876         (mult:GPF
3877                  (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3878                  (match_operand:GPF 2 "register_operand" "w")))]
3879   "TARGET_FLOAT"
3880   "fnmul\\t%<s>0, %<s>1, %<s>2"
3881   [(set_attr "v8type" "fmul")
3882    (set_attr "type" "fmul<s>")
3883    (set_attr "mode" "<MODE>")]
3886 (define_insn "div<mode>3"
3887   [(set (match_operand:GPF 0 "register_operand" "=w")
3888         (div:GPF
3889          (match_operand:GPF 1 "register_operand" "w")
3890          (match_operand:GPF 2 "register_operand" "w")))]
3891   "TARGET_FLOAT"
3892   "fdiv\\t%<s>0, %<s>1, %<s>2"
3893   [(set_attr "v8type" "fdiv")
3894    (set_attr "type" "fdiv<s>")
3895    (set_attr "mode" "<MODE>")]
3898 (define_insn "neg<mode>2"
3899   [(set (match_operand:GPF 0 "register_operand" "=w")
3900         (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
3901   "TARGET_FLOAT"
3902   "fneg\\t%<s>0, %<s>1"
3903   [(set_attr "v8type" "ffarith")
3904    (set_attr "type" "ffarith<s>")
3905    (set_attr "mode" "<MODE>")]
3908 (define_insn "sqrt<mode>2"
3909   [(set (match_operand:GPF 0 "register_operand" "=w")
3910         (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
3911   "TARGET_FLOAT"
3912   "fsqrt\\t%<s>0, %<s>1"
3913   [(set_attr "v8type" "fsqrt")
3914    (set_attr "type" "fsqrt<s>")
3915    (set_attr "mode" "<MODE>")]
3918 (define_insn "abs<mode>2"
3919   [(set (match_operand:GPF 0 "register_operand" "=w")
3920         (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
3921   "TARGET_FLOAT"
3922   "fabs\\t%<s>0, %<s>1"
3923   [(set_attr "v8type" "ffarith")
3924    (set_attr "type" "ffarith<s>")
3925    (set_attr "mode" "<MODE>")]
3928 ;; Given that smax/smin do not specify the result when either input is NaN,
3929 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
3930 ;; for smin.
3932 (define_insn "smax<mode>3"
3933   [(set (match_operand:GPF 0 "register_operand" "=w")
3934         (smax:GPF (match_operand:GPF 1 "register_operand" "w")
3935                   (match_operand:GPF 2 "register_operand" "w")))]
3936   "TARGET_FLOAT"
3937   "fmaxnm\\t%<s>0, %<s>1, %<s>2"
3938   [(set_attr "v8type" "fminmax")
3939    (set_attr "type" "f_minmax<s>")
3940    (set_attr "mode" "<MODE>")]
3943 (define_insn "smin<mode>3"
3944   [(set (match_operand:GPF 0 "register_operand" "=w")
3945         (smin:GPF (match_operand:GPF 1 "register_operand" "w")
3946                   (match_operand:GPF 2 "register_operand" "w")))]
3947   "TARGET_FLOAT"
3948   "fminnm\\t%<s>0, %<s>1, %<s>2"
3949   [(set_attr "v8type" "fminmax")
3950    (set_attr "type" "f_minmax<s>")
3951    (set_attr "mode" "<MODE>")]
3954 ;; -------------------------------------------------------------------
3955 ;; Reload support
3956 ;; -------------------------------------------------------------------
3958 (define_expand "aarch64_reload_mov<mode>"
3959   [(set (match_operand:TX 0 "register_operand" "=w")
3960         (match_operand:TX 1 "register_operand" "w"))
3961    (clobber (match_operand:DI 2 "register_operand" "=&r"))
3962   ]
3963   ""
3964   {
3965     rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
3966     rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
3967     gen_aarch64_movtilow_tilow (op0, op1);
3968     gen_aarch64_movdi_tihigh (operands[2], op1);
3969     gen_aarch64_movtihigh_di (op0, operands[2]);
3970     DONE;
3971   }
3974 ;; The following secondary reload helpers patterns are invoked
3975 ;; after or during reload as we don't want these patterns to start
3976 ;; kicking in during the combiner.
3978 (define_insn "aarch64_movdi_<mode>low"
3979   [(set (match_operand:DI 0 "register_operand" "=r")
3980         (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
3981   "reload_completed || reload_in_progress"
3982   "fmov\\t%x0, %d1"
3983   [(set_attr "v8type" "fmovf2i")
3984    (set_attr "type" "f_mrc")
3985    (set_attr "mode"   "DI")
3986    (set_attr "length" "4")
3987   ])
3989 (define_insn "aarch64_movdi_<mode>high"
3990   [(set (match_operand:DI 0 "register_operand" "=r")
3991         (truncate:DI
3992           (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
3993                        (const_int 64))))]
3994   "reload_completed || reload_in_progress"
3995   "fmov\\t%x0, %1.d[1]"
3996   [(set_attr "v8type" "fmovf2i")
3997    (set_attr "type" "f_mrc")
3998    (set_attr "mode"   "DI")
3999    (set_attr "length" "4")
4000   ])
4002 (define_insn "aarch64_mov<mode>high_di"
4003   [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
4004                          (const_int 64) (const_int 64))
4005         (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4006   "reload_completed || reload_in_progress"
4007   "fmov\\t%0.d[1], %x1"
4008   [(set_attr "v8type" "fmovi2f")
4009    (set_attr "type" "f_mcr")
4010    (set_attr "mode"   "DI")
4011    (set_attr "length" "4")
4012   ])
4014 (define_insn "aarch64_mov<mode>low_di"
4015   [(set (match_operand:TX 0 "register_operand" "=w")
4016         (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4017   "reload_completed || reload_in_progress"
4018   "fmov\\t%d0, %x1"
4019   [(set_attr "v8type" "fmovi2f")
4020    (set_attr "type" "f_mcr")
4021    (set_attr "mode"   "DI")
4022    (set_attr "length" "4")
4023   ])
4025 (define_insn "aarch64_movtilow_tilow"
4026   [(set (match_operand:TI 0 "register_operand" "=w")
4027         (zero_extend:TI 
4028           (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
4029   "reload_completed || reload_in_progress"
4030   "fmov\\t%d0, %d1"
4031   [(set_attr "v8type" "fmovi2f")
4032    (set_attr "type" "f_mcr")
4033    (set_attr "mode"   "DI")
4034    (set_attr "length" "4")
4035   ])
4037 ;; There is a deliberate reason why the parameters of high and lo_sum's
4038 ;; don't have modes for ADRP and ADD instructions.  This is to allow high
4039 ;; and lo_sum's to be used with the labels defining the jump tables in
4040 ;; rodata section.
4042 (define_expand "add_losym"
4043   [(set (match_operand 0 "register_operand" "=r")
4044         (lo_sum (match_operand 1 "register_operand" "r")
4045                 (match_operand 2 "aarch64_valid_symref" "S")))]
4046   ""
4048   enum machine_mode mode = GET_MODE (operands[0]);
4050   emit_insn ((mode == DImode
4051               ? gen_add_losym_di
4052               : gen_add_losym_si) (operands[0],
4053                                    operands[1],
4054                                    operands[2]));
4055   DONE;
4058 (define_insn "add_losym_<mode>"
4059   [(set (match_operand:P 0 "register_operand" "=r")
4060         (lo_sum:P (match_operand:P 1 "register_operand" "r")
4061                   (match_operand 2 "aarch64_valid_symref" "S")))]
4062   ""
4063   "add\\t%<w>0, %<w>1, :lo12:%a2"
4064   [(set_attr "v8type" "alu")
4065    (set_attr "type" "alu_reg")
4066    (set_attr "mode" "<MODE>")]
4069 (define_insn "ldr_got_small_<mode>"
4070   [(set (match_operand:PTR 0 "register_operand" "=r")
4071         (unspec:PTR [(mem:PTR (lo_sum:PTR
4072                               (match_operand:PTR 1 "register_operand" "r")
4073                               (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
4074                     UNSPEC_GOTSMALLPIC))]
4075   ""
4076   "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
4077   [(set_attr "v8type" "load1")
4078    (set_attr "type" "load1")
4079    (set_attr "mode" "<MODE>")]
4082 (define_insn "ldr_got_small_sidi"
4083   [(set (match_operand:DI 0 "register_operand" "=r")
4084         (zero_extend:DI
4085          (unspec:SI [(mem:SI (lo_sum:DI
4086                              (match_operand:DI 1 "register_operand" "r")
4087                              (match_operand:DI 2 "aarch64_valid_symref" "S")))]
4088                     UNSPEC_GOTSMALLPIC)))]
4089   "TARGET_ILP32"
4090   "ldr\\t%w0, [%1, #:got_lo12:%a2]"
4091   [(set_attr "v8type" "load1")
4092    (set_attr "type" "load1")
4093    (set_attr "mode" "DI")]
4096 (define_insn "ldr_got_tiny"
4097   [(set (match_operand:DI 0 "register_operand" "=r")
4098         (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
4099                    UNSPEC_GOTTINYPIC))]
4100   ""
4101   "ldr\\t%0, %L1"
4102   [(set_attr "v8type" "load1")
4103    (set_attr "type" "load1")
4104    (set_attr "mode" "DI")]
4107 (define_insn "aarch64_load_tp_hard"
4108   [(set (match_operand:DI 0 "register_operand" "=r")
4109         (unspec:DI [(const_int 0)] UNSPEC_TLS))]
4110   ""
4111   "mrs\\t%0, tpidr_el0"
4112   [(set_attr "v8type" "mrs")
4113    (set_attr "type" "mrs")
4114    (set_attr "mode" "DI")]
4117 ;; The TLS ABI specifically requires that the compiler does not schedule
4118 ;; instructions in the TLS stubs, in order to enable linker relaxation.
4119 ;; Therefore we treat the stubs as an atomic sequence.
4120 (define_expand "tlsgd_small"
4121  [(parallel [(set (match_operand 0 "register_operand" "")
4122                   (call (mem:DI (match_dup 2)) (const_int 1)))
4123              (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
4124              (clobber (reg:DI LR_REGNUM))])]
4125  ""
4127   operands[2] = aarch64_tls_get_addr ();
4130 (define_insn "*tlsgd_small"
4131   [(set (match_operand 0 "register_operand" "")
4132         (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
4133    (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
4134    (clobber (reg:DI LR_REGNUM))
4135   ]
4136   ""
4137   "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
4138   [(set_attr "v8type" "call")
4139    (set_attr "type" "call")
4140    (set_attr "length" "16")])
4142 (define_insn "tlsie_small"
4143   [(set (match_operand:DI 0 "register_operand" "=r")
4144         (unspec:DI [(match_operand:DI 1 "aarch64_tls_ie_symref" "S")]
4145                    UNSPEC_GOTSMALLTLS))]
4146   ""
4147   "adrp\\t%0, %A1\;ldr\\t%0, [%0, #%L1]"
4148   [(set_attr "v8type" "load1")
4149    (set_attr "type" "load1")
4150    (set_attr "mode" "DI")
4151    (set_attr "length" "8")]
4154 (define_insn "tlsle_small"
4155   [(set (match_operand:DI 0 "register_operand" "=r")
4156         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
4157                    (match_operand:DI 2 "aarch64_tls_le_symref" "S")]
4158                    UNSPEC_GOTSMALLTLS))]
4159   ""
4160   "add\\t%0, %1, #%G2\;add\\t%0, %0, #%L2"
4161   [(set_attr "v8type" "alu")
4162    (set_attr "type" "alu_reg")
4163    (set_attr "mode" "DI")
4164    (set_attr "length" "8")]
4167 (define_insn "tlsdesc_small"
4168   [(set (reg:DI R0_REGNUM)
4169         (unspec:DI [(match_operand:DI 0 "aarch64_valid_symref" "S")]
4170                    UNSPEC_TLSDESC))
4171    (clobber (reg:DI LR_REGNUM))
4172    (clobber (match_scratch:DI 1 "=r"))]
4173   "TARGET_TLS_DESC"
4174   "adrp\\tx0, %A0\;ldr\\t%1, [x0, #%L0]\;add\\tx0, x0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
4175   [(set_attr "v8type" "call")
4176    (set_attr "type" "call")
4177    (set_attr "length" "16")])
4179 (define_insn "stack_tie"
4180   [(set (mem:BLK (scratch))
4181         (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
4182                      (match_operand:DI 1 "register_operand" "rk")]
4183                     UNSPEC_PRLG_STK))]
4184   ""
4185   ""
4186   [(set_attr "length" "0")]
4189 ;; Named pattern for expanding thread pointer reference.
4190 (define_expand "get_thread_pointerdi"
4191   [(match_operand:DI 0 "register_operand" "=r")]
4192   ""
4194   rtx tmp = aarch64_load_tp (operands[0]);
4195   if (tmp != operands[0])
4196     emit_move_insn (operands[0], tmp);
4197   DONE;
4200 ;; AdvSIMD Stuff
4201 (include "aarch64-simd.md")
4203 ;; Atomic Operations
4204 (include "atomics.md")