[AArch64] Remove simd_type
[official-gcc.git] / gcc / config / aarch64 / aarch64.md
blob47f3eb3f653dd199890db35f2ab4a3c56c3a1631
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" "cortexa53,cortexa15")
316           (const_string "no")
317           (const_string "yes"))))
319 ;; Scheduling
320 (include "../arm/cortex-a53.md")
321 (include "../arm/cortex-a15.md")
323 ;; -------------------------------------------------------------------
324 ;; Jumps and other miscellaneous insns
325 ;; -------------------------------------------------------------------
327 (define_insn "indirect_jump"
328   [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
329   ""
330   "br\\t%0"
331   [(set_attr "v8type" "branch")
332    (set_attr "type" "branch")]
335 (define_insn "jump"
336   [(set (pc) (label_ref (match_operand 0 "" "")))]
337   ""
338   "b\\t%l0"
339   [(set_attr "v8type" "branch")
340    (set_attr "type" "branch")]
343 (define_expand "cbranch<mode>4"
344   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
345                             [(match_operand:GPI 1 "register_operand" "")
346                              (match_operand:GPI 2 "aarch64_plus_operand" "")])
347                            (label_ref (match_operand 3 "" ""))
348                            (pc)))]
349   ""
350   "
351   operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
352                                          operands[2]);
353   operands[2] = const0_rtx;
354   "
357 (define_expand "cbranch<mode>4"
358   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
359                             [(match_operand:GPF 1 "register_operand" "")
360                              (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
361                            (label_ref (match_operand 3 "" ""))
362                            (pc)))]
363   ""
364   "
365   operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
366                                          operands[2]);
367   operands[2] = const0_rtx;
368   "
371 (define_insn "*condjump"
372   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
373                             [(match_operand 1 "cc_register" "") (const_int 0)])
374                            (label_ref (match_operand 2 "" ""))
375                            (pc)))]
376   ""
377   "b%m0\\t%l2"
378   [(set_attr "v8type" "branch")
379    (set_attr "type" "branch")]
382 (define_expand "casesi"
383   [(match_operand:SI 0 "register_operand" "")   ; Index
384    (match_operand:SI 1 "const_int_operand" "")  ; Lower bound
385    (match_operand:SI 2 "const_int_operand" "")  ; Total range
386    (match_operand:DI 3 "" "")                   ; Table label
387    (match_operand:DI 4 "" "")]                  ; Out of range label
388   ""
389   {
390     if (operands[1] != const0_rtx)
391       {
392         rtx reg = gen_reg_rtx (SImode);
394         /* Canonical RTL says that if you have:
396            (minus (X) (CONST))
398            then this should be emitted as:
400            (plus (X) (-CONST))
402            The use of trunc_int_for_mode ensures that the resulting
403            constant can be represented in SImode, this is important
404            for the corner case where operand[1] is INT_MIN.  */
406         operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
408         if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
409               (operands[1], SImode))
410           operands[1] = force_reg (SImode, operands[1]);
411         emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
412         operands[0] = reg;
413       }
415     if (!aarch64_plus_operand (operands[2], SImode))
416       operands[2] = force_reg (SImode, operands[2]);
417     emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
418                                                  const0_rtx),
419                                     operands[0], operands[2], operands[4]));
421     operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
422     emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
423                                          operands[3]));
424     DONE;
425   }
428 (define_insn "casesi_dispatch"
429   [(parallel
430     [(set (pc)
431           (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
432                            (match_operand:SI 1 "register_operand" "r")]
433                         UNSPEC_CASESI)))
434      (clobber (reg:CC CC_REGNUM))
435      (clobber (match_scratch:DI 3 "=r"))
436      (clobber (match_scratch:DI 4 "=r"))
437      (use (label_ref (match_operand 2 "" "")))])]
438   ""
439   "*
440   return aarch64_output_casesi (operands);
441   "
442   [(set_attr "length" "16")
443    (set_attr "v8type" "branch")
444    (set_attr "type" "branch")]
447 (define_insn "nop"
448   [(unspec[(const_int 0)] UNSPEC_NOP)]
449   ""
450   "nop"
451   [(set_attr "v8type" "misc")]
454 (define_expand "prologue"
455   [(clobber (const_int 0))]
456   ""
457   "
458   aarch64_expand_prologue ();
459   DONE;
460   "
463 (define_expand "epilogue"
464   [(clobber (const_int 0))]
465   ""
466   "
467   aarch64_expand_epilogue (false);
468   DONE;
469   "
472 (define_expand "sibcall_epilogue"
473   [(clobber (const_int 0))]
474   ""
475   "
476   aarch64_expand_epilogue (true);
477   DONE;
478   "
481 (define_insn "*do_return"
482   [(return)]
483   ""
484   "ret"
485   [(set_attr "v8type" "branch")
486    (set_attr "type" "branch")]
489 (define_insn "eh_return"
490   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
491     UNSPECV_EH_RETURN)]
492   ""
493   "#"
494   [(set_attr "v8type" "branch")
495    (set_attr "type" "branch")]
499 (define_split
500   [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
501     UNSPECV_EH_RETURN)]
502   "reload_completed"
503   [(set (match_dup 1) (match_dup 0))]
504   {
505     operands[1] = aarch64_final_eh_return_addr ();
506   }
509 (define_insn "*cb<optab><mode>1"
510   [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
511                                 (const_int 0))
512                            (label_ref (match_operand 1 "" ""))
513                            (pc)))]
514   ""
515   "<cbz>\\t%<w>0, %l1"
516   [(set_attr "v8type" "branch")
517    (set_attr "type" "branch")]
521 (define_insn "*tb<optab><mode>1"
522   [(set (pc) (if_then_else
523               (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
524                                     (const_int 1)
525                                     (match_operand 1 "const_int_operand" "n"))
526                    (const_int 0))
527              (label_ref (match_operand 2 "" ""))
528              (pc)))
529    (clobber (match_scratch:DI 3 "=r"))]
530   ""
531   "*
532   if (get_attr_length (insn) == 8)
533     return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
534   return \"<tbz>\\t%<w>0, %1, %l2\";
535   "
536   [(set_attr "v8type" "branch")
537    (set_attr "type" "branch")
538    (set_attr "mode" "<MODE>")
539    (set (attr "length")
540         (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
541                            (lt (minus (match_dup 2) (pc)) (const_int 32764)))
542                       (const_int 4)
543                       (const_int 8)))]
546 (define_insn "*cb<optab><mode>1"
547   [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
548                                  (const_int 0))
549                            (label_ref (match_operand 1 "" ""))
550                            (pc)))
551    (clobber (match_scratch:DI 2 "=r"))]
552   ""
553   "*
554   if (get_attr_length (insn) == 8)
555     return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
556   return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
557   "
558   [(set_attr "v8type" "branch")
559    (set_attr "type" "branch")
560    (set_attr "mode" "<MODE>")
561    (set (attr "length")
562         (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
563                            (lt (minus (match_dup 1) (pc)) (const_int 32764)))
564                       (const_int 4)
565                       (const_int 8)))]
568 ;; -------------------------------------------------------------------
569 ;; Subroutine calls and sibcalls
570 ;; -------------------------------------------------------------------
572 (define_expand "call"
573   [(parallel [(call (match_operand 0 "memory_operand" "")
574                     (match_operand 1 "general_operand" ""))
575               (use (match_operand 2 "" ""))
576               (clobber (reg:DI LR_REGNUM))])]
577   ""
578   "
579   {
580     rtx callee;
582     /* In an untyped call, we can get NULL for operand 2.  */
583     if (operands[2] == NULL)
584       operands[2] = const0_rtx;
586     /* Decide if we should generate indirect calls by loading the
587        64-bit address of the callee into a register before performing
588        the branch-and-link.  */
589     callee = XEXP (operands[0], 0);
590     if (GET_CODE (callee) == SYMBOL_REF
591         ? aarch64_is_long_call_p (callee)
592         : !REG_P (callee))
593       XEXP (operands[0], 0) = force_reg (Pmode, callee);
594   }"
597 (define_insn "*call_reg"
598   [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
599          (match_operand 1 "" ""))
600    (use (match_operand 2 "" ""))
601    (clobber (reg:DI LR_REGNUM))]
602   ""
603   "blr\\t%0"
604   [(set_attr "v8type" "call")
605    (set_attr "type" "call")]
608 (define_insn "*call_symbol"
609   [(call (mem:DI (match_operand:DI 0 "" ""))
610          (match_operand 1 "" ""))
611    (use (match_operand 2 "" ""))
612    (clobber (reg:DI LR_REGNUM))]
613   "GET_CODE (operands[0]) == SYMBOL_REF
614    && !aarch64_is_long_call_p (operands[0])"
615   "bl\\t%a0"
616   [(set_attr "v8type" "call")
617    (set_attr "type" "call")]
620 (define_expand "call_value"
621   [(parallel [(set (match_operand 0 "" "")
622                    (call (match_operand 1 "memory_operand" "")
623                          (match_operand 2 "general_operand" "")))
624               (use (match_operand 3 "" ""))
625               (clobber (reg:DI LR_REGNUM))])]
626   ""
627   "
628   {
629     rtx callee;
631     /* In an untyped call, we can get NULL for operand 3.  */
632     if (operands[3] == NULL)
633       operands[3] = const0_rtx;
635     /* Decide if we should generate indirect calls by loading the
636        64-bit address of the callee into a register before performing
637        the branch-and-link.  */
638     callee = XEXP (operands[1], 0);
639     if (GET_CODE (callee) == SYMBOL_REF
640         ? aarch64_is_long_call_p (callee)
641         : !REG_P (callee))
642       XEXP (operands[1], 0) = force_reg (Pmode, callee);
643   }"
646 (define_insn "*call_value_reg"
647   [(set (match_operand 0 "" "")
648         (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
649                       (match_operand 2 "" "")))
650    (use (match_operand 3 "" ""))
651    (clobber (reg:DI LR_REGNUM))]
652   ""
653   "blr\\t%1"
654   [(set_attr "v8type" "call")
655    (set_attr "type" "call")]
659 (define_insn "*call_value_symbol"
660   [(set (match_operand 0 "" "")
661         (call (mem:DI (match_operand:DI 1 "" ""))
662               (match_operand 2 "" "")))
663    (use (match_operand 3 "" ""))
664    (clobber (reg:DI LR_REGNUM))]
665   "GET_CODE (operands[1]) == SYMBOL_REF
666    && !aarch64_is_long_call_p (operands[1])"
667   "bl\\t%a1"
668   [(set_attr "v8type" "call")
669    (set_attr "type" "call")]
672 (define_expand "sibcall"
673   [(parallel [(call (match_operand 0 "memory_operand" "")
674                     (match_operand 1 "general_operand" ""))
675               (return)
676               (use (match_operand 2 "" ""))])]
677   ""
678   {
679     if (operands[2] == NULL_RTX)
680       operands[2] = const0_rtx;
681   }
684 (define_expand "sibcall_value"
685   [(parallel [(set (match_operand 0 "" "")
686                    (call (match_operand 1 "memory_operand" "")
687                          (match_operand 2 "general_operand" "")))
688               (return)
689               (use (match_operand 3 "" ""))])]
690   ""
691   {
692     if (operands[3] == NULL_RTX)
693       operands[3] = const0_rtx;
694   }
697 (define_insn "*sibcall_insn"
698   [(call (mem:DI (match_operand:DI 0 "" "X"))
699          (match_operand 1 "" ""))
700    (return)
701    (use (match_operand 2 "" ""))]
702   "GET_CODE (operands[0]) == SYMBOL_REF"
703   "b\\t%a0"
704   [(set_attr "v8type" "branch")
705    (set_attr "type" "branch")]
709 (define_insn "*sibcall_value_insn"
710   [(set (match_operand 0 "" "")
711         (call (mem:DI (match_operand 1 "" "X"))
712               (match_operand 2 "" "")))
713    (return)
714    (use (match_operand 3 "" ""))]
715   "GET_CODE (operands[1]) == SYMBOL_REF"
716   "b\\t%a1"
717   [(set_attr "v8type" "branch")
718    (set_attr "type" "branch")]
721 ;; Call subroutine returning any type.
723 (define_expand "untyped_call"
724   [(parallel [(call (match_operand 0 "")
725                     (const_int 0))
726               (match_operand 1 "")
727               (match_operand 2 "")])]
728   ""
730   int i;
732   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
734   for (i = 0; i < XVECLEN (operands[2], 0); i++)
735     {
736       rtx set = XVECEXP (operands[2], 0, i);
737       emit_move_insn (SET_DEST (set), SET_SRC (set));
738     }
740   /* The optimizer does not know that the call sets the function value
741      registers we stored in the result block.  We avoid problems by
742      claiming that all hard registers are used and clobbered at this
743      point.  */
744   emit_insn (gen_blockage ());
745   DONE;
748 ;; -------------------------------------------------------------------
749 ;; Moves
750 ;; -------------------------------------------------------------------
752 (define_expand "mov<mode>"
753   [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
754         (match_operand:SHORT 1 "general_operand" ""))]
755   ""
756   "
757     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
758       operands[1] = force_reg (<MODE>mode, operands[1]);
759   "
762 (define_insn "*mov<mode>_aarch64"
763   [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r,   *w,r,*w, m, m, r,*w,*w")
764         (match_operand:SHORT 1 "general_operand"      " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
765   "(register_operand (operands[0], <MODE>mode)
766     || aarch64_reg_or_zero (operands[1], <MODE>mode))"
768    switch (which_alternative)
769      {
770      case 0:
771        return "mov\t%w0, %w1";
772      case 1:
773        return "mov\t%w0, %1";
774      case 2:
775        return aarch64_output_scalar_simd_mov_immediate (operands[1],
776                                                         <MODE>mode);
777      case 3:
778        return "ldr<size>\t%w0, %1";
779      case 4:
780        return "ldr\t%<size>0, %1";
781      case 5:
782        return "str<size>\t%w1, %0";
783      case 6:
784        return "str\t%<size>1, %0";
785      case 7:
786        return "umov\t%w0, %1.<v>[0]";
787      case 8:
788        return "dup\t%0.<Vallxd>, %w1";
789      case 9:
790        return "dup\t%<Vetype>0, %1.<v>[0]";
791      default:
792        gcc_unreachable ();
793      }
795   [(set_attr "v8type" "move,alu,alu,load1,load1,store1,store1,*,*,*")
796    (set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
797                      neon_from_gp<q>,neon_from_gp<q>, neon_dup")
798    (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")
799    (set_attr "mode" "<MODE>")]
802 (define_expand "mov<mode>"
803   [(set (match_operand:GPI 0 "nonimmediate_operand" "")
804         (match_operand:GPI 1 "general_operand" ""))]
805   ""
806   "
807     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
808       operands[1] = force_reg (<MODE>mode, operands[1]);
810     if (CONSTANT_P (operands[1]))
811       {
812         aarch64_expand_mov_immediate (operands[0], operands[1]);
813         DONE;
814       }
815   "
818 (define_insn "*movsi_aarch64"
819   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m,  m,r,r  ,*w, r,*w")
820         (match_operand:SI 1 "aarch64_mov_operand"  " r,r,k,M,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
821   "(register_operand (operands[0], SImode)
822     || aarch64_reg_or_zero (operands[1], SImode))"
823   "@
824    mov\\t%w0, %w1
825    mov\\t%w0, %w1
826    mov\\t%w0, %w1
827    mov\\t%w0, %1
828    ldr\\t%w0, %1
829    ldr\\t%s0, %1
830    str\\t%w1, %0
831    str\\t%s1, %0
832    adr\\t%x0, %a1
833    adrp\\t%x0, %A1
834    fmov\\t%s0, %w1
835    fmov\\t%w0, %s1
836    fmov\\t%s0, %s1"
837   [(set_attr "v8type" "move,move,move,alu,load1,load1,store1,store1,adr,adr,fmov,fmov,fmov")
838    (set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
839                      adr,adr,fmov,fmov,fmov")
840    (set_attr "mode" "SI")
841    (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
844 (define_insn "*movdi_aarch64"
845   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m,  m,r,r,  *w, r,*w,w")
846         (match_operand:DI 1 "aarch64_mov_operand"  " r,r,k,N,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))]
847   "(register_operand (operands[0], DImode)
848     || aarch64_reg_or_zero (operands[1], DImode))"
849   "@
850    mov\\t%x0, %x1
851    mov\\t%0, %x1
852    mov\\t%x0, %1
853    mov\\t%x0, %1
854    ldr\\t%x0, %1
855    ldr\\t%d0, %1
856    str\\t%x1, %0
857    str\\t%d1, %0
858    adr\\t%x0, %a1
859    adrp\\t%x0, %A1
860    fmov\\t%d0, %x1
861    fmov\\t%x0, %d1
862    fmov\\t%d0, %d1
863    movi\\t%d0, %1"
864   [(set_attr "v8type" "move,move,move,alu,load1,load1,store1,store1,adr,adr,fmov,fmov,fmov,fmov")
865    (set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
866                      adr,adr,fmov,fmov,fmov,fmov")
867    (set_attr "mode" "DI")
868    (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
869    (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
872 (define_insn "insv_imm<mode>"
873   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
874                           (const_int 16)
875                           (match_operand:GPI 1 "const_int_operand" "n"))
876         (match_operand:GPI 2 "const_int_operand" "n"))]
877   "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
878    && UINTVAL (operands[1]) % 16 == 0"
879   "movk\\t%<w>0, %X2, lsl %1"
880   [(set_attr "v8type" "movk")
881    (set_attr "type" "mov_imm")
882    (set_attr "mode" "<MODE>")]
885 (define_expand "movti"
886   [(set (match_operand:TI 0 "nonimmediate_operand" "")
887         (match_operand:TI 1 "general_operand" ""))]
888   ""
889   "
890     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
891       operands[1] = force_reg (TImode, operands[1]);
892   "
895 (define_insn "*movti_aarch64"
896   [(set (match_operand:TI 0
897          "nonimmediate_operand"  "=r, *w,r ,*w,r  ,Ump,Ump,*w,m")
898         (match_operand:TI 1
899          "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r  ,Z  , m,*w"))]
900   "(register_operand (operands[0], TImode)
901     || aarch64_reg_or_zero (operands[1], TImode))"
902   "@
903    #
904    #
905    #
906    orr\\t%0.16b, %1.16b, %1.16b
907    ldp\\t%0, %H0, %1
908    stp\\t%1, %H1, %0
909    stp\\txzr, xzr, %0
910    ldr\\t%q0, %1
911    str\\t%q1, %0"
912   [(set_attr "v8type" "move2,fmovi2f,fmovf2i,*, \
913                        load2,store2,store2,fpsimd_load,fpsimd_store")
914    (set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \
915                              load2,store2,store2,f_loadd,f_stored")
916    (set_attr "mode" "DI,DI,DI,TI,DI,DI,DI,TI,TI")
917    (set_attr "length" "8,8,8,4,4,4,4,4,4")
918    (set_attr "simd" "*,*,*,yes,*,*,*,*,*")
919    (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
922 ;; Split a TImode register-register or register-immediate move into
923 ;; its component DImode pieces, taking care to handle overlapping
924 ;; source and dest registers.
925 (define_split
926    [(set (match_operand:TI 0 "register_operand" "")
927          (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
928   "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
929   [(const_int 0)]
931   aarch64_split_128bit_move (operands[0], operands[1]);
932   DONE;
935 (define_expand "mov<mode>"
936   [(set (match_operand:GPF 0 "nonimmediate_operand" "")
937         (match_operand:GPF 1 "general_operand" ""))]
938   ""
939   "
940     if (!TARGET_FLOAT)
941      {
942         sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
943         FAIL;
944      }
946     if (GET_CODE (operands[0]) == MEM)
947       operands[1] = force_reg (<MODE>mode, operands[1]);
948   "
951 (define_insn "*movsf_aarch64"
952   [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w  ,w,m,r,m ,r")
953         (match_operand:SF 1 "general_operand"      "?rY, w,w,Ufc,m,w,m,rY,r"))]
954   "TARGET_FLOAT && (register_operand (operands[0], SFmode)
955     || register_operand (operands[1], SFmode))"
956   "@
957    fmov\\t%s0, %w1
958    fmov\\t%w0, %s1
959    fmov\\t%s0, %s1
960    fmov\\t%s0, %1
961    ldr\\t%s0, %1
962    str\\t%s1, %0
963    ldr\\t%w0, %1
964    str\\t%w1, %0
965    mov\\t%w0, %w1"
966   [(set_attr "v8type" "fmovi2f,fmovf2i,\
967                        fmov,fconst,fpsimd_load,\
968                        fpsimd_store,fpsimd_load,fpsimd_store,fmov")
969    (set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
970                      f_loads,f_stores,f_loads,f_stores,fmov")
971    (set_attr "mode" "SF")]
974 (define_insn "*movdf_aarch64"
975   [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w  ,w,m,r,m ,r")
976         (match_operand:DF 1 "general_operand"      "?rY, w,w,Ufc,m,w,m,rY,r"))]
977   "TARGET_FLOAT && (register_operand (operands[0], DFmode)
978     || register_operand (operands[1], DFmode))"
979   "@
980    fmov\\t%d0, %x1
981    fmov\\t%x0, %d1
982    fmov\\t%d0, %d1
983    fmov\\t%d0, %1
984    ldr\\t%d0, %1
985    str\\t%d1, %0
986    ldr\\t%x0, %1
987    str\\t%x1, %0
988    mov\\t%x0, %x1"
989   [(set_attr "v8type" "fmovi2f,fmovf2i,\
990                        fmov,fconst,fpsimd_load,\
991                        fpsimd_store,fpsimd_load,fpsimd_store,move")
992    (set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
993                      f_loadd,f_stored,f_loadd,f_stored,mov_reg")
994    (set_attr "mode" "DF")]
997 (define_expand "movtf"
998   [(set (match_operand:TF 0 "nonimmediate_operand" "")
999         (match_operand:TF 1 "general_operand" ""))]
1000   ""
1001   "
1002     if (!TARGET_FLOAT)
1003      {
1004         sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
1005         FAIL;
1006      }
1008     if (GET_CODE (operands[0]) == MEM)
1009       operands[1] = force_reg (TFmode, operands[1]);
1010   "
1013 (define_insn "*movtf_aarch64"
1014   [(set (match_operand:TF 0
1015          "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
1016         (match_operand:TF 1
1017          "general_operand"      " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
1018   "TARGET_FLOAT && (register_operand (operands[0], TFmode)
1019     || register_operand (operands[1], TFmode))"
1020   "@
1021    orr\\t%0.16b, %1.16b, %1.16b
1022    #
1023    #
1024    #
1025    movi\\t%0.2d, #0
1026    fmov\\t%s0, wzr
1027    ldr\\t%q0, %1
1028    str\\t%q1, %0
1029    ldp\\t%0, %H0, %1
1030    stp\\t%1, %H1, %0"
1031   [(set_attr "v8type" "logic,move2,fmovi2f,fmovf2i,fconst,fconst,fpsimd_load,fpsimd_store,fpsimd_load2,fpsimd_store2")
1032    (set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,fconstd,fconstd,\
1033                      f_loadd,f_stored,neon_load1_2reg,neon_store1_2reg")
1034    (set_attr "mode" "DF,DF,DF,DF,DF,DF,TF,TF,DF,DF")
1035    (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
1036    (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
1037    (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
1040 (define_split
1041    [(set (match_operand:TF 0 "register_operand" "")
1042          (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
1043   "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
1044   [(const_int 0)]
1045   {
1046     aarch64_split_128bit_move (operands[0], operands[1]);
1047     DONE;
1048   }
1051 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1052 ;; fairly lax checking on the second memory operation.
1053 (define_insn "load_pair<mode>"
1054   [(set (match_operand:GPI 0 "register_operand" "=r")
1055         (match_operand:GPI 1 "aarch64_mem_pair_operand" "Ump"))
1056    (set (match_operand:GPI 2 "register_operand" "=r")
1057         (match_operand:GPI 3 "memory_operand" "m"))]
1058   "rtx_equal_p (XEXP (operands[3], 0),
1059                 plus_constant (Pmode,
1060                                XEXP (operands[1], 0),
1061                                GET_MODE_SIZE (<MODE>mode)))"
1062   "ldp\\t%<w>0, %<w>2, %1"
1063   [(set_attr "v8type" "load2")
1064    (set_attr "type" "load2")
1065    (set_attr "mode" "<MODE>")]
1068 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1069 ;; fairly lax checking on the second memory operation.
1070 (define_insn "store_pair<mode>"
1071   [(set (match_operand:GPI 0 "aarch64_mem_pair_operand" "=Ump")
1072         (match_operand:GPI 1 "register_operand" "r"))
1073    (set (match_operand:GPI 2 "memory_operand" "=m")
1074         (match_operand:GPI 3 "register_operand" "r"))]
1075   "rtx_equal_p (XEXP (operands[2], 0),
1076                 plus_constant (Pmode,
1077                                XEXP (operands[0], 0),
1078                                GET_MODE_SIZE (<MODE>mode)))"
1079   "stp\\t%<w>1, %<w>3, %0"
1080   [(set_attr "v8type" "store2")
1081    (set_attr "type" "store2")
1082    (set_attr "mode" "<MODE>")]
1085 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1086 ;; fairly lax checking on the second memory operation.
1087 (define_insn "load_pair<mode>"
1088   [(set (match_operand:GPF 0 "register_operand" "=w")
1089         (match_operand:GPF 1 "aarch64_mem_pair_operand" "Ump"))
1090    (set (match_operand:GPF 2 "register_operand" "=w")
1091         (match_operand:GPF 3 "memory_operand" "m"))]
1092   "rtx_equal_p (XEXP (operands[3], 0),
1093                 plus_constant (Pmode,
1094                                XEXP (operands[1], 0),
1095                                GET_MODE_SIZE (<MODE>mode)))"
1096   "ldp\\t%<w>0, %<w>2, %1"
1097   [(set_attr "v8type" "fpsimd_load2")
1098    (set_attr "type" "neon_load1_2reg<q>")
1099    (set_attr "mode" "<MODE>")]
1102 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1103 ;; fairly lax checking on the second memory operation.
1104 (define_insn "store_pair<mode>"
1105   [(set (match_operand:GPF 0 "aarch64_mem_pair_operand" "=Ump")
1106         (match_operand:GPF 1 "register_operand" "w"))
1107    (set (match_operand:GPF 2 "memory_operand" "=m")
1108         (match_operand:GPF 3 "register_operand" "w"))]
1109   "rtx_equal_p (XEXP (operands[2], 0),
1110                 plus_constant (Pmode,
1111                                XEXP (operands[0], 0),
1112                                GET_MODE_SIZE (<MODE>mode)))"
1113   "stp\\t%<w>1, %<w>3, %0"
1114   [(set_attr "v8type" "fpsimd_store2")
1115    (set_attr "type" "neon_store1_2reg<q>")
1116    (set_attr "mode" "<MODE>")]
1119 ;; Load pair with writeback.  This is primarily used in function epilogues
1120 ;; when restoring [fp,lr]
1121 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
1122   [(parallel
1123     [(set (match_operand:P 0 "register_operand" "=k")
1124           (plus:P (match_operand:P 1 "register_operand" "0")
1125                   (match_operand:P 4 "const_int_operand" "n")))
1126      (set (match_operand:GPI 2 "register_operand" "=r")
1127           (mem:GPI (plus:P (match_dup 1)
1128                    (match_dup 4))))
1129      (set (match_operand:GPI 3 "register_operand" "=r")
1130           (mem:GPI (plus:P (match_dup 1)
1131                    (match_operand:P 5 "const_int_operand" "n"))))])]
1132   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1133   "ldp\\t%<w>2, %<w>3, [%1], %4"
1134   [(set_attr "v8type" "load2")
1135    (set_attr "type" "load2")
1136    (set_attr "mode" "<GPI:MODE>")]
1139 ;; Store pair with writeback.  This is primarily used in function prologues
1140 ;; when saving [fp,lr]
1141 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
1142   [(parallel
1143     [(set (match_operand:P 0 "register_operand" "=&k")
1144           (plus:P (match_operand:P 1 "register_operand" "0")
1145                   (match_operand:P 4 "const_int_operand" "n")))
1146      (set (mem:GPI (plus:P (match_dup 0)
1147                    (match_dup 4)))
1148           (match_operand:GPI 2 "register_operand" "r"))
1149      (set (mem:GPI (plus:P (match_dup 0)
1150                    (match_operand:P 5 "const_int_operand" "n")))
1151           (match_operand:GPI 3 "register_operand" "r"))])]
1152   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1153   "stp\\t%<w>2, %<w>3, [%0, %4]!"
1154   [(set_attr "v8type" "store2")
1155    (set_attr "type" "store2")
1156    (set_attr "mode" "<GPI:MODE>")]
1159 ;; -------------------------------------------------------------------
1160 ;; Sign/Zero extension
1161 ;; -------------------------------------------------------------------
1163 (define_expand "<optab>sidi2"
1164   [(set (match_operand:DI 0 "register_operand")
1165         (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1166   ""
1169 (define_insn "*extendsidi2_aarch64"
1170   [(set (match_operand:DI 0 "register_operand" "=r,r")
1171         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1172   ""
1173   "@
1174    sxtw\t%0, %w1
1175    ldrsw\t%0, %1"
1176   [(set_attr "v8type" "extend,load1")
1177    (set_attr "type" "extend,load1")
1178    (set_attr "mode" "DI")]
1181 (define_insn "*zero_extendsidi2_aarch64"
1182   [(set (match_operand:DI 0 "register_operand" "=r,r")
1183         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1184   ""
1185   "@
1186    uxtw\t%0, %w1
1187    ldr\t%w0, %1"
1188   [(set_attr "v8type" "extend,load1")
1189    (set_attr "type" "extend,load1")
1190    (set_attr "mode" "DI")]
1193 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1194   [(set (match_operand:GPI 0 "register_operand")
1195         (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1196   ""
1199 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1200   [(set (match_operand:GPI 0 "register_operand" "=r,r")
1201         (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1202   ""
1203   "@
1204    sxt<SHORT:size>\t%<GPI:w>0, %w1
1205    ldrs<SHORT:size>\t%<GPI:w>0, %1"
1206   [(set_attr "v8type" "extend,load1")
1207    (set_attr "type" "extend,load1")
1208    (set_attr "mode" "<GPI:MODE>")]
1211 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1212   [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1213         (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1214   ""
1215   "@
1216    uxt<SHORT:size>\t%<GPI:w>0, %w1
1217    ldr<SHORT:size>\t%w0, %1
1218    ldr\t%<SHORT:size>0, %1"
1219   [(set_attr "v8type" "extend,load1,load1")
1220    (set_attr "type" "extend,load1,load1")
1221    (set_attr "mode" "<GPI:MODE>")]
1224 (define_expand "<optab>qihi2"
1225   [(set (match_operand:HI 0 "register_operand")
1226         (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1227   ""
1230 (define_insn "*<optab>qihi2_aarch64"
1231   [(set (match_operand:HI 0 "register_operand" "=r,r")
1232         (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1233   ""
1234   "@
1235    <su>xtb\t%w0, %w1
1236    <ldrxt>b\t%w0, %1"
1237   [(set_attr "v8type" "extend,load1")
1238    (set_attr "type" "extend,load1")
1239    (set_attr "mode" "HI")]
1242 ;; -------------------------------------------------------------------
1243 ;; Simple arithmetic
1244 ;; -------------------------------------------------------------------
1246 (define_expand "add<mode>3"
1247   [(set
1248     (match_operand:GPI 0 "register_operand" "")
1249     (plus:GPI (match_operand:GPI 1 "register_operand" "")
1250               (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1251   ""
1252   "
1253   if (! aarch64_plus_operand (operands[2], VOIDmode))
1254     {
1255       rtx subtarget = ((optimize && can_create_pseudo_p ())
1256                        ? gen_reg_rtx (<MODE>mode) : operands[0]);
1257       HOST_WIDE_INT imm = INTVAL (operands[2]);
1259       if (imm < 0)
1260         imm = -(-imm & ~0xfff);
1261       else
1262         imm &= ~0xfff;
1264       emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1265       operands[1] = subtarget;
1266       operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1267     }
1268   "
1271 (define_insn "*addsi3_aarch64"
1272   [(set
1273     (match_operand:SI 0 "register_operand" "=rk,rk,rk")
1274     (plus:SI
1275      (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1276      (match_operand:SI 2 "aarch64_plus_operand" "I,r,J")))]
1277   ""
1278   "@
1279   add\\t%w0, %w1, %2
1280   add\\t%w0, %w1, %w2
1281   sub\\t%w0, %w1, #%n2"
1282   [(set_attr "v8type" "alu")
1283    (set_attr "type" "alu_imm,alu_reg,alu_imm")
1284    (set_attr "mode" "SI")]
1287 ;; zero_extend version of above
1288 (define_insn "*addsi3_aarch64_uxtw"
1289   [(set
1290     (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1291     (zero_extend:DI
1292      (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1293               (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1294   ""
1295   "@
1296   add\\t%w0, %w1, %2
1297   add\\t%w0, %w1, %w2
1298   sub\\t%w0, %w1, #%n2"
1299   [(set_attr "v8type" "alu")
1300    (set_attr "type" "alu_imm,alu_reg,alu_imm")
1301    (set_attr "mode" "SI")]
1304 (define_insn "*adddi3_aarch64"
1305   [(set
1306     (match_operand:DI 0 "register_operand" "=rk,rk,rk,!w")
1307     (plus:DI
1308      (match_operand:DI 1 "register_operand" "%rk,rk,rk,!w")
1309      (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,!w")))]
1310   ""
1311   "@
1312   add\\t%x0, %x1, %2
1313   add\\t%x0, %x1, %x2
1314   sub\\t%x0, %x1, #%n2
1315   add\\t%d0, %d1, %d2"
1316   [(set_attr "v8type" "alu")
1317    (set_attr "type" "alu_imm,alu_reg,alu_imm,alu_reg")
1318    (set_attr "mode" "DI")
1319    (set_attr "simd" "*,*,*,yes")]
1322 (define_insn "*add<mode>3_compare0"
1323   [(set (reg:CC_NZ CC_REGNUM)
1324         (compare:CC_NZ
1325          (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1326                    (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1327          (const_int 0)))
1328    (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1329         (plus:GPI (match_dup 1) (match_dup 2)))]
1330   ""
1331   "@
1332   adds\\t%<w>0, %<w>1, %<w>2
1333   adds\\t%<w>0, %<w>1, %<w>2
1334   subs\\t%<w>0, %<w>1, #%n2"
1335   [(set_attr "v8type" "alus")
1336    (set_attr "type" "alus_reg,alus_imm,alus_imm")
1337    (set_attr "mode" "<MODE>")]
1340 ;; zero_extend version of above
1341 (define_insn "*addsi3_compare0_uxtw"
1342   [(set (reg:CC_NZ CC_REGNUM)
1343         (compare:CC_NZ
1344          (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1345                   (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1346          (const_int 0)))
1347    (set (match_operand:DI 0 "register_operand" "=r,r,r")
1348         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1349   ""
1350   "@
1351   adds\\t%w0, %w1, %w2
1352   adds\\t%w0, %w1, %w2
1353   subs\\t%w0, %w1, #%n2"
1354   [(set_attr "v8type" "alus")
1355    (set_attr "type" "alus_reg,alus_imm,alus_imm")
1356    (set_attr "mode" "SI")]
1359 (define_insn "*adds_mul_imm_<mode>"
1360   [(set (reg:CC_NZ CC_REGNUM)
1361         (compare:CC_NZ
1362          (plus:GPI (mult:GPI
1363                     (match_operand:GPI 1 "register_operand" "r")
1364                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1365                    (match_operand:GPI 3 "register_operand" "r"))
1366          (const_int 0)))
1367    (set (match_operand:GPI 0 "register_operand" "=r")
1368         (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1369                   (match_dup 3)))]
1370   ""
1371   "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1372   [(set_attr "v8type" "alus_shift")
1373    (set_attr "type" "alus_shift_imm")
1374    (set_attr "mode" "<MODE>")]
1377 (define_insn "*subs_mul_imm_<mode>"
1378   [(set (reg:CC_NZ CC_REGNUM)
1379         (compare:CC_NZ
1380          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1381                     (mult:GPI
1382                      (match_operand:GPI 2 "register_operand" "r")
1383                      (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1384          (const_int 0)))
1385    (set (match_operand:GPI 0 "register_operand" "=r")
1386         (minus:GPI (match_dup 1)
1387                    (mult:GPI (match_dup 2) (match_dup 3))))]
1388   ""
1389   "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1390   [(set_attr "v8type" "alus_shift")
1391    (set_attr "type" "alus_shift_imm")
1392    (set_attr "mode" "<MODE>")]
1395 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1396   [(set (reg:CC_NZ CC_REGNUM)
1397         (compare:CC_NZ
1398          (plus:GPI
1399           (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1400           (match_operand:GPI 2 "register_operand" "r"))
1401         (const_int 0)))
1402    (set (match_operand:GPI 0 "register_operand" "=r")
1403         (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1404   ""
1405   "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1406   [(set_attr "v8type" "alus_ext")
1407    (set_attr "type" "alus_ext")
1408    (set_attr "mode" "<GPI:MODE>")]
1411 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1412   [(set (reg:CC_NZ CC_REGNUM)
1413         (compare:CC_NZ
1414          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1415                     (ANY_EXTEND:GPI
1416                      (match_operand:ALLX 2 "register_operand" "r")))
1417         (const_int 0)))
1418    (set (match_operand:GPI 0 "register_operand" "=r")
1419         (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1420   ""
1421   "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1422   [(set_attr "v8type" "alus_ext")
1423    (set_attr "type" "alus_ext")
1424    (set_attr "mode" "<GPI:MODE>")]
1427 (define_insn "*adds_<optab><mode>_multp2"
1428   [(set (reg:CC_NZ CC_REGNUM)
1429         (compare:CC_NZ
1430          (plus:GPI (ANY_EXTRACT:GPI
1431                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1432                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1433                     (match_operand 3 "const_int_operand" "n")
1434                     (const_int 0))
1435                    (match_operand:GPI 4 "register_operand" "r"))
1436         (const_int 0)))
1437    (set (match_operand:GPI 0 "register_operand" "=r")
1438         (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1439                                    (match_dup 3)
1440                                    (const_int 0))
1441                   (match_dup 4)))]
1442   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1443   "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1444   [(set_attr "v8type" "alus_ext")
1445    (set_attr "type" "alus_ext")
1446    (set_attr "mode" "<MODE>")]
1449 (define_insn "*subs_<optab><mode>_multp2"
1450   [(set (reg:CC_NZ CC_REGNUM)
1451         (compare:CC_NZ
1452          (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1453                     (ANY_EXTRACT:GPI
1454                      (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1455                                (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1456                      (match_operand 3 "const_int_operand" "n")
1457                      (const_int 0)))
1458         (const_int 0)))
1459    (set (match_operand:GPI 0 "register_operand" "=r")
1460         (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1461                                   (mult:GPI (match_dup 1) (match_dup 2))
1462                                   (match_dup 3)
1463                                   (const_int 0))))]
1464   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1465   "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1466   [(set_attr "v8type" "alus_ext")
1467    (set_attr "type" "alus_ext")
1468    (set_attr "mode" "<MODE>")]
1471 (define_insn "*add<mode>3nr_compare0"
1472   [(set (reg:CC_NZ CC_REGNUM)
1473         (compare:CC_NZ
1474          (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1475                    (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1476          (const_int 0)))]
1477   ""
1478   "@
1479   cmn\\t%<w>0, %<w>1
1480   cmn\\t%<w>0, %<w>1
1481   cmp\\t%<w>0, #%n1"
1482   [(set_attr "v8type" "alus")
1483    (set_attr "type" "alus_reg,alus_imm,alus_imm")
1484    (set_attr "mode" "<MODE>")]
1487 (define_insn "*compare_neg<mode>"
1488   [(set (reg:CC_SWP CC_REGNUM)
1489         (compare:CC_SWP
1490          (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1491          (match_operand:GPI 1 "register_operand" "r")))]
1492   ""
1493   "cmn\\t%<w>1, %<w>0"
1494   [(set_attr "v8type" "alus")
1495    (set_attr "type" "alus_reg")
1496    (set_attr "mode" "<MODE>")]
1499 (define_insn "*add_<shift>_<mode>"
1500   [(set (match_operand:GPI 0 "register_operand" "=r")
1501         (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1502                               (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1503                   (match_operand:GPI 3 "register_operand" "r")))]
1504   ""
1505   "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1506   [(set_attr "v8type" "alu_shift")
1507    (set_attr "type" "alu_shift_imm")
1508    (set_attr "mode" "<MODE>")]
1511 ;; zero_extend version of above
1512 (define_insn "*add_<shift>_si_uxtw"
1513   [(set (match_operand:DI 0 "register_operand" "=r")
1514         (zero_extend:DI
1515          (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1516                              (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1517                   (match_operand:SI 3 "register_operand" "r"))))]
1518   ""
1519   "add\\t%w0, %w3, %w1, <shift> %2"
1520   [(set_attr "v8type" "alu_shift")
1521    (set_attr "type" "alu_shift_imm")
1522    (set_attr "mode" "SI")]
1525 (define_insn "*add_mul_imm_<mode>"
1526   [(set (match_operand:GPI 0 "register_operand" "=r")
1527         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1528                             (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1529                   (match_operand:GPI 3 "register_operand" "r")))]
1530   ""
1531   "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1532   [(set_attr "v8type" "alu_shift")
1533    (set_attr "type" "alu_shift_imm")
1534    (set_attr "mode" "<MODE>")]
1537 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1538   [(set (match_operand:GPI 0 "register_operand" "=rk")
1539         (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1540                   (match_operand:GPI 2 "register_operand" "r")))]
1541   ""
1542   "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1543   [(set_attr "v8type" "alu_ext")
1544    (set_attr "type" "alu_ext")
1545    (set_attr "mode" "<GPI:MODE>")]
1548 ;; zero_extend version of above
1549 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1550   [(set (match_operand:DI 0 "register_operand" "=rk")
1551         (zero_extend:DI
1552          (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1553                   (match_operand:GPI 2 "register_operand" "r"))))]
1554   ""
1555   "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1556   [(set_attr "v8type" "alu_ext")
1557    (set_attr "type" "alu_ext")
1558    (set_attr "mode" "SI")]
1561 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1562   [(set (match_operand:GPI 0 "register_operand" "=rk")
1563         (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1564                                (match_operand:ALLX 1 "register_operand" "r"))
1565                               (match_operand 2 "aarch64_imm3" "Ui3"))
1566                   (match_operand:GPI 3 "register_operand" "r")))]
1567   ""
1568   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1569   [(set_attr "v8type" "alu_ext")
1570    (set_attr "type" "alu_ext")
1571    (set_attr "mode" "<GPI:MODE>")]
1574 ;; zero_extend version of above
1575 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1576   [(set (match_operand:DI 0 "register_operand" "=rk")
1577         (zero_extend:DI
1578          (plus:SI (ashift:SI (ANY_EXTEND:SI
1579                               (match_operand:SHORT 1 "register_operand" "r"))
1580                              (match_operand 2 "aarch64_imm3" "Ui3"))
1581                   (match_operand:SI 3 "register_operand" "r"))))]
1582   ""
1583   "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1584   [(set_attr "v8type" "alu_ext")
1585    (set_attr "type" "alu_ext")
1586    (set_attr "mode" "SI")]
1589 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1590   [(set (match_operand:GPI 0 "register_operand" "=rk")
1591         (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1592                              (match_operand:ALLX 1 "register_operand" "r"))
1593                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1594                   (match_operand:GPI 3 "register_operand" "r")))]
1595   ""
1596   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1597   [(set_attr "v8type" "alu_ext")
1598    (set_attr "type" "alu_ext")
1599    (set_attr "mode" "<GPI:MODE>")]
1602 ;; zero_extend version of above
1603 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1604   [(set (match_operand:DI 0 "register_operand" "=rk")
1605         (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1606                              (match_operand:SHORT 1 "register_operand" "r"))
1607                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1608                   (match_operand:SI 3 "register_operand" "r"))))]
1609   ""
1610   "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1611   [(set_attr "v8type" "alu_ext")
1612    (set_attr "type" "alu_ext")
1613    (set_attr "mode" "SI")]
1616 (define_insn "*add_<optab><mode>_multp2"
1617   [(set (match_operand:GPI 0 "register_operand" "=rk")
1618         (plus:GPI (ANY_EXTRACT:GPI
1619                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1620                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1621                    (match_operand 3 "const_int_operand" "n")
1622                    (const_int 0))
1623                   (match_operand:GPI 4 "register_operand" "r")))]
1624   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1625   "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1626   [(set_attr "v8type" "alu_ext")
1627    (set_attr "type" "alu_ext")
1628    (set_attr "mode" "<MODE>")]
1631 ;; zero_extend version of above
1632 (define_insn "*add_<optab>si_multp2_uxtw"
1633   [(set (match_operand:DI 0 "register_operand" "=rk")
1634         (zero_extend:DI
1635          (plus:SI (ANY_EXTRACT:SI
1636                    (mult:SI (match_operand:SI 1 "register_operand" "r")
1637                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1638                    (match_operand 3 "const_int_operand" "n")
1639                    (const_int 0))
1640                   (match_operand:SI 4 "register_operand" "r"))))]
1641   "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1642   "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1643   [(set_attr "v8type" "alu_ext")
1644    (set_attr "type" "alu_ext")
1645    (set_attr "mode" "SI")]
1648 (define_insn "*add<mode>3_carryin"
1649   [(set
1650     (match_operand:GPI 0 "register_operand" "=r")
1651     (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1652               (plus:GPI
1653                 (match_operand:GPI 1 "register_operand" "r")
1654                 (match_operand:GPI 2 "register_operand" "r"))))]
1655    ""
1656    "adc\\t%<w>0, %<w>1, %<w>2"
1657   [(set_attr "v8type" "adc")
1658    (set_attr "type" "adc_reg")
1659    (set_attr "mode" "<MODE>")]
1662 ;; zero_extend version of above
1663 (define_insn "*addsi3_carryin_uxtw"
1664   [(set
1665     (match_operand:DI 0 "register_operand" "=r")
1666     (zero_extend:DI
1667      (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1668               (plus:SI
1669                (match_operand:SI 1 "register_operand" "r")
1670                (match_operand:SI 2 "register_operand" "r")))))]
1671    ""
1672    "adc\\t%w0, %w1, %w2"
1673   [(set_attr "v8type" "adc")
1674    (set_attr "type" "adc_reg")
1675    (set_attr "mode" "SI")]
1678 (define_insn "*add<mode>3_carryin_alt1"
1679   [(set
1680     (match_operand:GPI 0 "register_operand" "=r")
1681     (plus:GPI (plus:GPI
1682                 (match_operand:GPI 1 "register_operand" "r")
1683                 (match_operand:GPI 2 "register_operand" "r"))
1684               (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1685    ""
1686    "adc\\t%<w>0, %<w>1, %<w>2"
1687   [(set_attr "v8type" "adc")
1688    (set_attr "type" "adc_reg")
1689    (set_attr "mode" "<MODE>")]
1692 ;; zero_extend version of above
1693 (define_insn "*addsi3_carryin_alt1_uxtw"
1694   [(set
1695     (match_operand:DI 0 "register_operand" "=r")
1696     (zero_extend:DI
1697      (plus:SI (plus:SI
1698                (match_operand:SI 1 "register_operand" "r")
1699                (match_operand:SI 2 "register_operand" "r"))
1700               (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1701    ""
1702    "adc\\t%w0, %w1, %w2"
1703   [(set_attr "v8type" "adc")
1704    (set_attr "type" "adc_reg")
1705    (set_attr "mode" "SI")]
1708 (define_insn "*add<mode>3_carryin_alt2"
1709   [(set
1710     (match_operand:GPI 0 "register_operand" "=r")
1711     (plus:GPI (plus:GPI
1712                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1713                 (match_operand:GPI 1 "register_operand" "r"))
1714               (match_operand:GPI 2 "register_operand" "r")))]
1715    ""
1716    "adc\\t%<w>0, %<w>1, %<w>2"
1717   [(set_attr "v8type" "adc")
1718    (set_attr "type" "adc_reg")
1719    (set_attr "mode" "<MODE>")]
1722 ;; zero_extend version of above
1723 (define_insn "*addsi3_carryin_alt2_uxtw"
1724   [(set
1725     (match_operand:DI 0 "register_operand" "=r")
1726     (zero_extend:DI
1727      (plus:SI (plus:SI
1728                (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1729                (match_operand:SI 1 "register_operand" "r"))
1730               (match_operand:SI 2 "register_operand" "r"))))]
1731    ""
1732    "adc\\t%w0, %w1, %w2"
1733   [(set_attr "v8type" "adc")
1734    (set_attr "type" "adc_reg")
1735    (set_attr "mode" "SI")]
1738 (define_insn "*add<mode>3_carryin_alt3"
1739   [(set
1740     (match_operand:GPI 0 "register_operand" "=r")
1741     (plus:GPI (plus:GPI
1742                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1743                 (match_operand:GPI 2 "register_operand" "r"))
1744               (match_operand:GPI 1 "register_operand" "r")))]
1745    ""
1746    "adc\\t%<w>0, %<w>1, %<w>2"
1747   [(set_attr "v8type" "adc")
1748    (set_attr "type" "adc_reg")
1749    (set_attr "mode" "<MODE>")]
1752 ;; zero_extend version of above
1753 (define_insn "*addsi3_carryin_alt3_uxtw"
1754   [(set
1755     (match_operand:DI 0 "register_operand" "=r")
1756     (zero_extend:DI
1757      (plus:SI (plus:SI
1758                (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1759                (match_operand:SI 2 "register_operand" "r"))
1760               (match_operand:SI 1 "register_operand" "r"))))]
1761    ""
1762    "adc\\t%w0, %w1, %w2"
1763   [(set_attr "v8type" "adc")
1764    (set_attr "type" "adc_reg")
1765    (set_attr "mode" "SI")]
1768 (define_insn "*add_uxt<mode>_multp2"
1769   [(set (match_operand:GPI 0 "register_operand" "=rk")
1770         (plus:GPI (and:GPI
1771                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1772                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1773                    (match_operand 3 "const_int_operand" "n"))
1774                   (match_operand:GPI 4 "register_operand" "r")))]
1775   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1776   "*
1777   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1778                                            INTVAL (operands[3])));
1779   return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1780   [(set_attr "v8type" "alu_ext")
1781    (set_attr "type" "alu_ext")
1782    (set_attr "mode" "<MODE>")]
1785 ;; zero_extend version of above
1786 (define_insn "*add_uxtsi_multp2_uxtw"
1787   [(set (match_operand:DI 0 "register_operand" "=rk")
1788         (zero_extend:DI
1789          (plus:SI (and:SI
1790                    (mult:SI (match_operand:SI 1 "register_operand" "r")
1791                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1792                    (match_operand 3 "const_int_operand" "n"))
1793                   (match_operand:SI 4 "register_operand" "r"))))]
1794   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1795   "*
1796   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1797                                            INTVAL (operands[3])));
1798   return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1799   [(set_attr "v8type" "alu_ext")
1800    (set_attr "type" "alu_ext")
1801    (set_attr "mode" "SI")]
1804 (define_insn "subsi3"
1805   [(set (match_operand:SI 0 "register_operand" "=rk")
1806         (minus:SI (match_operand:SI 1 "register_operand" "r")
1807                    (match_operand:SI 2 "register_operand" "r")))]
1808   ""
1809   "sub\\t%w0, %w1, %w2"
1810   [(set_attr "v8type" "alu")
1811    (set_attr "type" "alu_reg")
1812    (set_attr "mode" "SI")]
1815 ;; zero_extend version of above
1816 (define_insn "*subsi3_uxtw"
1817   [(set (match_operand:DI 0 "register_operand" "=rk")
1818         (zero_extend:DI
1819          (minus:SI (match_operand:SI 1 "register_operand" "r")
1820                    (match_operand:SI 2 "register_operand" "r"))))]
1821   ""
1822   "sub\\t%w0, %w1, %w2"
1823   [(set_attr "v8type" "alu")
1824    (set_attr "type" "alu_reg")
1825    (set_attr "mode" "SI")]
1828 (define_insn "subdi3"
1829   [(set (match_operand:DI 0 "register_operand" "=rk,!w")
1830         (minus:DI (match_operand:DI 1 "register_operand" "r,!w")
1831                    (match_operand:DI 2 "register_operand" "r,!w")))]
1832   ""
1833   "@
1834    sub\\t%x0, %x1, %x2
1835    sub\\t%d0, %d1, %d2"
1836   [(set_attr "v8type" "alu")
1837    (set_attr "type" "alu_reg")
1838    (set_attr "mode" "DI")
1839    (set_attr "simd" "*,yes")]
1843 (define_insn "*sub<mode>3_compare0"
1844   [(set (reg:CC_NZ CC_REGNUM)
1845         (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1846                                   (match_operand:GPI 2 "register_operand" "r"))
1847                        (const_int 0)))
1848    (set (match_operand:GPI 0 "register_operand" "=r")
1849         (minus:GPI (match_dup 1) (match_dup 2)))]
1850   ""
1851   "subs\\t%<w>0, %<w>1, %<w>2"
1852   [(set_attr "v8type" "alus")
1853    (set_attr "type" "alus_reg")
1854    (set_attr "mode" "<MODE>")]
1857 ;; zero_extend version of above
1858 (define_insn "*subsi3_compare0_uxtw"
1859   [(set (reg:CC_NZ CC_REGNUM)
1860         (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1861                                  (match_operand:SI 2 "register_operand" "r"))
1862                        (const_int 0)))
1863    (set (match_operand:DI 0 "register_operand" "=r")
1864         (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1865   ""
1866   "subs\\t%w0, %w1, %w2"
1867   [(set_attr "v8type" "alus")
1868    (set_attr "type" "alus_reg")
1869    (set_attr "mode" "SI")]
1872 (define_insn "*sub_<shift>_<mode>"
1873   [(set (match_operand:GPI 0 "register_operand" "=r")
1874         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1875                    (ASHIFT:GPI
1876                     (match_operand:GPI 1 "register_operand" "r")
1877                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1878   ""
1879   "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1880   [(set_attr "v8type" "alu_shift")
1881    (set_attr "type" "alu_shift_imm")
1882    (set_attr "mode" "<MODE>")]
1885 ;; zero_extend version of above
1886 (define_insn "*sub_<shift>_si_uxtw"
1887   [(set (match_operand:DI 0 "register_operand" "=r")
1888         (zero_extend:DI
1889          (minus:SI (match_operand:SI 3 "register_operand" "r")
1890                    (ASHIFT:SI
1891                     (match_operand:SI 1 "register_operand" "r")
1892                     (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1893   ""
1894   "sub\\t%w0, %w3, %w1, <shift> %2"
1895   [(set_attr "v8type" "alu_shift")
1896    (set_attr "type" "alu_shift_imm")
1897    (set_attr "mode" "SI")]
1900 (define_insn "*sub_mul_imm_<mode>"
1901   [(set (match_operand:GPI 0 "register_operand" "=r")
1902         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1903                    (mult:GPI
1904                     (match_operand:GPI 1 "register_operand" "r")
1905                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1906   ""
1907   "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1908   [(set_attr "v8type" "alu_shift")
1909    (set_attr "type" "alu_shift_imm")
1910    (set_attr "mode" "<MODE>")]
1913 ;; zero_extend version of above
1914 (define_insn "*sub_mul_imm_si_uxtw"
1915   [(set (match_operand:DI 0 "register_operand" "=r")
1916         (zero_extend:DI
1917          (minus:SI (match_operand:SI 3 "register_operand" "r")
1918                    (mult:SI
1919                     (match_operand:SI 1 "register_operand" "r")
1920                     (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
1921   ""
1922   "sub\\t%w0, %w3, %w1, lsl %p2"
1923   [(set_attr "v8type" "alu_shift")
1924    (set_attr "type" "alu_shift_imm")
1925    (set_attr "mode" "SI")]
1928 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
1929   [(set (match_operand:GPI 0 "register_operand" "=rk")
1930         (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1931                    (ANY_EXTEND:GPI
1932                     (match_operand:ALLX 2 "register_operand" "r"))))]
1933   ""
1934   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1935   [(set_attr "v8type" "alu_ext")
1936    (set_attr "type" "alu_ext")
1937    (set_attr "mode" "<GPI:MODE>")]
1940 ;; zero_extend version of above
1941 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
1942   [(set (match_operand:DI 0 "register_operand" "=rk")
1943         (zero_extend:DI
1944          (minus:SI (match_operand:SI 1 "register_operand" "r")
1945                    (ANY_EXTEND:SI
1946                     (match_operand:SHORT 2 "register_operand" "r")))))]
1947   ""
1948   "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
1949   [(set_attr "v8type" "alu_ext")
1950    (set_attr "type" "alu_ext")
1951    (set_attr "mode" "SI")]
1954 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
1955   [(set (match_operand:GPI 0 "register_operand" "=rk")
1956         (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1957                    (ashift:GPI (ANY_EXTEND:GPI
1958                                 (match_operand:ALLX 2 "register_operand" "r"))
1959                                (match_operand 3 "aarch64_imm3" "Ui3"))))]
1960   ""
1961   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1962   [(set_attr "v8type" "alu_ext")
1963    (set_attr "type" "alu_ext")
1964    (set_attr "mode" "<GPI:MODE>")]
1967 ;; zero_extend version of above
1968 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
1969   [(set (match_operand:DI 0 "register_operand" "=rk")
1970         (zero_extend:DI
1971          (minus:SI (match_operand:SI 1 "register_operand" "r")
1972                    (ashift:SI (ANY_EXTEND:SI
1973                                (match_operand:SHORT 2 "register_operand" "r"))
1974                               (match_operand 3 "aarch64_imm3" "Ui3")))))]
1975   ""
1976   "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
1977   [(set_attr "v8type" "alu_ext")
1978    (set_attr "type" "alu_ext")
1979    (set_attr "mode" "SI")]
1982 (define_insn "*sub_<optab><mode>_multp2"
1983   [(set (match_operand:GPI 0 "register_operand" "=rk")
1984         (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1985                    (ANY_EXTRACT:GPI
1986                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1987                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1988                     (match_operand 3 "const_int_operand" "n")
1989                     (const_int 0))))]
1990   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1991   "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1992   [(set_attr "v8type" "alu_ext")
1993    (set_attr "type" "alu_ext")
1994    (set_attr "mode" "<MODE>")]
1997 ;; zero_extend version of above
1998 (define_insn "*sub_<optab>si_multp2_uxtw"
1999   [(set (match_operand:DI 0 "register_operand" "=rk")
2000         (zero_extend:DI
2001          (minus:SI (match_operand:SI 4 "register_operand" "r")
2002                    (ANY_EXTRACT:SI
2003                     (mult:SI (match_operand:SI 1 "register_operand" "r")
2004                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2005                     (match_operand 3 "const_int_operand" "n")
2006                     (const_int 0)))))]
2007   "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
2008   "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
2009   [(set_attr "v8type" "alu_ext")
2010    (set_attr "type" "alu_ext")
2011    (set_attr "mode" "SI")]
2014 (define_insn "*sub<mode>3_carryin"
2015   [(set
2016     (match_operand:GPI 0 "register_operand" "=r")
2017     (minus:GPI (minus:GPI
2018                 (match_operand:GPI 1 "register_operand" "r")
2019                 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2020                (match_operand:GPI 2 "register_operand" "r")))]
2021    ""
2022    "sbc\\t%<w>0, %<w>1, %<w>2"
2023   [(set_attr "v8type" "adc")
2024    (set_attr "type" "adc_reg")
2025    (set_attr "mode" "<MODE>")]
2028 ;; zero_extend version of the above
2029 (define_insn "*subsi3_carryin_uxtw"
2030   [(set
2031     (match_operand:DI 0 "register_operand" "=r")
2032     (zero_extend:DI
2033      (minus:SI (minus:SI
2034                 (match_operand:SI 1 "register_operand" "r")
2035                 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2036                (match_operand:SI 2 "register_operand" "r"))))]
2037    ""
2038    "sbc\\t%w0, %w1, %w2"
2039   [(set_attr "v8type" "adc")
2040    (set_attr "type" "adc_reg")
2041    (set_attr "mode" "SI")]
2044 (define_insn "*sub_uxt<mode>_multp2"
2045   [(set (match_operand:GPI 0 "register_operand" "=rk")
2046         (minus:GPI (match_operand:GPI 4 "register_operand" "r")
2047                    (and:GPI
2048                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2049                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2050                     (match_operand 3 "const_int_operand" "n"))))]
2051   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2052   "*
2053   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2054                                            INTVAL (operands[3])));
2055   return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
2056   [(set_attr "v8type" "alu_ext")
2057    (set_attr "type" "alu_ext")
2058    (set_attr "mode" "<MODE>")]
2061 ;; zero_extend version of above
2062 (define_insn "*sub_uxtsi_multp2_uxtw"
2063   [(set (match_operand:DI 0 "register_operand" "=rk")
2064         (zero_extend:DI
2065          (minus:SI (match_operand:SI 4 "register_operand" "r")
2066                    (and:SI
2067                     (mult:SI (match_operand:SI 1 "register_operand" "r")
2068                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2069                     (match_operand 3 "const_int_operand" "n")))))]
2070   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2071   "*
2072   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2073                                            INTVAL (operands[3])));
2074   return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
2075   [(set_attr "v8type" "alu_ext")
2076    (set_attr "type" "alu_ext")
2077    (set_attr "mode" "SI")]
2080 (define_insn_and_split "absdi2"
2081   [(set (match_operand:DI 0 "register_operand" "=r,w")
2082         (abs:DI (match_operand:DI 1 "register_operand" "r,w")))
2083    (clobber (match_scratch:DI 2 "=&r,X"))]
2084   ""
2085   "@
2086    #
2087    abs\\t%d0, %d1"
2088   "reload_completed
2089    && GP_REGNUM_P (REGNO (operands[0]))
2090    && GP_REGNUM_P (REGNO (operands[1]))"
2091   [(const_int 0)]
2092   {
2093     emit_insn (gen_rtx_SET (VOIDmode, operands[2],
2094                             gen_rtx_XOR (DImode,
2095                                          gen_rtx_ASHIFTRT (DImode,
2096                                                            operands[1],
2097                                                            GEN_INT (63)),
2098                                          operands[1])));
2099     emit_insn (gen_rtx_SET (VOIDmode,
2100                             operands[0],
2101                             gen_rtx_MINUS (DImode,
2102                                            operands[2],
2103                                            gen_rtx_ASHIFTRT (DImode,
2104                                                              operands[1],
2105                                                              GEN_INT (63)))));
2106     DONE;
2107   }
2108   [(set_attr "v8type" "alu")
2109    (set_attr "type" "alu_reg")
2110    (set_attr "mode" "DI")]
2113 (define_insn "neg<mode>2"
2114   [(set (match_operand:GPI 0 "register_operand" "=r,w")
2115         (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
2116   ""
2117   "@
2118    neg\\t%<w>0, %<w>1
2119    neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
2120   [(set_attr "v8type" "alu")
2121    (set_attr "type" "alu_reg, neon_neg<q>")
2122    (set_attr "simd" "*,yes")
2123    (set_attr "mode" "<MODE>")]
2126 ;; zero_extend version of above
2127 (define_insn "*negsi2_uxtw"
2128   [(set (match_operand:DI 0 "register_operand" "=r")
2129         (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
2130   ""
2131   "neg\\t%w0, %w1"
2132   [(set_attr "v8type" "alu")
2133    (set_attr "type" "alu_reg")
2134    (set_attr "mode" "SI")]
2137 (define_insn "*ngc<mode>"
2138   [(set (match_operand:GPI 0 "register_operand" "=r")
2139         (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2140                    (match_operand:GPI 1 "register_operand" "r")))]
2141   ""
2142   "ngc\\t%<w>0, %<w>1"
2143   [(set_attr "v8type" "adc")
2144    (set_attr "type" "adc_reg")
2145    (set_attr "mode" "<MODE>")]
2148 (define_insn "*ngcsi_uxtw"
2149   [(set (match_operand:DI 0 "register_operand" "=r")
2150         (zero_extend:DI
2151          (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2152                    (match_operand:SI 1 "register_operand" "r"))))]
2153   ""
2154   "ngc\\t%w0, %w1"
2155   [(set_attr "v8type" "adc")
2156    (set_attr "type" "adc_reg")
2157    (set_attr "mode" "SI")]
2160 (define_insn "*neg<mode>2_compare0"
2161   [(set (reg:CC_NZ CC_REGNUM)
2162         (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2163                        (const_int 0)))
2164    (set (match_operand:GPI 0 "register_operand" "=r")
2165         (neg:GPI (match_dup 1)))]
2166   ""
2167   "negs\\t%<w>0, %<w>1"
2168   [(set_attr "v8type" "alus")
2169    (set_attr "type" "alus_reg")
2170    (set_attr "mode" "<MODE>")]
2173 ;; zero_extend version of above
2174 (define_insn "*negsi2_compare0_uxtw"
2175   [(set (reg:CC_NZ CC_REGNUM)
2176         (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
2177                        (const_int 0)))
2178    (set (match_operand:DI 0 "register_operand" "=r")
2179         (zero_extend:DI (neg:SI (match_dup 1))))]
2180   ""
2181   "negs\\t%w0, %w1"
2182   [(set_attr "v8type" "alus")
2183    (set_attr "type" "alus_reg")
2184    (set_attr "mode" "SI")]
2187 (define_insn "*neg_<shift><mode>3_compare0"
2188   [(set (reg:CC_NZ CC_REGNUM)
2189         (compare:CC_NZ
2190          (neg:GPI (ASHIFT:GPI
2191                    (match_operand:GPI 1 "register_operand" "r")
2192                    (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2193          (const_int 0)))
2194    (set (match_operand:GPI 0 "register_operand" "=r")
2195         (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2196   ""
2197   "negs\\t%<w>0, %<w>1, <shift> %2"
2198   [(set_attr "v8type" "alus_shift")
2199    (set_attr "type" "alus_shift_imm")
2200    (set_attr "mode" "<MODE>")]
2203 (define_insn "*neg_<shift>_<mode>2"
2204   [(set (match_operand:GPI 0 "register_operand" "=r")
2205         (neg:GPI (ASHIFT:GPI
2206                   (match_operand:GPI 1 "register_operand" "r")
2207                   (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2208   ""
2209   "neg\\t%<w>0, %<w>1, <shift> %2"
2210   [(set_attr "v8type" "alu_shift")
2211    (set_attr "type" "alu_shift_imm")
2212    (set_attr "mode" "<MODE>")]
2215 ;; zero_extend version of above
2216 (define_insn "*neg_<shift>_si2_uxtw"
2217   [(set (match_operand:DI 0 "register_operand" "=r")
2218         (zero_extend:DI
2219          (neg:SI (ASHIFT:SI
2220                   (match_operand:SI 1 "register_operand" "r")
2221                   (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2222   ""
2223   "neg\\t%w0, %w1, <shift> %2"
2224   [(set_attr "v8type" "alu_shift")
2225    (set_attr "type" "alu_shift_imm")
2226    (set_attr "mode" "SI")]
2229 (define_insn "*neg_mul_imm_<mode>2"
2230   [(set (match_operand:GPI 0 "register_operand" "=r")
2231         (neg:GPI (mult:GPI
2232                   (match_operand:GPI 1 "register_operand" "r")
2233                   (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2234   ""
2235   "neg\\t%<w>0, %<w>1, lsl %p2"
2236   [(set_attr "v8type" "alu_shift")
2237    (set_attr "type" "alu_shift_imm")
2238    (set_attr "mode" "<MODE>")]
2241 ;; zero_extend version of above
2242 (define_insn "*neg_mul_imm_si2_uxtw"
2243   [(set (match_operand:DI 0 "register_operand" "=r")
2244         (zero_extend:DI
2245          (neg:SI (mult:SI
2246                   (match_operand:SI 1 "register_operand" "r")
2247                   (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2248   ""
2249   "neg\\t%w0, %w1, lsl %p2"
2250   [(set_attr "v8type" "alu_shift")
2251    (set_attr "type" "alu_shift_imm")
2252    (set_attr "mode" "SI")]
2255 (define_insn "mul<mode>3"
2256   [(set (match_operand:GPI 0 "register_operand" "=r")
2257         (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2258                   (match_operand:GPI 2 "register_operand" "r")))]
2259   ""
2260   "mul\\t%<w>0, %<w>1, %<w>2"
2261   [(set_attr "v8type" "mult")
2262    (set_attr "type" "mul")
2263    (set_attr "mode" "<MODE>")]
2266 ;; zero_extend version of above
2267 (define_insn "*mulsi3_uxtw"
2268   [(set (match_operand:DI 0 "register_operand" "=r")
2269         (zero_extend:DI
2270          (mult:SI (match_operand:SI 1 "register_operand" "r")
2271                   (match_operand:SI 2 "register_operand" "r"))))]
2272   ""
2273   "mul\\t%w0, %w1, %w2"
2274   [(set_attr "v8type" "mult")
2275    (set_attr "type" "mul")
2276    (set_attr "mode" "SI")]
2279 (define_insn "*madd<mode>"
2280   [(set (match_operand:GPI 0 "register_operand" "=r")
2281         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2282                             (match_operand:GPI 2 "register_operand" "r"))
2283                   (match_operand:GPI 3 "register_operand" "r")))]
2284   ""
2285   "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2286   [(set_attr "v8type" "madd")
2287    (set_attr "type" "mla")
2288    (set_attr "mode" "<MODE>")]
2291 ;; zero_extend version of above
2292 (define_insn "*maddsi_uxtw"
2293   [(set (match_operand:DI 0 "register_operand" "=r")
2294         (zero_extend:DI
2295          (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2296                            (match_operand:SI 2 "register_operand" "r"))
2297                   (match_operand:SI 3 "register_operand" "r"))))]
2298   ""
2299   "madd\\t%w0, %w1, %w2, %w3"
2300   [(set_attr "v8type" "madd")
2301    (set_attr "type" "mla")
2302    (set_attr "mode" "SI")]
2305 (define_insn "*msub<mode>"
2306   [(set (match_operand:GPI 0 "register_operand" "=r")
2307         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2308                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2309                              (match_operand:GPI 2 "register_operand" "r"))))]
2311   ""
2312   "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2313   [(set_attr "v8type" "madd")
2314    (set_attr "type" "mla")
2315    (set_attr "mode" "<MODE>")]
2318 ;; zero_extend version of above
2319 (define_insn "*msubsi_uxtw"
2320   [(set (match_operand:DI 0 "register_operand" "=r")
2321         (zero_extend:DI
2322          (minus:SI (match_operand:SI 3 "register_operand" "r")
2323                    (mult:SI (match_operand:SI 1 "register_operand" "r")
2324                             (match_operand:SI 2 "register_operand" "r")))))]
2326   ""
2327   "msub\\t%w0, %w1, %w2, %w3"
2328   [(set_attr "v8type" "madd")
2329    (set_attr "type" "mla")
2330    (set_attr "mode" "SI")]
2333 (define_insn "*mul<mode>_neg"
2334   [(set (match_operand:GPI 0 "register_operand" "=r")
2335         (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2336                   (match_operand:GPI 2 "register_operand" "r")))]
2338   ""
2339   "mneg\\t%<w>0, %<w>1, %<w>2"
2340   [(set_attr "v8type" "mult")
2341    (set_attr "type" "mul")
2342    (set_attr "mode" "<MODE>")]
2345 ;; zero_extend version of above
2346 (define_insn "*mulsi_neg_uxtw"
2347   [(set (match_operand:DI 0 "register_operand" "=r")
2348         (zero_extend:DI
2349          (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2350                   (match_operand:SI 2 "register_operand" "r"))))]
2352   ""
2353   "mneg\\t%w0, %w1, %w2"
2354   [(set_attr "v8type" "mult")
2355    (set_attr "type" "mul")
2356    (set_attr "mode" "SI")]
2359 (define_insn "<su_optab>mulsidi3"
2360   [(set (match_operand:DI 0 "register_operand" "=r")
2361         (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2362                  (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2363   ""
2364   "<su>mull\\t%0, %w1, %w2"
2365   [(set_attr "v8type" "mull")
2366    (set_attr "type" "<su>mull")
2367    (set_attr "mode" "DI")]
2370 (define_insn "<su_optab>maddsidi4"
2371   [(set (match_operand:DI 0 "register_operand" "=r")
2372         (plus:DI (mult:DI
2373                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2374                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2375                  (match_operand:DI 3 "register_operand" "r")))]
2376   ""
2377   "<su>maddl\\t%0, %w1, %w2, %3"
2378   [(set_attr "v8type" "maddl")
2379    (set_attr "type" "<su>mlal")
2380    (set_attr "mode" "DI")]
2383 (define_insn "<su_optab>msubsidi4"
2384   [(set (match_operand:DI 0 "register_operand" "=r")
2385         (minus:DI
2386          (match_operand:DI 3 "register_operand" "r")
2387          (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2388                   (ANY_EXTEND:DI
2389                    (match_operand:SI 2 "register_operand" "r")))))]
2390   ""
2391   "<su>msubl\\t%0, %w1, %w2, %3"
2392   [(set_attr "v8type" "maddl")
2393    (set_attr "type" "<su>mlal")
2394    (set_attr "mode" "DI")]
2397 (define_insn "*<su_optab>mulsidi_neg"
2398   [(set (match_operand:DI 0 "register_operand" "=r")
2399         (mult:DI (neg:DI
2400                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2401                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2402   ""
2403   "<su>mnegl\\t%0, %w1, %w2"
2404   [(set_attr "v8type" "mull")
2405    (set_attr "type" "<su>mull")
2406    (set_attr "mode" "DI")]
2409 (define_insn "<su>muldi3_highpart"
2410   [(set (match_operand:DI 0 "register_operand" "=r")
2411         (truncate:DI
2412          (lshiftrt:TI
2413           (mult:TI
2414            (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2415            (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2416           (const_int 64))))]
2417   ""
2418   "<su>mulh\\t%0, %1, %2"
2419   [(set_attr "v8type" "mulh")
2420    (set_attr "type" "<su>mull")
2421    (set_attr "mode" "DI")]
2424 (define_insn "<su_optab>div<mode>3"
2425   [(set (match_operand:GPI 0 "register_operand" "=r")
2426         (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2427                      (match_operand:GPI 2 "register_operand" "r")))]
2428   ""
2429   "<su>div\\t%<w>0, %<w>1, %<w>2"
2430   [(set_attr "v8type" "<su>div")
2431    (set_attr "type" "<su>div")
2432    (set_attr "mode" "<MODE>")]
2435 ;; zero_extend version of above
2436 (define_insn "*<su_optab>divsi3_uxtw"
2437   [(set (match_operand:DI 0 "register_operand" "=r")
2438         (zero_extend:DI
2439          (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2440                      (match_operand:SI 2 "register_operand" "r"))))]
2441   ""
2442   "<su>div\\t%w0, %w1, %w2"
2443   [(set_attr "v8type" "<su>div")
2444    (set_attr "type" "<su>div")
2445    (set_attr "mode" "SI")]
2448 ;; -------------------------------------------------------------------
2449 ;; Comparison insns
2450 ;; -------------------------------------------------------------------
2452 (define_insn "*cmp<mode>"
2453   [(set (reg:CC CC_REGNUM)
2454         (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2455                     (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2456   ""
2457   "@
2458    cmp\\t%<w>0, %<w>1
2459    cmp\\t%<w>0, %<w>1
2460    cmn\\t%<w>0, #%n1"
2461   [(set_attr "v8type" "alus")
2462    (set_attr "type" "alus_reg,alus_imm,alus_imm")
2463    (set_attr "mode" "<MODE>")]
2466 (define_insn "*cmp<mode>"
2467   [(set (reg:CCFP CC_REGNUM)
2468         (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2469                       (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2470    "TARGET_FLOAT"
2471    "@
2472     fcmp\\t%<s>0, #0.0
2473     fcmp\\t%<s>0, %<s>1"
2474   [(set_attr "v8type" "fcmp")
2475    (set_attr "type" "fcmp<s>")
2476    (set_attr "mode" "<MODE>")]
2479 (define_insn "*cmpe<mode>"
2480   [(set (reg:CCFPE CC_REGNUM)
2481         (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2482                        (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2483    "TARGET_FLOAT"
2484    "@
2485     fcmpe\\t%<s>0, #0.0
2486     fcmpe\\t%<s>0, %<s>1"
2487   [(set_attr "v8type" "fcmp")
2488    (set_attr "type" "fcmp<s>")
2489    (set_attr "mode" "<MODE>")]
2492 (define_insn "*cmp_swp_<shift>_reg<mode>"
2493   [(set (reg:CC_SWP CC_REGNUM)
2494         (compare:CC_SWP (ASHIFT:GPI
2495                          (match_operand:GPI 0 "register_operand" "r")
2496                          (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2497                         (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2498   ""
2499   "cmp\\t%<w>2, %<w>0, <shift> %1"
2500   [(set_attr "v8type" "alus_shift")
2501    (set_attr "type" "alus_shift_imm")
2502    (set_attr "mode" "<MODE>")]
2505 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2506   [(set (reg:CC_SWP CC_REGNUM)
2507         (compare:CC_SWP (ANY_EXTEND:GPI
2508                          (match_operand:ALLX 0 "register_operand" "r"))
2509                         (match_operand:GPI 1 "register_operand" "r")))]
2510   ""
2511   "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2512   [(set_attr "v8type" "alus_ext")
2513    (set_attr "type" "alus_ext")
2514    (set_attr "mode" "<GPI:MODE>")]
2517 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2518   [(set (reg:CC_SWP CC_REGNUM)
2519         (compare:CC_SWP (ashift:GPI
2520                          (ANY_EXTEND:GPI
2521                           (match_operand:ALLX 0 "register_operand" "r"))
2522                          (match_operand 1 "aarch64_imm3" "Ui3"))
2523         (match_operand:GPI 2 "register_operand" "r")))]
2524   ""
2525   "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2526   [(set_attr "v8type" "alus_ext")
2527    (set_attr "type" "alus_ext")
2528    (set_attr "mode" "<GPI:MODE>")]
2531 ;; -------------------------------------------------------------------
2532 ;; Store-flag and conditional select insns
2533 ;; -------------------------------------------------------------------
2535 (define_expand "cstore<mode>4"
2536   [(set (match_operand:SI 0 "register_operand" "")
2537         (match_operator:SI 1 "aarch64_comparison_operator"
2538          [(match_operand:GPI 2 "register_operand" "")
2539           (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2540   ""
2541   "
2542   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2543                                       operands[3]);
2544   operands[3] = const0_rtx;
2545   "
2548 (define_expand "cstore<mode>4"
2549   [(set (match_operand:SI 0 "register_operand" "")
2550         (match_operator:SI 1 "aarch64_comparison_operator"
2551          [(match_operand:GPF 2 "register_operand" "")
2552           (match_operand:GPF 3 "register_operand" "")]))]
2553   ""
2554   "
2555   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2556                                       operands[3]);
2557   operands[3] = const0_rtx;
2558   "
2561 (define_insn "*cstore<mode>_insn"
2562   [(set (match_operand:ALLI 0 "register_operand" "=r")
2563         (match_operator:ALLI 1 "aarch64_comparison_operator"
2564          [(match_operand 2 "cc_register" "") (const_int 0)]))]
2565   ""
2566   "cset\\t%<w>0, %m1"
2567   [(set_attr "v8type" "csel")
2568    (set_attr "type" "csel")
2569    (set_attr "mode" "<MODE>")]
2572 ;; zero_extend version of the above
2573 (define_insn "*cstoresi_insn_uxtw"
2574   [(set (match_operand:DI 0 "register_operand" "=r")
2575         (zero_extend:DI
2576          (match_operator:SI 1 "aarch64_comparison_operator"
2577           [(match_operand 2 "cc_register" "") (const_int 0)])))]
2578   ""
2579   "cset\\t%w0, %m1"
2580   [(set_attr "v8type" "csel")
2581    (set_attr "type" "csel")
2582    (set_attr "mode" "SI")]
2585 (define_insn "cstore<mode>_neg"
2586   [(set (match_operand:ALLI 0 "register_operand" "=r")
2587         (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2588                   [(match_operand 2 "cc_register" "") (const_int 0)])))]
2589   ""
2590   "csetm\\t%<w>0, %m1"
2591   [(set_attr "v8type" "csel")
2592    (set_attr "type" "csel")
2593    (set_attr "mode" "<MODE>")]
2596 ;; zero_extend version of the above
2597 (define_insn "*cstoresi_neg_uxtw"
2598   [(set (match_operand:DI 0 "register_operand" "=r")
2599         (zero_extend:DI
2600          (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2601                   [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2602   ""
2603   "csetm\\t%w0, %m1"
2604   [(set_attr "v8type" "csel")
2605    (set_attr "type" "csel")
2606    (set_attr "mode" "SI")]
2609 (define_expand "cmov<mode>6"
2610   [(set (match_operand:GPI 0 "register_operand" "")
2611         (if_then_else:GPI
2612          (match_operator 1 "aarch64_comparison_operator"
2613           [(match_operand:GPI 2 "register_operand" "")
2614            (match_operand:GPI 3 "aarch64_plus_operand" "")])
2615          (match_operand:GPI 4 "register_operand" "")
2616          (match_operand:GPI 5 "register_operand" "")))]
2617   ""
2618   "
2619   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2620                                       operands[3]);
2621   operands[3] = const0_rtx;
2622   "
2625 (define_expand "cmov<mode>6"
2626   [(set (match_operand:GPF 0 "register_operand" "")
2627         (if_then_else:GPF
2628          (match_operator 1 "aarch64_comparison_operator"
2629           [(match_operand:GPF 2 "register_operand" "")
2630            (match_operand:GPF 3 "register_operand" "")])
2631          (match_operand:GPF 4 "register_operand" "")
2632          (match_operand:GPF 5 "register_operand" "")))]
2633   ""
2634   "
2635   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2636                                       operands[3]);
2637   operands[3] = const0_rtx;
2638   "
2641 (define_insn "*cmov<mode>_insn"
2642   [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2643         (if_then_else:ALLI
2644          (match_operator 1 "aarch64_comparison_operator"
2645           [(match_operand 2 "cc_register" "") (const_int 0)])
2646          (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2647          (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2648   "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2649      || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2650   ;; Final two alternatives should be unreachable, but included for completeness
2651   "@
2652    csel\\t%<w>0, %<w>3, %<w>4, %m1
2653    csinv\\t%<w>0, %<w>3, <w>zr, %m1
2654    csinv\\t%<w>0, %<w>4, <w>zr, %M1
2655    csinc\\t%<w>0, %<w>3, <w>zr, %m1
2656    csinc\\t%<w>0, %<w>4, <w>zr, %M1
2657    mov\\t%<w>0, -1
2658    mov\\t%<w>0, 1"
2659   [(set_attr "v8type" "csel")
2660    (set_attr "type" "csel")
2661    (set_attr "mode" "<MODE>")]
2664 ;; zero_extend version of above
2665 (define_insn "*cmovsi_insn_uxtw"
2666   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2667         (zero_extend:DI
2668          (if_then_else:SI
2669           (match_operator 1 "aarch64_comparison_operator"
2670            [(match_operand 2 "cc_register" "") (const_int 0)])
2671           (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2672           (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2673   "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2674      || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2675   ;; Final two alternatives should be unreachable, but included for completeness
2676   "@
2677    csel\\t%w0, %w3, %w4, %m1
2678    csinv\\t%w0, %w3, wzr, %m1
2679    csinv\\t%w0, %w4, wzr, %M1
2680    csinc\\t%w0, %w3, wzr, %m1
2681    csinc\\t%w0, %w4, wzr, %M1
2682    mov\\t%w0, -1
2683    mov\\t%w0, 1"
2684   [(set_attr "v8type" "csel")
2685    (set_attr "type" "csel")
2686    (set_attr "mode" "SI")]
2689 (define_insn "*cmov<mode>_insn"
2690   [(set (match_operand:GPF 0 "register_operand" "=w")
2691         (if_then_else:GPF
2692          (match_operator 1 "aarch64_comparison_operator"
2693           [(match_operand 2 "cc_register" "") (const_int 0)])
2694          (match_operand:GPF 3 "register_operand" "w")
2695          (match_operand:GPF 4 "register_operand" "w")))]
2696   "TARGET_FLOAT"
2697   "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2698   [(set_attr "v8type" "fcsel")
2699    (set_attr "type" "fcsel")
2700    (set_attr "mode" "<MODE>")]
2703 (define_expand "mov<mode>cc"
2704   [(set (match_operand:ALLI 0 "register_operand" "")
2705         (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2706                            (match_operand:ALLI 2 "register_operand" "")
2707                            (match_operand:ALLI 3 "register_operand" "")))]
2708   ""
2709   {
2710     rtx ccreg;
2711     enum rtx_code code = GET_CODE (operands[1]);
2713     if (code == UNEQ || code == LTGT)
2714       FAIL;
2716     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2717                                   XEXP (operands[1], 1));
2718     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2719   }
2722 (define_expand "mov<GPF:mode><GPI:mode>cc"
2723   [(set (match_operand:GPI 0 "register_operand" "")
2724         (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2725                           (match_operand:GPF 2 "register_operand" "")
2726                           (match_operand:GPF 3 "register_operand" "")))]
2727   ""
2728   {
2729     rtx ccreg;
2730     enum rtx_code code = GET_CODE (operands[1]);
2732     if (code == UNEQ || code == LTGT)
2733       FAIL;
2735     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2736                                   XEXP (operands[1], 1));
2737     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2738   }
2741 (define_insn "*csinc2<mode>_insn"
2742   [(set (match_operand:GPI 0 "register_operand" "=r")
2743         (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator"
2744                   [(match_operand:CC 3 "cc_register" "") (const_int 0)])
2745                  (match_operand:GPI 1 "register_operand" "r")))]
2746   ""
2747   "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2748   [(set_attr "v8type" "csel")
2749    (set_attr "type" "csel")
2750    (set_attr "mode" "<MODE>")])
2752 (define_insn "csinc3<mode>_insn"
2753   [(set (match_operand:GPI 0 "register_operand" "=r")
2754         (if_then_else:GPI
2755           (match_operator:GPI 1 "aarch64_comparison_operator"
2756            [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2757           (plus:GPI (match_operand:GPI 3 "register_operand" "r")
2758                     (const_int 1))
2759           (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2760   ""
2761   "csinc\\t%<w>0, %<w>4, %<w>3, %M1"
2762   [(set_attr "v8type" "csel")
2763    (set_attr "type" "csel")
2764    (set_attr "mode" "<MODE>")]
2767 (define_insn "*csinv3<mode>_insn"
2768   [(set (match_operand:GPI 0 "register_operand" "=r")
2769         (if_then_else:GPI
2770           (match_operator:GPI 1 "aarch64_comparison_operator"
2771            [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2772           (not:GPI (match_operand:GPI 3 "register_operand" "r"))
2773           (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2774   ""
2775   "csinv\\t%<w>0, %<w>4, %<w>3, %M1"
2776   [(set_attr "v8type" "csel")
2777    (set_attr "type" "csel")
2778    (set_attr "mode" "<MODE>")])
2780 (define_insn "*csneg3<mode>_insn"
2781   [(set (match_operand:GPI 0 "register_operand" "=r")
2782         (if_then_else:GPI
2783           (match_operator:GPI 1 "aarch64_comparison_operator"
2784            [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2785           (neg:GPI (match_operand:GPI 3 "register_operand" "r"))
2786           (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2787   ""
2788   "csneg\\t%<w>0, %<w>4, %<w>3, %M1"
2789   [(set_attr "v8type" "csel")
2790    (set_attr "type" "csel")
2791    (set_attr "mode" "<MODE>")])
2793 ;; -------------------------------------------------------------------
2794 ;; Logical operations
2795 ;; -------------------------------------------------------------------
2797 (define_insn "<optab><mode>3"
2798   [(set (match_operand:GPI 0 "register_operand" "=r,rk")
2799         (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2800                      (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
2801   ""
2802   "<logical>\\t%<w>0, %<w>1, %<w>2"
2803   [(set_attr "v8type" "logic,logic_imm")
2804    (set_attr "type" "logic_reg,logic_imm")
2805    (set_attr "mode" "<MODE>")])
2807 ;; zero_extend version of above
2808 (define_insn "*<optab>si3_uxtw"
2809   [(set (match_operand:DI 0 "register_operand" "=r,rk")
2810         (zero_extend:DI
2811          (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2812                      (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2813   ""
2814   "<logical>\\t%w0, %w1, %w2"
2815   [(set_attr "v8type" "logic,logic_imm")
2816    (set_attr "type" "logic_reg,logic_imm")
2817    (set_attr "mode" "SI")])
2819 (define_insn "*and<mode>3_compare0"
2820   [(set (reg:CC_NZ CC_REGNUM)
2821         (compare:CC_NZ
2822          (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2823                   (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2824          (const_int 0)))
2825    (set (match_operand:GPI 0 "register_operand" "=r,r")
2826         (and:GPI (match_dup 1) (match_dup 2)))]
2827   ""
2828   "ands\\t%<w>0, %<w>1, %<w>2"
2829   [(set_attr "v8type" "logics,logics_imm")
2830    (set_attr "type" "logics_reg,logics_imm")
2831    (set_attr "mode" "<MODE>")]
2834 ;; zero_extend version of above
2835 (define_insn "*andsi3_compare0_uxtw"
2836   [(set (reg:CC_NZ CC_REGNUM)
2837         (compare:CC_NZ
2838          (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2839                  (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2840          (const_int 0)))
2841    (set (match_operand:DI 0 "register_operand" "=r,r")
2842         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2843   ""
2844   "ands\\t%w0, %w1, %w2"
2845   [(set_attr "v8type" "logics,logics_imm")
2846    (set_attr "type" "logics_reg,logics_imm")
2847    (set_attr "mode" "SI")]
2850 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2851   [(set (reg:CC_NZ CC_REGNUM)
2852         (compare:CC_NZ
2853          (and:GPI (SHIFT:GPI
2854                    (match_operand:GPI 1 "register_operand" "r")
2855                    (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2856                   (match_operand:GPI 3 "register_operand" "r"))
2857          (const_int 0)))
2858    (set (match_operand:GPI 0 "register_operand" "=r")
2859         (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2860   ""
2861   "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2862   [(set_attr "v8type" "logics_shift")
2863    (set_attr "type" "logics_shift_imm")
2864    (set_attr "mode" "<MODE>")]
2867 ;; zero_extend version of above
2868 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2869   [(set (reg:CC_NZ CC_REGNUM)
2870         (compare:CC_NZ
2871          (and:SI (SHIFT:SI
2872                   (match_operand:SI 1 "register_operand" "r")
2873                   (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2874                  (match_operand:SI 3 "register_operand" "r"))
2875          (const_int 0)))
2876    (set (match_operand:DI 0 "register_operand" "=r")
2877         (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2878                                 (match_dup 3))))]
2879   ""
2880   "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2881   [(set_attr "v8type" "logics_shift")
2882    (set_attr "type" "logics_shift_imm")
2883    (set_attr "mode" "SI")]
2886 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2887   [(set (match_operand:GPI 0 "register_operand" "=r")
2888         (LOGICAL:GPI (SHIFT:GPI
2889                       (match_operand:GPI 1 "register_operand" "r")
2890                       (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2891                      (match_operand:GPI 3 "register_operand" "r")))]
2892   ""
2893   "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2894   [(set_attr "v8type" "logic_shift")
2895    (set_attr "type" "logic_shift_imm")
2896    (set_attr "mode" "<MODE>")])
2898 ;; zero_extend version of above
2899 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
2900   [(set (match_operand:DI 0 "register_operand" "=r")
2901         (zero_extend:DI
2902          (LOGICAL:SI (SHIFT:SI
2903                       (match_operand:SI 1 "register_operand" "r")
2904                       (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2905                      (match_operand:SI 3 "register_operand" "r"))))]
2906   ""
2907   "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2908   [(set_attr "v8type" "logic_shift")
2909    (set_attr "type" "logic_shift_imm")
2910    (set_attr "mode" "SI")])
2912 (define_insn "one_cmpl<mode>2"
2913   [(set (match_operand:GPI 0 "register_operand" "=r")
2914         (not:GPI (match_operand:GPI 1 "register_operand" "r")))]
2915   ""
2916   "mvn\\t%<w>0, %<w>1"
2917   [(set_attr "v8type" "logic")
2918    (set_attr "type" "logic_reg")
2919    (set_attr "mode" "<MODE>")])
2921 (define_insn "*one_cmpl_<optab><mode>2"
2922   [(set (match_operand:GPI 0 "register_operand" "=r")
2923         (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
2924                             (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2925   ""
2926   "mvn\\t%<w>0, %<w>1, <shift> %2"
2927   [(set_attr "v8type" "logic_shift")
2928    (set_attr "type" "logic_shift_imm")
2929    (set_attr "mode" "<MODE>")])
2931 (define_insn "*<LOGICAL:optab>_one_cmpl<mode>3"
2932   [(set (match_operand:GPI 0 "register_operand" "=r")
2933         (LOGICAL:GPI (not:GPI
2934                       (match_operand:GPI 1 "register_operand" "r"))
2935                      (match_operand:GPI 2 "register_operand" "r")))]
2936   ""
2937   "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1"
2938   [(set_attr "v8type" "logic")
2939    (set_attr "type" "logic_reg")
2940    (set_attr "mode" "<MODE>")])
2942 (define_insn "*and_one_cmpl<mode>3_compare0"
2943   [(set (reg:CC_NZ CC_REGNUM)
2944         (compare:CC_NZ
2945          (and:GPI (not:GPI
2946                    (match_operand:GPI 1 "register_operand" "r"))
2947                   (match_operand:GPI 2 "register_operand" "r"))
2948          (const_int 0)))
2949    (set (match_operand:GPI 0 "register_operand" "=r")
2950         (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
2951   ""
2952   "bics\\t%<w>0, %<w>2, %<w>1"
2953   [(set_attr "v8type" "logics")
2954    (set_attr "type" "logics_reg")
2955    (set_attr "mode" "<MODE>")])
2957 ;; zero_extend version of above
2958 (define_insn "*and_one_cmplsi3_compare0_uxtw"
2959   [(set (reg:CC_NZ CC_REGNUM)
2960         (compare:CC_NZ
2961          (and:SI (not:SI
2962                   (match_operand:SI 1 "register_operand" "r"))
2963                  (match_operand:SI 2 "register_operand" "r"))
2964          (const_int 0)))
2965    (set (match_operand:DI 0 "register_operand" "=r")
2966         (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
2967   ""
2968   "bics\\t%w0, %w2, %w1"
2969   [(set_attr "v8type" "logics")
2970    (set_attr "type" "logics_reg")
2971    (set_attr "mode" "SI")])
2973 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
2974   [(set (match_operand:GPI 0 "register_operand" "=r")
2975         (LOGICAL:GPI (not:GPI
2976                       (SHIFT:GPI
2977                        (match_operand:GPI 1 "register_operand" "r")
2978                        (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2979                      (match_operand:GPI 3 "register_operand" "r")))]
2980   ""
2981   "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2982   [(set_attr "v8type" "logic_shift")
2983    (set_attr "type" "logics_shift_imm")
2984    (set_attr "mode" "<MODE>")])
2986 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
2987   [(set (reg:CC_NZ CC_REGNUM)
2988         (compare:CC_NZ
2989          (and:GPI (not:GPI
2990                    (SHIFT:GPI
2991                     (match_operand:GPI 1 "register_operand" "r")
2992                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2993                   (match_operand:GPI 3 "register_operand" "r"))
2994          (const_int 0)))
2995    (set (match_operand:GPI 0 "register_operand" "=r")
2996         (and:GPI (not:GPI
2997                   (SHIFT:GPI
2998                    (match_dup 1) (match_dup 2))) (match_dup 3)))]
2999   ""
3000   "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3001   [(set_attr "v8type" "logics_shift")
3002    (set_attr "type" "logics_shift_imm")
3003    (set_attr "mode" "<MODE>")])
3005 ;; zero_extend version of above
3006 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
3007   [(set (reg:CC_NZ CC_REGNUM)
3008         (compare:CC_NZ
3009          (and:SI (not:SI
3010                   (SHIFT:SI
3011                    (match_operand:SI 1 "register_operand" "r")
3012                    (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
3013                  (match_operand:SI 3 "register_operand" "r"))
3014          (const_int 0)))
3015    (set (match_operand:DI 0 "register_operand" "=r")
3016         (zero_extend:DI (and:SI
3017                          (not:SI
3018                           (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
3019   ""
3020   "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3021   [(set_attr "v8type" "logics_shift")
3022    (set_attr "type" "logics_shift_imm")
3023    (set_attr "mode" "SI")])
3025 (define_insn "clz<mode>2"
3026   [(set (match_operand:GPI 0 "register_operand" "=r")
3027         (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
3028   ""
3029   "clz\\t%<w>0, %<w>1"
3030   [(set_attr "v8type" "clz")
3031    (set_attr "type" "clz")
3032    (set_attr "mode" "<MODE>")])
3034 (define_expand "ffs<mode>2"
3035   [(match_operand:GPI 0 "register_operand")
3036    (match_operand:GPI 1 "register_operand")]
3037   ""
3038   {
3039     rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
3040     rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
3042     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3043     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3044     emit_insn (gen_csinc3<mode>_insn (operands[0], x, ccreg, operands[0], const0_rtx));
3045     DONE;
3046   }
3049 (define_insn "clrsb<mode>2"
3050   [(set (match_operand:GPI 0 "register_operand" "=r")
3051         (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_CLS))]
3052   ""
3053   "cls\\t%<w>0, %<w>1"
3054   [(set_attr "v8type" "clz")
3055    (set_attr "type" "clz")
3056    (set_attr "mode" "<MODE>")])
3058 (define_insn "rbit<mode>2"
3059   [(set (match_operand:GPI 0 "register_operand" "=r")
3060         (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
3061   ""
3062   "rbit\\t%<w>0, %<w>1"
3063   [(set_attr "v8type" "rbit")
3064    (set_attr "type" "rbit")
3065    (set_attr "mode" "<MODE>")])
3067 (define_expand "ctz<mode>2"
3068   [(match_operand:GPI 0 "register_operand")
3069    (match_operand:GPI 1 "register_operand")]
3070   ""
3071   {
3072     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3073     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3074     DONE;
3075   }
3078 (define_insn "*and<mode>3nr_compare0"
3079   [(set (reg:CC_NZ CC_REGNUM)
3080         (compare:CC_NZ
3081          (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
3082                   (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
3083          (const_int 0)))]
3084   ""
3085   "tst\\t%<w>0, %<w>1"
3086   [(set_attr "v8type" "logics")
3087    (set_attr "type" "logics_reg")
3088    (set_attr "mode" "<MODE>")])
3090 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
3091   [(set (reg:CC_NZ CC_REGNUM)
3092         (compare:CC_NZ
3093          (and:GPI (SHIFT:GPI
3094                    (match_operand:GPI 0 "register_operand" "r")
3095                    (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
3096                   (match_operand:GPI 2 "register_operand" "r"))
3097         (const_int 0)))]
3098   ""
3099   "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
3100   [(set_attr "v8type" "logics_shift")
3101    (set_attr "type" "logics_shift_imm")
3102    (set_attr "mode" "<MODE>")])
3104 ;; -------------------------------------------------------------------
3105 ;; Shifts
3106 ;; -------------------------------------------------------------------
3108 (define_expand "<optab><mode>3"
3109   [(set (match_operand:GPI 0 "register_operand")
3110         (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
3111                     (match_operand:QI 2 "nonmemory_operand")))]
3112   ""
3113   {
3114     if (CONST_INT_P (operands[2]))
3115       {
3116         operands[2] = GEN_INT (INTVAL (operands[2])
3117                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3119         if (operands[2] == const0_rtx)
3120           {
3121             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3122             DONE;
3123           }
3124       }
3125   }
3128 (define_expand "ashl<mode>3"
3129   [(set (match_operand:SHORT 0 "register_operand")
3130         (ashift:SHORT (match_operand:SHORT 1 "register_operand")
3131                       (match_operand:QI 2 "nonmemory_operand")))]
3132   ""
3133   {
3134     if (CONST_INT_P (operands[2]))
3135       {
3136         operands[2] = GEN_INT (INTVAL (operands[2])
3137                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3139         if (operands[2] == const0_rtx)
3140           {
3141             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3142             DONE;
3143           }
3144       }
3145   }
3148 (define_expand "rotr<mode>3"
3149   [(set (match_operand:GPI 0 "register_operand")
3150         (rotatert:GPI (match_operand:GPI 1 "register_operand")
3151                       (match_operand:QI 2 "nonmemory_operand")))]
3152   ""
3153   {
3154     if (CONST_INT_P (operands[2]))
3155       {
3156         operands[2] = GEN_INT (INTVAL (operands[2])
3157                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3159         if (operands[2] == const0_rtx)
3160           {
3161             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3162             DONE;
3163           }
3164       }
3165   }
3168 (define_expand "rotl<mode>3"
3169   [(set (match_operand:GPI 0 "register_operand")
3170         (rotatert:GPI (match_operand:GPI 1 "register_operand")
3171                       (match_operand:QI 2 "nonmemory_operand")))]
3172   ""
3173   {
3174     /* (SZ - cnt) % SZ == -cnt % SZ */
3175     if (CONST_INT_P (operands[2]))
3176       {
3177         operands[2] = GEN_INT ((-INTVAL (operands[2]))
3178                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3179         if (operands[2] == const0_rtx)
3180           {
3181             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3182             DONE;
3183           }
3184       }
3185     else
3186       operands[2] = expand_simple_unop (QImode, NEG, operands[2],
3187                                         NULL_RTX, 1);
3188   }
3191 ;; Logical left shift using SISD or Integer instruction
3192 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
3193   [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3194         (ashift:GPI
3195           (match_operand:GPI 1 "register_operand" "w,w,r")
3196           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3197   ""
3198   "@
3199    shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3200    ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
3201    lsl\t%<w>0, %<w>1, %<w>2"
3202   [(set_attr "simd" "yes,yes,no")
3203    (set_attr "v8type" "*,*,shift")
3204    (set_attr "type" "neon_shift_imm<q>, neon_shift_reg<q>,shift_reg")
3205    (set_attr "mode" "*,*,<MODE>")]
3208 ;; Logical right shift using SISD or Integer instruction
3209 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3210   [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3211         (lshiftrt:GPI
3212           (match_operand:GPI 1 "register_operand" "w,w,r")
3213           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3214   ""
3215   "@
3216    ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3217    #
3218    lsr\t%<w>0, %<w>1, %<w>2"
3219   [(set_attr "simd" "yes,yes,no")
3220    (set_attr "v8type" "*,*,shift")
3221    (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")
3222    (set_attr "mode" "*,*,<MODE>")]
3225 (define_split
3226   [(set (match_operand:DI 0 "aarch64_simd_register")
3227         (lshiftrt:DI
3228            (match_operand:DI 1 "aarch64_simd_register")
3229            (match_operand:QI 2 "aarch64_simd_register")))]
3230   "TARGET_SIMD && reload_completed"
3231   [(set (match_dup 2)
3232         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3233    (set (match_dup 0)
3234         (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_USHL))]
3235   ""
3238 (define_split
3239   [(set (match_operand:SI 0 "aarch64_simd_register")
3240         (lshiftrt:SI
3241            (match_operand:SI 1 "aarch64_simd_register")
3242            (match_operand:QI 2 "aarch64_simd_register")))]
3243   "TARGET_SIMD && reload_completed"
3244   [(set (match_dup 2)
3245         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3246    (set (match_dup 0)
3247         (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_USHL_2S))]
3248   ""
3251 ;; Arithmetic right shift using SISD or Integer instruction
3252 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3253   [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3254         (ashiftrt:GPI
3255           (match_operand:GPI 1 "register_operand" "w,w,r")
3256           (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,rUs<cmode>")))]
3257   ""
3258   "@
3259    sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3260    #
3261    asr\t%<w>0, %<w>1, %<w>2"
3262   [(set_attr "simd" "yes,yes,no")
3263    (set_attr "v8type" "*,*,shift")
3264    (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")
3265    (set_attr "mode" "*,*,<MODE>")]
3268 (define_split
3269   [(set (match_operand:DI 0 "aarch64_simd_register")
3270         (ashiftrt:DI
3271            (match_operand:DI 1 "aarch64_simd_register")
3272            (match_operand:QI 2 "aarch64_simd_register")))]
3273   "TARGET_SIMD && reload_completed"
3274   [(set (match_dup 2)
3275         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3276    (set (match_dup 0)
3277         (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_SSHL))]
3278   ""
3281 (define_split
3282   [(set (match_operand:SI 0 "aarch64_simd_register")
3283         (ashiftrt:SI
3284            (match_operand:SI 1 "aarch64_simd_register")
3285            (match_operand:QI 2 "aarch64_simd_register")))]
3286   "TARGET_SIMD && reload_completed"
3287   [(set (match_dup 2)
3288         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3289    (set (match_dup 0)
3290         (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_SSHL_2S))]
3291   ""
3294 (define_insn "*aarch64_sisd_ushl"
3295   [(set (match_operand:DI 0 "register_operand" "=w")
3296         (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3297                     (match_operand:QI 2 "register_operand" "w")]
3298                    UNSPEC_SISD_USHL))]
3299   "TARGET_SIMD"
3300   "ushl\t%d0, %d1, %d2"
3301   [(set_attr "simd" "yes")
3302    (set_attr "type" "neon_shift_reg")]
3305 (define_insn "*aarch64_ushl_2s"
3306   [(set (match_operand:SI 0 "register_operand" "=w")
3307         (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3308                     (match_operand:QI 2 "register_operand" "w")]
3309                    UNSPEC_USHL_2S))]
3310   "TARGET_SIMD"
3311   "ushl\t%0.2s, %1.2s, %2.2s"
3312   [(set_attr "simd" "yes")
3313    (set_attr "type" "neon_shift_reg")]
3316 (define_insn "*aarch64_sisd_sshl"
3317   [(set (match_operand:DI 0 "register_operand" "=w")
3318         (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3319                     (match_operand:QI 2 "register_operand" "w")]
3320                    UNSPEC_SISD_SSHL))]
3321   "TARGET_SIMD"
3322   "sshl\t%d0, %d1, %d2"
3323   [(set_attr "simd" "yes")
3324    (set_attr "type" "neon_shift_reg")]
3327 (define_insn "*aarch64_sshl_2s"
3328   [(set (match_operand:SI 0 "register_operand" "=w")
3329         (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3330                     (match_operand:QI 2 "register_operand" "w")]
3331                    UNSPEC_SSHL_2S))]
3332   "TARGET_SIMD"
3333   "sshl\t%0.2s, %1.2s, %2.2s"
3334   [(set_attr "simd" "yes")
3335    (set_attr "type" "neon_shift_reg")]
3338 (define_insn "*aarch64_sisd_neg_qi"
3339   [(set (match_operand:QI 0 "register_operand" "=w")
3340         (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3341                    UNSPEC_SISD_NEG))]
3342   "TARGET_SIMD"
3343   "neg\t%d0, %d1"
3344   [(set_attr "simd" "yes")
3345    (set_attr "type" "neon_neg")]
3348 ;; Rotate right
3349 (define_insn "*ror<mode>3_insn"
3350   [(set (match_operand:GPI 0 "register_operand" "=r")
3351         (rotatert:GPI
3352           (match_operand:GPI 1 "register_operand" "r")
3353           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3354   ""
3355   "ror\\t%<w>0, %<w>1, %<w>2"
3356   [(set_attr "v8type" "shift")
3357    (set_attr "type" "shift_reg")
3358    (set_attr "mode" "<MODE>")]
3361 ;; zero_extend version of above
3362 (define_insn "*<optab>si3_insn_uxtw"
3363   [(set (match_operand:DI 0 "register_operand" "=r")
3364         (zero_extend:DI (SHIFT:SI
3365          (match_operand:SI 1 "register_operand" "r")
3366          (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3367   ""
3368   "<shift>\\t%w0, %w1, %w2"
3369   [(set_attr "v8type" "shift")
3370    (set_attr "type" "shift_reg")
3371    (set_attr "mode" "SI")]
3374 (define_insn "*ashl<mode>3_insn"
3375   [(set (match_operand:SHORT 0 "register_operand" "=r")
3376         (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3377                       (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
3378   ""
3379   "lsl\\t%<w>0, %<w>1, %<w>2"
3380   [(set_attr "v8type" "shift")
3381    (set_attr "type" "shift_reg")
3382    (set_attr "mode" "<MODE>")]
3385 (define_insn "*<optab><mode>3_insn"
3386   [(set (match_operand:SHORT 0 "register_operand" "=r")
3387         (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3388                       (match_operand 2 "const_int_operand" "n")))]
3389   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3391   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3392   return "<bfshift>\t%w0, %w1, %2, %3";
3394   [(set_attr "v8type" "bfm")
3395    (set_attr "type" "bfm")
3396    (set_attr "mode" "<MODE>")]
3399 (define_insn "*extr<mode>5_insn"
3400   [(set (match_operand:GPI 0 "register_operand" "=r")
3401         (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3402                              (match_operand 3 "const_int_operand" "n"))
3403                  (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3404                                (match_operand 4 "const_int_operand" "n"))))]
3405   "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3406    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3407   "extr\\t%<w>0, %<w>1, %<w>2, %4"
3408   [(set_attr "v8type" "shift")
3409    (set_attr "type" "shift_imm")
3410    (set_attr "mode" "<MODE>")]
3413 ;; zero_extend version of the above
3414 (define_insn "*extrsi5_insn_uxtw"
3415   [(set (match_operand:DI 0 "register_operand" "=r")
3416         (zero_extend:DI
3417          (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3418                             (match_operand 3 "const_int_operand" "n"))
3419                  (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3420                               (match_operand 4 "const_int_operand" "n")))))]
3421   "UINTVAL (operands[3]) < 32 &&
3422    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3423   "extr\\t%w0, %w1, %w2, %4"
3424   [(set_attr "v8type" "shift")
3425    (set_attr "type" "shift_imm")
3426    (set_attr "mode" "SI")]
3429 (define_insn "*ror<mode>3_insn"
3430   [(set (match_operand:GPI 0 "register_operand" "=r")
3431         (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3432                     (match_operand 2 "const_int_operand" "n")))]
3433   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3435   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3436   return "ror\\t%<w>0, %<w>1, %3";
3438   [(set_attr "v8type" "shift")
3439    (set_attr "type" "shift_imm")
3440    (set_attr "mode" "<MODE>")]
3443 ;; zero_extend version of the above
3444 (define_insn "*rorsi3_insn_uxtw"
3445   [(set (match_operand:DI 0 "register_operand" "=r")
3446         (zero_extend:DI
3447          (rotate:SI (match_operand:SI 1 "register_operand" "r")
3448                     (match_operand 2 "const_int_operand" "n"))))]
3449   "UINTVAL (operands[2]) < 32"
3451   operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3452   return "ror\\t%w0, %w1, %3";
3454   [(set_attr "v8type" "shift")
3455    (set_attr "type" "shift_imm")
3456    (set_attr "mode" "SI")]
3459 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3460   [(set (match_operand:GPI 0 "register_operand" "=r")
3461         (ANY_EXTEND:GPI
3462          (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3463                        (match_operand 2 "const_int_operand" "n"))))]
3464   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3466   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3467   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3469   [(set_attr "v8type" "bfm")
3470    (set_attr "type" "bfm")
3471    (set_attr "mode" "<GPI:MODE>")]
3474 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3475   [(set (match_operand:GPI 0 "register_operand" "=r")
3476         (zero_extend:GPI
3477          (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3478                          (match_operand 2 "const_int_operand" "n"))))]
3479   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3481   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3482   return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3484   [(set_attr "v8type" "bfm")
3485    (set_attr "type" "bfm")
3486    (set_attr "mode" "<GPI:MODE>")]
3489 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3490   [(set (match_operand:GPI 0 "register_operand" "=r")
3491         (sign_extend:GPI
3492          (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3493                          (match_operand 2 "const_int_operand" "n"))))]
3494   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3496   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3497   return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3499   [(set_attr "v8type" "bfm")
3500    (set_attr "type" "bfm")
3501    (set_attr "mode" "<GPI:MODE>")]
3504 ;; -------------------------------------------------------------------
3505 ;; Bitfields
3506 ;; -------------------------------------------------------------------
3508 (define_expand "<optab>"
3509   [(set (match_operand:DI 0 "register_operand" "=r")
3510         (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3511                         (match_operand 2 "const_int_operand" "n")
3512                         (match_operand 3 "const_int_operand" "n")))]
3513   ""
3514   ""
3517 (define_insn "*<optab><mode>"
3518   [(set (match_operand:GPI 0 "register_operand" "=r")
3519         (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3520                          (match_operand 2 "const_int_operand" "n")
3521                          (match_operand 3 "const_int_operand" "n")))]
3522   ""
3523   "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3524   [(set_attr "v8type" "bfm")
3525    (set_attr "type" "bfm")
3526    (set_attr "mode" "<MODE>")]
3529 ;; Bitfield Insert (insv)
3530 (define_expand "insv<mode>"
3531   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3532                           (match_operand 1 "const_int_operand")
3533                           (match_operand 2 "const_int_operand"))
3534         (match_operand:GPI 3 "general_operand"))]
3535   ""
3537   unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3538   unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3539   rtx value = operands[3];
3541   if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3542     FAIL;
3544   if (CONST_INT_P (value))
3545     {
3546       unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3548       /* Prefer AND/OR for inserting all zeros or all ones.  */
3549       if ((UINTVAL (value) & mask) == 0
3550            || (UINTVAL (value) & mask) == mask)
3551         FAIL;
3553       /* 16-bit aligned 16-bit wide insert is handled by insv_imm.  */
3554       if (width == 16 && (pos % 16) == 0)
3555         DONE;
3556     }
3557   operands[3] = force_reg (<MODE>mode, value);
3560 (define_insn "*insv_reg<mode>"
3561   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3562                           (match_operand 1 "const_int_operand" "n")
3563                           (match_operand 2 "const_int_operand" "n"))
3564         (match_operand:GPI 3 "register_operand" "r"))]
3565   "!(UINTVAL (operands[1]) == 0
3566      || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3567          > GET_MODE_BITSIZE (<MODE>mode)))"
3568   "bfi\\t%<w>0, %<w>3, %2, %1"
3569   [(set_attr "v8type" "bfm")
3570    (set_attr "type" "bfm")
3571    (set_attr "mode" "<MODE>")]
3574 (define_insn "*extr_insv_lower_reg<mode>"
3575   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3576                           (match_operand 1 "const_int_operand" "n")
3577                           (const_int 0))
3578         (zero_extract:GPI (match_operand:GPI 2 "register_operand" "+r")
3579                           (match_dup 1)
3580                           (match_operand 3 "const_int_operand" "n")))]
3581   "!(UINTVAL (operands[1]) == 0
3582      || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3583          > GET_MODE_BITSIZE (<MODE>mode)))"
3584   "bfxil\\t%<w>0, %<w>2, %3, %1"
3585   [(set_attr "v8type" "bfm")
3586    (set_attr "type" "bfm")
3587    (set_attr "mode" "<MODE>")]
3590 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3591   [(set (match_operand:GPI 0 "register_operand" "=r")
3592         (ashift:GPI (ANY_EXTEND:GPI
3593                      (match_operand:ALLX 1 "register_operand" "r"))
3594                     (match_operand 2 "const_int_operand" "n")))]
3595   "UINTVAL (operands[2]) < <GPI:sizen>"
3597   operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3598               ? GEN_INT (<ALLX:sizen>)
3599               : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3600   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3602   [(set_attr "v8type" "bfm")
3603    (set_attr "type" "bfm")
3604    (set_attr "mode" "<GPI:MODE>")]
3607 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3609 (define_insn "*andim_ashift<mode>_bfiz"
3610   [(set (match_operand:GPI 0 "register_operand" "=r")
3611         (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3612                              (match_operand 2 "const_int_operand" "n"))
3613                  (match_operand 3 "const_int_operand" "n")))]
3614   "exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3615    && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3616   "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3617   [(set_attr "v8type" "bfm")
3618    (set_attr "type" "bfm")
3619    (set_attr "mode" "<MODE>")]
3622 (define_insn "bswap<mode>2"
3623   [(set (match_operand:GPI 0 "register_operand" "=r")
3624         (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3625   ""
3626   "rev\\t%<w>0, %<w>1"
3627   [(set_attr "v8type" "rev")
3628    (set_attr "type" "rev")
3629    (set_attr "mode" "<MODE>")]
3632 (define_insn "bswaphi2"
3633   [(set (match_operand:HI 0 "register_operand" "=r")
3634         (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3635   ""
3636   "rev16\\t%w0, %w1"
3637   [(set_attr "v8type" "rev")
3638    (set_attr "type" "rev")
3639    (set_attr "mode" "HI")]
3642 ;; zero_extend version of above
3643 (define_insn "*bswapsi2_uxtw"
3644   [(set (match_operand:DI 0 "register_operand" "=r")
3645         (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3646   ""
3647   "rev\\t%w0, %w1"
3648   [(set_attr "v8type" "rev")
3649    (set_attr "type" "rev")
3650    (set_attr "mode" "SI")]
3653 ;; -------------------------------------------------------------------
3654 ;; Floating-point intrinsics
3655 ;; -------------------------------------------------------------------
3657 ;; frint floating-point round to integral standard patterns.
3658 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round.
3660 (define_insn "<frint_pattern><mode>2"
3661   [(set (match_operand:GPF 0 "register_operand" "=w")
3662         (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3663          FRINT))]
3664   "TARGET_FLOAT"
3665   "frint<frint_suffix>\\t%<s>0, %<s>1"
3666   [(set_attr "v8type" "frint")
3667    (set_attr "type" "f_rint<s>")
3668    (set_attr "mode" "<MODE>")]
3671 ;; frcvt floating-point round to integer and convert standard patterns.
3672 ;; Expands to lbtrunc, lceil, lfloor, lround.
3673 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3674   [(set (match_operand:GPI 0 "register_operand" "=r")
3675         (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3676                       FCVT)))]
3677   "TARGET_FLOAT"
3678   "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3679   [(set_attr "v8type" "fcvtf2i")
3680    (set_attr "type" "f_cvtf2i")
3681    (set_attr "mode" "<GPF:MODE>")
3682    (set_attr "mode2" "<GPI:MODE>")]
3685 ;; fma - no throw
3687 (define_insn "fma<mode>4"
3688   [(set (match_operand:GPF 0 "register_operand" "=w")
3689         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3690                  (match_operand:GPF 2 "register_operand" "w")
3691                  (match_operand:GPF 3 "register_operand" "w")))]
3692   "TARGET_FLOAT"
3693   "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3694   [(set_attr "v8type" "fmadd")
3695    (set_attr "type" "fmac<s>")
3696    (set_attr "mode" "<MODE>")]
3699 (define_insn "fnma<mode>4"
3700   [(set (match_operand:GPF 0 "register_operand" "=w")
3701         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3702                  (match_operand:GPF 2 "register_operand" "w")
3703                  (match_operand:GPF 3 "register_operand" "w")))]
3704   "TARGET_FLOAT"
3705   "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3706   [(set_attr "v8type" "fmadd")
3707    (set_attr "type" "fmac<s>")
3708    (set_attr "mode" "<MODE>")]
3711 (define_insn "fms<mode>4"
3712   [(set (match_operand:GPF 0 "register_operand" "=w")
3713         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3714                  (match_operand:GPF 2 "register_operand" "w")
3715                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3716   "TARGET_FLOAT"
3717   "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3718   [(set_attr "v8type" "fmadd")
3719    (set_attr "type" "fmac<s>")
3720    (set_attr "mode" "<MODE>")]
3723 (define_insn "fnms<mode>4"
3724   [(set (match_operand:GPF 0 "register_operand" "=w")
3725         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3726                  (match_operand:GPF 2 "register_operand" "w")
3727                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3728   "TARGET_FLOAT"
3729   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3730   [(set_attr "v8type" "fmadd")
3731    (set_attr "type" "fmac<s>")
3732    (set_attr "mode" "<MODE>")]
3735 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3736 (define_insn "*fnmadd<mode>4"
3737   [(set (match_operand:GPF 0 "register_operand" "=w")
3738         (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3739                           (match_operand:GPF 2 "register_operand" "w")
3740                           (match_operand:GPF 3 "register_operand" "w"))))]
3741   "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3742   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3743   [(set_attr "v8type" "fmadd")
3744    (set_attr "type" "fmac<s>")
3745    (set_attr "mode" "<MODE>")]
3748 ;; -------------------------------------------------------------------
3749 ;; Floating-point conversions
3750 ;; -------------------------------------------------------------------
3752 (define_insn "extendsfdf2"
3753   [(set (match_operand:DF 0 "register_operand" "=w")
3754         (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3755   "TARGET_FLOAT"
3756   "fcvt\\t%d0, %s1"
3757   [(set_attr "v8type" "fcvt")
3758    (set_attr "type" "f_cvt")
3759    (set_attr "mode" "DF")
3760    (set_attr "mode2" "SF")]
3763 (define_insn "truncdfsf2"
3764   [(set (match_operand:SF 0 "register_operand" "=w")
3765         (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3766   "TARGET_FLOAT"
3767   "fcvt\\t%s0, %d1"
3768   [(set_attr "v8type" "fcvt")
3769    (set_attr "type" "f_cvt")
3770    (set_attr "mode" "SF")
3771    (set_attr "mode2" "DF")]
3774 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3775   [(set (match_operand:GPI 0 "register_operand" "=r")
3776         (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3777   "TARGET_FLOAT"
3778   "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3779   [(set_attr "v8type" "fcvtf2i")
3780    (set_attr "type" "f_cvtf2i")
3781    (set_attr "mode" "<GPF:MODE>")
3782    (set_attr "mode2" "<GPI:MODE>")]
3785 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3786   [(set (match_operand:GPI 0 "register_operand" "=r")
3787         (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3788   "TARGET_FLOAT"
3789   "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3790   [(set_attr "v8type" "fcvtf2i")
3791    (set_attr "type" "f_cvtf2i")
3792    (set_attr "mode" "<GPF:MODE>")
3793    (set_attr "mode2" "<GPI:MODE>")]
3796 (define_insn "float<GPI:mode><GPF:mode>2"
3797   [(set (match_operand:GPF 0 "register_operand" "=w")
3798         (float:GPF (match_operand:GPI 1 "register_operand" "r")))]
3799   "TARGET_FLOAT"
3800   "scvtf\\t%<GPF:s>0, %<GPI:w>1"
3801   [(set_attr "v8type" "fcvti2f")
3802    (set_attr "type" "f_cvti2f")
3803    (set_attr "mode" "<GPF:MODE>")
3804    (set_attr "mode2" "<GPI:MODE>")]
3807 (define_insn "floatuns<GPI:mode><GPF:mode>2"
3808   [(set (match_operand:GPF 0 "register_operand" "=w")
3809         (unsigned_float:GPF (match_operand:GPI 1 "register_operand" "r")))]
3810   "TARGET_FLOAT"
3811   "ucvtf\\t%<GPF:s>0, %<GPI:w>1"
3812   [(set_attr "v8type" "fcvt")
3813    (set_attr "type" "f_cvt")
3814    (set_attr "mode" "<GPF:MODE>")
3815    (set_attr "mode2" "<GPI:MODE>")]
3818 ;; -------------------------------------------------------------------
3819 ;; Floating-point arithmetic
3820 ;; -------------------------------------------------------------------
3822 (define_insn "add<mode>3"
3823   [(set (match_operand:GPF 0 "register_operand" "=w")
3824         (plus:GPF
3825          (match_operand:GPF 1 "register_operand" "w")
3826          (match_operand:GPF 2 "register_operand" "w")))]
3827   "TARGET_FLOAT"
3828   "fadd\\t%<s>0, %<s>1, %<s>2"
3829   [(set_attr "v8type" "fadd")
3830    (set_attr "type" "fadd<s>")
3831    (set_attr "mode" "<MODE>")]
3834 (define_insn "sub<mode>3"
3835   [(set (match_operand:GPF 0 "register_operand" "=w")
3836         (minus:GPF
3837          (match_operand:GPF 1 "register_operand" "w")
3838          (match_operand:GPF 2 "register_operand" "w")))]
3839   "TARGET_FLOAT"
3840   "fsub\\t%<s>0, %<s>1, %<s>2"
3841   [(set_attr "v8type" "fadd")
3842    (set_attr "type" "fadd<s>")
3843    (set_attr "mode" "<MODE>")]
3846 (define_insn "mul<mode>3"
3847   [(set (match_operand:GPF 0 "register_operand" "=w")
3848         (mult:GPF
3849          (match_operand:GPF 1 "register_operand" "w")
3850          (match_operand:GPF 2 "register_operand" "w")))]
3851   "TARGET_FLOAT"
3852   "fmul\\t%<s>0, %<s>1, %<s>2"
3853   [(set_attr "v8type" "fmul")
3854    (set_attr "type" "fmul<s>")
3855    (set_attr "mode" "<MODE>")]
3858 (define_insn "*fnmul<mode>3"
3859   [(set (match_operand:GPF 0 "register_operand" "=w")
3860         (mult:GPF
3861                  (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3862                  (match_operand:GPF 2 "register_operand" "w")))]
3863   "TARGET_FLOAT"
3864   "fnmul\\t%<s>0, %<s>1, %<s>2"
3865   [(set_attr "v8type" "fmul")
3866    (set_attr "type" "fmul<s>")
3867    (set_attr "mode" "<MODE>")]
3870 (define_insn "div<mode>3"
3871   [(set (match_operand:GPF 0 "register_operand" "=w")
3872         (div:GPF
3873          (match_operand:GPF 1 "register_operand" "w")
3874          (match_operand:GPF 2 "register_operand" "w")))]
3875   "TARGET_FLOAT"
3876   "fdiv\\t%<s>0, %<s>1, %<s>2"
3877   [(set_attr "v8type" "fdiv")
3878    (set_attr "type" "fdiv<s>")
3879    (set_attr "mode" "<MODE>")]
3882 (define_insn "neg<mode>2"
3883   [(set (match_operand:GPF 0 "register_operand" "=w")
3884         (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
3885   "TARGET_FLOAT"
3886   "fneg\\t%<s>0, %<s>1"
3887   [(set_attr "v8type" "ffarith")
3888    (set_attr "type" "ffarith<s>")
3889    (set_attr "mode" "<MODE>")]
3892 (define_insn "sqrt<mode>2"
3893   [(set (match_operand:GPF 0 "register_operand" "=w")
3894         (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
3895   "TARGET_FLOAT"
3896   "fsqrt\\t%<s>0, %<s>1"
3897   [(set_attr "v8type" "fsqrt")
3898    (set_attr "type" "fsqrt<s>")
3899    (set_attr "mode" "<MODE>")]
3902 (define_insn "abs<mode>2"
3903   [(set (match_operand:GPF 0 "register_operand" "=w")
3904         (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
3905   "TARGET_FLOAT"
3906   "fabs\\t%<s>0, %<s>1"
3907   [(set_attr "v8type" "ffarith")
3908    (set_attr "type" "ffarith<s>")
3909    (set_attr "mode" "<MODE>")]
3912 ;; Given that smax/smin do not specify the result when either input is NaN,
3913 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
3914 ;; for smin.
3916 (define_insn "smax<mode>3"
3917   [(set (match_operand:GPF 0 "register_operand" "=w")
3918         (smax:GPF (match_operand:GPF 1 "register_operand" "w")
3919                   (match_operand:GPF 2 "register_operand" "w")))]
3920   "TARGET_FLOAT"
3921   "fmaxnm\\t%<s>0, %<s>1, %<s>2"
3922   [(set_attr "v8type" "fminmax")
3923    (set_attr "type" "f_minmax<s>")
3924    (set_attr "mode" "<MODE>")]
3927 (define_insn "smin<mode>3"
3928   [(set (match_operand:GPF 0 "register_operand" "=w")
3929         (smin:GPF (match_operand:GPF 1 "register_operand" "w")
3930                   (match_operand:GPF 2 "register_operand" "w")))]
3931   "TARGET_FLOAT"
3932   "fminnm\\t%<s>0, %<s>1, %<s>2"
3933   [(set_attr "v8type" "fminmax")
3934    (set_attr "type" "f_minmax<s>")
3935    (set_attr "mode" "<MODE>")]
3938 ;; -------------------------------------------------------------------
3939 ;; Reload support
3940 ;; -------------------------------------------------------------------
3942 (define_expand "aarch64_reload_mov<mode>"
3943   [(set (match_operand:TX 0 "register_operand" "=w")
3944         (match_operand:TX 1 "register_operand" "w"))
3945    (clobber (match_operand:DI 2 "register_operand" "=&r"))
3946   ]
3947   ""
3948   {
3949     rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
3950     rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
3951     gen_aarch64_movtilow_tilow (op0, op1);
3952     gen_aarch64_movdi_tihigh (operands[2], op1);
3953     gen_aarch64_movtihigh_di (op0, operands[2]);
3954     DONE;
3955   }
3958 ;; The following secondary reload helpers patterns are invoked
3959 ;; after or during reload as we don't want these patterns to start
3960 ;; kicking in during the combiner.
3962 (define_insn "aarch64_movdi_<mode>low"
3963   [(set (match_operand:DI 0 "register_operand" "=r")
3964         (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
3965   "reload_completed || reload_in_progress"
3966   "fmov\\t%x0, %d1"
3967   [(set_attr "v8type" "fmovf2i")
3968    (set_attr "type" "f_mrc")
3969    (set_attr "mode"   "DI")
3970    (set_attr "length" "4")
3971   ])
3973 (define_insn "aarch64_movdi_<mode>high"
3974   [(set (match_operand:DI 0 "register_operand" "=r")
3975         (truncate:DI
3976           (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
3977                        (const_int 64))))]
3978   "reload_completed || reload_in_progress"
3979   "fmov\\t%x0, %1.d[1]"
3980   [(set_attr "v8type" "fmovf2i")
3981    (set_attr "type" "f_mrc")
3982    (set_attr "mode"   "DI")
3983    (set_attr "length" "4")
3984   ])
3986 (define_insn "aarch64_mov<mode>high_di"
3987   [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
3988                          (const_int 64) (const_int 64))
3989         (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
3990   "reload_completed || reload_in_progress"
3991   "fmov\\t%0.d[1], %x1"
3992   [(set_attr "v8type" "fmovi2f")
3993    (set_attr "type" "f_mcr")
3994    (set_attr "mode"   "DI")
3995    (set_attr "length" "4")
3996   ])
3998 (define_insn "aarch64_mov<mode>low_di"
3999   [(set (match_operand:TX 0 "register_operand" "=w")
4000         (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4001   "reload_completed || reload_in_progress"
4002   "fmov\\t%d0, %x1"
4003   [(set_attr "v8type" "fmovi2f")
4004    (set_attr "type" "f_mcr")
4005    (set_attr "mode"   "DI")
4006    (set_attr "length" "4")
4007   ])
4009 (define_insn "aarch64_movtilow_tilow"
4010   [(set (match_operand:TI 0 "register_operand" "=w")
4011         (zero_extend:TI 
4012           (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
4013   "reload_completed || reload_in_progress"
4014   "fmov\\t%d0, %d1"
4015   [(set_attr "v8type" "fmovi2f")
4016    (set_attr "type" "f_mcr")
4017    (set_attr "mode"   "DI")
4018    (set_attr "length" "4")
4019   ])
4021 ;; There is a deliberate reason why the parameters of high and lo_sum's
4022 ;; don't have modes for ADRP and ADD instructions.  This is to allow high
4023 ;; and lo_sum's to be used with the labels defining the jump tables in
4024 ;; rodata section.
4026 (define_expand "add_losym"
4027   [(set (match_operand 0 "register_operand" "=r")
4028         (lo_sum (match_operand 1 "register_operand" "r")
4029                 (match_operand 2 "aarch64_valid_symref" "S")))]
4030   ""
4032   enum machine_mode mode = GET_MODE (operands[0]);
4034   emit_insn ((mode == DImode
4035               ? gen_add_losym_di
4036               : gen_add_losym_si) (operands[0],
4037                                    operands[1],
4038                                    operands[2]));
4039   DONE;
4042 (define_insn "add_losym_<mode>"
4043   [(set (match_operand:P 0 "register_operand" "=r")
4044         (lo_sum:P (match_operand:P 1 "register_operand" "r")
4045                   (match_operand 2 "aarch64_valid_symref" "S")))]
4046   ""
4047   "add\\t%<w>0, %<w>1, :lo12:%a2"
4048   [(set_attr "v8type" "alu")
4049    (set_attr "type" "alu_reg")
4050    (set_attr "mode" "<MODE>")]
4053 (define_insn "ldr_got_small_<mode>"
4054   [(set (match_operand:PTR 0 "register_operand" "=r")
4055         (unspec:PTR [(mem:PTR (lo_sum:PTR
4056                               (match_operand:PTR 1 "register_operand" "r")
4057                               (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
4058                     UNSPEC_GOTSMALLPIC))]
4059   ""
4060   "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
4061   [(set_attr "v8type" "load1")
4062    (set_attr "type" "load1")
4063    (set_attr "mode" "<MODE>")]
4066 (define_insn "ldr_got_small_sidi"
4067   [(set (match_operand:DI 0 "register_operand" "=r")
4068         (zero_extend:DI
4069          (unspec:SI [(mem:SI (lo_sum:DI
4070                              (match_operand:DI 1 "register_operand" "r")
4071                              (match_operand:DI 2 "aarch64_valid_symref" "S")))]
4072                     UNSPEC_GOTSMALLPIC)))]
4073   "TARGET_ILP32"
4074   "ldr\\t%w0, [%1, #:got_lo12:%a2]"
4075   [(set_attr "v8type" "load1")
4076    (set_attr "type" "load1")
4077    (set_attr "mode" "DI")]
4080 (define_insn "ldr_got_tiny"
4081   [(set (match_operand:DI 0 "register_operand" "=r")
4082         (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
4083                    UNSPEC_GOTTINYPIC))]
4084   ""
4085   "ldr\\t%0, %L1"
4086   [(set_attr "v8type" "load1")
4087    (set_attr "type" "load1")
4088    (set_attr "mode" "DI")]
4091 (define_insn "aarch64_load_tp_hard"
4092   [(set (match_operand:DI 0 "register_operand" "=r")
4093         (unspec:DI [(const_int 0)] UNSPEC_TLS))]
4094   ""
4095   "mrs\\t%0, tpidr_el0"
4096   [(set_attr "v8type" "mrs")
4097    (set_attr "type" "mrs")
4098    (set_attr "mode" "DI")]
4101 ;; The TLS ABI specifically requires that the compiler does not schedule
4102 ;; instructions in the TLS stubs, in order to enable linker relaxation.
4103 ;; Therefore we treat the stubs as an atomic sequence.
4104 (define_expand "tlsgd_small"
4105  [(parallel [(set (match_operand 0 "register_operand" "")
4106                   (call (mem:DI (match_dup 2)) (const_int 1)))
4107              (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
4108              (clobber (reg:DI LR_REGNUM))])]
4109  ""
4111   operands[2] = aarch64_tls_get_addr ();
4114 (define_insn "*tlsgd_small"
4115   [(set (match_operand 0 "register_operand" "")
4116         (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
4117    (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
4118    (clobber (reg:DI LR_REGNUM))
4119   ]
4120   ""
4121   "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
4122   [(set_attr "v8type" "call")
4123    (set_attr "type" "call")
4124    (set_attr "length" "16")])
4126 (define_insn "tlsie_small"
4127   [(set (match_operand:DI 0 "register_operand" "=r")
4128         (unspec:DI [(match_operand:DI 1 "aarch64_tls_ie_symref" "S")]
4129                    UNSPEC_GOTSMALLTLS))]
4130   ""
4131   "adrp\\t%0, %A1\;ldr\\t%0, [%0, #%L1]"
4132   [(set_attr "v8type" "load1")
4133    (set_attr "type" "load1")
4134    (set_attr "mode" "DI")
4135    (set_attr "length" "8")]
4138 (define_insn "tlsle_small"
4139   [(set (match_operand:DI 0 "register_operand" "=r")
4140         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
4141                    (match_operand:DI 2 "aarch64_tls_le_symref" "S")]
4142                    UNSPEC_GOTSMALLTLS))]
4143   ""
4144   "add\\t%0, %1, #%G2\;add\\t%0, %0, #%L2"
4145   [(set_attr "v8type" "alu")
4146    (set_attr "type" "alu_reg")
4147    (set_attr "mode" "DI")
4148    (set_attr "length" "8")]
4151 (define_insn "tlsdesc_small"
4152   [(set (reg:DI R0_REGNUM)
4153         (unspec:DI [(match_operand:DI 0 "aarch64_valid_symref" "S")]
4154                    UNSPEC_TLSDESC))
4155    (clobber (reg:DI LR_REGNUM))
4156    (clobber (match_scratch:DI 1 "=r"))]
4157   "TARGET_TLS_DESC"
4158   "adrp\\tx0, %A0\;ldr\\t%1, [x0, #%L0]\;add\\tx0, x0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
4159   [(set_attr "v8type" "call")
4160    (set_attr "type" "call")
4161    (set_attr "length" "16")])
4163 (define_insn "stack_tie"
4164   [(set (mem:BLK (scratch))
4165         (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
4166                      (match_operand:DI 1 "register_operand" "rk")]
4167                     UNSPEC_PRLG_STK))]
4168   ""
4169   ""
4170   [(set_attr "length" "0")]
4173 ;; Named pattern for expanding thread pointer reference.
4174 (define_expand "get_thread_pointerdi"
4175   [(match_operand:DI 0 "register_operand" "=r")]
4176   ""
4178   rtx tmp = aarch64_load_tp (operands[0]);
4179   if (tmp != operands[0])
4180     emit_move_insn (operands[0], tmp);
4181   DONE;
4184 ;; AdvSIMD Stuff
4185 (include "aarch64-simd.md")
4187 ;; Atomic Operations
4188 (include "atomics.md")