[AArch64] Fix output assembly bug under TLSIE ILP32
[official-gcc.git] / gcc / config / aarch64 / aarch64.md
blob208f58f6dcdb291cead5e8e024808b712651f239
1 ;; Machine description for AArch64 architecture.
2 ;; Copyright (C) 2009-2015 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_CRC32B
71     UNSPEC_CRC32CB
72     UNSPEC_CRC32CH
73     UNSPEC_CRC32CW
74     UNSPEC_CRC32CX
75     UNSPEC_CRC32H
76     UNSPEC_CRC32W
77     UNSPEC_CRC32X
78     UNSPEC_URECPE
79     UNSPEC_FRECPE
80     UNSPEC_FRECPS
81     UNSPEC_FRECPX
82     UNSPEC_FRINTA
83     UNSPEC_FRINTI
84     UNSPEC_FRINTM
85     UNSPEC_FRINTN
86     UNSPEC_FRINTP
87     UNSPEC_FRINTX
88     UNSPEC_FRINTZ
89     UNSPEC_GOTSMALLPIC
90     UNSPEC_GOTSMALLPIC28K
91     UNSPEC_GOTSMALLTLS
92     UNSPEC_GOTTINYPIC
93     UNSPEC_GOTTINYTLS
94     UNSPEC_LD1
95     UNSPEC_LD2
96     UNSPEC_LD2_DUP
97     UNSPEC_LD3
98     UNSPEC_LD3_DUP
99     UNSPEC_LD4
100     UNSPEC_LD4_DUP
101     UNSPEC_LD2_LANE
102     UNSPEC_LD3_LANE
103     UNSPEC_LD4_LANE
104     UNSPEC_MB
105     UNSPEC_NOP
106     UNSPEC_PRLG_STK
107     UNSPEC_RBIT
108     UNSPEC_SISD_NEG
109     UNSPEC_SISD_SSHL
110     UNSPEC_SISD_USHL
111     UNSPEC_SSHL_2S
112     UNSPEC_ST1
113     UNSPEC_ST2
114     UNSPEC_ST3
115     UNSPEC_ST4
116     UNSPEC_ST2_LANE
117     UNSPEC_ST3_LANE
118     UNSPEC_ST4_LANE
119     UNSPEC_TLS
120     UNSPEC_TLSDESC
121     UNSPEC_TLSLE12
122     UNSPEC_TLSLE24
123     UNSPEC_TLSLE32
124     UNSPEC_TLSLE48
125     UNSPEC_USHL_2S
126     UNSPEC_VSTRUCTDUMMY
127     UNSPEC_SP_SET
128     UNSPEC_SP_TEST
131 (define_c_enum "unspecv" [
132     UNSPECV_EH_RETURN           ; Represent EH_RETURN
133     UNSPECV_GET_FPCR            ; Represent fetch of FPCR content.
134     UNSPECV_SET_FPCR            ; Represent assign of FPCR content.
135     UNSPECV_GET_FPSR            ; Represent fetch of FPSR content.
136     UNSPECV_SET_FPSR            ; Represent assign of FPSR content.
137   ]
140 ;; If further include files are added the defintion of MD_INCLUDES
141 ;; must be updated.
143 (include "constraints.md")
144 (include "predicates.md")
145 (include "iterators.md")
147 ;; -------------------------------------------------------------------
148 ;; Instruction types and attributes
149 ;; -------------------------------------------------------------------
151 ; The "type" attribute is included here from AArch32 backend to be able
152 ; to share pipeline descriptions.
153 (include "../arm/types.md")
155 ;; It is important to set the fp or simd attributes to yes when a pattern
156 ;; alternative uses the FP or SIMD register files, usually signified by use of
157 ;; the 'w' constraint.  This will ensure that the alternative will be
158 ;; disabled when compiling with -mgeneral-regs-only or with the +nofp/+nosimd
159 ;; architecture extensions.  If all the alternatives in a pattern use the
160 ;; FP or SIMD registers then the pattern predicate should include TARGET_FLOAT
161 ;; or TARGET_SIMD.
163 ;; Attribute that specifies whether or not the instruction touches fp
164 ;; registers.  When this is set to yes for an alternative, that alternative
165 ;; will be disabled when !TARGET_FLOAT.
166 (define_attr "fp" "no,yes" (const_string "no"))
168 ;; Attribute that specifies whether or not the instruction touches simd
169 ;; registers.  When this is set to yes for an alternative, that alternative
170 ;; will be disabled when !TARGET_SIMD.
171 (define_attr "simd" "no,yes" (const_string "no"))
173 (define_attr "length" ""
174   (const_int 4))
176 ;; Attribute that controls whether an alternative is enabled or not.
177 ;; Currently it is only used to disable alternatives which touch fp or simd
178 ;; registers when -mgeneral-regs-only is specified.
179 (define_attr "enabled" "no,yes"
180   (cond [(ior
181         (and (eq_attr "fp" "yes")
182              (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
183         (and (eq_attr "simd" "yes")
184              (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
185              (const_string "no")
186         ] (const_string "yes")))
188 ;; Attribute that specifies whether we are dealing with a branch to a
189 ;; label that is far away, i.e. further away than the maximum/minimum
190 ;; representable in a signed 21-bits number.
191 ;; 0 :=: no
192 ;; 1 :=: yes
193 (define_attr "far_branch" "" (const_int 0))
195 ;; -------------------------------------------------------------------
196 ;; Pipeline descriptions and scheduling
197 ;; -------------------------------------------------------------------
199 ;; Processor types.
200 (include "aarch64-tune.md")
202 ;; Scheduling
203 (include "../arm/cortex-a53.md")
204 (include "../arm/cortex-a57.md")
205 (include "thunderx.md")
206 (include "../arm/xgene1.md")
208 ;; -------------------------------------------------------------------
209 ;; Jumps and other miscellaneous insns
210 ;; -------------------------------------------------------------------
212 (define_insn "indirect_jump"
213   [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
214   ""
215   "br\\t%0"
216   [(set_attr "type" "branch")]
219 (define_insn "jump"
220   [(set (pc) (label_ref (match_operand 0 "" "")))]
221   ""
222   "b\\t%l0"
223   [(set_attr "type" "branch")]
226 (define_expand "cbranch<mode>4"
227   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
228                             [(match_operand:GPI 1 "register_operand" "")
229                              (match_operand:GPI 2 "aarch64_plus_operand" "")])
230                            (label_ref (match_operand 3 "" ""))
231                            (pc)))]
232   ""
233   "
234   operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
235                                          operands[2]);
236   operands[2] = const0_rtx;
237   "
240 (define_expand "cbranch<mode>4"
241   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
242                             [(match_operand:GPF 1 "register_operand" "")
243                              (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
244                            (label_ref (match_operand 3 "" ""))
245                            (pc)))]
246   ""
247   "
248   operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
249                                          operands[2]);
250   operands[2] = const0_rtx;
251   "
254 (define_expand "cbranchcc4"
255   [(set (pc) (if_then_else
256               (match_operator 0 "aarch64_comparison_operator"
257                [(match_operand 1 "cc_register" "")
258                 (match_operand 2 "const0_operand")])
259               (label_ref (match_operand 3 "" ""))
260               (pc)))]
261   ""
262   "")
264 (define_insn "ccmp_and<mode>"
265   [(set (match_operand 1 "ccmp_cc_register" "")
266         (compare
267          (and:SI
268           (match_operator 4 "aarch64_comparison_operator"
269            [(match_operand 0 "ccmp_cc_register" "")
270             (const_int 0)])
271           (match_operator 5 "aarch64_comparison_operator"
272            [(match_operand:GPI 2 "register_operand" "r,r,r")
273             (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")]))
274          (const_int 0)))]
275   "aarch64_ccmp_mode_to_code (GET_MODE (operands[1])) == GET_CODE (operands[5])"
276   "@
277    ccmp\\t%<w>2, %<w>3, %k5, %m4
278    ccmp\\t%<w>2, %<w>3, %k5, %m4
279    ccmn\\t%<w>2, #%n3, %k5, %m4"
280   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
283 (define_insn "ccmp_ior<mode>"
284   [(set (match_operand 1 "ccmp_cc_register" "")
285         (compare
286          (ior:SI
287           (match_operator 4 "aarch64_comparison_operator"
288            [(match_operand 0 "ccmp_cc_register" "")
289             (const_int 0)])
290           (match_operator 5 "aarch64_comparison_operator"
291            [(match_operand:GPI 2 "register_operand" "r,r,r")
292             (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")]))
293          (const_int 0)))]
294   "aarch64_ccmp_mode_to_code (GET_MODE (operands[1])) == GET_CODE (operands[5])"
295   "@
296    ccmp\\t%<w>2, %<w>3, %K5, %M4
297    ccmp\\t%<w>2, %<w>3, %K5, %M4
298    ccmn\\t%<w>2, #%n3, %K5, %M4"
299   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
302 (define_expand "cmp<mode>"
303   [(set (match_operand 0 "cc_register" "")
304         (match_operator:CC 1 "aarch64_comparison_operator"
305          [(match_operand:GPI 2 "register_operand" "")
306           (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
307   ""
308   {
309     operands[1] = gen_rtx_fmt_ee (COMPARE,
310                                   SELECT_CC_MODE (GET_CODE (operands[1]),
311                                                   operands[2], operands[3]),
312                                   operands[2], operands[3]);
313   }
316 ;; Expansion of signed mod by a power of 2 using CSNEG.
317 ;; For x0 % n where n is a power of 2 produce:
318 ;; negs   x1, x0
319 ;; and    x0, x0, #(n - 1)
320 ;; and    x1, x1, #(n - 1)
321 ;; csneg  x0, x0, x1, mi
323 (define_expand "mod<mode>3"
324   [(match_operand:GPI 0 "register_operand" "")
325    (match_operand:GPI 1 "register_operand" "")
326    (match_operand:GPI 2 "const_int_operand" "")]
327   ""
328   {
329     HOST_WIDE_INT val = INTVAL (operands[2]);
331     if (val <= 0
332        || exact_log2 (val) <= 0
333        || !aarch64_bitmask_imm (val - 1, <MODE>mode))
334       FAIL;
336     rtx mask = GEN_INT (val - 1);
338     /* In the special case of x0 % 2 we can do the even shorter:
339         cmp    x0, xzr
340         and    x0, x0, 1
341         cneg   x0, x0, lt.  */
342     if (val == 2)
343       {
344         rtx masked = gen_reg_rtx (<MODE>mode);
345         rtx ccreg = aarch64_gen_compare_reg (LT, operands[1], const0_rtx);
346         emit_insn (gen_and<mode>3 (masked, operands[1], mask));
347         rtx x = gen_rtx_LT (VOIDmode, ccreg, const0_rtx);
348         emit_insn (gen_csneg3<mode>_insn (operands[0], x, masked, masked));
349         DONE;
350       }
352     rtx neg_op = gen_reg_rtx (<MODE>mode);
353     rtx_insn *insn = emit_insn (gen_neg<mode>2_compare0 (neg_op, operands[1]));
355     /* Extract the condition register and mode.  */
356     rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
357     rtx cc_reg = SET_DEST (cmp);
358     rtx cond = gen_rtx_GE (VOIDmode, cc_reg, const0_rtx);
360     rtx masked_pos = gen_reg_rtx (<MODE>mode);
361     emit_insn (gen_and<mode>3 (masked_pos, operands[1], mask));
363     rtx masked_neg = gen_reg_rtx (<MODE>mode);
364     emit_insn (gen_and<mode>3 (masked_neg, neg_op, mask));
366     emit_insn (gen_csneg3<mode>_insn (operands[0], cond,
367                                        masked_neg, masked_pos));
368     DONE;
369   }
372 (define_insn "*condjump"
373   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
374                             [(match_operand 1 "cc_register" "") (const_int 0)])
375                            (label_ref (match_operand 2 "" ""))
376                            (pc)))]
377   ""
378   {
379     if (get_attr_length (insn) == 8)
380       return aarch64_gen_far_branch (operands, 2, "Lbcond", "b%M0\\t");
381     else
382       return  "b%m0\\t%l2";
383   }
384   [(set_attr "type" "branch")
385    (set (attr "length")
386         (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576))
387                            (lt (minus (match_dup 2) (pc)) (const_int 1048572)))
388                       (const_int 4)
389                       (const_int 8)))
390    (set (attr "far_branch")
391         (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576))
392                            (lt (minus (match_dup 2) (pc)) (const_int 1048572)))
393                       (const_int 0)
394                       (const_int 1)))]
397 (define_expand "casesi"
398   [(match_operand:SI 0 "register_operand" "")   ; Index
399    (match_operand:SI 1 "const_int_operand" "")  ; Lower bound
400    (match_operand:SI 2 "const_int_operand" "")  ; Total range
401    (match_operand:DI 3 "" "")                   ; Table label
402    (match_operand:DI 4 "" "")]                  ; Out of range label
403   ""
404   {
405     if (operands[1] != const0_rtx)
406       {
407         rtx reg = gen_reg_rtx (SImode);
409         /* Canonical RTL says that if you have:
411            (minus (X) (CONST))
413            then this should be emitted as:
415            (plus (X) (-CONST))
417            The use of trunc_int_for_mode ensures that the resulting
418            constant can be represented in SImode, this is important
419            for the corner case where operand[1] is INT_MIN.  */
421         operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
423         if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
424               (operands[1], SImode))
425           operands[1] = force_reg (SImode, operands[1]);
426         emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
427         operands[0] = reg;
428       }
430     if (!aarch64_plus_operand (operands[2], SImode))
431       operands[2] = force_reg (SImode, operands[2]);
432     emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
433                                                  const0_rtx),
434                                     operands[0], operands[2], operands[4]));
436     operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
437     emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
438                                          operands[3]));
439     DONE;
440   }
443 (define_insn "casesi_dispatch"
444   [(parallel
445     [(set (pc)
446           (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
447                            (match_operand:SI 1 "register_operand" "r")]
448                         UNSPEC_CASESI)))
449      (clobber (reg:CC CC_REGNUM))
450      (clobber (match_scratch:DI 3 "=r"))
451      (clobber (match_scratch:DI 4 "=r"))
452      (use (label_ref (match_operand 2 "" "")))])]
453   ""
454   "*
455   return aarch64_output_casesi (operands);
456   "
457   [(set_attr "length" "16")
458    (set_attr "type" "branch")]
461 (define_insn "nop"
462   [(unspec[(const_int 0)] UNSPEC_NOP)]
463   ""
464   "nop"
465   [(set_attr "type" "no_insn")]
468 (define_insn "prefetch"
469   [(prefetch (match_operand:DI 0 "register_operand" "r")
470             (match_operand:QI 1 "const_int_operand" "")
471             (match_operand:QI 2 "const_int_operand" ""))]
472   ""
473   {
474     const char * pftype[2][4] = 
475     {
476       {"prfm\\tPLDL1STRM, %a0",
477        "prfm\\tPLDL3KEEP, %a0",
478        "prfm\\tPLDL2KEEP, %a0",
479        "prfm\\tPLDL1KEEP, %a0"},
480       {"prfm\\tPSTL1STRM, %a0",
481        "prfm\\tPSTL3KEEP, %a0",
482        "prfm\\tPSTL2KEEP, %a0",
483        "prfm\\tPSTL1KEEP, %a0"},
484     };
486     int locality = INTVAL (operands[2]);
488     gcc_assert (IN_RANGE (locality, 0, 3));
490     return pftype[INTVAL(operands[1])][locality];
491   }
492   [(set_attr "type" "load1")]
495 (define_insn "trap"
496   [(trap_if (const_int 1) (const_int 8))]
497   ""
498   "brk #1000"
499   [(set_attr "type" "trap")])
501 (define_expand "prologue"
502   [(clobber (const_int 0))]
503   ""
504   "
505   aarch64_expand_prologue ();
506   DONE;
507   "
510 (define_expand "epilogue"
511   [(clobber (const_int 0))]
512   ""
513   "
514   aarch64_expand_epilogue (false);
515   DONE;
516   "
519 (define_expand "sibcall_epilogue"
520   [(clobber (const_int 0))]
521   ""
522   "
523   aarch64_expand_epilogue (true);
524   DONE;
525   "
528 (define_insn "*do_return"
529   [(return)]
530   ""
531   "ret"
532   [(set_attr "type" "branch")]
535 (define_expand "return"
536   [(simple_return)]
537   "aarch64_use_return_insn_p ()"
538   ""
541 (define_insn "simple_return"
542   [(simple_return)]
543   ""
544   "ret"
545   [(set_attr "type" "branch")]
548 (define_insn "eh_return"
549   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
550     UNSPECV_EH_RETURN)]
551   ""
552   "#"
553   [(set_attr "type" "branch")]
557 (define_split
558   [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
559     UNSPECV_EH_RETURN)]
560   "reload_completed"
561   [(set (match_dup 1) (match_dup 0))]
562   {
563     operands[1] = aarch64_final_eh_return_addr ();
564   }
567 (define_insn "*cb<optab><mode>1"
568   [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
569                                 (const_int 0))
570                            (label_ref (match_operand 1 "" ""))
571                            (pc)))]
572   ""
573   {
574     if (get_attr_length (insn) == 8)
575       return aarch64_gen_far_branch (operands, 1, "Lcb", "<inv_cb>\\t%<w>0, ");
576     else
577       return "<cbz>\\t%<w>0, %l1";
578   }
579   [(set_attr "type" "branch")
580    (set (attr "length")
581         (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -1048576))
582                            (lt (minus (match_dup 1) (pc)) (const_int 1048572)))
583                       (const_int 4)
584                       (const_int 8)))
585    (set (attr "far_branch")
586         (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576))
587                            (lt (minus (match_dup 2) (pc)) (const_int 1048572)))
588                       (const_int 0)
589                       (const_int 1)))]
592 (define_insn "*tb<optab><mode>1"
593   [(set (pc) (if_then_else
594               (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
595                                     (const_int 1)
596                                     (match_operand 1 "const_int_operand" "n"))
597                    (const_int 0))
598              (label_ref (match_operand 2 "" ""))
599              (pc)))
600    (clobber (reg:CC CC_REGNUM))]
601   ""
602   {
603     if (get_attr_length (insn) == 8)
604       {
605         if (get_attr_far_branch (insn) == 1)
606           return aarch64_gen_far_branch (operands, 2, "Ltb",
607                                          "<inv_tb>\\t%<w>0, %1, ");
608         else
609           {
610             operands[1] = GEN_INT (HOST_WIDE_INT_1U << UINTVAL (operands[1]));
611             return "tst\t%<w>0, %1\;<bcond>\t%l2";
612           }
613       }
614     else
615       return "<tbz>\t%<w>0, %1, %l2";
616   }
617   [(set_attr "type" "branch")
618    (set (attr "length")
619         (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
620                            (lt (minus (match_dup 2) (pc)) (const_int 32764)))
621                       (const_int 4)
622                       (const_int 8)))
623    (set (attr "far_branch")
624         (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576))
625                            (lt (minus (match_dup 2) (pc)) (const_int 1048572)))
626                       (const_int 0)
627                       (const_int 1)))]
631 (define_insn "*cb<optab><mode>1"
632   [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
633                                  (const_int 0))
634                            (label_ref (match_operand 1 "" ""))
635                            (pc)))
636    (clobber (reg:CC CC_REGNUM))]
637   ""
638   {
639     if (get_attr_length (insn) == 8)
640       {
641         if (get_attr_far_branch (insn) == 1)
642           return aarch64_gen_far_branch (operands, 1, "Ltb",
643                                          "<inv_tb>\\t%<w>0, <sizem1>, ");
644         else
645           {
646             char buf[64];
647             uint64_t val = ((uint64_t) 1)
648                 << (GET_MODE_SIZE (<MODE>mode) * BITS_PER_UNIT - 1);
649             sprintf (buf, "tst\t%%<w>0, %" PRId64, val);
650             output_asm_insn (buf, operands);
651             return "<bcond>\t%l1";
652           }
653       }
654     else
655       return "<tbz>\t%<w>0, <sizem1>, %l1";
656   }
657   [(set_attr "type" "branch")
658    (set (attr "length")
659         (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
660                            (lt (minus (match_dup 1) (pc)) (const_int 32764)))
661                       (const_int 4)
662                       (const_int 8)))
663    (set (attr "far_branch")
664         (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -1048576))
665                            (lt (minus (match_dup 1) (pc)) (const_int 1048572)))
666                       (const_int 0)
667                       (const_int 1)))]
670 ;; -------------------------------------------------------------------
671 ;; Subroutine calls and sibcalls
672 ;; -------------------------------------------------------------------
674 (define_expand "call_internal"
675   [(parallel [(call (match_operand 0 "memory_operand" "")
676                     (match_operand 1 "general_operand" ""))
677               (use (match_operand 2 "" ""))
678               (clobber (reg:DI LR_REGNUM))])])
680 (define_expand "call"
681   [(parallel [(call (match_operand 0 "memory_operand" "")
682                     (match_operand 1 "general_operand" ""))
683               (use (match_operand 2 "" ""))
684               (clobber (reg:DI LR_REGNUM))])]
685   ""
686   "
687   {
688     rtx callee, pat;
690     /* In an untyped call, we can get NULL for operand 2.  */
691     if (operands[2] == NULL)
692       operands[2] = const0_rtx;
694     /* Decide if we should generate indirect calls by loading the
695        64-bit address of the callee into a register before performing
696        the branch-and-link.  */
697     callee = XEXP (operands[0], 0);
698     if (GET_CODE (callee) == SYMBOL_REF
699         ? aarch64_is_long_call_p (callee)
700         : !REG_P (callee))
701       XEXP (operands[0], 0) = force_reg (Pmode, callee);
703     pat = gen_call_internal (operands[0], operands[1], operands[2]);
704     aarch64_emit_call_insn (pat);
705     DONE;
706   }"
709 (define_insn "*call_reg"
710   [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
711          (match_operand 1 "" ""))
712    (use (match_operand 2 "" ""))
713    (clobber (reg:DI LR_REGNUM))]
714   ""
715   "blr\\t%0"
716   [(set_attr "type" "call")]
719 (define_insn "*call_symbol"
720   [(call (mem:DI (match_operand:DI 0 "" ""))
721          (match_operand 1 "" ""))
722    (use (match_operand 2 "" ""))
723    (clobber (reg:DI LR_REGNUM))]
724   "GET_CODE (operands[0]) == SYMBOL_REF
725    && !aarch64_is_long_call_p (operands[0])
726    && !aarch64_is_noplt_call_p (operands[0])"
727   "bl\\t%a0"
728   [(set_attr "type" "call")]
731 (define_expand "call_value_internal"
732   [(parallel [(set (match_operand 0 "" "")
733                    (call (match_operand 1 "memory_operand" "")
734                          (match_operand 2 "general_operand" "")))
735               (use (match_operand 3 "" ""))
736               (clobber (reg:DI LR_REGNUM))])])
738 (define_expand "call_value"
739   [(parallel [(set (match_operand 0 "" "")
740                    (call (match_operand 1 "memory_operand" "")
741                          (match_operand 2 "general_operand" "")))
742               (use (match_operand 3 "" ""))
743               (clobber (reg:DI LR_REGNUM))])]
744   ""
745   "
746   {
747     rtx callee, pat;
749     /* In an untyped call, we can get NULL for operand 3.  */
750     if (operands[3] == NULL)
751       operands[3] = const0_rtx;
753     /* Decide if we should generate indirect calls by loading the
754        64-bit address of the callee into a register before performing
755        the branch-and-link.  */
756     callee = XEXP (operands[1], 0);
757     if (GET_CODE (callee) == SYMBOL_REF
758         ? aarch64_is_long_call_p (callee)
759         : !REG_P (callee))
760       XEXP (operands[1], 0) = force_reg (Pmode, callee);
762     pat = gen_call_value_internal (operands[0], operands[1], operands[2],
763                                    operands[3]);
764     aarch64_emit_call_insn (pat);
765     DONE;
766   }"
769 (define_insn "*call_value_reg"
770   [(set (match_operand 0 "" "")
771         (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
772                       (match_operand 2 "" "")))
773    (use (match_operand 3 "" ""))
774    (clobber (reg:DI LR_REGNUM))]
775   ""
776   "blr\\t%1"
777   [(set_attr "type" "call")]
781 (define_insn "*call_value_symbol"
782   [(set (match_operand 0 "" "")
783         (call (mem:DI (match_operand:DI 1 "" ""))
784               (match_operand 2 "" "")))
785    (use (match_operand 3 "" ""))
786    (clobber (reg:DI LR_REGNUM))]
787   "GET_CODE (operands[1]) == SYMBOL_REF
788    && !aarch64_is_long_call_p (operands[1])
789    && !aarch64_is_noplt_call_p (operands[1])"
790   "bl\\t%a1"
791   [(set_attr "type" "call")]
794 (define_expand "sibcall_internal"
795   [(parallel [(call (match_operand 0 "memory_operand" "")
796                     (match_operand 1 "general_operand" ""))
797               (return)
798               (use (match_operand 2 "" ""))])])
800 (define_expand "sibcall"
801   [(parallel [(call (match_operand 0 "memory_operand" "")
802                     (match_operand 1 "general_operand" ""))
803               (return)
804               (use (match_operand 2 "" ""))])]
805   ""
806   {
807     rtx pat;
809     if (!REG_P (XEXP (operands[0], 0))
810        && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
811      XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
813     if (operands[2] == NULL_RTX)
814       operands[2] = const0_rtx;
816     pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
817     aarch64_emit_call_insn (pat);
818     DONE;
819   }
822 (define_expand "sibcall_value_internal"
823   [(parallel [(set (match_operand 0 "" "")
824                    (call (match_operand 1 "memory_operand" "")
825                          (match_operand 2 "general_operand" "")))
826               (return)
827               (use (match_operand 3 "" ""))])])
829 (define_expand "sibcall_value"
830   [(parallel [(set (match_operand 0 "" "")
831                    (call (match_operand 1 "memory_operand" "")
832                          (match_operand 2 "general_operand" "")))
833               (return)
834               (use (match_operand 3 "" ""))])]
835   ""
836   {
837     rtx pat;
839     if (!REG_P (XEXP (operands[1], 0))
840        && (GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF))
841      XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
843     if (operands[3] == NULL_RTX)
844       operands[3] = const0_rtx;
846     pat = gen_sibcall_value_internal (operands[0], operands[1], operands[2],
847                                       operands[3]);
848     aarch64_emit_call_insn (pat);
849     DONE;
850   }
853 (define_insn "*sibcall_insn"
854   [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucs, Usf"))
855          (match_operand 1 "" ""))
856    (return)
857    (use (match_operand 2 "" ""))]
858   "SIBLING_CALL_P (insn)"
859   "@
860    br\\t%0
861    b\\t%a0"
862   [(set_attr "type" "branch, branch")]
865 (define_insn "*sibcall_value_insn"
866   [(set (match_operand 0 "" "")
867         (call (mem:DI
868                 (match_operand:DI 1 "aarch64_call_insn_operand" "Ucs, Usf"))
869               (match_operand 2 "" "")))
870    (return)
871    (use (match_operand 3 "" ""))]
872   "SIBLING_CALL_P (insn)"
873   "@
874    br\\t%1
875    b\\t%a1"
876   [(set_attr "type" "branch, branch")]
879 ;; Call subroutine returning any type.
881 (define_expand "untyped_call"
882   [(parallel [(call (match_operand 0 "")
883                     (const_int 0))
884               (match_operand 1 "")
885               (match_operand 2 "")])]
886   ""
888   int i;
890   emit_call_insn (gen_call (operands[0], const0_rtx, NULL));
892   for (i = 0; i < XVECLEN (operands[2], 0); i++)
893     {
894       rtx set = XVECEXP (operands[2], 0, i);
895       emit_move_insn (SET_DEST (set), SET_SRC (set));
896     }
898   /* The optimizer does not know that the call sets the function value
899      registers we stored in the result block.  We avoid problems by
900      claiming that all hard registers are used and clobbered at this
901      point.  */
902   emit_insn (gen_blockage ());
903   DONE;
906 ;; -------------------------------------------------------------------
907 ;; Moves
908 ;; -------------------------------------------------------------------
910 (define_expand "mov<mode>"
911   [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
912         (match_operand:SHORT 1 "general_operand" ""))]
913   ""
914   "
915     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
916       operands[1] = force_reg (<MODE>mode, operands[1]);
917   "
920 (define_insn "*mov<mode>_aarch64"
921   [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r,   *w,r,*w, m, m, r,*w,*w")
922         (match_operand:SHORT 1 "general_operand"      " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
923   "(register_operand (operands[0], <MODE>mode)
924     || aarch64_reg_or_zero (operands[1], <MODE>mode))"
926    switch (which_alternative)
927      {
928      case 0:
929        return "mov\t%w0, %w1";
930      case 1:
931        return "mov\t%w0, %1";
932      case 2:
933        return aarch64_output_scalar_simd_mov_immediate (operands[1],
934                                                         <MODE>mode);
935      case 3:
936        return "ldr<size>\t%w0, %1";
937      case 4:
938        return "ldr\t%<size>0, %1";
939      case 5:
940        return "str<size>\t%w1, %0";
941      case 6:
942        return "str\t%<size>1, %0";
943      case 7:
944        return "umov\t%w0, %1.<v>[0]";
945      case 8:
946        return "dup\t%0.<Vallxd>, %w1";
947      case 9:
948        return "dup\t%<Vetype>0, %1.<v>[0]";
949      default:
950        gcc_unreachable ();
951      }
953   [(set_attr "type" "mov_reg,mov_imm,neon_move,load1,load1,store1,store1,\
954                      neon_to_gp<q>,neon_from_gp<q>,neon_dup")
955    (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")]
958 (define_expand "mov<mode>"
959   [(set (match_operand:GPI 0 "nonimmediate_operand" "")
960         (match_operand:GPI 1 "general_operand" ""))]
961   ""
962   "
963     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
964       operands[1] = force_reg (<MODE>mode, operands[1]);
966     /* FIXME: RR we still need to fix up what we are doing with
967        symbol_refs and other types of constants.  */
968     if (CONSTANT_P (operands[1])
969         && !CONST_INT_P (operands[1]))
970      {
971        aarch64_expand_mov_immediate (operands[0], operands[1]);
972        DONE;
973      }
974   "
977 (define_insn_and_split "*movsi_aarch64"
978   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,r,*w,m,  m,r,r  ,*w, r,*w")
979         (match_operand:SI 1 "aarch64_mov_operand"  " r,r,k,M,n,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
980   "(register_operand (operands[0], SImode)
981     || aarch64_reg_or_zero (operands[1], SImode))"
982   "@
983    mov\\t%w0, %w1
984    mov\\t%w0, %w1
985    mov\\t%w0, %w1
986    mov\\t%w0, %1
987    #
988    ldr\\t%w0, %1
989    ldr\\t%s0, %1
990    str\\t%w1, %0
991    str\\t%s1, %0
992    adr\\t%x0, %a1
993    adrp\\t%x0, %A1
994    fmov\\t%s0, %w1
995    fmov\\t%w0, %s1
996    fmov\\t%s0, %s1"
997    "CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), SImode)
998     && GP_REGNUM_P (REGNO (operands[0]))"
999    [(const_int 0)]
1000    "{
1001        aarch64_expand_mov_immediate (operands[0], operands[1]);
1002        DONE;
1003     }"
1004   [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
1005                      adr,adr,f_mcr,f_mrc,fmov")
1006    (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
1009 (define_insn_and_split "*movdi_aarch64"
1010   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,r,*w,m,  m,r,r,  *w, r,*w,w")
1011         (match_operand:DI 1 "aarch64_mov_operand"  " r,r,k,N,n,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))]
1012   "(register_operand (operands[0], DImode)
1013     || aarch64_reg_or_zero (operands[1], DImode))"
1014   "@
1015    mov\\t%x0, %x1
1016    mov\\t%0, %x1
1017    mov\\t%x0, %1
1018    mov\\t%x0, %1
1019    #
1020    ldr\\t%x0, %1
1021    ldr\\t%d0, %1
1022    str\\t%x1, %0
1023    str\\t%d1, %0
1024    adr\\t%x0, %a1
1025    adrp\\t%x0, %A1
1026    fmov\\t%d0, %x1
1027    fmov\\t%x0, %d1
1028    fmov\\t%d0, %d1
1029    movi\\t%d0, %1"
1030    "(CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), DImode))
1031     && GP_REGNUM_P (REGNO (operands[0]))"
1032    [(const_int 0)]
1033    "{
1034        aarch64_expand_mov_immediate (operands[0], operands[1]);
1035        DONE;
1036     }"
1037   [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
1038                      adr,adr,f_mcr,f_mrc,fmov,neon_move")
1039    (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
1040    (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
1043 (define_insn "insv_imm<mode>"
1044   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
1045                           (const_int 16)
1046                           (match_operand:GPI 1 "const_int_operand" "n"))
1047         (match_operand:GPI 2 "const_int_operand" "n"))]
1048   "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
1049    && UINTVAL (operands[1]) % 16 == 0"
1050   "movk\\t%<w>0, %X2, lsl %1"
1051   [(set_attr "type" "mov_imm")]
1054 (define_expand "movti"
1055   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1056         (match_operand:TI 1 "general_operand" ""))]
1057   ""
1058   "
1059     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
1060       operands[1] = force_reg (TImode, operands[1]);
1061   "
1064 (define_insn "*movti_aarch64"
1065   [(set (match_operand:TI 0
1066          "nonimmediate_operand"  "=r, *w,r ,*w,r  ,Ump,Ump,*w,m")
1067         (match_operand:TI 1
1068          "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r  ,Z  , m,*w"))]
1069   "(register_operand (operands[0], TImode)
1070     || aarch64_reg_or_zero (operands[1], TImode))"
1071   "@
1072    #
1073    #
1074    #
1075    orr\\t%0.16b, %1.16b, %1.16b
1076    ldp\\t%0, %H0, %1
1077    stp\\t%1, %H1, %0
1078    stp\\txzr, xzr, %0
1079    ldr\\t%q0, %1
1080    str\\t%q1, %0"
1081   [(set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \
1082                              load2,store2,store2,f_loadd,f_stored")
1083    (set_attr "length" "8,8,8,4,4,4,4,4,4")
1084    (set_attr "simd" "*,*,*,yes,*,*,*,*,*")
1085    (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
1088 ;; Split a TImode register-register or register-immediate move into
1089 ;; its component DImode pieces, taking care to handle overlapping
1090 ;; source and dest registers.
1091 (define_split
1092    [(set (match_operand:TI 0 "register_operand" "")
1093          (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
1094   "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
1095   [(const_int 0)]
1097   aarch64_split_128bit_move (operands[0], operands[1]);
1098   DONE;
1101 (define_expand "mov<mode>"
1102   [(set (match_operand:GPF_TF_F16 0 "nonimmediate_operand" "")
1103         (match_operand:GPF_TF_F16 1 "general_operand" ""))]
1104   ""
1105   {
1106     if (!TARGET_FLOAT)
1107       {
1108         aarch64_err_no_fpadvsimd (<MODE>mode, "code");
1109         FAIL;
1110       }
1112     if (GET_CODE (operands[0]) == MEM
1113         && ! (GET_CODE (operands[1]) == CONST_DOUBLE
1114               && aarch64_float_const_zero_rtx_p (operands[1])))
1115       operands[1] = force_reg (<MODE>mode, operands[1]);
1116   }
1119 (define_insn "*movhf_aarch64"
1120   [(set (match_operand:HF 0 "nonimmediate_operand" "=w, ?r,w,w,m,r,m ,r")
1121         (match_operand:HF 1 "general_operand"      "?rY, w,w,m,w,m,rY,r"))]
1122   "TARGET_FLOAT && (register_operand (operands[0], HFmode)
1123     || register_operand (operands[1], HFmode))"
1124   "@
1125    mov\\t%0.h[0], %w1
1126    umov\\t%w0, %1.h[0]
1127    mov\\t%0.h[0], %1.h[0]
1128    ldr\\t%h0, %1
1129    str\\t%h1, %0
1130    ldrh\\t%w0, %1
1131    strh\\t%w1, %0
1132    mov\\t%w0, %w1"
1133   [(set_attr "type" "neon_from_gp,neon_to_gp,fmov,\
1134                      f_loads,f_stores,load1,store1,mov_reg")
1135    (set_attr "simd" "yes,yes,yes,*,*,*,*,*")
1136    (set_attr "fp"   "*,*,*,yes,yes,*,*,*")]
1139 (define_insn "*movsf_aarch64"
1140   [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w  ,w,m,r,m ,r")
1141         (match_operand:SF 1 "general_operand"      "?rY, w,w,Ufc,m,w,m,rY,r"))]
1142   "TARGET_FLOAT && (register_operand (operands[0], SFmode)
1143     || aarch64_reg_or_fp_zero (operands[1], SFmode))"
1144   "@
1145    fmov\\t%s0, %w1
1146    fmov\\t%w0, %s1
1147    fmov\\t%s0, %s1
1148    fmov\\t%s0, %1
1149    ldr\\t%s0, %1
1150    str\\t%s1, %0
1151    ldr\\t%w0, %1
1152    str\\t%w1, %0
1153    mov\\t%w0, %w1"
1154   [(set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
1155                      f_loads,f_stores,load1,store1,mov_reg")]
1158 (define_insn "*movdf_aarch64"
1159   [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w  ,w,m,r,m ,r")
1160         (match_operand:DF 1 "general_operand"      "?rY, w,w,Ufc,m,w,m,rY,r"))]
1161   "TARGET_FLOAT && (register_operand (operands[0], DFmode)
1162     || aarch64_reg_or_fp_zero (operands[1], DFmode))"
1163   "@
1164    fmov\\t%d0, %x1
1165    fmov\\t%x0, %d1
1166    fmov\\t%d0, %d1
1167    fmov\\t%d0, %1
1168    ldr\\t%d0, %1
1169    str\\t%d1, %0
1170    ldr\\t%x0, %1
1171    str\\t%x1, %0
1172    mov\\t%x0, %x1"
1173   [(set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
1174                      f_loadd,f_stored,load1,store1,mov_reg")]
1177 (define_insn "*movtf_aarch64"
1178   [(set (match_operand:TF 0
1179          "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump,Ump")
1180         (match_operand:TF 1
1181          "general_operand"      " w,?r, ?r,w ,Y,Y ,m,w,Ump,?r ,Y"))]
1182   "TARGET_FLOAT && (register_operand (operands[0], TFmode)
1183     || aarch64_reg_or_fp_zero (operands[1], TFmode))"
1184   "@
1185    orr\\t%0.16b, %1.16b, %1.16b
1186    #
1187    #
1188    #
1189    movi\\t%0.2d, #0
1190    fmov\\t%s0, wzr
1191    ldr\\t%q0, %1
1192    str\\t%q1, %0
1193    ldp\\t%0, %H0, %1
1194    stp\\t%1, %H1, %0
1195    stp\\txzr, xzr, %0"
1196   [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,neon_move_q,fconstd,\
1197                      f_loadd,f_stored,load2,store2,store2")
1198    (set_attr "length" "4,8,8,8,4,4,4,4,4,4,4")
1199    (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*,*")
1200    (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*,*")]
1203 (define_split
1204    [(set (match_operand:TF 0 "register_operand" "")
1205          (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
1206   "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
1207   [(const_int 0)]
1208   {
1209     aarch64_split_128bit_move (operands[0], operands[1]);
1210     DONE;
1211   }
1214 ;; 0 is dst
1215 ;; 1 is src
1216 ;; 2 is size of move in bytes
1217 ;; 3 is alignment
1219 (define_expand "movmemdi"
1220   [(match_operand:BLK 0 "memory_operand")
1221    (match_operand:BLK 1 "memory_operand")
1222    (match_operand:DI 2 "immediate_operand")
1223    (match_operand:DI 3 "immediate_operand")]
1224    "!STRICT_ALIGNMENT"
1226   if (aarch64_expand_movmem (operands))
1227     DONE;
1228   FAIL;
1232 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1233 ;; fairly lax checking on the second memory operation.
1234 (define_insn "load_pairsi"
1235   [(set (match_operand:SI 0 "register_operand" "=r,*w")
1236         (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1237    (set (match_operand:SI 2 "register_operand" "=r,*w")
1238         (match_operand:SI 3 "memory_operand" "m,m"))]
1239   "rtx_equal_p (XEXP (operands[3], 0),
1240                 plus_constant (Pmode,
1241                                XEXP (operands[1], 0),
1242                                GET_MODE_SIZE (SImode)))"
1243   "@
1244    ldp\\t%w0, %w2, %1
1245    ldp\\t%s0, %s2, %1"
1246   [(set_attr "type" "load2,neon_load1_2reg")
1247    (set_attr "fp" "*,yes")]
1250 (define_insn "load_pairdi"
1251   [(set (match_operand:DI 0 "register_operand" "=r,*w")
1252         (match_operand:DI 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1253    (set (match_operand:DI 2 "register_operand" "=r,*w")
1254         (match_operand:DI 3 "memory_operand" "m,m"))]
1255   "rtx_equal_p (XEXP (operands[3], 0),
1256                 plus_constant (Pmode,
1257                                XEXP (operands[1], 0),
1258                                GET_MODE_SIZE (DImode)))"
1259   "@
1260    ldp\\t%x0, %x2, %1
1261    ldp\\t%d0, %d2, %1"
1262   [(set_attr "type" "load2,neon_load1_2reg")
1263    (set_attr "fp" "*,yes")]
1267 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1268 ;; fairly lax checking on the second memory operation.
1269 (define_insn "store_pairsi"
1270   [(set (match_operand:SI 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1271         (match_operand:SI 1 "aarch64_reg_or_zero" "rZ,*w"))
1272    (set (match_operand:SI 2 "memory_operand" "=m,m")
1273         (match_operand:SI 3 "aarch64_reg_or_zero" "rZ,*w"))]
1274   "rtx_equal_p (XEXP (operands[2], 0),
1275                 plus_constant (Pmode,
1276                                XEXP (operands[0], 0),
1277                                GET_MODE_SIZE (SImode)))"
1278   "@
1279    stp\\t%w1, %w3, %0
1280    stp\\t%s1, %s3, %0"
1281   [(set_attr "type" "store2,neon_store1_2reg")
1282    (set_attr "fp" "*,yes")]
1285 (define_insn "store_pairdi"
1286   [(set (match_operand:DI 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1287         (match_operand:DI 1 "aarch64_reg_or_zero" "rZ,*w"))
1288    (set (match_operand:DI 2 "memory_operand" "=m,m")
1289         (match_operand:DI 3 "aarch64_reg_or_zero" "rZ,*w"))]
1290   "rtx_equal_p (XEXP (operands[2], 0),
1291                 plus_constant (Pmode,
1292                                XEXP (operands[0], 0),
1293                                GET_MODE_SIZE (DImode)))"
1294   "@
1295    stp\\t%x1, %x3, %0
1296    stp\\t%d1, %d3, %0"
1297   [(set_attr "type" "store2,neon_store1_2reg")
1298    (set_attr "fp" "*,yes")]
1301 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1302 ;; fairly lax checking on the second memory operation.
1303 (define_insn "load_pairsf"
1304   [(set (match_operand:SF 0 "register_operand" "=w,*r")
1305         (match_operand:SF 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1306    (set (match_operand:SF 2 "register_operand" "=w,*r")
1307         (match_operand:SF 3 "memory_operand" "m,m"))]
1308   "rtx_equal_p (XEXP (operands[3], 0),
1309                 plus_constant (Pmode,
1310                                XEXP (operands[1], 0),
1311                                GET_MODE_SIZE (SFmode)))"
1312   "@
1313    ldp\\t%s0, %s2, %1
1314    ldp\\t%w0, %w2, %1"
1315   [(set_attr "type" "neon_load1_2reg,load2")
1316    (set_attr "fp" "yes,*")]
1319 (define_insn "load_pairdf"
1320   [(set (match_operand:DF 0 "register_operand" "=w,*r")
1321         (match_operand:DF 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1322    (set (match_operand:DF 2 "register_operand" "=w,*r")
1323         (match_operand:DF 3 "memory_operand" "m,m"))]
1324   "rtx_equal_p (XEXP (operands[3], 0),
1325                 plus_constant (Pmode,
1326                                XEXP (operands[1], 0),
1327                                GET_MODE_SIZE (DFmode)))"
1328   "@
1329    ldp\\t%d0, %d2, %1
1330    ldp\\t%x0, %x2, %1"
1331   [(set_attr "type" "neon_load1_2reg,load2")
1332    (set_attr "fp" "yes,*")]
1335 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1336 ;; fairly lax checking on the second memory operation.
1337 (define_insn "store_pairsf"
1338   [(set (match_operand:SF 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1339         (match_operand:SF 1 "register_operand" "w,*r"))
1340    (set (match_operand:SF 2 "memory_operand" "=m,m")
1341         (match_operand:SF 3 "register_operand" "w,*r"))]
1342   "rtx_equal_p (XEXP (operands[2], 0),
1343                 plus_constant (Pmode,
1344                                XEXP (operands[0], 0),
1345                                GET_MODE_SIZE (SFmode)))"
1346   "@
1347    stp\\t%s1, %s3, %0
1348    stp\\t%w1, %w3, %0"
1349   [(set_attr "type" "neon_store1_2reg,store2")
1350    (set_attr "fp" "yes,*")]
1353 (define_insn "store_pairdf"
1354   [(set (match_operand:DF 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1355         (match_operand:DF 1 "register_operand" "w,*r"))
1356    (set (match_operand:DF 2 "memory_operand" "=m,m")
1357         (match_operand:DF 3 "register_operand" "w,*r"))]
1358   "rtx_equal_p (XEXP (operands[2], 0),
1359                 plus_constant (Pmode,
1360                                XEXP (operands[0], 0),
1361                                GET_MODE_SIZE (DFmode)))"
1362   "@
1363    stp\\t%d1, %d3, %0
1364    stp\\t%x1, %x3, %0"
1365   [(set_attr "type" "neon_store1_2reg,store2")
1366    (set_attr "fp" "yes,*")]
1369 ;; Load pair with post-index writeback.  This is primarily used in function
1370 ;; epilogues.
1371 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
1372   [(parallel
1373     [(set (match_operand:P 0 "register_operand" "=k")
1374           (plus:P (match_operand:P 1 "register_operand" "0")
1375                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1376      (set (match_operand:GPI 2 "register_operand" "=r")
1377           (mem:GPI (match_dup 1)))
1378      (set (match_operand:GPI 3 "register_operand" "=r")
1379           (mem:GPI (plus:P (match_dup 1)
1380                    (match_operand:P 5 "const_int_operand" "n"))))])]
1381   "INTVAL (operands[5]) == GET_MODE_SIZE (<GPI:MODE>mode)"
1382   "ldp\\t%<w>2, %<w>3, [%1], %4"
1383   [(set_attr "type" "load2")]
1386 (define_insn "loadwb_pair<GPF:mode>_<P:mode>"
1387   [(parallel
1388     [(set (match_operand:P 0 "register_operand" "=k")
1389           (plus:P (match_operand:P 1 "register_operand" "0")
1390                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1391      (set (match_operand:GPF 2 "register_operand" "=w")
1392           (mem:GPF (match_dup 1)))
1393      (set (match_operand:GPF 3 "register_operand" "=w")
1394           (mem:GPF (plus:P (match_dup 1)
1395                    (match_operand:P 5 "const_int_operand" "n"))))])]
1396   "INTVAL (operands[5]) == GET_MODE_SIZE (<GPF:MODE>mode)"
1397   "ldp\\t%<w>2, %<w>3, [%1], %4"
1398   [(set_attr "type" "neon_load1_2reg")]
1401 ;; Store pair with pre-index writeback.  This is primarily used in function
1402 ;; prologues.
1403 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
1404   [(parallel
1405     [(set (match_operand:P 0 "register_operand" "=&k")
1406           (plus:P (match_operand:P 1 "register_operand" "0")
1407                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1408      (set (mem:GPI (plus:P (match_dup 0)
1409                    (match_dup 4)))
1410           (match_operand:GPI 2 "register_operand" "r"))
1411      (set (mem:GPI (plus:P (match_dup 0)
1412                    (match_operand:P 5 "const_int_operand" "n")))
1413           (match_operand:GPI 3 "register_operand" "r"))])]
1414   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1415   "stp\\t%<w>2, %<w>3, [%0, %4]!"
1416   [(set_attr "type" "store2")]
1419 (define_insn "storewb_pair<GPF:mode>_<P:mode>"
1420   [(parallel
1421     [(set (match_operand:P 0 "register_operand" "=&k")
1422           (plus:P (match_operand:P 1 "register_operand" "0")
1423                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1424      (set (mem:GPF (plus:P (match_dup 0)
1425                    (match_dup 4)))
1426           (match_operand:GPF 2 "register_operand" "w"))
1427      (set (mem:GPF (plus:P (match_dup 0)
1428                    (match_operand:P 5 "const_int_operand" "n")))
1429           (match_operand:GPF 3 "register_operand" "w"))])]
1430   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPF:MODE>mode)"
1431   "stp\\t%<w>2, %<w>3, [%0, %4]!"
1432   [(set_attr "type" "neon_store1_2reg<q>")]
1435 ;; -------------------------------------------------------------------
1436 ;; Sign/Zero extension
1437 ;; -------------------------------------------------------------------
1439 (define_expand "<optab>sidi2"
1440   [(set (match_operand:DI 0 "register_operand")
1441         (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1442   ""
1445 (define_insn "*extendsidi2_aarch64"
1446   [(set (match_operand:DI 0 "register_operand" "=r,r")
1447         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1448   ""
1449   "@
1450    sxtw\t%0, %w1
1451    ldrsw\t%0, %1"
1452   [(set_attr "type" "extend,load1")]
1455 (define_insn "*load_pair_extendsidi2_aarch64"
1456   [(set (match_operand:DI 0 "register_operand" "=r")
1457         (sign_extend:DI (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump")))
1458    (set (match_operand:DI 2 "register_operand" "=r")
1459         (sign_extend:DI (match_operand:SI 3 "memory_operand" "m")))]
1460   "rtx_equal_p (XEXP (operands[3], 0),
1461                 plus_constant (Pmode,
1462                                XEXP (operands[1], 0),
1463                                GET_MODE_SIZE (SImode)))"
1464   "ldpsw\\t%0, %2, %1"
1465   [(set_attr "type" "load2")]
1468 (define_insn "*zero_extendsidi2_aarch64"
1469   [(set (match_operand:DI 0 "register_operand" "=r,r")
1470         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1471   ""
1472   "@
1473    uxtw\t%0, %w1
1474    ldr\t%w0, %1"
1475   [(set_attr "type" "extend,load1")]
1478 (define_insn "*load_pair_zero_extendsidi2_aarch64"
1479   [(set (match_operand:DI 0 "register_operand" "=r")
1480         (zero_extend:DI (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump")))
1481    (set (match_operand:DI 2 "register_operand" "=r")
1482         (zero_extend:DI (match_operand:SI 3 "memory_operand" "m")))]
1483   "rtx_equal_p (XEXP (operands[3], 0),
1484                 plus_constant (Pmode,
1485                                XEXP (operands[1], 0),
1486                                GET_MODE_SIZE (SImode)))"
1487   "ldp\\t%w0, %w2, %1"
1488   [(set_attr "type" "load2")]
1491 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1492   [(set (match_operand:GPI 0 "register_operand")
1493         (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1494   ""
1497 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1498   [(set (match_operand:GPI 0 "register_operand" "=r,r")
1499         (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1500   ""
1501   "@
1502    sxt<SHORT:size>\t%<GPI:w>0, %w1
1503    ldrs<SHORT:size>\t%<GPI:w>0, %1"
1504   [(set_attr "type" "extend,load1")]
1507 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1508   [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1509         (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1510   ""
1511   "@
1512    uxt<SHORT:size>\t%<GPI:w>0, %w1
1513    ldr<SHORT:size>\t%w0, %1
1514    ldr\t%<SHORT:size>0, %1"
1515   [(set_attr "type" "extend,load1,load1")]
1518 (define_expand "<optab>qihi2"
1519   [(set (match_operand:HI 0 "register_operand")
1520         (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1521   ""
1524 (define_insn "*<optab>qihi2_aarch64"
1525   [(set (match_operand:HI 0 "register_operand" "=r,r")
1526         (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1527   ""
1528   "@
1529    <su>xtb\t%w0, %w1
1530    <ldrxt>b\t%w0, %1"
1531   [(set_attr "type" "extend,load1")]
1534 ;; -------------------------------------------------------------------
1535 ;; Simple arithmetic
1536 ;; -------------------------------------------------------------------
1538 (define_expand "add<mode>3"
1539   [(set
1540     (match_operand:GPI 0 "register_operand" "")
1541     (plus:GPI (match_operand:GPI 1 "register_operand" "")
1542               (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1543   ""
1544   "
1545   if (! aarch64_plus_operand (operands[2], VOIDmode))
1546     {
1547       HOST_WIDE_INT imm = INTVAL (operands[2]);
1549       if (aarch64_move_imm (imm, <MODE>mode) && can_create_pseudo_p ())
1550         {
1551           rtx tmp = gen_reg_rtx (<MODE>mode);
1552           emit_move_insn (tmp, operands[2]);
1553           operands[2] = tmp;
1554         }
1555       else
1556         {
1557           rtx subtarget = ((optimize && can_create_pseudo_p ())
1558                            ? gen_reg_rtx (<MODE>mode) : operands[0]);
1560           if (imm < 0)
1561             imm = -(-imm & ~0xfff);
1562           else
1563             imm &= ~0xfff;
1565           emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1566           operands[1] = subtarget;
1567           operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1568         }
1569     }
1570   "
1573 (define_insn "*addsi3_aarch64"
1574   [(set
1575     (match_operand:SI 0 "register_operand" "=rk,rk,w,rk")
1576     (plus:SI
1577      (match_operand:SI 1 "register_operand" "%rk,rk,w,rk")
1578      (match_operand:SI 2 "aarch64_plus_operand" "I,r,w,J")))]
1579   ""
1580   "@
1581   add\\t%w0, %w1, %2
1582   add\\t%w0, %w1, %w2
1583   add\\t%0.2s, %1.2s, %2.2s
1584   sub\\t%w0, %w1, #%n2"
1585   [(set_attr "type" "alu_imm,alu_sreg,neon_add,alu_imm")
1586    (set_attr "simd" "*,*,yes,*")]
1589 ;; zero_extend version of above
1590 (define_insn "*addsi3_aarch64_uxtw"
1591   [(set
1592     (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1593     (zero_extend:DI
1594      (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1595               (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1596   ""
1597   "@
1598   add\\t%w0, %w1, %2
1599   add\\t%w0, %w1, %w2
1600   sub\\t%w0, %w1, #%n2"
1601   [(set_attr "type" "alu_imm,alu_sreg,alu_imm")]
1604 (define_insn "*adddi3_aarch64"
1605   [(set
1606     (match_operand:DI 0 "register_operand" "=rk,rk,rk,w")
1607     (plus:DI
1608      (match_operand:DI 1 "register_operand" "%rk,rk,rk,w")
1609      (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,w")))]
1610   ""
1611   "@
1612   add\\t%x0, %x1, %2
1613   add\\t%x0, %x1, %x2
1614   sub\\t%x0, %x1, #%n2
1615   add\\t%d0, %d1, %d2"
1616   [(set_attr "type" "alu_imm,alu_sreg,alu_imm,neon_add")
1617    (set_attr "simd" "*,*,*,yes")]
1620 (define_expand "addti3"
1621   [(set (match_operand:TI 0 "register_operand" "")
1622         (plus:TI (match_operand:TI 1 "register_operand" "")
1623                  (match_operand:TI 2 "register_operand" "")))]
1624   ""
1626   rtx low = gen_reg_rtx (DImode);
1627   emit_insn (gen_adddi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1628                                   gen_lowpart (DImode, operands[2])));
1630   rtx high = gen_reg_rtx (DImode);
1631   emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]),
1632                                  gen_highpart (DImode, operands[2])));
1634   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1635   emit_move_insn (gen_highpart (DImode, operands[0]), high);
1636   DONE;
1639 (define_insn "add<mode>3_compare0"
1640   [(set (reg:CC_NZ CC_REGNUM)
1641         (compare:CC_NZ
1642          (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1643                    (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1644          (const_int 0)))
1645    (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1646         (plus:GPI (match_dup 1) (match_dup 2)))]
1647   ""
1648   "@
1649   adds\\t%<w>0, %<w>1, %<w>2
1650   adds\\t%<w>0, %<w>1, %<w>2
1651   subs\\t%<w>0, %<w>1, #%n2"
1652   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1655 ;; zero_extend version of above
1656 (define_insn "*addsi3_compare0_uxtw"
1657   [(set (reg:CC_NZ CC_REGNUM)
1658         (compare:CC_NZ
1659          (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1660                   (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1661          (const_int 0)))
1662    (set (match_operand:DI 0 "register_operand" "=r,r,r")
1663         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1664   ""
1665   "@
1666   adds\\t%w0, %w1, %w2
1667   adds\\t%w0, %w1, %w2
1668   subs\\t%w0, %w1, #%n2"
1669   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1672 (define_insn "*adds_shift_imm_<mode>"
1673   [(set (reg:CC_NZ CC_REGNUM)
1674         (compare:CC_NZ
1675          (plus:GPI (ASHIFT:GPI 
1676                     (match_operand:GPI 1 "register_operand" "r")
1677                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1678                    (match_operand:GPI 3 "register_operand" "r"))
1679          (const_int 0)))
1680    (set (match_operand:GPI 0 "register_operand" "=r")
1681         (plus:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))
1682                   (match_dup 3)))]
1683   ""
1684   "adds\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1685   [(set_attr "type" "alus_shift_imm")]
1688 (define_insn "*subs_shift_imm_<mode>"
1689   [(set (reg:CC_NZ CC_REGNUM)
1690         (compare:CC_NZ
1691          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1692                     (ASHIFT:GPI
1693                      (match_operand:GPI 2 "register_operand" "r")
1694                      (match_operand:QI 3 "aarch64_shift_imm_<mode>" "n")))
1695          (const_int 0)))
1696    (set (match_operand:GPI 0 "register_operand" "=r")
1697         (minus:GPI (match_dup 1)
1698                    (ASHIFT:GPI (match_dup 2) (match_dup 3))))]
1699   ""
1700   "subs\\t%<w>0, %<w>1, %<w>2, <shift> %3"
1701   [(set_attr "type" "alus_shift_imm")]
1704 (define_insn "*adds_mul_imm_<mode>"
1705   [(set (reg:CC_NZ CC_REGNUM)
1706         (compare:CC_NZ
1707          (plus:GPI (mult:GPI
1708                     (match_operand:GPI 1 "register_operand" "r")
1709                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1710                    (match_operand:GPI 3 "register_operand" "r"))
1711          (const_int 0)))
1712    (set (match_operand:GPI 0 "register_operand" "=r")
1713         (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1714                   (match_dup 3)))]
1715   ""
1716   "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1717   [(set_attr "type" "alus_shift_imm")]
1720 (define_insn "*subs_mul_imm_<mode>"
1721   [(set (reg:CC_NZ CC_REGNUM)
1722         (compare:CC_NZ
1723          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1724                     (mult:GPI
1725                      (match_operand:GPI 2 "register_operand" "r")
1726                      (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1727          (const_int 0)))
1728    (set (match_operand:GPI 0 "register_operand" "=r")
1729         (minus:GPI (match_dup 1)
1730                    (mult:GPI (match_dup 2) (match_dup 3))))]
1731   ""
1732   "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1733   [(set_attr "type" "alus_shift_imm")]
1736 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1737   [(set (reg:CC_NZ CC_REGNUM)
1738         (compare:CC_NZ
1739          (plus:GPI
1740           (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1741           (match_operand:GPI 2 "register_operand" "r"))
1742         (const_int 0)))
1743    (set (match_operand:GPI 0 "register_operand" "=r")
1744         (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1745   ""
1746   "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1747   [(set_attr "type" "alus_ext")]
1750 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1751   [(set (reg:CC_NZ CC_REGNUM)
1752         (compare:CC_NZ
1753          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1754                     (ANY_EXTEND:GPI
1755                      (match_operand:ALLX 2 "register_operand" "r")))
1756         (const_int 0)))
1757    (set (match_operand:GPI 0 "register_operand" "=r")
1758         (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1759   ""
1760   "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1761   [(set_attr "type" "alus_ext")]
1764 (define_insn "*adds_<optab><ALLX:mode>_shift_<GPI:mode>"
1765   [(set (reg:CC_NZ CC_REGNUM)
1766         (compare:CC_NZ
1767          (plus:GPI (ashift:GPI 
1768                     (ANY_EXTEND:GPI 
1769                      (match_operand:ALLX 1 "register_operand" "r"))
1770                     (match_operand 2 "aarch64_imm3" "Ui3"))
1771                    (match_operand:GPI 3 "register_operand" "r"))
1772          (const_int 0)))
1773    (set (match_operand:GPI 0 "register_operand" "=rk")
1774         (plus:GPI (ashift:GPI (ANY_EXTEND:GPI (match_dup 1))
1775                               (match_dup 2))
1776                   (match_dup 3)))]
1777   ""
1778   "adds\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1779   [(set_attr "type" "alus_ext")]
1782 (define_insn "*subs_<optab><ALLX:mode>_shift_<GPI:mode>"
1783   [(set (reg:CC_NZ CC_REGNUM)
1784         (compare:CC_NZ
1785          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1786                     (ashift:GPI 
1787                      (ANY_EXTEND:GPI
1788                       (match_operand:ALLX 2 "register_operand" "r"))
1789                      (match_operand 3 "aarch64_imm3" "Ui3")))
1790          (const_int 0)))
1791    (set (match_operand:GPI 0 "register_operand" "=rk")
1792         (minus:GPI (match_dup 1)
1793                    (ashift:GPI (ANY_EXTEND:GPI (match_dup 2))
1794                                (match_dup 3))))]
1795   ""
1796   "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1797   [(set_attr "type" "alus_ext")]
1800 (define_insn "*adds_<optab><mode>_multp2"
1801   [(set (reg:CC_NZ CC_REGNUM)
1802         (compare:CC_NZ
1803          (plus:GPI (ANY_EXTRACT:GPI
1804                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1805                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1806                     (match_operand 3 "const_int_operand" "n")
1807                     (const_int 0))
1808                    (match_operand:GPI 4 "register_operand" "r"))
1809         (const_int 0)))
1810    (set (match_operand:GPI 0 "register_operand" "=r")
1811         (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1812                                    (match_dup 3)
1813                                    (const_int 0))
1814                   (match_dup 4)))]
1815   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1816   "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1817   [(set_attr "type" "alus_ext")]
1820 (define_insn "*subs_<optab><mode>_multp2"
1821   [(set (reg:CC_NZ CC_REGNUM)
1822         (compare:CC_NZ
1823          (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1824                     (ANY_EXTRACT:GPI
1825                      (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1826                                (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1827                      (match_operand 3 "const_int_operand" "n")
1828                      (const_int 0)))
1829         (const_int 0)))
1830    (set (match_operand:GPI 0 "register_operand" "=r")
1831         (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1832                                   (mult:GPI (match_dup 1) (match_dup 2))
1833                                   (match_dup 3)
1834                                   (const_int 0))))]
1835   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1836   "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1837   [(set_attr "type" "alus_ext")]
1840 (define_insn "*add<mode>3nr_compare0"
1841   [(set (reg:CC_NZ CC_REGNUM)
1842         (compare:CC_NZ
1843          (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1844                    (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1845          (const_int 0)))]
1846   ""
1847   "@
1848   cmn\\t%<w>0, %<w>1
1849   cmn\\t%<w>0, %<w>1
1850   cmp\\t%<w>0, #%n1"
1851   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1854 (define_insn "*compare_neg<mode>"
1855   [(set (reg:CC_Z CC_REGNUM)
1856         (compare:CC_Z
1857          (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1858          (match_operand:GPI 1 "register_operand" "r")))]
1859   ""
1860   "cmn\\t%<w>1, %<w>0"
1861   [(set_attr "type" "alus_sreg")]
1864 (define_insn "*add_<shift>_<mode>"
1865   [(set (match_operand:GPI 0 "register_operand" "=r")
1866         (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1867                               (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1868                   (match_operand:GPI 3 "register_operand" "r")))]
1869   ""
1870   "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1871   [(set_attr "type" "alu_shift_imm")]
1874 ;; zero_extend version of above
1875 (define_insn "*add_<shift>_si_uxtw"
1876   [(set (match_operand:DI 0 "register_operand" "=r")
1877         (zero_extend:DI
1878          (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1879                              (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1880                   (match_operand:SI 3 "register_operand" "r"))))]
1881   ""
1882   "add\\t%w0, %w3, %w1, <shift> %2"
1883   [(set_attr "type" "alu_shift_imm")]
1886 (define_insn "*add_mul_imm_<mode>"
1887   [(set (match_operand:GPI 0 "register_operand" "=r")
1888         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1889                             (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1890                   (match_operand:GPI 3 "register_operand" "r")))]
1891   ""
1892   "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1893   [(set_attr "type" "alu_shift_imm")]
1896 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1897   [(set (match_operand:GPI 0 "register_operand" "=rk")
1898         (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1899                   (match_operand:GPI 2 "register_operand" "r")))]
1900   ""
1901   "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1902   [(set_attr "type" "alu_ext")]
1905 ;; zero_extend version of above
1906 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1907   [(set (match_operand:DI 0 "register_operand" "=rk")
1908         (zero_extend:DI
1909          (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1910                   (match_operand:GPI 2 "register_operand" "r"))))]
1911   ""
1912   "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1913   [(set_attr "type" "alu_ext")]
1916 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1917   [(set (match_operand:GPI 0 "register_operand" "=rk")
1918         (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1919                                (match_operand:ALLX 1 "register_operand" "r"))
1920                               (match_operand 2 "aarch64_imm3" "Ui3"))
1921                   (match_operand:GPI 3 "register_operand" "r")))]
1922   ""
1923   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1924   [(set_attr "type" "alu_ext")]
1927 ;; zero_extend version of above
1928 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1929   [(set (match_operand:DI 0 "register_operand" "=rk")
1930         (zero_extend:DI
1931          (plus:SI (ashift:SI (ANY_EXTEND:SI
1932                               (match_operand:SHORT 1 "register_operand" "r"))
1933                              (match_operand 2 "aarch64_imm3" "Ui3"))
1934                   (match_operand:SI 3 "register_operand" "r"))))]
1935   ""
1936   "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1937   [(set_attr "type" "alu_ext")]
1940 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1941   [(set (match_operand:GPI 0 "register_operand" "=rk")
1942         (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1943                              (match_operand:ALLX 1 "register_operand" "r"))
1944                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1945                   (match_operand:GPI 3 "register_operand" "r")))]
1946   ""
1947   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1948   [(set_attr "type" "alu_ext")]
1951 ;; zero_extend version of above
1952 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1953   [(set (match_operand:DI 0 "register_operand" "=rk")
1954         (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1955                              (match_operand:SHORT 1 "register_operand" "r"))
1956                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1957                   (match_operand:SI 3 "register_operand" "r"))))]
1958   ""
1959   "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1960   [(set_attr "type" "alu_ext")]
1963 (define_insn "*add_<optab><mode>_multp2"
1964   [(set (match_operand:GPI 0 "register_operand" "=rk")
1965         (plus:GPI (ANY_EXTRACT:GPI
1966                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1967                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1968                    (match_operand 3 "const_int_operand" "n")
1969                    (const_int 0))
1970                   (match_operand:GPI 4 "register_operand" "r")))]
1971   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1972   "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1973   [(set_attr "type" "alu_ext")]
1976 ;; zero_extend version of above
1977 (define_insn "*add_<optab>si_multp2_uxtw"
1978   [(set (match_operand:DI 0 "register_operand" "=rk")
1979         (zero_extend:DI
1980          (plus:SI (ANY_EXTRACT:SI
1981                    (mult:SI (match_operand:SI 1 "register_operand" "r")
1982                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1983                    (match_operand 3 "const_int_operand" "n")
1984                    (const_int 0))
1985                   (match_operand:SI 4 "register_operand" "r"))))]
1986   "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1987   "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1988   [(set_attr "type" "alu_ext")]
1991 (define_insn "add<mode>3_carryin"
1992   [(set
1993     (match_operand:GPI 0 "register_operand" "=r")
1994     (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1995               (plus:GPI
1996                 (match_operand:GPI 1 "register_operand" "r")
1997                 (match_operand:GPI 2 "register_operand" "r"))))]
1998    ""
1999    "adc\\t%<w>0, %<w>1, %<w>2"
2000   [(set_attr "type" "adc_reg")]
2003 ;; zero_extend version of above
2004 (define_insn "*addsi3_carryin_uxtw"
2005   [(set
2006     (match_operand:DI 0 "register_operand" "=r")
2007     (zero_extend:DI
2008      (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
2009               (plus:SI
2010                (match_operand:SI 1 "register_operand" "r")
2011                (match_operand:SI 2 "register_operand" "r")))))]
2012    ""
2013    "adc\\t%w0, %w1, %w2"
2014   [(set_attr "type" "adc_reg")]
2017 (define_insn "*add<mode>3_carryin_alt1"
2018   [(set
2019     (match_operand:GPI 0 "register_operand" "=r")
2020     (plus:GPI (plus:GPI
2021                 (match_operand:GPI 1 "register_operand" "r")
2022                 (match_operand:GPI 2 "register_operand" "r"))
2023               (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
2024    ""
2025    "adc\\t%<w>0, %<w>1, %<w>2"
2026   [(set_attr "type" "adc_reg")]
2029 ;; zero_extend version of above
2030 (define_insn "*addsi3_carryin_alt1_uxtw"
2031   [(set
2032     (match_operand:DI 0 "register_operand" "=r")
2033     (zero_extend:DI
2034      (plus:SI (plus:SI
2035                (match_operand:SI 1 "register_operand" "r")
2036                (match_operand:SI 2 "register_operand" "r"))
2037               (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
2038    ""
2039    "adc\\t%w0, %w1, %w2"
2040   [(set_attr "type" "adc_reg")]
2043 (define_insn "*add<mode>3_carryin_alt2"
2044   [(set
2045     (match_operand:GPI 0 "register_operand" "=r")
2046     (plus:GPI (plus:GPI
2047                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
2048                 (match_operand:GPI 1 "register_operand" "r"))
2049               (match_operand:GPI 2 "register_operand" "r")))]
2050    ""
2051    "adc\\t%<w>0, %<w>1, %<w>2"
2052   [(set_attr "type" "adc_reg")]
2055 ;; zero_extend version of above
2056 (define_insn "*addsi3_carryin_alt2_uxtw"
2057   [(set
2058     (match_operand:DI 0 "register_operand" "=r")
2059     (zero_extend:DI
2060      (plus:SI (plus:SI
2061                (geu:SI (reg:CC CC_REGNUM) (const_int 0))
2062                (match_operand:SI 1 "register_operand" "r"))
2063               (match_operand:SI 2 "register_operand" "r"))))]
2064    ""
2065    "adc\\t%w0, %w1, %w2"
2066   [(set_attr "type" "adc_reg")]
2069 (define_insn "*add<mode>3_carryin_alt3"
2070   [(set
2071     (match_operand:GPI 0 "register_operand" "=r")
2072     (plus:GPI (plus:GPI
2073                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
2074                 (match_operand:GPI 2 "register_operand" "r"))
2075               (match_operand:GPI 1 "register_operand" "r")))]
2076    ""
2077    "adc\\t%<w>0, %<w>1, %<w>2"
2078   [(set_attr "type" "adc_reg")]
2081 ;; zero_extend version of above
2082 (define_insn "*addsi3_carryin_alt3_uxtw"
2083   [(set
2084     (match_operand:DI 0 "register_operand" "=r")
2085     (zero_extend:DI
2086      (plus:SI (plus:SI
2087                (geu:SI (reg:CC CC_REGNUM) (const_int 0))
2088                (match_operand:SI 2 "register_operand" "r"))
2089               (match_operand:SI 1 "register_operand" "r"))))]
2090    ""
2091    "adc\\t%w0, %w1, %w2"
2092   [(set_attr "type" "adc_reg")]
2095 (define_insn "*add_uxt<mode>_shift2"
2096   [(set (match_operand:GPI 0 "register_operand" "=rk")
2097         (plus:GPI (and:GPI
2098                    (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
2099                                (match_operand 2 "aarch64_imm3" "Ui3"))
2100                    (match_operand 3 "const_int_operand" "n"))
2101                   (match_operand:GPI 4 "register_operand" "r")))]
2102   "aarch64_uxt_size (INTVAL (operands[2]), INTVAL (operands[3])) != 0"
2103   "*
2104   operands[3] = GEN_INT (aarch64_uxt_size (INTVAL(operands[2]),
2105                                            INTVAL (operands[3])));
2106   return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %2\";"
2107   [(set_attr "type" "alu_ext")]
2110 ;; zero_extend version of above
2111 (define_insn "*add_uxtsi_shift2_uxtw"
2112   [(set (match_operand:DI 0 "register_operand" "=rk")
2113         (zero_extend:DI
2114          (plus:SI (and:SI
2115                    (ashift:SI (match_operand:SI 1 "register_operand" "r")
2116                               (match_operand 2 "aarch64_imm3" "Ui3"))
2117                    (match_operand 3 "const_int_operand" "n"))
2118                   (match_operand:SI 4 "register_operand" "r"))))]
2119   "aarch64_uxt_size (INTVAL (operands[2]), INTVAL (operands[3])) != 0"
2120   "*
2121   operands[3] = GEN_INT (aarch64_uxt_size (INTVAL (operands[2]),
2122                                            INTVAL (operands[3])));
2123   return \"add\t%w0, %w4, %w1, uxt%e3 %2\";"
2124   [(set_attr "type" "alu_ext")]
2127 (define_insn "*add_uxt<mode>_multp2"
2128   [(set (match_operand:GPI 0 "register_operand" "=rk")
2129         (plus:GPI (and:GPI
2130                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2131                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2132                    (match_operand 3 "const_int_operand" "n"))
2133                   (match_operand:GPI 4 "register_operand" "r")))]
2134   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
2135   "*
2136   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2137                                            INTVAL (operands[3])));
2138   return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
2139   [(set_attr "type" "alu_ext")]
2142 ;; zero_extend version of above
2143 (define_insn "*add_uxtsi_multp2_uxtw"
2144   [(set (match_operand:DI 0 "register_operand" "=rk")
2145         (zero_extend:DI
2146          (plus:SI (and:SI
2147                    (mult:SI (match_operand:SI 1 "register_operand" "r")
2148                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2149                    (match_operand 3 "const_int_operand" "n"))
2150                   (match_operand:SI 4 "register_operand" "r"))))]
2151   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
2152   "*
2153   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2154                                            INTVAL (operands[3])));
2155   return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
2156   [(set_attr "type" "alu_ext")]
2159 (define_insn "subsi3"
2160   [(set (match_operand:SI 0 "register_operand" "=rk")
2161         (minus:SI (match_operand:SI 1 "register_operand" "rk")
2162                   (match_operand:SI 2 "register_operand" "r")))]
2163   ""
2164   "sub\\t%w0, %w1, %w2"
2165   [(set_attr "type" "alu_sreg")]
2168 ;; zero_extend version of above
2169 (define_insn "*subsi3_uxtw"
2170   [(set (match_operand:DI 0 "register_operand" "=rk")
2171         (zero_extend:DI
2172          (minus:SI (match_operand:SI 1 "register_operand" "rk")
2173                    (match_operand:SI 2 "register_operand" "r"))))]
2174   ""
2175   "sub\\t%w0, %w1, %w2"
2176   [(set_attr "type" "alu_sreg")]
2179 (define_insn "subdi3"
2180   [(set (match_operand:DI 0 "register_operand" "=rk,w")
2181         (minus:DI (match_operand:DI 1 "register_operand" "rk,w")
2182                   (match_operand:DI 2 "register_operand" "r,w")))]
2183   ""
2184   "@
2185    sub\\t%x0, %x1, %x2
2186    sub\\t%d0, %d1, %d2"
2187   [(set_attr "type" "alu_sreg, neon_sub")
2188    (set_attr "simd" "*,yes")]
2191 (define_expand "subti3"
2192   [(set (match_operand:TI 0 "register_operand" "")
2193         (minus:TI (match_operand:TI 1 "register_operand" "")
2194                   (match_operand:TI 2 "register_operand" "")))]
2195   ""
2197   rtx low = gen_reg_rtx (DImode);
2198   emit_insn (gen_subdi3_compare0 (low, gen_lowpart (DImode, operands[1]),
2199                                   gen_lowpart (DImode, operands[2])));
2201   rtx high = gen_reg_rtx (DImode);
2202   emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]),
2203                                  gen_highpart (DImode, operands[2])));
2205   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2206   emit_move_insn (gen_highpart (DImode, operands[0]), high);
2207   DONE;
2210 (define_insn "sub<mode>3_compare0"
2211   [(set (reg:CC_NZ CC_REGNUM)
2212         (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
2213                                   (match_operand:GPI 2 "register_operand" "r"))
2214                        (const_int 0)))
2215    (set (match_operand:GPI 0 "register_operand" "=r")
2216         (minus:GPI (match_dup 1) (match_dup 2)))]
2217   ""
2218   "subs\\t%<w>0, %<w>1, %<w>2"
2219   [(set_attr "type" "alus_sreg")]
2222 ;; zero_extend version of above
2223 (define_insn "*subsi3_compare0_uxtw"
2224   [(set (reg:CC_NZ CC_REGNUM)
2225         (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
2226                                  (match_operand:SI 2 "register_operand" "r"))
2227                        (const_int 0)))
2228    (set (match_operand:DI 0 "register_operand" "=r")
2229         (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
2230   ""
2231   "subs\\t%w0, %w1, %w2"
2232   [(set_attr "type" "alus_sreg")]
2235 (define_insn "*sub_<shift>_<mode>"
2236   [(set (match_operand:GPI 0 "register_operand" "=r")
2237         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2238                    (ASHIFT:GPI
2239                     (match_operand:GPI 1 "register_operand" "r")
2240                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2241   ""
2242   "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
2243   [(set_attr "type" "alu_shift_imm")]
2246 ;; zero_extend version of above
2247 (define_insn "*sub_<shift>_si_uxtw"
2248   [(set (match_operand:DI 0 "register_operand" "=r")
2249         (zero_extend:DI
2250          (minus:SI (match_operand:SI 3 "register_operand" "r")
2251                    (ASHIFT:SI
2252                     (match_operand:SI 1 "register_operand" "r")
2253                     (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2254   ""
2255   "sub\\t%w0, %w3, %w1, <shift> %2"
2256   [(set_attr "type" "alu_shift_imm")]
2259 (define_insn "*sub_mul_imm_<mode>"
2260   [(set (match_operand:GPI 0 "register_operand" "=r")
2261         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2262                    (mult:GPI
2263                     (match_operand:GPI 1 "register_operand" "r")
2264                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2265   ""
2266   "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
2267   [(set_attr "type" "alu_shift_imm")]
2270 ;; zero_extend version of above
2271 (define_insn "*sub_mul_imm_si_uxtw"
2272   [(set (match_operand:DI 0 "register_operand" "=r")
2273         (zero_extend:DI
2274          (minus:SI (match_operand:SI 3 "register_operand" "r")
2275                    (mult:SI
2276                     (match_operand:SI 1 "register_operand" "r")
2277                     (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2278   ""
2279   "sub\\t%w0, %w3, %w1, lsl %p2"
2280   [(set_attr "type" "alu_shift_imm")]
2283 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
2284   [(set (match_operand:GPI 0 "register_operand" "=rk")
2285         (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
2286                    (ANY_EXTEND:GPI
2287                     (match_operand:ALLX 2 "register_operand" "r"))))]
2288   ""
2289   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
2290   [(set_attr "type" "alu_ext")]
2293 ;; zero_extend version of above
2294 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
2295   [(set (match_operand:DI 0 "register_operand" "=rk")
2296         (zero_extend:DI
2297          (minus:SI (match_operand:SI 1 "register_operand" "rk")
2298                    (ANY_EXTEND:SI
2299                     (match_operand:SHORT 2 "register_operand" "r")))))]
2300   ""
2301   "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
2302   [(set_attr "type" "alu_ext")]
2305 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
2306   [(set (match_operand:GPI 0 "register_operand" "=rk")
2307         (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
2308                    (ashift:GPI (ANY_EXTEND:GPI
2309                                 (match_operand:ALLX 2 "register_operand" "r"))
2310                                (match_operand 3 "aarch64_imm3" "Ui3"))))]
2311   ""
2312   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
2313   [(set_attr "type" "alu_ext")]
2316 ;; zero_extend version of above
2317 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
2318   [(set (match_operand:DI 0 "register_operand" "=rk")
2319         (zero_extend:DI
2320          (minus:SI (match_operand:SI 1 "register_operand" "rk")
2321                    (ashift:SI (ANY_EXTEND:SI
2322                                (match_operand:SHORT 2 "register_operand" "r"))
2323                               (match_operand 3 "aarch64_imm3" "Ui3")))))]
2324   ""
2325   "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
2326   [(set_attr "type" "alu_ext")]
2329 (define_insn "*sub_<optab><mode>_multp2"
2330   [(set (match_operand:GPI 0 "register_operand" "=rk")
2331         (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
2332                    (ANY_EXTRACT:GPI
2333                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2334                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2335                     (match_operand 3 "const_int_operand" "n")
2336                     (const_int 0))))]
2337   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
2338   "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
2339   [(set_attr "type" "alu_ext")]
2342 ;; zero_extend version of above
2343 (define_insn "*sub_<optab>si_multp2_uxtw"
2344   [(set (match_operand:DI 0 "register_operand" "=rk")
2345         (zero_extend:DI
2346          (minus:SI (match_operand:SI 4 "register_operand" "rk")
2347                    (ANY_EXTRACT:SI
2348                     (mult:SI (match_operand:SI 1 "register_operand" "r")
2349                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2350                     (match_operand 3 "const_int_operand" "n")
2351                     (const_int 0)))))]
2352   "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
2353   "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
2354   [(set_attr "type" "alu_ext")]
2357 (define_insn "sub<mode>3_carryin"
2358   [(set
2359     (match_operand:GPI 0 "register_operand" "=r")
2360     (minus:GPI (minus:GPI
2361                 (match_operand:GPI 1 "register_operand" "r")
2362                 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2363                (match_operand:GPI 2 "register_operand" "r")))]
2364    ""
2365    "sbc\\t%<w>0, %<w>1, %<w>2"
2366   [(set_attr "type" "adc_reg")]
2369 ;; zero_extend version of the above
2370 (define_insn "*subsi3_carryin_uxtw"
2371   [(set
2372     (match_operand:DI 0 "register_operand" "=r")
2373     (zero_extend:DI
2374      (minus:SI (minus:SI
2375                 (match_operand:SI 1 "register_operand" "r")
2376                 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2377                (match_operand:SI 2 "register_operand" "r"))))]
2378    ""
2379    "sbc\\t%w0, %w1, %w2"
2380   [(set_attr "type" "adc_reg")]
2383 (define_insn "*sub_uxt<mode>_shift2"
2384   [(set (match_operand:GPI 0 "register_operand" "=rk")
2385         (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
2386                    (and:GPI
2387                     (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
2388                                 (match_operand 2 "aarch64_imm3" "Ui3"))
2389                     (match_operand 3 "const_int_operand" "n"))))]
2390   "aarch64_uxt_size (INTVAL (operands[2]),INTVAL (operands[3])) != 0"
2391   "*
2392   operands[3] = GEN_INT (aarch64_uxt_size (INTVAL (operands[2]),
2393                                            INTVAL (operands[3])));
2394   return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %2\";"
2395   [(set_attr "type" "alu_ext")]
2398 ;; zero_extend version of above
2399 (define_insn "*sub_uxtsi_shift2_uxtw"
2400   [(set (match_operand:DI 0 "register_operand" "=rk")
2401         (zero_extend:DI
2402          (minus:SI (match_operand:SI 4 "register_operand" "rk")
2403                    (and:SI
2404                     (ashift:SI (match_operand:SI 1 "register_operand" "r")
2405                                (match_operand 2 "aarch64_imm3" "Ui3"))
2406                     (match_operand 3 "const_int_operand" "n")))))]
2407   "aarch64_uxt_size (INTVAL (operands[2]),INTVAL (operands[3])) != 0"
2408   "*
2409   operands[3] = GEN_INT (aarch64_uxt_size (INTVAL (operands[2]),
2410                                            INTVAL (operands[3])));
2411   return \"sub\t%w0, %w4, %w1, uxt%e3 %2\";"
2412   [(set_attr "type" "alu_ext")]
2415 (define_insn "*sub_uxt<mode>_multp2"
2416   [(set (match_operand:GPI 0 "register_operand" "=rk")
2417         (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
2418                    (and:GPI
2419                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2420                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2421                     (match_operand 3 "const_int_operand" "n"))))]
2422   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2423   "*
2424   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2425                                            INTVAL (operands[3])));
2426   return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
2427   [(set_attr "type" "alu_ext")]
2430 ;; zero_extend version of above
2431 (define_insn "*sub_uxtsi_multp2_uxtw"
2432   [(set (match_operand:DI 0 "register_operand" "=rk")
2433         (zero_extend:DI
2434          (minus:SI (match_operand:SI 4 "register_operand" "rk")
2435                    (and:SI
2436                     (mult:SI (match_operand:SI 1 "register_operand" "r")
2437                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2438                     (match_operand 3 "const_int_operand" "n")))))]
2439   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2440   "*
2441   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2442                                            INTVAL (operands[3])));
2443   return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
2444   [(set_attr "type" "alu_ext")]
2447 (define_expand "abs<mode>2"
2448   [(match_operand:GPI 0 "register_operand" "")
2449    (match_operand:GPI 1 "register_operand" "")]
2450   ""
2451   {
2452     rtx ccreg = aarch64_gen_compare_reg (LT, operands[1], const0_rtx);
2453     rtx x = gen_rtx_LT (VOIDmode, ccreg, const0_rtx);
2454     emit_insn (gen_csneg3<mode>_insn (operands[0], x, operands[1], operands[1]));
2455     DONE;
2456   }
2459 (define_insn "neg<mode>2"
2460   [(set (match_operand:GPI 0 "register_operand" "=r,w")
2461         (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
2462   ""
2463   "@
2464    neg\\t%<w>0, %<w>1
2465    neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
2466   [(set_attr "type" "alu_sreg, neon_neg<q>")
2467    (set_attr "simd" "*,yes")]
2470 ;; zero_extend version of above
2471 (define_insn "*negsi2_uxtw"
2472   [(set (match_operand:DI 0 "register_operand" "=r")
2473         (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
2474   ""
2475   "neg\\t%w0, %w1"
2476   [(set_attr "type" "alu_sreg")]
2479 (define_insn "*ngc<mode>"
2480   [(set (match_operand:GPI 0 "register_operand" "=r")
2481         (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2482                    (match_operand:GPI 1 "register_operand" "r")))]
2483   ""
2484   "ngc\\t%<w>0, %<w>1"
2485   [(set_attr "type" "adc_reg")]
2488 (define_insn "*ngcsi_uxtw"
2489   [(set (match_operand:DI 0 "register_operand" "=r")
2490         (zero_extend:DI
2491          (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2492                    (match_operand:SI 1 "register_operand" "r"))))]
2493   ""
2494   "ngc\\t%w0, %w1"
2495   [(set_attr "type" "adc_reg")]
2498 (define_insn "neg<mode>2_compare0"
2499   [(set (reg:CC_NZ CC_REGNUM)
2500         (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2501                        (const_int 0)))
2502    (set (match_operand:GPI 0 "register_operand" "=r")
2503         (neg:GPI (match_dup 1)))]
2504   ""
2505   "negs\\t%<w>0, %<w>1"
2506   [(set_attr "type" "alus_sreg")]
2509 ;; zero_extend version of above
2510 (define_insn "*negsi2_compare0_uxtw"
2511   [(set (reg:CC_NZ CC_REGNUM)
2512         (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
2513                        (const_int 0)))
2514    (set (match_operand:DI 0 "register_operand" "=r")
2515         (zero_extend:DI (neg:SI (match_dup 1))))]
2516   ""
2517   "negs\\t%w0, %w1"
2518   [(set_attr "type" "alus_sreg")]
2521 (define_insn "*neg_<shift><mode>3_compare0"
2522   [(set (reg:CC_NZ CC_REGNUM)
2523         (compare:CC_NZ
2524          (neg:GPI (ASHIFT:GPI
2525                    (match_operand:GPI 1 "register_operand" "r")
2526                    (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2527          (const_int 0)))
2528    (set (match_operand:GPI 0 "register_operand" "=r")
2529         (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2530   ""
2531   "negs\\t%<w>0, %<w>1, <shift> %2"
2532   [(set_attr "type" "alus_shift_imm")]
2535 (define_insn "*neg_<shift>_<mode>2"
2536   [(set (match_operand:GPI 0 "register_operand" "=r")
2537         (neg:GPI (ASHIFT:GPI
2538                   (match_operand:GPI 1 "register_operand" "r")
2539                   (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2540   ""
2541   "neg\\t%<w>0, %<w>1, <shift> %2"
2542   [(set_attr "type" "alu_shift_imm")]
2545 ;; zero_extend version of above
2546 (define_insn "*neg_<shift>_si2_uxtw"
2547   [(set (match_operand:DI 0 "register_operand" "=r")
2548         (zero_extend:DI
2549          (neg:SI (ASHIFT:SI
2550                   (match_operand:SI 1 "register_operand" "r")
2551                   (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2552   ""
2553   "neg\\t%w0, %w1, <shift> %2"
2554   [(set_attr "type" "alu_shift_imm")]
2557 (define_insn "*neg_mul_imm_<mode>2"
2558   [(set (match_operand:GPI 0 "register_operand" "=r")
2559         (neg:GPI (mult:GPI
2560                   (match_operand:GPI 1 "register_operand" "r")
2561                   (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2562   ""
2563   "neg\\t%<w>0, %<w>1, lsl %p2"
2564   [(set_attr "type" "alu_shift_imm")]
2567 ;; zero_extend version of above
2568 (define_insn "*neg_mul_imm_si2_uxtw"
2569   [(set (match_operand:DI 0 "register_operand" "=r")
2570         (zero_extend:DI
2571          (neg:SI (mult:SI
2572                   (match_operand:SI 1 "register_operand" "r")
2573                   (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2574   ""
2575   "neg\\t%w0, %w1, lsl %p2"
2576   [(set_attr "type" "alu_shift_imm")]
2579 (define_insn "mul<mode>3"
2580   [(set (match_operand:GPI 0 "register_operand" "=r")
2581         (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2582                   (match_operand:GPI 2 "register_operand" "r")))]
2583   ""
2584   "mul\\t%<w>0, %<w>1, %<w>2"
2585   [(set_attr "type" "mul")]
2588 ;; zero_extend version of above
2589 (define_insn "*mulsi3_uxtw"
2590   [(set (match_operand:DI 0 "register_operand" "=r")
2591         (zero_extend:DI
2592          (mult:SI (match_operand:SI 1 "register_operand" "r")
2593                   (match_operand:SI 2 "register_operand" "r"))))]
2594   ""
2595   "mul\\t%w0, %w1, %w2"
2596   [(set_attr "type" "mul")]
2599 (define_insn "madd<mode>"
2600   [(set (match_operand:GPI 0 "register_operand" "=r")
2601         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2602                             (match_operand:GPI 2 "register_operand" "r"))
2603                   (match_operand:GPI 3 "register_operand" "r")))]
2604   ""
2605   "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2606   [(set_attr "type" "mla")]
2609 ;; zero_extend version of above
2610 (define_insn "*maddsi_uxtw"
2611   [(set (match_operand:DI 0 "register_operand" "=r")
2612         (zero_extend:DI
2613          (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2614                            (match_operand:SI 2 "register_operand" "r"))
2615                   (match_operand:SI 3 "register_operand" "r"))))]
2616   ""
2617   "madd\\t%w0, %w1, %w2, %w3"
2618   [(set_attr "type" "mla")]
2621 (define_insn "*msub<mode>"
2622   [(set (match_operand:GPI 0 "register_operand" "=r")
2623         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2624                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2625                              (match_operand:GPI 2 "register_operand" "r"))))]
2627   ""
2628   "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2629   [(set_attr "type" "mla")]
2632 ;; zero_extend version of above
2633 (define_insn "*msubsi_uxtw"
2634   [(set (match_operand:DI 0 "register_operand" "=r")
2635         (zero_extend:DI
2636          (minus:SI (match_operand:SI 3 "register_operand" "r")
2637                    (mult:SI (match_operand:SI 1 "register_operand" "r")
2638                             (match_operand:SI 2 "register_operand" "r")))))]
2640   ""
2641   "msub\\t%w0, %w1, %w2, %w3"
2642   [(set_attr "type" "mla")]
2645 (define_insn "*mul<mode>_neg"
2646   [(set (match_operand:GPI 0 "register_operand" "=r")
2647         (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2648                   (match_operand:GPI 2 "register_operand" "r")))]
2650   ""
2651   "mneg\\t%<w>0, %<w>1, %<w>2"
2652   [(set_attr "type" "mul")]
2655 ;; zero_extend version of above
2656 (define_insn "*mulsi_neg_uxtw"
2657   [(set (match_operand:DI 0 "register_operand" "=r")
2658         (zero_extend:DI
2659          (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2660                   (match_operand:SI 2 "register_operand" "r"))))]
2662   ""
2663   "mneg\\t%w0, %w1, %w2"
2664   [(set_attr "type" "mul")]
2667 (define_insn "<su_optab>mulsidi3"
2668   [(set (match_operand:DI 0 "register_operand" "=r")
2669         (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2670                  (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2671   ""
2672   "<su>mull\\t%0, %w1, %w2"
2673   [(set_attr "type" "<su>mull")]
2676 (define_insn "<su_optab>maddsidi4"
2677   [(set (match_operand:DI 0 "register_operand" "=r")
2678         (plus:DI (mult:DI
2679                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2680                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2681                  (match_operand:DI 3 "register_operand" "r")))]
2682   ""
2683   "<su>maddl\\t%0, %w1, %w2, %3"
2684   [(set_attr "type" "<su>mlal")]
2687 (define_insn "<su_optab>msubsidi4"
2688   [(set (match_operand:DI 0 "register_operand" "=r")
2689         (minus:DI
2690          (match_operand:DI 3 "register_operand" "r")
2691          (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2692                   (ANY_EXTEND:DI
2693                    (match_operand:SI 2 "register_operand" "r")))))]
2694   ""
2695   "<su>msubl\\t%0, %w1, %w2, %3"
2696   [(set_attr "type" "<su>mlal")]
2699 (define_insn "*<su_optab>mulsidi_neg"
2700   [(set (match_operand:DI 0 "register_operand" "=r")
2701         (mult:DI (neg:DI
2702                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2703                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2704   ""
2705   "<su>mnegl\\t%0, %w1, %w2"
2706   [(set_attr "type" "<su>mull")]
2709 (define_expand "<su_optab>mulditi3"
2710   [(set (match_operand:TI 0 "register_operand")
2711         (mult:TI (ANY_EXTEND:TI (match_operand:DI 1 "register_operand"))
2712                  (ANY_EXTEND:TI (match_operand:DI 2 "register_operand"))))]
2713   ""
2715   rtx low = gen_reg_rtx (DImode);
2716   emit_insn (gen_muldi3 (low, operands[1], operands[2]));
2718   rtx high = gen_reg_rtx (DImode);
2719   emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2]));
2721   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2722   emit_move_insn (gen_highpart (DImode, operands[0]), high);
2723   DONE;
2726 ;; The default expansion of multi3 using umuldi3_highpart will perform
2727 ;; the additions in an order that fails to combine into two madd insns.
2728 (define_expand "multi3"
2729   [(set (match_operand:TI 0 "register_operand")
2730         (mult:TI (match_operand:TI 1 "register_operand")
2731                  (match_operand:TI 2 "register_operand")))]
2732   ""
2734   rtx l0 = gen_reg_rtx (DImode);
2735   rtx l1 = gen_lowpart (DImode, operands[1]);
2736   rtx l2 = gen_lowpart (DImode, operands[2]);
2737   rtx h0 = gen_reg_rtx (DImode);
2738   rtx h1 = gen_highpart (DImode, operands[1]);
2739   rtx h2 = gen_highpart (DImode, operands[2]);
2741   emit_insn (gen_muldi3 (l0, l1, l2));
2742   emit_insn (gen_umuldi3_highpart (h0, l1, l2));
2743   emit_insn (gen_madddi (h0, h1, l2, h0));
2744   emit_insn (gen_madddi (h0, l1, h2, h0));
2746   emit_move_insn (gen_lowpart (DImode, operands[0]), l0);
2747   emit_move_insn (gen_highpart (DImode, operands[0]), h0);
2748   DONE;
2751 (define_insn "<su>muldi3_highpart"
2752   [(set (match_operand:DI 0 "register_operand" "=r")
2753         (truncate:DI
2754          (lshiftrt:TI
2755           (mult:TI
2756            (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2757            (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2758           (const_int 64))))]
2759   ""
2760   "<su>mulh\\t%0, %1, %2"
2761   [(set_attr "type" "<su>mull")]
2764 (define_insn "<su_optab>div<mode>3"
2765   [(set (match_operand:GPI 0 "register_operand" "=r")
2766         (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2767                      (match_operand:GPI 2 "register_operand" "r")))]
2768   ""
2769   "<su>div\\t%<w>0, %<w>1, %<w>2"
2770   [(set_attr "type" "<su>div")]
2773 ;; zero_extend version of above
2774 (define_insn "*<su_optab>divsi3_uxtw"
2775   [(set (match_operand:DI 0 "register_operand" "=r")
2776         (zero_extend:DI
2777          (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2778                      (match_operand:SI 2 "register_operand" "r"))))]
2779   ""
2780   "<su>div\\t%w0, %w1, %w2"
2781   [(set_attr "type" "<su>div")]
2784 ;; -------------------------------------------------------------------
2785 ;; Comparison insns
2786 ;; -------------------------------------------------------------------
2788 (define_insn "*cmp<mode>"
2789   [(set (reg:CC CC_REGNUM)
2790         (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2791                     (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2792   ""
2793   "@
2794    cmp\\t%<w>0, %<w>1
2795    cmp\\t%<w>0, %<w>1
2796    cmn\\t%<w>0, #%n1"
2797   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
2800 (define_insn "*cmp<mode>"
2801   [(set (reg:CCFP CC_REGNUM)
2802         (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2803                       (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2804    "TARGET_FLOAT"
2805    "@
2806     fcmp\\t%<s>0, #0.0
2807     fcmp\\t%<s>0, %<s>1"
2808   [(set_attr "type" "fcmp<s>")]
2811 (define_insn "*cmpe<mode>"
2812   [(set (reg:CCFPE CC_REGNUM)
2813         (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2814                        (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2815    "TARGET_FLOAT"
2816    "@
2817     fcmpe\\t%<s>0, #0.0
2818     fcmpe\\t%<s>0, %<s>1"
2819   [(set_attr "type" "fcmp<s>")]
2822 (define_insn "*cmp_swp_<shift>_reg<mode>"
2823   [(set (reg:CC_SWP CC_REGNUM)
2824         (compare:CC_SWP (ASHIFT:GPI
2825                          (match_operand:GPI 0 "register_operand" "r")
2826                          (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2827                         (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2828   ""
2829   "cmp\\t%<w>2, %<w>0, <shift> %1"
2830   [(set_attr "type" "alus_shift_imm")]
2833 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2834   [(set (reg:CC_SWP CC_REGNUM)
2835         (compare:CC_SWP (ANY_EXTEND:GPI
2836                          (match_operand:ALLX 0 "register_operand" "r"))
2837                         (match_operand:GPI 1 "register_operand" "r")))]
2838   ""
2839   "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2840   [(set_attr "type" "alus_ext")]
2843 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2844   [(set (reg:CC_SWP CC_REGNUM)
2845         (compare:CC_SWP (ashift:GPI
2846                          (ANY_EXTEND:GPI
2847                           (match_operand:ALLX 0 "register_operand" "r"))
2848                          (match_operand 1 "aarch64_imm3" "Ui3"))
2849         (match_operand:GPI 2 "register_operand" "r")))]
2850   ""
2851   "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2852   [(set_attr "type" "alus_ext")]
2855 ;; -------------------------------------------------------------------
2856 ;; Store-flag and conditional select insns
2857 ;; -------------------------------------------------------------------
2859 (define_expand "cstore<mode>4"
2860   [(set (match_operand:SI 0 "register_operand" "")
2861         (match_operator:SI 1 "aarch64_comparison_operator"
2862          [(match_operand:GPI 2 "register_operand" "")
2863           (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2864   ""
2865   "
2866   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2867                                       operands[3]);
2868   operands[3] = const0_rtx;
2869   "
2872 (define_expand "cstorecc4"
2873   [(set (match_operand:SI 0 "register_operand")
2874        (match_operator 1 "aarch64_comparison_operator"
2875         [(match_operand 2 "ccmp_cc_register")
2876          (match_operand 3 "const0_operand")]))]
2877   ""
2879   emit_insn (gen_rtx_SET (operands[0], operands[1]));
2880   DONE;
2884 (define_expand "cstore<mode>4"
2885   [(set (match_operand:SI 0 "register_operand" "")
2886         (match_operator:SI 1 "aarch64_comparison_operator"
2887          [(match_operand:GPF 2 "register_operand" "")
2888           (match_operand:GPF 3 "register_operand" "")]))]
2889   ""
2890   "
2891   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2892                                       operands[3]);
2893   operands[3] = const0_rtx;
2894   "
2897 (define_insn "*cstore<mode>_insn"
2898   [(set (match_operand:ALLI 0 "register_operand" "=r")
2899         (match_operator:ALLI 1 "aarch64_comparison_operator"
2900          [(match_operand 2 "cc_register" "") (const_int 0)]))]
2901   ""
2902   "cset\\t%<w>0, %m1"
2903   [(set_attr "type" "csel")]
2906 ;; zero_extend version of the above
2907 (define_insn "*cstoresi_insn_uxtw"
2908   [(set (match_operand:DI 0 "register_operand" "=r")
2909         (zero_extend:DI
2910          (match_operator:SI 1 "aarch64_comparison_operator"
2911           [(match_operand 2 "cc_register" "") (const_int 0)])))]
2912   ""
2913   "cset\\t%w0, %m1"
2914   [(set_attr "type" "csel")]
2917 (define_insn "cstore<mode>_neg"
2918   [(set (match_operand:ALLI 0 "register_operand" "=r")
2919         (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2920                   [(match_operand 2 "cc_register" "") (const_int 0)])))]
2921   ""
2922   "csetm\\t%<w>0, %m1"
2923   [(set_attr "type" "csel")]
2926 ;; zero_extend version of the above
2927 (define_insn "*cstoresi_neg_uxtw"
2928   [(set (match_operand:DI 0 "register_operand" "=r")
2929         (zero_extend:DI
2930          (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2931                   [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2932   ""
2933   "csetm\\t%w0, %m1"
2934   [(set_attr "type" "csel")]
2937 (define_expand "cmov<mode>6"
2938   [(set (match_operand:GPI 0 "register_operand" "")
2939         (if_then_else:GPI
2940          (match_operator 1 "aarch64_comparison_operator"
2941           [(match_operand:GPI 2 "register_operand" "")
2942            (match_operand:GPI 3 "aarch64_plus_operand" "")])
2943          (match_operand:GPI 4 "register_operand" "")
2944          (match_operand:GPI 5 "register_operand" "")))]
2945   ""
2946   "
2947   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2948                                       operands[3]);
2949   operands[3] = const0_rtx;
2950   "
2953 (define_expand "cmov<mode>6"
2954   [(set (match_operand:GPF 0 "register_operand" "")
2955         (if_then_else:GPF
2956          (match_operator 1 "aarch64_comparison_operator"
2957           [(match_operand:GPF 2 "register_operand" "")
2958            (match_operand:GPF 3 "register_operand" "")])
2959          (match_operand:GPF 4 "register_operand" "")
2960          (match_operand:GPF 5 "register_operand" "")))]
2961   ""
2962   "
2963   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2964                                       operands[3]);
2965   operands[3] = const0_rtx;
2966   "
2969 (define_insn "*cmov<mode>_insn"
2970   [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2971         (if_then_else:ALLI
2972          (match_operator 1 "aarch64_comparison_operator"
2973           [(match_operand 2 "cc_register" "") (const_int 0)])
2974          (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2975          (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2976   "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2977      || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2978   ;; Final two alternatives should be unreachable, but included for completeness
2979   "@
2980    csel\\t%<w>0, %<w>3, %<w>4, %m1
2981    csinv\\t%<w>0, %<w>3, <w>zr, %m1
2982    csinv\\t%<w>0, %<w>4, <w>zr, %M1
2983    csinc\\t%<w>0, %<w>3, <w>zr, %m1
2984    csinc\\t%<w>0, %<w>4, <w>zr, %M1
2985    mov\\t%<w>0, -1
2986    mov\\t%<w>0, 1"
2987   [(set_attr "type" "csel")]
2990 ;; zero_extend version of above
2991 (define_insn "*cmovsi_insn_uxtw"
2992   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2993         (zero_extend:DI
2994          (if_then_else:SI
2995           (match_operator 1 "aarch64_comparison_operator"
2996            [(match_operand 2 "cc_register" "") (const_int 0)])
2997           (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2998           (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2999   "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
3000      || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
3001   ;; Final two alternatives should be unreachable, but included for completeness
3002   "@
3003    csel\\t%w0, %w3, %w4, %m1
3004    csinv\\t%w0, %w3, wzr, %m1
3005    csinv\\t%w0, %w4, wzr, %M1
3006    csinc\\t%w0, %w3, wzr, %m1
3007    csinc\\t%w0, %w4, wzr, %M1
3008    mov\\t%w0, -1
3009    mov\\t%w0, 1"
3010   [(set_attr "type" "csel")]
3013 (define_insn "*cmovdi_insn_uxtw"
3014   [(set (match_operand:DI 0 "register_operand" "=r")
3015         (if_then_else:DI
3016          (match_operator 1 "aarch64_comparison_operator"
3017           [(match_operand 2 "cc_register" "") (const_int 0)])
3018          (zero_extend:DI (match_operand:SI 3 "register_operand" "r"))
3019          (zero_extend:DI (match_operand:SI 4 "register_operand" "r"))))]
3020   ""
3021   "csel\\t%w0, %w3, %w4, %m1"
3022   [(set_attr "type" "csel")]
3025 (define_insn "*cmov<mode>_insn"
3026   [(set (match_operand:GPF 0 "register_operand" "=w")
3027         (if_then_else:GPF
3028          (match_operator 1 "aarch64_comparison_operator"
3029           [(match_operand 2 "cc_register" "") (const_int 0)])
3030          (match_operand:GPF 3 "register_operand" "w")
3031          (match_operand:GPF 4 "register_operand" "w")))]
3032   "TARGET_FLOAT"
3033   "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
3034   [(set_attr "type" "fcsel")]
3037 (define_expand "mov<mode>cc"
3038   [(set (match_operand:ALLI 0 "register_operand" "")
3039         (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
3040                            (match_operand:ALLI 2 "register_operand" "")
3041                            (match_operand:ALLI 3 "register_operand" "")))]
3042   ""
3043   {
3044     enum rtx_code code = GET_CODE (operands[1]);
3046     if (code == UNEQ || code == LTGT)
3047       FAIL;
3049     if (!ccmp_cc_register (XEXP (operands[1], 0),
3050                            GET_MODE (XEXP (operands[1], 0))))
3051       {
3052         rtx ccreg;
3053         ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
3054                                          XEXP (operands[1], 1));
3055         operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
3056       }
3057   }
3060 (define_expand "mov<GPF:mode><GPI:mode>cc"
3061   [(set (match_operand:GPI 0 "register_operand" "")
3062         (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
3063                           (match_operand:GPF 2 "register_operand" "")
3064                           (match_operand:GPF 3 "register_operand" "")))]
3065   ""
3066   {
3067     rtx ccreg;
3068     enum rtx_code code = GET_CODE (operands[1]);
3070     if (code == UNEQ || code == LTGT)
3071       FAIL;
3073     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
3074                                   XEXP (operands[1], 1));
3075     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
3076   }
3079 (define_expand "mov<mode>cc"
3080   [(set (match_operand:GPF 0 "register_operand" "")
3081         (if_then_else:GPF (match_operand 1 "aarch64_comparison_operator" "")
3082                           (match_operand:GPF 2 "register_operand" "")
3083                           (match_operand:GPF 3 "register_operand" "")))]
3084   ""
3085   {
3086     rtx ccreg;
3087     enum rtx_code code = GET_CODE (operands[1]);
3089     if (code == UNEQ || code == LTGT)
3090       FAIL;
3092     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
3093                                   XEXP (operands[1], 1));
3094     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
3095   }
3099 ;; CRC32 instructions.
3100 (define_insn "aarch64_<crc_variant>"
3101   [(set (match_operand:SI 0 "register_operand" "=r")
3102         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
3103                     (match_operand:<crc_mode> 2 "register_operand" "r")]
3104          CRC))]
3105   "TARGET_CRC32"
3106   {
3107     if (GET_MODE_BITSIZE (GET_MODE (operands[2])) >= 64)
3108       return "<crc_variant>\\t%w0, %w1, %x2";
3109     else
3110       return "<crc_variant>\\t%w0, %w1, %w2";
3111   }
3112   [(set_attr "type" "crc")]
3115 (define_insn "*csinc2<mode>_insn"
3116   [(set (match_operand:GPI 0 "register_operand" "=r")
3117         (plus:GPI (match_operand 2 "aarch64_comparison_operation" "")
3118                   (match_operand:GPI 1 "register_operand" "r")))]
3119   ""
3120   "cinc\\t%<w>0, %<w>1, %m2"
3121   [(set_attr "type" "csel")]
3124 (define_insn "csinc3<mode>_insn"
3125   [(set (match_operand:GPI 0 "register_operand" "=r")
3126         (if_then_else:GPI
3127           (match_operand 1 "aarch64_comparison_operation" "")
3128           (plus:GPI (match_operand:GPI 2 "register_operand" "r")
3129                     (const_int 1))
3130           (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
3131   ""
3132   "csinc\\t%<w>0, %<w>3, %<w>2, %M1"
3133   [(set_attr "type" "csel")]
3136 (define_insn "*csinv3<mode>_insn"
3137   [(set (match_operand:GPI 0 "register_operand" "=r")
3138         (if_then_else:GPI
3139           (match_operand 1 "aarch64_comparison_operation" "")
3140           (not:GPI (match_operand:GPI 2 "register_operand" "r"))
3141           (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
3142   ""
3143   "csinv\\t%<w>0, %<w>3, %<w>2, %M1"
3144   [(set_attr "type" "csel")]
3147 (define_insn "csneg3_uxtw_insn"
3148   [(set (match_operand:DI 0 "register_operand" "=r")
3149         (zero_extend:DI
3150           (if_then_else:SI
3151             (match_operand 1 "aarch64_comparison_operation" "")
3152             (neg:SI (match_operand:SI 2 "register_operand" "r"))
3153             (match_operand:SI 3 "aarch64_reg_or_zero" "rZ"))))]
3154   ""
3155   "csneg\\t%w0, %w3, %w2, %M1"
3156   [(set_attr "type" "csel")]
3159 (define_insn "csneg3<mode>_insn"
3160   [(set (match_operand:GPI 0 "register_operand" "=r")
3161         (if_then_else:GPI
3162           (match_operand 1 "aarch64_comparison_operation" "")
3163           (neg:GPI (match_operand:GPI 2 "register_operand" "r"))
3164           (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
3165   ""
3166   "csneg\\t%<w>0, %<w>3, %<w>2, %M1"
3167   [(set_attr "type" "csel")]
3170 ;; -------------------------------------------------------------------
3171 ;; Logical operations
3172 ;; -------------------------------------------------------------------
3174 (define_insn "<optab><mode>3"
3175   [(set (match_operand:GPI 0 "register_operand" "=r,rk,w")
3176         (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r,w")
3177                      (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>,w")))]
3178   ""
3179   "@
3180   <logical>\\t%<w>0, %<w>1, %<w>2
3181   <logical>\\t%<w>0, %<w>1, %<w>2
3182   <logical>\\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
3183   [(set_attr "type" "logic_reg,logic_imm,neon_logic")
3184    (set_attr "simd" "*,*,yes")]
3187 ;; zero_extend version of above
3188 (define_insn "*<optab>si3_uxtw"
3189   [(set (match_operand:DI 0 "register_operand" "=r,rk")
3190         (zero_extend:DI
3191          (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
3192                      (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
3193   ""
3194   "<logical>\\t%w0, %w1, %w2"
3195   [(set_attr "type" "logic_reg,logic_imm")]
3198 (define_insn "*and<mode>3_compare0"
3199   [(set (reg:CC_NZ CC_REGNUM)
3200         (compare:CC_NZ
3201          (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
3202                   (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
3203          (const_int 0)))
3204    (set (match_operand:GPI 0 "register_operand" "=r,r")
3205         (and:GPI (match_dup 1) (match_dup 2)))]
3206   ""
3207   "ands\\t%<w>0, %<w>1, %<w>2"
3208   [(set_attr "type" "logics_reg,logics_imm")]
3211 ;; zero_extend version of above
3212 (define_insn "*andsi3_compare0_uxtw"
3213   [(set (reg:CC_NZ CC_REGNUM)
3214         (compare:CC_NZ
3215          (and:SI (match_operand:SI 1 "register_operand" "%r,r")
3216                  (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
3217          (const_int 0)))
3218    (set (match_operand:DI 0 "register_operand" "=r,r")
3219         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
3220   ""
3221   "ands\\t%w0, %w1, %w2"
3222   [(set_attr "type" "logics_reg,logics_imm")]
3225 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
3226   [(set (reg:CC_NZ CC_REGNUM)
3227         (compare:CC_NZ
3228          (and:GPI (SHIFT:GPI
3229                    (match_operand:GPI 1 "register_operand" "r")
3230                    (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3231                   (match_operand:GPI 3 "register_operand" "r"))
3232          (const_int 0)))
3233    (set (match_operand:GPI 0 "register_operand" "=r")
3234         (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
3235   ""
3236   "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3237   [(set_attr "type" "logics_shift_imm")]
3240 ;; zero_extend version of above
3241 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
3242   [(set (reg:CC_NZ CC_REGNUM)
3243         (compare:CC_NZ
3244          (and:SI (SHIFT:SI
3245                   (match_operand:SI 1 "register_operand" "r")
3246                   (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3247                  (match_operand:SI 3 "register_operand" "r"))
3248          (const_int 0)))
3249    (set (match_operand:DI 0 "register_operand" "=r")
3250         (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
3251                                 (match_dup 3))))]
3252   ""
3253   "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3254   [(set_attr "type" "logics_shift_imm")]
3257 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
3258   [(set (match_operand:GPI 0 "register_operand" "=r")
3259         (LOGICAL:GPI (SHIFT:GPI
3260                       (match_operand:GPI 1 "register_operand" "r")
3261                       (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3262                      (match_operand:GPI 3 "register_operand" "r")))]
3263   ""
3264   "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3265   [(set_attr "type" "logic_shift_imm")]
3268 (define_insn "*<optab>_rol<mode>3"
3269   [(set (match_operand:GPI 0 "register_operand" "=r")
3270         (LOGICAL:GPI (rotate:GPI
3271                       (match_operand:GPI 1 "register_operand" "r")
3272                       (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3273                      (match_operand:GPI 3 "register_operand" "r")))]
3274   ""
3275   "<logical>\\t%<w>0, %<w>3, %<w>1, ror (<sizen> - %2)"
3276   [(set_attr "type" "logic_shift_imm")]
3279 ;; zero_extend versions of above
3280 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
3281   [(set (match_operand:DI 0 "register_operand" "=r")
3282         (zero_extend:DI
3283          (LOGICAL:SI (SHIFT:SI
3284                       (match_operand:SI 1 "register_operand" "r")
3285                       (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3286                      (match_operand:SI 3 "register_operand" "r"))))]
3287   ""
3288   "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3289   [(set_attr "type" "logic_shift_imm")]
3292 (define_insn "*<optab>_rolsi3_uxtw"
3293   [(set (match_operand:DI 0 "register_operand" "=r")
3294         (zero_extend:DI
3295          (LOGICAL:SI (rotate:SI
3296                       (match_operand:SI 1 "register_operand" "r")
3297                       (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3298                      (match_operand:SI 3 "register_operand" "r"))))]
3299   ""
3300   "<logical>\\t%w0, %w3, %w1, ror (32 - %2)"
3301   [(set_attr "type" "logic_shift_imm")]
3304 (define_insn "one_cmpl<mode>2"
3305   [(set (match_operand:GPI 0 "register_operand" "=r,w")
3306         (not:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
3307   ""
3308   "@
3309   mvn\\t%<w>0, %<w>1
3310   mvn\\t%0.8b, %1.8b"
3311   [(set_attr "type" "logic_reg,neon_logic")
3312    (set_attr "simd" "*,yes")]
3315 (define_insn "*one_cmpl_<optab><mode>2"
3316   [(set (match_operand:GPI 0 "register_operand" "=r")
3317         (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
3318                             (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
3319   ""
3320   "mvn\\t%<w>0, %<w>1, <shift> %2"
3321   [(set_attr "type" "logic_shift_imm")]
3324 ;; Binary logical operators negating one operand, i.e. (a & !b), (a | !b).
3326 (define_insn "*<NLOGICAL:optab>_one_cmpl<mode>3"
3327   [(set (match_operand:GPI 0 "register_operand" "=r,w")
3328         (NLOGICAL:GPI (not:GPI (match_operand:GPI 1 "register_operand" "r,w"))
3329                      (match_operand:GPI 2 "register_operand" "r,w")))]
3330   ""
3331   "@
3332   <NLOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1
3333   <NLOGICAL:nlogical>\\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>"
3334   [(set_attr "type" "logic_reg,neon_logic")
3335    (set_attr "simd" "*,yes")]
3338 (define_insn "*<NLOGICAL:optab>_one_cmplsidi3_ze"
3339   [(set (match_operand:DI 0 "register_operand" "=r")
3340         (zero_extend:DI
3341           (NLOGICAL:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3342                        (match_operand:SI 2 "register_operand" "r"))))]
3343   ""
3344   "<NLOGICAL:nlogical>\\t%w0, %w2, %w1"
3345   [(set_attr "type" "logic_reg")]
3348 (define_insn "*xor_one_cmplsidi3_ze"
3349   [(set (match_operand:DI 0 "register_operand" "=r")
3350         (zero_extend:DI
3351           (not:SI (xor:SI (match_operand:SI 1 "register_operand" "r")
3352                           (match_operand:SI 2 "register_operand" "r")))))]
3353   ""
3354   "eon\\t%w0, %w1, %w2"
3355   [(set_attr "type" "logic_reg")]
3358 ;; (xor (not a) b) is simplify_rtx-ed down to (not (xor a b)).
3359 ;; eon does not operate on SIMD registers so the vector variant must be split.
3360 (define_insn_and_split "*xor_one_cmpl<mode>3"
3361   [(set (match_operand:GPI 0 "register_operand" "=r,w")
3362         (not:GPI (xor:GPI (match_operand:GPI 1 "register_operand" "r,?w")
3363                           (match_operand:GPI 2 "register_operand" "r,w"))))]
3364   ""
3365   "@
3366   eon\\t%<w>0, %<w>1, %<w>2
3367   #"
3368   "reload_completed && FP_REGNUM_P (REGNO (operands[0]))" ;; For SIMD registers.
3369   [(set (match_operand:GPI 0 "register_operand" "=w")
3370         (xor:GPI (match_operand:GPI 1 "register_operand" "w")
3371                  (match_operand:GPI 2 "register_operand" "w")))
3372    (set (match_dup 0) (not:GPI (match_dup 0)))]
3373   ""
3374   [(set_attr "type" "logic_reg,multiple")
3375    (set_attr "simd" "*,yes")]
3378 (define_insn "*and_one_cmpl<mode>3_compare0"
3379   [(set (reg:CC_NZ CC_REGNUM)
3380         (compare:CC_NZ
3381          (and:GPI (not:GPI
3382                    (match_operand:GPI 1 "register_operand" "r"))
3383                   (match_operand:GPI 2 "register_operand" "r"))
3384          (const_int 0)))
3385    (set (match_operand:GPI 0 "register_operand" "=r")
3386         (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
3387   ""
3388   "bics\\t%<w>0, %<w>2, %<w>1"
3389   [(set_attr "type" "logics_reg")]
3392 ;; zero_extend version of above
3393 (define_insn "*and_one_cmplsi3_compare0_uxtw"
3394   [(set (reg:CC_NZ CC_REGNUM)
3395         (compare:CC_NZ
3396          (and:SI (not:SI
3397                   (match_operand:SI 1 "register_operand" "r"))
3398                  (match_operand:SI 2 "register_operand" "r"))
3399          (const_int 0)))
3400    (set (match_operand:DI 0 "register_operand" "=r")
3401         (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
3402   ""
3403   "bics\\t%w0, %w2, %w1"
3404   [(set_attr "type" "logics_reg")]
3407 (define_insn "*and_one_cmpl<mode>3_compare0_no_reuse"
3408   [(set (reg:CC_NZ CC_REGNUM)
3409     (compare:CC_NZ
3410      (and:GPI (not:GPI
3411            (match_operand:GPI 0 "register_operand" "r"))
3412           (match_operand:GPI 1 "register_operand" "r"))
3413      (const_int 0)))]
3414   ""
3415   "bics\\t<w>zr, %<w>1, %<w>0"
3416   [(set_attr "type" "logics_reg")]
3419 (define_insn "<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
3420   [(set (match_operand:GPI 0 "register_operand" "=r")
3421         (LOGICAL:GPI (not:GPI
3422                       (SHIFT:GPI
3423                        (match_operand:GPI 1 "register_operand" "r")
3424                        (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
3425                      (match_operand:GPI 3 "register_operand" "r")))]
3426   ""
3427   "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3428   [(set_attr "type" "logic_shift_imm")]
3431 (define_insn "*eor_one_cmpl_<SHIFT:optab><mode>3_alt"
3432   [(set (match_operand:GPI 0 "register_operand" "=r")
3433         (not:GPI (xor:GPI
3434                       (SHIFT:GPI
3435                        (match_operand:GPI 1 "register_operand" "r")
3436                        (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3437                      (match_operand:GPI 3 "register_operand" "r"))))]
3438   ""
3439   "eon\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3440   [(set_attr "type" "logic_shift_imm")]
3443 ;; Zero-extend version of the above.
3444 (define_insn "*eor_one_cmpl_<SHIFT:optab>sidi3_alt_ze"
3445   [(set (match_operand:DI 0 "register_operand" "=r")
3446         (zero_extend:DI
3447           (not:SI (xor:SI
3448                     (SHIFT:SI
3449                       (match_operand:SI 1 "register_operand" "r")
3450                       (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3451                     (match_operand:SI 3 "register_operand" "r")))))]
3452   ""
3453   "eon\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3454   [(set_attr "type" "logic_shift_imm")]
3457 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
3458   [(set (reg:CC_NZ CC_REGNUM)
3459         (compare:CC_NZ
3460          (and:GPI (not:GPI
3461                    (SHIFT:GPI
3462                     (match_operand:GPI 1 "register_operand" "r")
3463                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
3464                   (match_operand:GPI 3 "register_operand" "r"))
3465          (const_int 0)))
3466    (set (match_operand:GPI 0 "register_operand" "=r")
3467         (and:GPI (not:GPI
3468                   (SHIFT:GPI
3469                    (match_dup 1) (match_dup 2))) (match_dup 3)))]
3470   ""
3471   "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3472   [(set_attr "type" "logics_shift_imm")]
3475 ;; zero_extend version of above
3476 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
3477   [(set (reg:CC_NZ CC_REGNUM)
3478         (compare:CC_NZ
3479          (and:SI (not:SI
3480                   (SHIFT:SI
3481                    (match_operand:SI 1 "register_operand" "r")
3482                    (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
3483                  (match_operand:SI 3 "register_operand" "r"))
3484          (const_int 0)))
3485    (set (match_operand:DI 0 "register_operand" "=r")
3486         (zero_extend:DI (and:SI
3487                          (not:SI
3488                           (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
3489   ""
3490   "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3491   [(set_attr "type" "logics_shift_imm")]
3494 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0_no_reuse"
3495   [(set (reg:CC_NZ CC_REGNUM)
3496     (compare:CC_NZ
3497      (and:GPI (not:GPI
3498            (SHIFT:GPI
3499             (match_operand:GPI 0 "register_operand" "r")
3500             (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n")))
3501           (match_operand:GPI 2 "register_operand" "r"))
3502      (const_int 0)))]
3503   ""
3504   "bics\\t<w>zr, %<w>2, %<w>0, <SHIFT:shift> %1"
3505   [(set_attr "type" "logics_shift_imm")]
3508 (define_insn "clz<mode>2"
3509   [(set (match_operand:GPI 0 "register_operand" "=r")
3510         (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
3511   ""
3512   "clz\\t%<w>0, %<w>1"
3513   [(set_attr "type" "clz")]
3516 (define_expand "ffs<mode>2"
3517   [(match_operand:GPI 0 "register_operand")
3518    (match_operand:GPI 1 "register_operand")]
3519   ""
3520   {
3521     rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
3522     rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
3524     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3525     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3526     emit_insn (gen_csinc3<mode>_insn (operands[0], x, operands[0], const0_rtx));
3527     DONE;
3528   }
3531 (define_insn "clrsb<mode>2"
3532   [(set (match_operand:GPI 0 "register_operand" "=r")
3533         (clrsb:GPI (match_operand:GPI 1 "register_operand" "r")))]
3534   ""
3535   "cls\\t%<w>0, %<w>1"
3536   [(set_attr "type" "clz")]
3539 (define_insn "rbit<mode>2"
3540   [(set (match_operand:GPI 0 "register_operand" "=r")
3541         (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
3542   ""
3543   "rbit\\t%<w>0, %<w>1"
3544   [(set_attr "type" "rbit")]
3547 (define_expand "ctz<mode>2"
3548   [(match_operand:GPI 0 "register_operand")
3549    (match_operand:GPI 1 "register_operand")]
3550   ""
3551   {
3552     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3553     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3554     DONE;
3555   }
3558 (define_insn "*and<mode>3nr_compare0"
3559   [(set (reg:CC_NZ CC_REGNUM)
3560         (compare:CC_NZ
3561          (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
3562                   (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
3563          (const_int 0)))]
3564   ""
3565   "tst\\t%<w>0, %<w>1"
3566   [(set_attr "type" "logics_reg,logics_imm")]
3569 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
3570   [(set (reg:CC_NZ CC_REGNUM)
3571         (compare:CC_NZ
3572          (and:GPI (SHIFT:GPI
3573                    (match_operand:GPI 0 "register_operand" "r")
3574                    (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
3575                   (match_operand:GPI 2 "register_operand" "r"))
3576         (const_int 0)))]
3577   ""
3578   "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
3579   [(set_attr "type" "logics_shift_imm")]
3582 ;; -------------------------------------------------------------------
3583 ;; Shifts
3584 ;; -------------------------------------------------------------------
3586 (define_expand "<optab><mode>3"
3587   [(set (match_operand:GPI 0 "register_operand")
3588         (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
3589                     (match_operand:QI 2 "nonmemory_operand")))]
3590   ""
3591   {
3592     if (CONST_INT_P (operands[2]))
3593       {
3594         operands[2] = GEN_INT (INTVAL (operands[2])
3595                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3597         if (operands[2] == const0_rtx)
3598           {
3599             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3600             DONE;
3601           }
3602       }
3603   }
3606 (define_expand "ashl<mode>3"
3607   [(set (match_operand:SHORT 0 "register_operand")
3608         (ashift:SHORT (match_operand:SHORT 1 "register_operand")
3609                       (match_operand:QI 2 "nonmemory_operand")))]
3610   ""
3611   {
3612     if (CONST_INT_P (operands[2]))
3613       {
3614         operands[2] = GEN_INT (INTVAL (operands[2])
3615                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3617         if (operands[2] == const0_rtx)
3618           {
3619             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3620             DONE;
3621           }
3622       }
3623     else
3624       FAIL;
3625   }
3628 (define_expand "rotr<mode>3"
3629   [(set (match_operand:GPI 0 "register_operand")
3630         (rotatert:GPI (match_operand:GPI 1 "register_operand")
3631                       (match_operand:QI 2 "nonmemory_operand")))]
3632   ""
3633   {
3634     if (CONST_INT_P (operands[2]))
3635       {
3636         operands[2] = GEN_INT (INTVAL (operands[2])
3637                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3639         if (operands[2] == const0_rtx)
3640           {
3641             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3642             DONE;
3643           }
3644       }
3645   }
3648 (define_expand "rotl<mode>3"
3649   [(set (match_operand:GPI 0 "register_operand")
3650         (rotatert:GPI (match_operand:GPI 1 "register_operand")
3651                       (match_operand:QI 2 "nonmemory_operand")))]
3652   ""
3653   {
3654     /* (SZ - cnt) % SZ == -cnt % SZ */
3655     if (CONST_INT_P (operands[2]))
3656       {
3657         operands[2] = GEN_INT ((-INTVAL (operands[2]))
3658                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3659         if (operands[2] == const0_rtx)
3660           {
3661             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3662             DONE;
3663           }
3664       }
3665     else
3666       operands[2] = expand_simple_unop (QImode, NEG, operands[2],
3667                                         NULL_RTX, 1);
3668   }
3671 ;; Logical left shift using SISD or Integer instruction
3672 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
3673   [(set (match_operand:GPI 0 "register_operand" "=r,w,w")
3674         (ashift:GPI
3675           (match_operand:GPI 1 "register_operand" "r,w,w")
3676           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>,Us<cmode>,w")))]
3677   ""
3678   "@
3679    lsl\t%<w>0, %<w>1, %<w>2
3680    shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3681    ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>"
3682   [(set_attr "simd" "no,yes,yes")
3683    (set_attr "type" "shift_reg,neon_shift_imm<q>, neon_shift_reg<q>")]
3686 ;; Logical right shift using SISD or Integer instruction
3687 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3688   [(set (match_operand:GPI 0 "register_operand" "=r,w,&w,&w")
3689         (lshiftrt:GPI
3690           (match_operand:GPI 1 "register_operand" "r,w,w,w")
3691           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>,Us<cmode>,w,0")))]
3692   ""
3693   "@
3694    lsr\t%<w>0, %<w>1, %<w>2
3695    ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3696    #
3697    #"
3698   [(set_attr "simd" "no,yes,yes,yes")
3699    (set_attr "type" "shift_reg,neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>")]
3702 (define_split
3703   [(set (match_operand:DI 0 "aarch64_simd_register")
3704         (lshiftrt:DI
3705            (match_operand:DI 1 "aarch64_simd_register")
3706            (match_operand:QI 2 "aarch64_simd_register")))]
3707   "TARGET_SIMD && reload_completed"
3708   [(set (match_dup 3)
3709         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3710    (set (match_dup 0)
3711         (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_USHL))]
3712   {
3713     operands[3] = gen_lowpart (QImode, operands[0]);
3714   }
3717 (define_split
3718   [(set (match_operand:SI 0 "aarch64_simd_register")
3719         (lshiftrt:SI
3720            (match_operand:SI 1 "aarch64_simd_register")
3721            (match_operand:QI 2 "aarch64_simd_register")))]
3722   "TARGET_SIMD && reload_completed"
3723   [(set (match_dup 3)
3724         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3725    (set (match_dup 0)
3726         (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_USHL_2S))]
3727   {
3728     operands[3] = gen_lowpart (QImode, operands[0]);
3729   }
3732 ;; Arithmetic right shift using SISD or Integer instruction
3733 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3734   [(set (match_operand:GPI 0 "register_operand" "=r,w,&w,&w")
3735         (ashiftrt:GPI
3736           (match_operand:GPI 1 "register_operand" "r,w,w,w")
3737           (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "rUs<cmode>,Us<cmode>,w,0")))]
3738   ""
3739   "@
3740    asr\t%<w>0, %<w>1, %<w>2
3741    sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3742    #
3743    #"
3744   [(set_attr "simd" "no,yes,yes,yes")
3745    (set_attr "type" "shift_reg,neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>")]
3748 (define_split
3749   [(set (match_operand:DI 0 "aarch64_simd_register")
3750         (ashiftrt:DI
3751            (match_operand:DI 1 "aarch64_simd_register")
3752            (match_operand:QI 2 "aarch64_simd_register")))]
3753   "TARGET_SIMD && reload_completed"
3754   [(set (match_dup 3)
3755         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3756    (set (match_dup 0)
3757         (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_SSHL))]
3759   operands[3] = gen_lowpart (QImode, operands[0]);
3763 (define_split
3764   [(set (match_operand:SI 0 "aarch64_simd_register")
3765         (ashiftrt:SI
3766            (match_operand:SI 1 "aarch64_simd_register")
3767            (match_operand:QI 2 "aarch64_simd_register")))]
3768   "TARGET_SIMD && reload_completed"
3769   [(set (match_dup 3)
3770         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3771    (set (match_dup 0)
3772         (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_SSHL_2S))]
3774   operands[3] = gen_lowpart (QImode, operands[0]);
3778 (define_insn "*aarch64_sisd_ushl"
3779   [(set (match_operand:DI 0 "register_operand" "=w")
3780         (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3781                     (match_operand:QI 2 "register_operand" "w")]
3782                    UNSPEC_SISD_USHL))]
3783   "TARGET_SIMD"
3784   "ushl\t%d0, %d1, %d2"
3785   [(set_attr "simd" "yes")
3786    (set_attr "type" "neon_shift_reg")]
3789 (define_insn "*aarch64_ushl_2s"
3790   [(set (match_operand:SI 0 "register_operand" "=w")
3791         (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3792                     (match_operand:QI 2 "register_operand" "w")]
3793                    UNSPEC_USHL_2S))]
3794   "TARGET_SIMD"
3795   "ushl\t%0.2s, %1.2s, %2.2s"
3796   [(set_attr "simd" "yes")
3797    (set_attr "type" "neon_shift_reg")]
3800 (define_insn "*aarch64_sisd_sshl"
3801   [(set (match_operand:DI 0 "register_operand" "=w")
3802         (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3803                     (match_operand:QI 2 "register_operand" "w")]
3804                    UNSPEC_SISD_SSHL))]
3805   "TARGET_SIMD"
3806   "sshl\t%d0, %d1, %d2"
3807   [(set_attr "simd" "yes")
3808    (set_attr "type" "neon_shift_reg")]
3811 (define_insn "*aarch64_sshl_2s"
3812   [(set (match_operand:SI 0 "register_operand" "=w")
3813         (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3814                     (match_operand:QI 2 "register_operand" "w")]
3815                    UNSPEC_SSHL_2S))]
3816   "TARGET_SIMD"
3817   "sshl\t%0.2s, %1.2s, %2.2s"
3818   [(set_attr "simd" "yes")
3819    (set_attr "type" "neon_shift_reg")]
3822 (define_insn "*aarch64_sisd_neg_qi"
3823   [(set (match_operand:QI 0 "register_operand" "=w")
3824         (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3825                    UNSPEC_SISD_NEG))]
3826   "TARGET_SIMD"
3827   "neg\t%d0, %d1"
3828   [(set_attr "simd" "yes")
3829    (set_attr "type" "neon_neg")]
3832 ;; Rotate right
3833 (define_insn "*ror<mode>3_insn"
3834   [(set (match_operand:GPI 0 "register_operand" "=r,r")
3835      (rotatert:GPI
3836        (match_operand:GPI 1 "register_operand" "r,r")
3837        (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "r,Us<cmode>")))]
3838   ""
3839   "ror\\t%<w>0, %<w>1, %<w>2"
3840   [(set_attr "type" "shift_reg, rotate_imm")]
3843 ;; zero_extend version of above
3844 (define_insn "*<optab>si3_insn_uxtw"
3845   [(set (match_operand:DI 0 "register_operand" "=r")
3846         (zero_extend:DI (SHIFT:SI
3847          (match_operand:SI 1 "register_operand" "r")
3848          (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3849   ""
3850   "<shift>\\t%w0, %w1, %w2"
3851   [(set_attr "type" "shift_reg")]
3854 (define_insn "*<optab><mode>3_insn"
3855   [(set (match_operand:SHORT 0 "register_operand" "=r")
3856         (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3857                       (match_operand 2 "const_int_operand" "n")))]
3858   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3860   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3861   return "<bfshift>\t%w0, %w1, %2, %3";
3863   [(set_attr "type" "bfm")]
3866 (define_insn "*extr<mode>5_insn"
3867   [(set (match_operand:GPI 0 "register_operand" "=r")
3868         (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3869                              (match_operand 3 "const_int_operand" "n"))
3870                  (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3871                                (match_operand 4 "const_int_operand" "n"))))]
3872   "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3873    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3874   "extr\\t%<w>0, %<w>1, %<w>2, %4"
3875   [(set_attr "type" "shift_imm")]
3878 ;; There are no canonicalisation rules for ashift and lshiftrt inside an ior
3879 ;; so we have to match both orderings.
3880 (define_insn "*extr<mode>5_insn_alt"
3881   [(set (match_operand:GPI 0 "register_operand" "=r")
3882         (ior:GPI  (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3883                                 (match_operand 4 "const_int_operand" "n"))
3884                   (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3885                               (match_operand 3 "const_int_operand" "n"))))]
3886   "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode)
3887    && (UINTVAL (operands[3]) + UINTVAL (operands[4])
3888        == GET_MODE_BITSIZE (<MODE>mode))"
3889   "extr\\t%<w>0, %<w>1, %<w>2, %4"
3890   [(set_attr "type" "shift_imm")]
3893 ;; zero_extend version of the above
3894 (define_insn "*extrsi5_insn_uxtw"
3895   [(set (match_operand:DI 0 "register_operand" "=r")
3896         (zero_extend:DI
3897          (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3898                             (match_operand 3 "const_int_operand" "n"))
3899                  (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3900                               (match_operand 4 "const_int_operand" "n")))))]
3901   "UINTVAL (operands[3]) < 32 &&
3902    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3903   "extr\\t%w0, %w1, %w2, %4"
3904   [(set_attr "type" "shift_imm")]
3907 (define_insn "*extrsi5_insn_uxtw_alt"
3908   [(set (match_operand:DI 0 "register_operand" "=r")
3909         (zero_extend:DI
3910          (ior:SI (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3911                                (match_operand 4 "const_int_operand" "n"))
3912                  (ashift:SI (match_operand:SI 1 "register_operand" "r")
3913                             (match_operand 3 "const_int_operand" "n")))))]
3914   "UINTVAL (operands[3]) < 32 &&
3915    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3916   "extr\\t%w0, %w1, %w2, %4"
3917   [(set_attr "type" "shift_imm")]
3920 (define_insn "*ror<mode>3_insn"
3921   [(set (match_operand:GPI 0 "register_operand" "=r")
3922         (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3923                     (match_operand 2 "const_int_operand" "n")))]
3924   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3926   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3927   return "ror\\t%<w>0, %<w>1, %3";
3929   [(set_attr "type" "rotate_imm")]
3932 ;; zero_extend version of the above
3933 (define_insn "*rorsi3_insn_uxtw"
3934   [(set (match_operand:DI 0 "register_operand" "=r")
3935         (zero_extend:DI
3936          (rotate:SI (match_operand:SI 1 "register_operand" "r")
3937                     (match_operand 2 "const_int_operand" "n"))))]
3938   "UINTVAL (operands[2]) < 32"
3940   operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3941   return "ror\\t%w0, %w1, %3";
3943   [(set_attr "type" "rotate_imm")]
3946 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3947   [(set (match_operand:GPI 0 "register_operand" "=r")
3948         (ANY_EXTEND:GPI
3949          (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3950                        (match_operand 2 "const_int_operand" "n"))))]
3951   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3953   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3954   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3956   [(set_attr "type" "bfm")]
3959 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3960   [(set (match_operand:GPI 0 "register_operand" "=r")
3961         (zero_extend:GPI
3962          (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3963                          (match_operand 2 "const_int_operand" "n"))))]
3964   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3966   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3967   return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3969   [(set_attr "type" "bfm")]
3972 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3973   [(set (match_operand:GPI 0 "register_operand" "=r")
3974         (sign_extend:GPI
3975          (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3976                          (match_operand 2 "const_int_operand" "n"))))]
3977   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3979   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3980   return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3982   [(set_attr "type" "bfm")]
3985 ;; -------------------------------------------------------------------
3986 ;; Bitfields
3987 ;; -------------------------------------------------------------------
3989 (define_expand "<optab>"
3990   [(set (match_operand:DI 0 "register_operand" "=r")
3991         (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3992                         (match_operand 2 "const_int_operand" "n")
3993                         (match_operand 3 "const_int_operand" "n")))]
3994   ""
3995   ""
3998 (define_insn "*<optab><mode>"
3999   [(set (match_operand:GPI 0 "register_operand" "=r")
4000         (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
4001                          (match_operand 2 "const_int_operand" "n")
4002                          (match_operand 3 "const_int_operand" "n")))]
4003   ""
4004   "<su>bfx\\t%<w>0, %<w>1, %3, %2"
4005   [(set_attr "type" "bfm")]
4008 ;; Bitfield Insert (insv)
4009 (define_expand "insv<mode>"
4010   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
4011                           (match_operand 1 "const_int_operand")
4012                           (match_operand 2 "const_int_operand"))
4013         (match_operand:GPI 3 "general_operand"))]
4014   ""
4016   unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
4017   unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
4018   rtx value = operands[3];
4020   if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
4021     FAIL;
4023   if (CONST_INT_P (value))
4024     {
4025       unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
4027       /* Prefer AND/OR for inserting all zeros or all ones.  */
4028       if ((UINTVAL (value) & mask) == 0
4029            || (UINTVAL (value) & mask) == mask)
4030         FAIL;
4032       /* 16-bit aligned 16-bit wide insert is handled by insv_imm.  */
4033       if (width == 16 && (pos % 16) == 0)
4034         DONE;
4035     }
4036   operands[3] = force_reg (<MODE>mode, value);
4039 (define_insn "*insv_reg<mode>"
4040   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
4041                           (match_operand 1 "const_int_operand" "n")
4042                           (match_operand 2 "const_int_operand" "n"))
4043         (match_operand:GPI 3 "register_operand" "r"))]
4044   "!(UINTVAL (operands[1]) == 0
4045      || (UINTVAL (operands[2]) + UINTVAL (operands[1])
4046          > GET_MODE_BITSIZE (<MODE>mode)))"
4047   "bfi\\t%<w>0, %<w>3, %2, %1"
4048   [(set_attr "type" "bfm")]
4051 (define_insn "*aarch64_bfi<GPI:mode><ALLX:mode>4"
4052   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
4053                           (match_operand 1 "const_int_operand" "n")
4054                           (match_operand 2 "const_int_operand" "n"))
4055         (zero_extend:GPI (match_operand:ALLX 3  "register_operand" "r")))]
4056   "UINTVAL (operands[1]) <= <ALLX:sizen>"
4057   "bfi\\t%<GPI:w>0, %<GPI:w>3, %2, %1"
4058   [(set_attr "type" "bfm")]
4061 (define_insn "*extr_insv_lower_reg<mode>"
4062   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
4063                           (match_operand 1 "const_int_operand" "n")
4064                           (const_int 0))
4065         (zero_extract:GPI (match_operand:GPI 2 "register_operand" "r")
4066                           (match_dup 1)
4067                           (match_operand 3 "const_int_operand" "n")))]
4068   "!(UINTVAL (operands[1]) == 0
4069      || (UINTVAL (operands[3]) + UINTVAL (operands[1])
4070          > GET_MODE_BITSIZE (<MODE>mode)))"
4071   "bfxil\\t%<w>0, %<w>2, %3, %1"
4072   [(set_attr "type" "bfm")]
4075 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
4076   [(set (match_operand:GPI 0 "register_operand" "=r")
4077         (ashift:GPI (ANY_EXTEND:GPI
4078                      (match_operand:ALLX 1 "register_operand" "r"))
4079                     (match_operand 2 "const_int_operand" "n")))]
4080   "UINTVAL (operands[2]) < <GPI:sizen>"
4082   operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
4083               ? GEN_INT (<ALLX:sizen>)
4084               : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
4085   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
4087   [(set_attr "type" "bfm")]
4090 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
4092 (define_insn "*andim_ashift<mode>_bfiz"
4093   [(set (match_operand:GPI 0 "register_operand" "=r")
4094         (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
4095                              (match_operand 2 "const_int_operand" "n"))
4096                  (match_operand 3 "const_int_operand" "n")))]
4097   "(INTVAL (operands[2]) < (<GPI:sizen>))
4098    && exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
4099    && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
4100   "ubfiz\\t%<w>0, %<w>1, %2, %P3"
4101   [(set_attr "type" "bfm")]
4104 (define_insn "bswap<mode>2"
4105   [(set (match_operand:GPI 0 "register_operand" "=r")
4106         (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
4107   ""
4108   "rev\\t%<w>0, %<w>1"
4109   [(set_attr "type" "rev")]
4112 (define_insn "bswaphi2"
4113   [(set (match_operand:HI 0 "register_operand" "=r")
4114         (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
4115   ""
4116   "rev16\\t%w0, %w1"
4117   [(set_attr "type" "rev")]
4120 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
4121 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
4122 ;; each valid permutation.
4124 (define_insn "rev16<mode>2"
4125   [(set (match_operand:GPI 0 "register_operand" "=r")
4126         (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
4127                                       (const_int 8))
4128                           (match_operand:GPI 3 "const_int_operand" "n"))
4129                  (and:GPI (lshiftrt:GPI (match_dup 1)
4130                                         (const_int 8))
4131                           (match_operand:GPI 2 "const_int_operand" "n"))))]
4132   "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
4133    && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
4134   "rev16\\t%<w>0, %<w>1"
4135   [(set_attr "type" "rev")]
4138 (define_insn "rev16<mode>2_alt"
4139   [(set (match_operand:GPI 0 "register_operand" "=r")
4140         (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r")
4141                                         (const_int 8))
4142                           (match_operand:GPI 2 "const_int_operand" "n"))
4143                  (and:GPI (ashift:GPI (match_dup 1)
4144                                       (const_int 8))
4145                           (match_operand:GPI 3 "const_int_operand" "n"))))]
4146   "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
4147    && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
4148   "rev16\\t%<w>0, %<w>1"
4149   [(set_attr "type" "rev")]
4152 ;; zero_extend version of above
4153 (define_insn "*bswapsi2_uxtw"
4154   [(set (match_operand:DI 0 "register_operand" "=r")
4155         (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
4156   ""
4157   "rev\\t%w0, %w1"
4158   [(set_attr "type" "rev")]
4161 ;; -------------------------------------------------------------------
4162 ;; Floating-point intrinsics
4163 ;; -------------------------------------------------------------------
4165 ;; frint floating-point round to integral standard patterns.
4166 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round, frintn.
4168 (define_insn "<frint_pattern><mode>2"
4169   [(set (match_operand:GPF 0 "register_operand" "=w")
4170         (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
4171          FRINT))]
4172   "TARGET_FLOAT"
4173   "frint<frint_suffix>\\t%<s>0, %<s>1"
4174   [(set_attr "type" "f_rint<s>")]
4177 ;; frcvt floating-point round to integer and convert standard patterns.
4178 ;; Expands to lbtrunc, lceil, lfloor, lround.
4179 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
4180   [(set (match_operand:GPI 0 "register_operand" "=r")
4181         (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
4182                       FCVT)))]
4183   "TARGET_FLOAT"
4184   "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
4185   [(set_attr "type" "f_cvtf2i")]
4188 ;; fma - no throw
4190 (define_insn "fma<mode>4"
4191   [(set (match_operand:GPF 0 "register_operand" "=w")
4192         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
4193                  (match_operand:GPF 2 "register_operand" "w")
4194                  (match_operand:GPF 3 "register_operand" "w")))]
4195   "TARGET_FLOAT"
4196   "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
4197   [(set_attr "type" "fmac<s>")]
4200 (define_insn "fnma<mode>4"
4201   [(set (match_operand:GPF 0 "register_operand" "=w")
4202         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
4203                  (match_operand:GPF 2 "register_operand" "w")
4204                  (match_operand:GPF 3 "register_operand" "w")))]
4205   "TARGET_FLOAT"
4206   "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
4207   [(set_attr "type" "fmac<s>")]
4210 (define_insn "fms<mode>4"
4211   [(set (match_operand:GPF 0 "register_operand" "=w")
4212         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
4213                  (match_operand:GPF 2 "register_operand" "w")
4214                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
4215   "TARGET_FLOAT"
4216   "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
4217   [(set_attr "type" "fmac<s>")]
4220 (define_insn "fnms<mode>4"
4221   [(set (match_operand:GPF 0 "register_operand" "=w")
4222         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
4223                  (match_operand:GPF 2 "register_operand" "w")
4224                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
4225   "TARGET_FLOAT"
4226   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
4227   [(set_attr "type" "fmac<s>")]
4230 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
4231 (define_insn "*fnmadd<mode>4"
4232   [(set (match_operand:GPF 0 "register_operand" "=w")
4233         (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
4234                           (match_operand:GPF 2 "register_operand" "w")
4235                           (match_operand:GPF 3 "register_operand" "w"))))]
4236   "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
4237   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
4238   [(set_attr "type" "fmac<s>")]
4241 ;; -------------------------------------------------------------------
4242 ;; Floating-point conversions
4243 ;; -------------------------------------------------------------------
4245 (define_insn "extendsfdf2"
4246   [(set (match_operand:DF 0 "register_operand" "=w")
4247         (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
4248   "TARGET_FLOAT"
4249   "fcvt\\t%d0, %s1"
4250   [(set_attr "type" "f_cvt")]
4253 (define_insn "extendhfsf2"
4254   [(set (match_operand:SF 0 "register_operand" "=w")
4255         (float_extend:SF (match_operand:HF 1 "register_operand" "w")))]
4256   "TARGET_FLOAT"
4257   "fcvt\\t%s0, %h1"
4258   [(set_attr "type" "f_cvt")]
4261 (define_insn "extendhfdf2"
4262   [(set (match_operand:DF 0 "register_operand" "=w")
4263         (float_extend:DF (match_operand:HF 1 "register_operand" "w")))]
4264   "TARGET_FLOAT"
4265   "fcvt\\t%d0, %h1"
4266   [(set_attr "type" "f_cvt")]
4269 (define_insn "truncdfsf2"
4270   [(set (match_operand:SF 0 "register_operand" "=w")
4271         (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
4272   "TARGET_FLOAT"
4273   "fcvt\\t%s0, %d1"
4274   [(set_attr "type" "f_cvt")]
4277 (define_insn "truncsfhf2"
4278   [(set (match_operand:HF 0 "register_operand" "=w")
4279         (float_truncate:HF (match_operand:SF 1 "register_operand" "w")))]
4280   "TARGET_FLOAT"
4281   "fcvt\\t%h0, %s1"
4282   [(set_attr "type" "f_cvt")]
4285 (define_insn "truncdfhf2"
4286   [(set (match_operand:HF 0 "register_operand" "=w")
4287         (float_truncate:HF (match_operand:DF 1 "register_operand" "w")))]
4288   "TARGET_FLOAT"
4289   "fcvt\\t%h0, %d1"
4290   [(set_attr "type" "f_cvt")]
4293 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
4294   [(set (match_operand:GPI 0 "register_operand" "=r")
4295         (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
4296   "TARGET_FLOAT"
4297   "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
4298   [(set_attr "type" "f_cvtf2i")]
4301 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
4302   [(set (match_operand:GPI 0 "register_operand" "=r")
4303         (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
4304   "TARGET_FLOAT"
4305   "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
4306   [(set_attr "type" "f_cvtf2i")]
4309 (define_insn "<optab><fcvt_target><GPF:mode>2"
4310   [(set (match_operand:GPF 0 "register_operand" "=w,w")
4311         (FLOATUORS:GPF (match_operand:<FCVT_TARGET> 1 "register_operand" "w,r")))]
4312   "TARGET_FLOAT"
4313   "@
4314    <su_optab>cvtf\t%<GPF:s>0, %<s>1
4315    <su_optab>cvtf\t%<GPF:s>0, %<w1>1"
4316   [(set_attr "simd" "yes,no")
4317    (set_attr "fp" "no,yes")
4318    (set_attr "type" "neon_int_to_fp_<Vetype>,f_cvti2f")]
4321 (define_insn "<optab><fcvt_iesize><GPF:mode>2"
4322   [(set (match_operand:GPF 0 "register_operand" "=w")
4323         (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand" "r")))]
4324   "TARGET_FLOAT"
4325   "<su_optab>cvtf\t%<GPF:s>0, %<w2>1"
4326   [(set_attr "type" "f_cvti2f")]
4329 ;; -------------------------------------------------------------------
4330 ;; Floating-point arithmetic
4331 ;; -------------------------------------------------------------------
4333 (define_insn "add<mode>3"
4334   [(set (match_operand:GPF 0 "register_operand" "=w")
4335         (plus:GPF
4336          (match_operand:GPF 1 "register_operand" "w")
4337          (match_operand:GPF 2 "register_operand" "w")))]
4338   "TARGET_FLOAT"
4339   "fadd\\t%<s>0, %<s>1, %<s>2"
4340   [(set_attr "type" "fadd<s>")]
4343 (define_insn "sub<mode>3"
4344   [(set (match_operand:GPF 0 "register_operand" "=w")
4345         (minus:GPF
4346          (match_operand:GPF 1 "register_operand" "w")
4347          (match_operand:GPF 2 "register_operand" "w")))]
4348   "TARGET_FLOAT"
4349   "fsub\\t%<s>0, %<s>1, %<s>2"
4350   [(set_attr "type" "fadd<s>")]
4353 (define_insn "mul<mode>3"
4354   [(set (match_operand:GPF 0 "register_operand" "=w")
4355         (mult:GPF
4356          (match_operand:GPF 1 "register_operand" "w")
4357          (match_operand:GPF 2 "register_operand" "w")))]
4358   "TARGET_FLOAT"
4359   "fmul\\t%<s>0, %<s>1, %<s>2"
4360   [(set_attr "type" "fmul<s>")]
4363 (define_insn "*fnmul<mode>3"
4364   [(set (match_operand:GPF 0 "register_operand" "=w")
4365         (mult:GPF
4366                  (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
4367                  (match_operand:GPF 2 "register_operand" "w")))]
4368   "TARGET_FLOAT && !flag_rounding_math"
4369   "fnmul\\t%<s>0, %<s>1, %<s>2"
4370   [(set_attr "type" "fmul<s>")]
4373 (define_insn "*fnmul<mode>3"
4374   [(set (match_operand:GPF 0 "register_operand" "=w")
4375         (neg:GPF (mult:GPF
4376                  (match_operand:GPF 1 "register_operand" "w")
4377                  (match_operand:GPF 2 "register_operand" "w"))))]
4378   "TARGET_FLOAT"
4379   "fnmul\\t%<s>0, %<s>1, %<s>2"
4380   [(set_attr "type" "fmul<s>")]
4383 (define_insn "div<mode>3"
4384   [(set (match_operand:GPF 0 "register_operand" "=w")
4385         (div:GPF
4386          (match_operand:GPF 1 "register_operand" "w")
4387          (match_operand:GPF 2 "register_operand" "w")))]
4388   "TARGET_FLOAT"
4389   "fdiv\\t%<s>0, %<s>1, %<s>2"
4390   [(set_attr "type" "fdiv<s>")]
4393 (define_insn "neg<mode>2"
4394   [(set (match_operand:GPF 0 "register_operand" "=w")
4395         (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
4396   "TARGET_FLOAT"
4397   "fneg\\t%<s>0, %<s>1"
4398   [(set_attr "type" "ffarith<s>")]
4401 (define_insn "sqrt<mode>2"
4402   [(set (match_operand:GPF 0 "register_operand" "=w")
4403         (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
4404   "TARGET_FLOAT"
4405   "fsqrt\\t%<s>0, %<s>1"
4406   [(set_attr "type" "fsqrt<s>")]
4409 (define_insn "abs<mode>2"
4410   [(set (match_operand:GPF 0 "register_operand" "=w")
4411         (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
4412   "TARGET_FLOAT"
4413   "fabs\\t%<s>0, %<s>1"
4414   [(set_attr "type" "ffarith<s>")]
4417 ;; Given that smax/smin do not specify the result when either input is NaN,
4418 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
4419 ;; for smin.
4421 (define_insn "smax<mode>3"
4422   [(set (match_operand:GPF 0 "register_operand" "=w")
4423         (smax:GPF (match_operand:GPF 1 "register_operand" "w")
4424                   (match_operand:GPF 2 "register_operand" "w")))]
4425   "TARGET_FLOAT"
4426   "fmaxnm\\t%<s>0, %<s>1, %<s>2"
4427   [(set_attr "type" "f_minmax<s>")]
4430 (define_insn "smin<mode>3"
4431   [(set (match_operand:GPF 0 "register_operand" "=w")
4432         (smin:GPF (match_operand:GPF 1 "register_operand" "w")
4433                   (match_operand:GPF 2 "register_operand" "w")))]
4434   "TARGET_FLOAT"
4435   "fminnm\\t%<s>0, %<s>1, %<s>2"
4436   [(set_attr "type" "f_minmax<s>")]
4439 ;; For copysign (x, y), we want to generate:
4441 ;;   LDR d2, #(1 << 63)
4442 ;;   BSL v2.8b, [y], [x]
4444 ;; or another, equivalent, sequence using one of BSL/BIT/BIF.
4445 ;; aarch64_simd_bsldf will select the best suited of these instructions
4446 ;; to generate based on register allocation, and knows how to partially
4447 ;; constant fold based on the values of X and Y, so expand through that.
4449 (define_expand "copysigndf3"
4450   [(match_operand:DF 0 "register_operand")
4451    (match_operand:DF 1 "register_operand")
4452    (match_operand:DF 2 "register_operand")]
4453   "TARGET_FLOAT && TARGET_SIMD"
4455   rtx mask = gen_reg_rtx (DImode);
4456   emit_move_insn (mask, GEN_INT (HOST_WIDE_INT_1U << 63));
4457   emit_insn (gen_aarch64_simd_bsldf (operands[0], mask,
4458                                      operands[2], operands[1]));
4459   DONE;
4463 ;; As above, but we must first get to a 64-bit value if we wish to use
4464 ;; aarch64_simd_bslv2sf.
4466 (define_expand "copysignsf3"
4467   [(match_operand:SF 0 "register_operand")
4468    (match_operand:SF 1 "register_operand")
4469    (match_operand:SF 2 "register_operand")]
4470   "TARGET_FLOAT && TARGET_SIMD"
4472   rtx mask = gen_reg_rtx (DImode);
4474   /* Juggle modes to get us in to a vector mode for BSL.  */
4475   rtx op1 = lowpart_subreg (V2SFmode, operands[1], SFmode);
4476   rtx op2 = lowpart_subreg (V2SFmode, operands[2], SFmode);
4477   rtx tmp = gen_reg_rtx (V2SFmode);
4478   emit_move_insn (mask, GEN_INT (HOST_WIDE_INT_1U << 31));
4479   emit_insn (gen_aarch64_simd_bslv2sf (tmp, mask, op2, op1));
4480   emit_move_insn (operands[0], lowpart_subreg (SFmode, tmp, V2SFmode));
4481   DONE;
4485 ;; -------------------------------------------------------------------
4486 ;; Reload support
4487 ;; -------------------------------------------------------------------
4488 ;; Reload Scalar Floating point modes from constant pool.
4489 ;; The AArch64 port doesn't have __int128 constant move support.
4490 (define_expand "aarch64_reload_movcp<GPF_TF:mode><P:mode>"
4491  [(set (match_operand:GPF_TF 0 "register_operand" "=w")
4492        (mem:GPF_TF (match_operand 1 "aarch64_constant_pool_symref" "S")))
4493   (clobber (match_operand:P 2 "register_operand" "=&r"))]
4494  "TARGET_FLOAT && nopcrelative_literal_loads"
4496    aarch64_expand_mov_immediate (operands[2], XEXP (operands[1], 0));
4497    emit_move_insn (operands[0], gen_rtx_MEM (<GPF_TF:MODE>mode, operands[2]));
4498    DONE;
4502 ;; Reload Vector modes from constant pool.
4503 (define_expand "aarch64_reload_movcp<VALL:mode><P:mode>"
4504  [(set (match_operand:VALL 0 "register_operand" "=w")
4505        (mem:VALL (match_operand 1 "aarch64_constant_pool_symref" "S")))
4506   (clobber (match_operand:P 2 "register_operand" "=&r"))]
4507  "TARGET_FLOAT && nopcrelative_literal_loads"
4509    aarch64_expand_mov_immediate (operands[2], XEXP (operands[1], 0));
4510    emit_move_insn (operands[0], gen_rtx_MEM (<VALL:MODE>mode, operands[2]));
4511    DONE;
4515 (define_expand "aarch64_reload_mov<mode>"
4516   [(set (match_operand:TX 0 "register_operand" "=w")
4517         (match_operand:TX 1 "register_operand" "w"))
4518    (clobber (match_operand:DI 2 "register_operand" "=&r"))
4519   ]
4520   "TARGET_FLOAT"
4521   {
4522     rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
4523     rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
4524     gen_aarch64_movtilow_tilow (op0, op1);
4525     gen_aarch64_movdi_tihigh (operands[2], op1);
4526     gen_aarch64_movtihigh_di (op0, operands[2]);
4527     DONE;
4528   }
4531 ;; The following secondary reload helpers patterns are invoked
4532 ;; after or during reload as we don't want these patterns to start
4533 ;; kicking in during the combiner.
4535 (define_insn "aarch64_movdi_<mode>low"
4536   [(set (match_operand:DI 0 "register_operand" "=r")
4537         (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
4538   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4539   "fmov\\t%x0, %d1"
4540   [(set_attr "type" "f_mrc")
4541    (set_attr "length" "4")
4542   ])
4544 (define_insn "aarch64_movdi_<mode>high"
4545   [(set (match_operand:DI 0 "register_operand" "=r")
4546         (truncate:DI
4547           (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
4548                        (const_int 64))))]
4549   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4550   "fmov\\t%x0, %1.d[1]"
4551   [(set_attr "type" "f_mrc")
4552    (set_attr "length" "4")
4553   ])
4555 (define_insn "aarch64_mov<mode>high_di"
4556   [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
4557                          (const_int 64) (const_int 64))
4558         (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4559   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4560   "fmov\\t%0.d[1], %x1"
4561   [(set_attr "type" "f_mcr")
4562    (set_attr "length" "4")
4563   ])
4565 (define_insn "aarch64_mov<mode>low_di"
4566   [(set (match_operand:TX 0 "register_operand" "=w")
4567         (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4568   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4569   "fmov\\t%d0, %x1"
4570   [(set_attr "type" "f_mcr")
4571    (set_attr "length" "4")
4572   ])
4574 (define_insn "aarch64_movtilow_tilow"
4575   [(set (match_operand:TI 0 "register_operand" "=w")
4576         (zero_extend:TI
4577           (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
4578   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4579   "fmov\\t%d0, %d1"
4580   [(set_attr "type" "fmov")
4581    (set_attr "length" "4")
4582   ])
4584 ;; There is a deliberate reason why the parameters of high and lo_sum's
4585 ;; don't have modes for ADRP and ADD instructions.  This is to allow high
4586 ;; and lo_sum's to be used with the labels defining the jump tables in
4587 ;; rodata section.
4589 (define_expand "add_losym"
4590   [(set (match_operand 0 "register_operand" "=r")
4591         (lo_sum (match_operand 1 "register_operand" "r")
4592                 (match_operand 2 "aarch64_valid_symref" "S")))]
4593   ""
4595   machine_mode mode = GET_MODE (operands[0]);
4597   emit_insn ((mode == DImode
4598               ? gen_add_losym_di
4599               : gen_add_losym_si) (operands[0],
4600                                    operands[1],
4601                                    operands[2]));
4602   DONE;
4605 (define_insn "add_losym_<mode>"
4606   [(set (match_operand:P 0 "register_operand" "=r")
4607         (lo_sum:P (match_operand:P 1 "register_operand" "r")
4608                   (match_operand 2 "aarch64_valid_symref" "S")))]
4609   ""
4610   "add\\t%<w>0, %<w>1, :lo12:%a2"
4611   [(set_attr "type" "alu_imm")]
4614 (define_insn "ldr_got_small_<mode>"
4615   [(set (match_operand:PTR 0 "register_operand" "=r")
4616         (unspec:PTR [(mem:PTR (lo_sum:PTR
4617                               (match_operand:PTR 1 "register_operand" "r")
4618                               (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
4619                     UNSPEC_GOTSMALLPIC))]
4620   ""
4621   "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
4622   [(set_attr "type" "load1")]
4625 (define_insn "ldr_got_small_sidi"
4626   [(set (match_operand:DI 0 "register_operand" "=r")
4627         (zero_extend:DI
4628          (unspec:SI [(mem:SI (lo_sum:DI
4629                              (match_operand:DI 1 "register_operand" "r")
4630                              (match_operand:DI 2 "aarch64_valid_symref" "S")))]
4631                     UNSPEC_GOTSMALLPIC)))]
4632   "TARGET_ILP32"
4633   "ldr\\t%w0, [%1, #:got_lo12:%a2]"
4634   [(set_attr "type" "load1")]
4637 (define_insn "ldr_got_small_28k_<mode>"
4638   [(set (match_operand:PTR 0 "register_operand" "=r")
4639         (unspec:PTR [(mem:PTR (lo_sum:PTR
4640                               (match_operand:PTR 1 "register_operand" "r")
4641                               (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
4642                     UNSPEC_GOTSMALLPIC28K))]
4643   ""
4644   "ldr\\t%<w>0, [%1, #:<got_modifier>:%a2]"
4645   [(set_attr "type" "load1")]
4648 (define_insn "ldr_got_small_28k_sidi"
4649   [(set (match_operand:DI 0 "register_operand" "=r")
4650         (zero_extend:DI
4651          (unspec:SI [(mem:SI (lo_sum:DI
4652                              (match_operand:DI 1 "register_operand" "r")
4653                              (match_operand:DI 2 "aarch64_valid_symref" "S")))]
4654                     UNSPEC_GOTSMALLPIC28K)))]
4655   "TARGET_ILP32"
4656   "ldr\\t%w0, [%1, #:gotpage_lo14:%a2]"
4657   [(set_attr "type" "load1")]
4660 (define_insn "ldr_got_tiny"
4661   [(set (match_operand:DI 0 "register_operand" "=r")
4662         (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
4663                    UNSPEC_GOTTINYPIC))]
4664   ""
4665   "ldr\\t%0, %L1"
4666   [(set_attr "type" "load1")]
4669 (define_insn "aarch64_load_tp_hard"
4670   [(set (match_operand:DI 0 "register_operand" "=r")
4671         (unspec:DI [(const_int 0)] UNSPEC_TLS))]
4672   ""
4673   "mrs\\t%0, tpidr_el0"
4674   [(set_attr "type" "mrs")]
4677 ;; The TLS ABI specifically requires that the compiler does not schedule
4678 ;; instructions in the TLS stubs, in order to enable linker relaxation.
4679 ;; Therefore we treat the stubs as an atomic sequence.
4680 (define_expand "tlsgd_small"
4681  [(parallel [(set (match_operand 0 "register_operand" "")
4682                   (call (mem:DI (match_dup 2)) (const_int 1)))
4683              (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
4684              (clobber (reg:DI LR_REGNUM))])]
4685  ""
4687   operands[2] = aarch64_tls_get_addr ();
4690 (define_insn "*tlsgd_small"
4691   [(set (match_operand 0 "register_operand" "")
4692         (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
4693    (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
4694    (clobber (reg:DI LR_REGNUM))
4695   ]
4696   ""
4697   "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
4698   [(set_attr "type" "call")
4699    (set_attr "length" "16")])
4701 (define_insn "tlsie_small_<mode>"
4702   [(set (match_operand:PTR 0 "register_operand" "=r")
4703         (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
4704                    UNSPEC_GOTSMALLTLS))]
4705   ""
4706   "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
4707   [(set_attr "type" "load1")
4708    (set_attr "length" "8")]
4711 (define_insn "tlsie_small_sidi"
4712   [(set (match_operand:DI 0 "register_operand" "=r")
4713         (zero_extend:DI
4714           (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")]
4715                       UNSPEC_GOTSMALLTLS)))]
4716   ""
4717   "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
4718   [(set_attr "type" "load1")
4719    (set_attr "length" "8")]
4722 (define_insn "tlsie_tiny_<mode>"
4723   [(set (match_operand:PTR 0 "register_operand" "=&r")
4724         (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")
4725                      (match_operand:PTR 2 "register_operand" "r")]
4726                    UNSPEC_GOTTINYTLS))]
4727   ""
4728   "ldr\\t%<w>0, %L1\;add\\t%<w>0, %<w>0, %<w>2"
4729   [(set_attr "type" "multiple")
4730    (set_attr "length" "8")]
4733 (define_insn "tlsie_tiny_sidi"
4734   [(set (match_operand:DI 0 "register_operand" "=&r")
4735         (zero_extend:DI
4736           (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")
4737                       (match_operand:DI 2 "register_operand" "r")
4738                       ]
4739                       UNSPEC_GOTTINYTLS)))]
4740   ""
4741   "ldr\\t%w0, %L1\;add\\t%w0, %w0, %w2"
4742   [(set_attr "type" "multiple")
4743    (set_attr "length" "8")]
4746 (define_insn "tlsle12_<mode>"
4747   [(set (match_operand:P 0 "register_operand" "=r")
4748         (unspec:P [(match_operand:P 1 "register_operand" "r")
4749                    (match_operand 2 "aarch64_tls_le_symref" "S")]
4750                    UNSPEC_TLSLE12))]
4751   ""
4752   "add\\t%<w>0, %<w>1, #%L2";
4753   [(set_attr "type" "alu_sreg")
4754    (set_attr "length" "4")]
4757 (define_insn "tlsle24_<mode>"
4758   [(set (match_operand:P 0 "register_operand" "=r")
4759         (unspec:P [(match_operand:P 1 "register_operand" "r")
4760                    (match_operand 2 "aarch64_tls_le_symref" "S")]
4761                    UNSPEC_TLSLE24))]
4762   ""
4763   "add\\t%<w>0, %<w>1, #%G2, lsl #12\;add\\t%<w>0, %<w>0, #%L2"
4764   [(set_attr "type" "multiple")
4765    (set_attr "length" "8")]
4768 (define_insn "tlsle32_<mode>"
4769   [(set (match_operand:P 0 "register_operand" "=r")
4770         (unspec:P [(match_operand 1 "aarch64_tls_le_symref" "S")]
4771                    UNSPEC_TLSLE32))]
4772   ""
4773   "movz\\t%<w>0, #:tprel_g1:%1\;movk\\t%<w>0, #:tprel_g0_nc:%1"
4774   [(set_attr "type" "multiple")
4775    (set_attr "length" "8")]
4778 (define_insn "tlsle48_<mode>"
4779   [(set (match_operand:P 0 "register_operand" "=r")
4780         (unspec:P [(match_operand 1 "aarch64_tls_le_symref" "S")]
4781                    UNSPEC_TLSLE48))]
4782   ""
4783   "movz\\t%<w>0, #:tprel_g2:%1\;movk\\t%<w>0, #:tprel_g1_nc:%1\;movk\\t%<w>0, #:tprel_g0_nc:%1"
4784   [(set_attr "type" "multiple")
4785    (set_attr "length" "12")]
4788 (define_insn "tlsdesc_small_<mode>"
4789   [(set (reg:PTR R0_REGNUM)
4790         (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
4791                    UNSPEC_TLSDESC))
4792    (clobber (reg:DI LR_REGNUM))
4793    (clobber (reg:CC CC_REGNUM))
4794    (clobber (match_scratch:DI 1 "=r"))]
4795   "TARGET_TLS_DESC"
4796   "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
4797   [(set_attr "type" "call")
4798    (set_attr "length" "16")])
4800 (define_insn "stack_tie"
4801   [(set (mem:BLK (scratch))
4802         (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
4803                      (match_operand:DI 1 "register_operand" "rk")]
4804                     UNSPEC_PRLG_STK))]
4805   ""
4806   ""
4807   [(set_attr "length" "0")]
4810 ;; Named pattern for expanding thread pointer reference.
4811 (define_expand "get_thread_pointerdi"
4812   [(match_operand:DI 0 "register_operand" "=r")]
4813   ""
4815   rtx tmp = aarch64_load_tp (operands[0]);
4816   if (tmp != operands[0])
4817     emit_move_insn (operands[0], tmp);
4818   DONE;
4821 ;; Named patterns for stack smashing protection.
4822 (define_expand "stack_protect_set"
4823   [(match_operand 0 "memory_operand")
4824    (match_operand 1 "memory_operand")]
4825   ""
4827   machine_mode mode = GET_MODE (operands[0]);
4829   emit_insn ((mode == DImode
4830               ? gen_stack_protect_set_di
4831               : gen_stack_protect_set_si) (operands[0], operands[1]));
4832   DONE;
4835 (define_insn "stack_protect_set_<mode>"
4836   [(set (match_operand:PTR 0 "memory_operand" "=m")
4837         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
4838          UNSPEC_SP_SET))
4839    (set (match_scratch:PTR 2 "=&r") (const_int 0))]
4840   ""
4841   "ldr\\t%<w>2, %1\;str\\t%<w>2, %0\;mov\t%<w>2,0"
4842   [(set_attr "length" "12")
4843    (set_attr "type" "multiple")])
4845 (define_expand "stack_protect_test"
4846   [(match_operand 0 "memory_operand")
4847    (match_operand 1 "memory_operand")
4848    (match_operand 2)]
4849   ""
4851   rtx result;
4852   machine_mode mode = GET_MODE (operands[0]);
4854   result = gen_reg_rtx(mode);
4856   emit_insn ((mode == DImode
4857               ? gen_stack_protect_test_di
4858               : gen_stack_protect_test_si) (result,
4859                                             operands[0],
4860                                             operands[1]));
4862   if (mode == DImode)
4863     emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4864                                     result, const0_rtx, operands[2]));
4865   else
4866     emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4867                                     result, const0_rtx, operands[2]));
4868   DONE;
4871 (define_insn "stack_protect_test_<mode>"
4872   [(set (match_operand:PTR 0 "register_operand" "=r")
4873         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
4874                      (match_operand:PTR 2 "memory_operand" "m")]
4875          UNSPEC_SP_TEST))
4876    (clobber (match_scratch:PTR 3 "=&r"))]
4877   ""
4878   "ldr\t%<w>3, %x1\;ldr\t%<w>0, %x2\;eor\t%<w>0, %<w>3, %<w>0"
4879   [(set_attr "length" "12")
4880    (set_attr "type" "multiple")])
4882 ;; Write Floating-point Control Register.
4883 (define_insn "set_fpcr"
4884   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
4885   ""
4886   "msr\\tfpcr, %0"
4887   [(set_attr "type" "mrs")])
4889 ;; Read Floating-point Control Register.
4890 (define_insn "get_fpcr"
4891   [(set (match_operand:SI 0 "register_operand" "=r")
4892         (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
4893   ""
4894   "mrs\\t%0, fpcr"
4895   [(set_attr "type" "mrs")])
4897 ;; Write Floating-point Status Register.
4898 (define_insn "set_fpsr"
4899   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
4900   ""
4901   "msr\\tfpsr, %0"
4902   [(set_attr "type" "mrs")])
4904 ;; Read Floating-point Status Register.
4905 (define_insn "get_fpsr"
4906   [(set (match_operand:SI 0 "register_operand" "=r")
4907         (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
4908   ""
4909   "mrs\\t%0, fpsr"
4910   [(set_attr "type" "mrs")])
4913 ;; Define the subtract-one-and-jump insns so loop.c
4914 ;; knows what to generate.
4915 (define_expand "doloop_end"
4916   [(use (match_operand 0 "" ""))      ; loop pseudo
4917    (use (match_operand 1 "" ""))]     ; label
4918   "optimize > 0 && flag_modulo_sched"
4920   rtx s0;
4921   rtx bcomp;
4922   rtx loc_ref;
4923   rtx cc_reg;
4924   rtx insn;
4925   rtx cmp;
4927   /* Currently SMS relies on the do-loop pattern to recognize loops
4928      where (1) the control part consists of all insns defining and/or
4929      using a certain 'count' register and (2) the loop count can be
4930      adjusted by modifying this register prior to the loop.
4931      ??? The possible introduction of a new block to initialize the
4932      new IV can potentially affect branch optimizations.  */
4934   if (GET_MODE (operands[0]) != DImode)
4935     FAIL;
4937   s0 = operands [0];
4938   insn = emit_insn (gen_adddi3_compare0 (s0, s0, GEN_INT (-1)));
4940   cmp = XVECEXP (PATTERN (insn), 0, 0);
4941   cc_reg = SET_DEST (cmp);
4942   bcomp = gen_rtx_NE (VOIDmode, cc_reg, const0_rtx);
4943   loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
4944   emit_jump_insn (gen_rtx_SET (pc_rtx,
4945                                gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
4946                                                      loc_ref, pc_rtx)));
4947   DONE;
4950 ;; AdvSIMD Stuff
4951 (include "aarch64-simd.md")
4953 ;; Atomic Operations
4954 (include "atomics.md")
4956 ;; ldp/stp peephole patterns
4957 (include "aarch64-ldpstp.md")