[AArch64] Fix type of *<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3 pattern
[official-gcc.git] / gcc / config / aarch64 / aarch64.md
blob11123d619ab3b21de92dd30904ba23245b864395
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_GOTSMALLTLS
91     UNSPEC_GOTTINYPIC
92     UNSPEC_LD1
93     UNSPEC_LD2
94     UNSPEC_LD2_DUP
95     UNSPEC_LD3
96     UNSPEC_LD3_DUP
97     UNSPEC_LD4
98     UNSPEC_LD4_DUP
99     UNSPEC_LD2_LANE
100     UNSPEC_LD3_LANE
101     UNSPEC_LD4_LANE
102     UNSPEC_MB
103     UNSPEC_NOP
104     UNSPEC_PRLG_STK
105     UNSPEC_RBIT
106     UNSPEC_SISD_NEG
107     UNSPEC_SISD_SSHL
108     UNSPEC_SISD_USHL
109     UNSPEC_SSHL_2S
110     UNSPEC_ST1
111     UNSPEC_ST2
112     UNSPEC_ST3
113     UNSPEC_ST4
114     UNSPEC_ST2_LANE
115     UNSPEC_ST3_LANE
116     UNSPEC_ST4_LANE
117     UNSPEC_TLS
118     UNSPEC_TLSDESC
119     UNSPEC_USHL_2S
120     UNSPEC_VSTRUCTDUMMY
121     UNSPEC_SP_SET
122     UNSPEC_SP_TEST
125 (define_c_enum "unspecv" [
126     UNSPECV_EH_RETURN           ; Represent EH_RETURN
127     UNSPECV_GET_FPCR            ; Represent fetch of FPCR content.
128     UNSPECV_SET_FPCR            ; Represent assign of FPCR content.
129     UNSPECV_GET_FPSR            ; Represent fetch of FPSR content.
130     UNSPECV_SET_FPSR            ; Represent assign of FPSR content.
131   ]
134 ;; If further include files are added the defintion of MD_INCLUDES
135 ;; must be updated.
137 (include "constraints.md")
138 (include "predicates.md")
139 (include "iterators.md")
141 ;; -------------------------------------------------------------------
142 ;; Instruction types and attributes
143 ;; -------------------------------------------------------------------
145 ; The "type" attribute is is included here from AArch32 backend to be able
146 ; to share pipeline descriptions.
147 (include "../arm/types.md")
149 ;; It is important to set the fp or simd attributes to yes when a pattern
150 ;; alternative uses the FP or SIMD register files, usually signified by use of
151 ;; the 'w' constraint.  This will ensure that the alternative will be
152 ;; disabled when compiling with -mgeneral-regs-only or with the +nofp/+nosimd
153 ;; architecture extensions.  If all the alternatives in a pattern use the
154 ;; FP or SIMD registers then the pattern predicate should include TARGET_FLOAT
155 ;; or TARGET_SIMD.
157 ;; Attribute that specifies whether or not the instruction touches fp
158 ;; registers.  When this is set to yes for an alternative, that alternative
159 ;; will be disabled when !TARGET_FLOAT.
160 (define_attr "fp" "no,yes" (const_string "no"))
162 ;; Attribute that specifies whether or not the instruction touches simd
163 ;; registers.  When this is set to yes for an alternative, that alternative
164 ;; will be disabled when !TARGET_SIMD.
165 (define_attr "simd" "no,yes" (const_string "no"))
167 (define_attr "length" ""
168   (const_int 4))
170 ;; Attribute that controls whether an alternative is enabled or not.
171 ;; Currently it is only used to disable alternatives which touch fp or simd
172 ;; registers when -mgeneral-regs-only is specified.
173 (define_attr "enabled" "no,yes"
174   (cond [(ior
175         (and (eq_attr "fp" "yes")
176              (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
177         (and (eq_attr "simd" "yes")
178              (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
179              (const_string "no")
180         ] (const_string "yes")))
182 ;; -------------------------------------------------------------------
183 ;; Pipeline descriptions and scheduling
184 ;; -------------------------------------------------------------------
186 ;; Processor types.
187 (include "aarch64-tune.md")
189 ;; Scheduling
190 (include "../arm/cortex-a53.md")
191 (include "../arm/cortex-a57.md")
192 (include "thunderx.md")
193 (include "../arm/xgene1.md")
195 ;; -------------------------------------------------------------------
196 ;; Jumps and other miscellaneous insns
197 ;; -------------------------------------------------------------------
199 (define_insn "indirect_jump"
200   [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
201   ""
202   "br\\t%0"
203   [(set_attr "type" "branch")]
206 (define_insn "jump"
207   [(set (pc) (label_ref (match_operand 0 "" "")))]
208   ""
209   "b\\t%l0"
210   [(set_attr "type" "branch")]
213 (define_expand "cbranch<mode>4"
214   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
215                             [(match_operand:GPI 1 "register_operand" "")
216                              (match_operand:GPI 2 "aarch64_plus_operand" "")])
217                            (label_ref (match_operand 3 "" ""))
218                            (pc)))]
219   ""
220   "
221   operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
222                                          operands[2]);
223   operands[2] = const0_rtx;
224   "
227 (define_expand "cbranch<mode>4"
228   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
229                             [(match_operand:GPF 1 "register_operand" "")
230                              (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
231                            (label_ref (match_operand 3 "" ""))
232                            (pc)))]
233   ""
234   "
235   operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
236                                          operands[2]);
237   operands[2] = const0_rtx;
238   "
241 (define_expand "cbranchcc4"
242   [(set (pc) (if_then_else
243               (match_operator 0 "aarch64_comparison_operator"
244                [(match_operand 1 "cc_register" "")
245                 (match_operand 2 "const0_operand")])
246               (label_ref (match_operand 3 "" ""))
247               (pc)))]
248   ""
249   "")
251 (define_insn "ccmp_and<mode>"
252   [(set (match_operand 1 "ccmp_cc_register" "")
253         (compare
254          (and:SI
255           (match_operator 4 "aarch64_comparison_operator"
256            [(match_operand 0 "ccmp_cc_register" "")
257             (const_int 0)])
258           (match_operator 5 "aarch64_comparison_operator"
259            [(match_operand:GPI 2 "register_operand" "r,r,r")
260             (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")]))
261          (const_int 0)))]
262   "aarch64_ccmp_mode_to_code (GET_MODE (operands[1])) == GET_CODE (operands[5])"
263   "@
264    ccmp\\t%<w>2, %<w>3, %k5, %m4
265    ccmp\\t%<w>2, %<w>3, %k5, %m4
266    ccmn\\t%<w>2, #%n3, %k5, %m4"
267   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
270 (define_insn "ccmp_ior<mode>"
271   [(set (match_operand 1 "ccmp_cc_register" "")
272         (compare
273          (ior:SI
274           (match_operator 4 "aarch64_comparison_operator"
275            [(match_operand 0 "ccmp_cc_register" "")
276             (const_int 0)])
277           (match_operator 5 "aarch64_comparison_operator"
278            [(match_operand:GPI 2 "register_operand" "r,r,r")
279             (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")]))
280          (const_int 0)))]
281   "aarch64_ccmp_mode_to_code (GET_MODE (operands[1])) == GET_CODE (operands[5])"
282   "@
283    ccmp\\t%<w>2, %<w>3, %K5, %M4
284    ccmp\\t%<w>2, %<w>3, %K5, %M4
285    ccmn\\t%<w>2, #%n3, %K5, %M4"
286   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
289 (define_expand "cmp<mode>"
290   [(set (match_operand 0 "cc_register" "")
291         (match_operator:CC 1 "aarch64_comparison_operator"
292          [(match_operand:GPI 2 "register_operand" "")
293           (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
294   ""
295   {
296     operands[1] = gen_rtx_fmt_ee (COMPARE,
297                                   SELECT_CC_MODE (GET_CODE (operands[1]),
298                                                   operands[2], operands[3]),
299                                   operands[2], operands[3]);
300   }
303 (define_insn "*condjump"
304   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
305                             [(match_operand 1 "cc_register" "") (const_int 0)])
306                            (label_ref (match_operand 2 "" ""))
307                            (pc)))]
308   ""
309   "b%m0\\t%l2"
310   [(set_attr "type" "branch")]
313 (define_expand "casesi"
314   [(match_operand:SI 0 "register_operand" "")   ; Index
315    (match_operand:SI 1 "const_int_operand" "")  ; Lower bound
316    (match_operand:SI 2 "const_int_operand" "")  ; Total range
317    (match_operand:DI 3 "" "")                   ; Table label
318    (match_operand:DI 4 "" "")]                  ; Out of range label
319   ""
320   {
321     if (operands[1] != const0_rtx)
322       {
323         rtx reg = gen_reg_rtx (SImode);
325         /* Canonical RTL says that if you have:
327            (minus (X) (CONST))
329            then this should be emitted as:
331            (plus (X) (-CONST))
333            The use of trunc_int_for_mode ensures that the resulting
334            constant can be represented in SImode, this is important
335            for the corner case where operand[1] is INT_MIN.  */
337         operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
339         if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
340               (operands[1], SImode))
341           operands[1] = force_reg (SImode, operands[1]);
342         emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
343         operands[0] = reg;
344       }
346     if (!aarch64_plus_operand (operands[2], SImode))
347       operands[2] = force_reg (SImode, operands[2]);
348     emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
349                                                  const0_rtx),
350                                     operands[0], operands[2], operands[4]));
352     operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
353     emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
354                                          operands[3]));
355     DONE;
356   }
359 (define_insn "casesi_dispatch"
360   [(parallel
361     [(set (pc)
362           (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
363                            (match_operand:SI 1 "register_operand" "r")]
364                         UNSPEC_CASESI)))
365      (clobber (reg:CC CC_REGNUM))
366      (clobber (match_scratch:DI 3 "=r"))
367      (clobber (match_scratch:DI 4 "=r"))
368      (use (label_ref (match_operand 2 "" "")))])]
369   ""
370   "*
371   return aarch64_output_casesi (operands);
372   "
373   [(set_attr "length" "16")
374    (set_attr "type" "branch")]
377 (define_insn "nop"
378   [(unspec[(const_int 0)] UNSPEC_NOP)]
379   ""
380   "nop"
381   [(set_attr "type" "no_insn")]
384 (define_insn "prefetch"
385   [(prefetch (match_operand:DI 0 "address_operand" "r")
386             (match_operand:QI 1 "const_int_operand" "")
387             (match_operand:QI 2 "const_int_operand" ""))]
388   ""
389   {
390     const char * pftype[2][4] = 
391     {
392       {"prfm\\tPLDL1STRM, %a0",
393        "prfm\\tPLDL3KEEP, %a0",
394        "prfm\\tPLDL2KEEP, %a0",
395        "prfm\\tPLDL1KEEP, %a0"},
396       {"prfm\\tPSTL1STRM, %a0",
397        "prfm\\tPSTL3KEEP, %a0",
398        "prfm\\tPSTL2KEEP, %a0",
399        "prfm\\tPSTL1KEEP, %a0"},
400     };
402     int locality = INTVAL (operands[2]);
404     gcc_assert (IN_RANGE (locality, 0, 3));
406     return pftype[INTVAL(operands[1])][locality];
407   }
408   [(set_attr "type" "load1")]
411 (define_insn "trap"
412   [(trap_if (const_int 1) (const_int 8))]
413   ""
414   "brk #1000"
415   [(set_attr "type" "trap")])
417 (define_expand "prologue"
418   [(clobber (const_int 0))]
419   ""
420   "
421   aarch64_expand_prologue ();
422   DONE;
423   "
426 (define_expand "epilogue"
427   [(clobber (const_int 0))]
428   ""
429   "
430   aarch64_expand_epilogue (false);
431   DONE;
432   "
435 (define_expand "sibcall_epilogue"
436   [(clobber (const_int 0))]
437   ""
438   "
439   aarch64_expand_epilogue (true);
440   DONE;
441   "
444 (define_insn "*do_return"
445   [(return)]
446   ""
447   "ret"
448   [(set_attr "type" "branch")]
451 (define_expand "return"
452   [(simple_return)]
453   "aarch64_use_return_insn_p ()"
454   ""
457 (define_insn "simple_return"
458   [(simple_return)]
459   ""
460   "ret"
461   [(set_attr "type" "branch")]
464 (define_insn "eh_return"
465   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
466     UNSPECV_EH_RETURN)]
467   ""
468   "#"
469   [(set_attr "type" "branch")]
473 (define_split
474   [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
475     UNSPECV_EH_RETURN)]
476   "reload_completed"
477   [(set (match_dup 1) (match_dup 0))]
478   {
479     operands[1] = aarch64_final_eh_return_addr ();
480   }
483 (define_insn "*cb<optab><mode>1"
484   [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
485                                 (const_int 0))
486                            (label_ref (match_operand 1 "" ""))
487                            (pc)))]
488   ""
489   "<cbz>\\t%<w>0, %l1"
490   [(set_attr "type" "branch")]
494 (define_insn "*tb<optab><mode>1"
495   [(set (pc) (if_then_else
496               (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
497                                     (const_int 1)
498                                     (match_operand 1 "const_int_operand" "n"))
499                    (const_int 0))
500              (label_ref (match_operand 2 "" ""))
501              (pc)))
502    (clobber (reg:CC CC_REGNUM))]
503   ""
504   {
505     if (get_attr_length (insn) == 8)
506       {
507         operands[1] = GEN_INT (HOST_WIDE_INT_1U << UINTVAL (operands[1]));
508         return "tst\t%<w>0, %1\;<bcond>\t%l2";
509       }
510     else
511       return "<tbz>\t%<w>0, %1, %l2";
512   }
513   [(set_attr "type" "branch")
514    (set (attr "length")
515         (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
516                            (lt (minus (match_dup 2) (pc)) (const_int 32764)))
517                       (const_int 4)
518                       (const_int 8)))]
521 (define_insn "*cb<optab><mode>1"
522   [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
523                                  (const_int 0))
524                            (label_ref (match_operand 1 "" ""))
525                            (pc)))
526    (clobber (reg:CC CC_REGNUM))]
527   ""
528   {
529     if (get_attr_length (insn) == 8)
530       {
531         char buf[64];
532         uint64_t val = ((uint64_t ) 1)
533                         << (GET_MODE_SIZE (<MODE>mode) * BITS_PER_UNIT - 1);
534         sprintf (buf, "tst\t%%<w>0, %" PRId64, val);
535         output_asm_insn (buf, operands);
536         return "<bcond>\t%l1";
537       }
538     else
539       return "<tbz>\t%<w>0, <sizem1>, %l1";
540   }
541   [(set_attr "type" "branch")
542    (set (attr "length")
543         (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
544                            (lt (minus (match_dup 1) (pc)) (const_int 32764)))
545                       (const_int 4)
546                       (const_int 8)))]
549 ;; -------------------------------------------------------------------
550 ;; Subroutine calls and sibcalls
551 ;; -------------------------------------------------------------------
553 (define_expand "call_internal"
554   [(parallel [(call (match_operand 0 "memory_operand" "")
555                     (match_operand 1 "general_operand" ""))
556               (use (match_operand 2 "" ""))
557               (clobber (reg:DI LR_REGNUM))])])
559 (define_expand "call"
560   [(parallel [(call (match_operand 0 "memory_operand" "")
561                     (match_operand 1 "general_operand" ""))
562               (use (match_operand 2 "" ""))
563               (clobber (reg:DI LR_REGNUM))])]
564   ""
565   "
566   {
567     rtx callee, pat;
569     /* In an untyped call, we can get NULL for operand 2.  */
570     if (operands[2] == NULL)
571       operands[2] = const0_rtx;
573     /* Decide if we should generate indirect calls by loading the
574        64-bit address of the callee into a register before performing
575        the branch-and-link.  */
576     callee = XEXP (operands[0], 0);
577     if (GET_CODE (callee) == SYMBOL_REF
578         ? aarch64_is_long_call_p (callee)
579         : !REG_P (callee))
580       XEXP (operands[0], 0) = force_reg (Pmode, callee);
582     pat = gen_call_internal (operands[0], operands[1], operands[2]);
583     aarch64_emit_call_insn (pat);
584     DONE;
585   }"
588 (define_insn "*call_reg"
589   [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
590          (match_operand 1 "" ""))
591    (use (match_operand 2 "" ""))
592    (clobber (reg:DI LR_REGNUM))]
593   ""
594   "blr\\t%0"
595   [(set_attr "type" "call")]
598 (define_insn "*call_symbol"
599   [(call (mem:DI (match_operand:DI 0 "" ""))
600          (match_operand 1 "" ""))
601    (use (match_operand 2 "" ""))
602    (clobber (reg:DI LR_REGNUM))]
603   "GET_CODE (operands[0]) == SYMBOL_REF
604    && !aarch64_is_long_call_p (operands[0])"
605   "bl\\t%a0"
606   [(set_attr "type" "call")]
609 (define_expand "call_value_internal"
610   [(parallel [(set (match_operand 0 "" "")
611                    (call (match_operand 1 "memory_operand" "")
612                          (match_operand 2 "general_operand" "")))
613               (use (match_operand 3 "" ""))
614               (clobber (reg:DI LR_REGNUM))])])
616 (define_expand "call_value"
617   [(parallel [(set (match_operand 0 "" "")
618                    (call (match_operand 1 "memory_operand" "")
619                          (match_operand 2 "general_operand" "")))
620               (use (match_operand 3 "" ""))
621               (clobber (reg:DI LR_REGNUM))])]
622   ""
623   "
624   {
625     rtx callee, pat;
627     /* In an untyped call, we can get NULL for operand 3.  */
628     if (operands[3] == NULL)
629       operands[3] = const0_rtx;
631     /* Decide if we should generate indirect calls by loading the
632        64-bit address of the callee into a register before performing
633        the branch-and-link.  */
634     callee = XEXP (operands[1], 0);
635     if (GET_CODE (callee) == SYMBOL_REF
636         ? aarch64_is_long_call_p (callee)
637         : !REG_P (callee))
638       XEXP (operands[1], 0) = force_reg (Pmode, callee);
640     pat = gen_call_value_internal (operands[0], operands[1], operands[2],
641                                    operands[3]);
642     aarch64_emit_call_insn (pat);
643     DONE;
644   }"
647 (define_insn "*call_value_reg"
648   [(set (match_operand 0 "" "")
649         (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
650                       (match_operand 2 "" "")))
651    (use (match_operand 3 "" ""))
652    (clobber (reg:DI LR_REGNUM))]
653   ""
654   "blr\\t%1"
655   [(set_attr "type" "call")]
659 (define_insn "*call_value_symbol"
660   [(set (match_operand 0 "" "")
661         (call (mem:DI (match_operand:DI 1 "" ""))
662               (match_operand 2 "" "")))
663    (use (match_operand 3 "" ""))
664    (clobber (reg:DI LR_REGNUM))]
665   "GET_CODE (operands[1]) == SYMBOL_REF
666    && !aarch64_is_long_call_p (operands[1])"
667   "bl\\t%a1"
668   [(set_attr "type" "call")]
671 (define_expand "sibcall_internal"
672   [(parallel [(call (match_operand 0 "memory_operand" "")
673                     (match_operand 1 "general_operand" ""))
674               (return)
675               (use (match_operand 2 "" ""))])])
677 (define_expand "sibcall"
678   [(parallel [(call (match_operand 0 "memory_operand" "")
679                     (match_operand 1 "general_operand" ""))
680               (return)
681               (use (match_operand 2 "" ""))])]
682   ""
683   {
684     rtx pat;
686     if (!REG_P (XEXP (operands[0], 0))
687        && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
688      XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
690     if (operands[2] == NULL_RTX)
691       operands[2] = const0_rtx;
693     pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
694     aarch64_emit_call_insn (pat);
695     DONE;
696   }
699 (define_expand "sibcall_value_internal"
700   [(parallel [(set (match_operand 0 "" "")
701                    (call (match_operand 1 "memory_operand" "")
702                          (match_operand 2 "general_operand" "")))
703               (return)
704               (use (match_operand 3 "" ""))])])
706 (define_expand "sibcall_value"
707   [(parallel [(set (match_operand 0 "" "")
708                    (call (match_operand 1 "memory_operand" "")
709                          (match_operand 2 "general_operand" "")))
710               (return)
711               (use (match_operand 3 "" ""))])]
712   ""
713   {
714     rtx pat;
716     if (!REG_P (XEXP (operands[1], 0))
717        && (GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF))
718      XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
720     if (operands[3] == NULL_RTX)
721       operands[3] = const0_rtx;
723     pat = gen_sibcall_value_internal (operands[0], operands[1], operands[2],
724                                       operands[3]);
725     aarch64_emit_call_insn (pat);
726     DONE;
727   }
730 (define_insn "*sibcall_insn"
731   [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucs, Usf"))
732          (match_operand 1 "" ""))
733    (return)
734    (use (match_operand 2 "" ""))]
735   "SIBLING_CALL_P (insn)"
736   "@
737    br\\t%0
738    b\\t%a0"
739   [(set_attr "type" "branch, branch")]
742 (define_insn "*sibcall_value_insn"
743   [(set (match_operand 0 "" "")
744         (call (mem:DI
745                 (match_operand:DI 1 "aarch64_call_insn_operand" "Ucs, Usf"))
746               (match_operand 2 "" "")))
747    (return)
748    (use (match_operand 3 "" ""))]
749   "SIBLING_CALL_P (insn)"
750   "@
751    br\\t%1
752    b\\t%a1"
753   [(set_attr "type" "branch, branch")]
756 ;; Call subroutine returning any type.
758 (define_expand "untyped_call"
759   [(parallel [(call (match_operand 0 "")
760                     (const_int 0))
761               (match_operand 1 "")
762               (match_operand 2 "")])]
763   ""
765   int i;
767   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
769   for (i = 0; i < XVECLEN (operands[2], 0); i++)
770     {
771       rtx set = XVECEXP (operands[2], 0, i);
772       emit_move_insn (SET_DEST (set), SET_SRC (set));
773     }
775   /* The optimizer does not know that the call sets the function value
776      registers we stored in the result block.  We avoid problems by
777      claiming that all hard registers are used and clobbered at this
778      point.  */
779   emit_insn (gen_blockage ());
780   DONE;
783 ;; -------------------------------------------------------------------
784 ;; Moves
785 ;; -------------------------------------------------------------------
787 (define_expand "mov<mode>"
788   [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
789         (match_operand:SHORT 1 "general_operand" ""))]
790   ""
791   "
792     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
793       operands[1] = force_reg (<MODE>mode, operands[1]);
794   "
797 (define_insn "*mov<mode>_aarch64"
798   [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r,   *w,r,*w, m, m, r,*w,*w")
799         (match_operand:SHORT 1 "general_operand"      " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
800   "(register_operand (operands[0], <MODE>mode)
801     || aarch64_reg_or_zero (operands[1], <MODE>mode))"
803    switch (which_alternative)
804      {
805      case 0:
806        return "mov\t%w0, %w1";
807      case 1:
808        return "mov\t%w0, %1";
809      case 2:
810        return aarch64_output_scalar_simd_mov_immediate (operands[1],
811                                                         <MODE>mode);
812      case 3:
813        return "ldr<size>\t%w0, %1";
814      case 4:
815        return "ldr\t%<size>0, %1";
816      case 5:
817        return "str<size>\t%w1, %0";
818      case 6:
819        return "str\t%<size>1, %0";
820      case 7:
821        return "umov\t%w0, %1.<v>[0]";
822      case 8:
823        return "dup\t%0.<Vallxd>, %w1";
824      case 9:
825        return "dup\t%<Vetype>0, %1.<v>[0]";
826      default:
827        gcc_unreachable ();
828      }
830   [(set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
831                      neon_to_gp<q>,neon_from_gp<q>,neon_dup")
832    (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")]
835 (define_expand "mov<mode>"
836   [(set (match_operand:GPI 0 "nonimmediate_operand" "")
837         (match_operand:GPI 1 "general_operand" ""))]
838   ""
839   "
840     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
841       operands[1] = force_reg (<MODE>mode, operands[1]);
843     /* FIXME: RR we still need to fix up what we are doing with
844        symbol_refs and other types of constants.  */
845     if (CONSTANT_P (operands[1])
846         && !CONST_INT_P (operands[1]))
847      {
848        aarch64_expand_mov_immediate (operands[0], operands[1]);
849        DONE;
850      }
851   "
854 (define_insn_and_split "*movsi_aarch64"
855   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,r,*w,m,  m,r,r  ,*w, r,*w")
856         (match_operand:SI 1 "aarch64_mov_operand"  " r,r,k,M,n,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
857   "(register_operand (operands[0], SImode)
858     || aarch64_reg_or_zero (operands[1], SImode))"
859   "@
860    mov\\t%w0, %w1
861    mov\\t%w0, %w1
862    mov\\t%w0, %w1
863    mov\\t%w0, %1
864    #
865    ldr\\t%w0, %1
866    ldr\\t%s0, %1
867    str\\t%w1, %0
868    str\\t%s1, %0
869    adr\\t%x0, %a1
870    adrp\\t%x0, %A1
871    fmov\\t%s0, %w1
872    fmov\\t%w0, %s1
873    fmov\\t%s0, %s1"
874    "CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), SImode)
875     && GP_REGNUM_P (REGNO (operands[0]))"
876    [(const_int 0)]
877    "{
878        aarch64_expand_mov_immediate (operands[0], operands[1]);
879        DONE;
880     }"
881   [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
882                      adr,adr,f_mcr,f_mrc,fmov")
883    (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
886 (define_insn_and_split "*movdi_aarch64"
887   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,r,*w,m,  m,r,r,  *w, r,*w,w")
888         (match_operand:DI 1 "aarch64_mov_operand"  " r,r,k,N,n,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))]
889   "(register_operand (operands[0], DImode)
890     || aarch64_reg_or_zero (operands[1], DImode))"
891   "@
892    mov\\t%x0, %x1
893    mov\\t%0, %x1
894    mov\\t%x0, %1
895    mov\\t%x0, %1
896    #
897    ldr\\t%x0, %1
898    ldr\\t%d0, %1
899    str\\t%x1, %0
900    str\\t%d1, %0
901    adr\\t%x0, %a1
902    adrp\\t%x0, %A1
903    fmov\\t%d0, %x1
904    fmov\\t%x0, %d1
905    fmov\\t%d0, %d1
906    movi\\t%d0, %1"
907    "(CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), DImode))
908     && GP_REGNUM_P (REGNO (operands[0]))"
909    [(const_int 0)]
910    "{
911        aarch64_expand_mov_immediate (operands[0], operands[1]);
912        DONE;
913     }"
914   [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
915                      adr,adr,f_mcr,f_mrc,fmov,fmov")
916    (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
917    (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
920 (define_insn "insv_imm<mode>"
921   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
922                           (const_int 16)
923                           (match_operand:GPI 1 "const_int_operand" "n"))
924         (match_operand:GPI 2 "const_int_operand" "n"))]
925   "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
926    && UINTVAL (operands[1]) % 16 == 0"
927   "movk\\t%<w>0, %X2, lsl %1"
928   [(set_attr "type" "mov_imm")]
931 (define_expand "movti"
932   [(set (match_operand:TI 0 "nonimmediate_operand" "")
933         (match_operand:TI 1 "general_operand" ""))]
934   ""
935   "
936     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
937       operands[1] = force_reg (TImode, operands[1]);
938   "
941 (define_insn "*movti_aarch64"
942   [(set (match_operand:TI 0
943          "nonimmediate_operand"  "=r, *w,r ,*w,r  ,Ump,Ump,*w,m")
944         (match_operand:TI 1
945          "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r  ,Z  , m,*w"))]
946   "(register_operand (operands[0], TImode)
947     || aarch64_reg_or_zero (operands[1], TImode))"
948   "@
949    #
950    #
951    #
952    orr\\t%0.16b, %1.16b, %1.16b
953    ldp\\t%0, %H0, %1
954    stp\\t%1, %H1, %0
955    stp\\txzr, xzr, %0
956    ldr\\t%q0, %1
957    str\\t%q1, %0"
958   [(set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \
959                              load2,store2,store2,f_loadd,f_stored")
960    (set_attr "length" "8,8,8,4,4,4,4,4,4")
961    (set_attr "simd" "*,*,*,yes,*,*,*,*,*")
962    (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
965 ;; Split a TImode register-register or register-immediate move into
966 ;; its component DImode pieces, taking care to handle overlapping
967 ;; source and dest registers.
968 (define_split
969    [(set (match_operand:TI 0 "register_operand" "")
970          (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
971   "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
972   [(const_int 0)]
974   aarch64_split_128bit_move (operands[0], operands[1]);
975   DONE;
978 (define_expand "mov<mode>"
979   [(set (match_operand:GPF 0 "nonimmediate_operand" "")
980         (match_operand:GPF 1 "general_operand" ""))]
981   ""
982   "
983     if (!TARGET_FLOAT)
984      {
985         sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
986         FAIL;
987      }
989     if (GET_CODE (operands[0]) == MEM)
990       operands[1] = force_reg (<MODE>mode, operands[1]);
991   "
994 (define_insn "*movsf_aarch64"
995   [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w  ,w,m,r,m ,r")
996         (match_operand:SF 1 "general_operand"      "?rY, w,w,Ufc,m,w,m,rY,r"))]
997   "TARGET_FLOAT && (register_operand (operands[0], SFmode)
998     || register_operand (operands[1], SFmode))"
999   "@
1000    fmov\\t%s0, %w1
1001    fmov\\t%w0, %s1
1002    fmov\\t%s0, %s1
1003    fmov\\t%s0, %1
1004    ldr\\t%s0, %1
1005    str\\t%s1, %0
1006    ldr\\t%w0, %1
1007    str\\t%w1, %0
1008    mov\\t%w0, %w1"
1009   [(set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
1010                      f_loads,f_stores,f_loads,f_stores,mov_reg")]
1013 (define_insn "*movdf_aarch64"
1014   [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w  ,w,m,r,m ,r")
1015         (match_operand:DF 1 "general_operand"      "?rY, w,w,Ufc,m,w,m,rY,r"))]
1016   "TARGET_FLOAT && (register_operand (operands[0], DFmode)
1017     || register_operand (operands[1], DFmode))"
1018   "@
1019    fmov\\t%d0, %x1
1020    fmov\\t%x0, %d1
1021    fmov\\t%d0, %d1
1022    fmov\\t%d0, %1
1023    ldr\\t%d0, %1
1024    str\\t%d1, %0
1025    ldr\\t%x0, %1
1026    str\\t%x1, %0
1027    mov\\t%x0, %x1"
1028   [(set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
1029                      f_loadd,f_stored,f_loadd,f_stored,mov_reg")]
1032 (define_expand "movtf"
1033   [(set (match_operand:TF 0 "nonimmediate_operand" "")
1034         (match_operand:TF 1 "general_operand" ""))]
1035   ""
1036   "
1037     if (!TARGET_FLOAT)
1038      {
1039         sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
1040         FAIL;
1041      }
1043     if (GET_CODE (operands[0]) == MEM)
1044       operands[1] = force_reg (TFmode, operands[1]);
1045   "
1048 (define_insn "*movtf_aarch64"
1049   [(set (match_operand:TF 0
1050          "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
1051         (match_operand:TF 1
1052          "general_operand"      " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
1053   "TARGET_FLOAT && (register_operand (operands[0], TFmode)
1054     || register_operand (operands[1], TFmode))"
1055   "@
1056    orr\\t%0.16b, %1.16b, %1.16b
1057    #
1058    #
1059    #
1060    movi\\t%0.2d, #0
1061    fmov\\t%s0, wzr
1062    ldr\\t%q0, %1
1063    str\\t%q1, %0
1064    ldp\\t%0, %H0, %1
1065    stp\\t%1, %H1, %0"
1066   [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,fconstd,fconstd,\
1067                      f_loadd,f_stored,neon_load1_2reg,neon_store1_2reg")
1068    (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
1069    (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
1070    (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
1073 (define_split
1074    [(set (match_operand:TF 0 "register_operand" "")
1075          (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
1076   "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
1077   [(const_int 0)]
1078   {
1079     aarch64_split_128bit_move (operands[0], operands[1]);
1080     DONE;
1081   }
1084 ;; 0 is dst
1085 ;; 1 is src
1086 ;; 2 is size of move in bytes
1087 ;; 3 is alignment
1089 (define_expand "movmemdi"
1090   [(match_operand:BLK 0 "memory_operand")
1091    (match_operand:BLK 1 "memory_operand")
1092    (match_operand:DI 2 "immediate_operand")
1093    (match_operand:DI 3 "immediate_operand")]
1094    "!STRICT_ALIGNMENT"
1096   if (aarch64_expand_movmem (operands))
1097     DONE;
1098   FAIL;
1102 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1103 ;; fairly lax checking on the second memory operation.
1104 (define_insn "load_pairsi"
1105   [(set (match_operand:SI 0 "register_operand" "=r,*w")
1106         (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1107    (set (match_operand:SI 2 "register_operand" "=r,*w")
1108         (match_operand:SI 3 "memory_operand" "m,m"))]
1109   "rtx_equal_p (XEXP (operands[3], 0),
1110                 plus_constant (Pmode,
1111                                XEXP (operands[1], 0),
1112                                GET_MODE_SIZE (SImode)))"
1113   "@
1114    ldp\\t%w0, %w2, %1
1115    ldp\\t%s0, %s2, %1"
1116   [(set_attr "type" "load2,neon_load1_2reg")
1117    (set_attr "fp" "*,yes")]
1120 (define_insn "load_pairdi"
1121   [(set (match_operand:DI 0 "register_operand" "=r,*w")
1122         (match_operand:DI 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1123    (set (match_operand:DI 2 "register_operand" "=r,*w")
1124         (match_operand:DI 3 "memory_operand" "m,m"))]
1125   "rtx_equal_p (XEXP (operands[3], 0),
1126                 plus_constant (Pmode,
1127                                XEXP (operands[1], 0),
1128                                GET_MODE_SIZE (DImode)))"
1129   "@
1130    ldp\\t%x0, %x2, %1
1131    ldp\\t%d0, %d2, %1"
1132   [(set_attr "type" "load2,neon_load1_2reg")
1133    (set_attr "fp" "*,yes")]
1137 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1138 ;; fairly lax checking on the second memory operation.
1139 (define_insn "store_pairsi"
1140   [(set (match_operand:SI 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1141         (match_operand:SI 1 "aarch64_reg_or_zero" "rZ,*w"))
1142    (set (match_operand:SI 2 "memory_operand" "=m,m")
1143         (match_operand:SI 3 "aarch64_reg_or_zero" "rZ,*w"))]
1144   "rtx_equal_p (XEXP (operands[2], 0),
1145                 plus_constant (Pmode,
1146                                XEXP (operands[0], 0),
1147                                GET_MODE_SIZE (SImode)))"
1148   "@
1149    stp\\t%w1, %w3, %0
1150    stp\\t%s1, %s3, %0"
1151   [(set_attr "type" "store2,neon_store1_2reg")
1152    (set_attr "fp" "*,yes")]
1155 (define_insn "store_pairdi"
1156   [(set (match_operand:DI 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1157         (match_operand:DI 1 "aarch64_reg_or_zero" "rZ,*w"))
1158    (set (match_operand:DI 2 "memory_operand" "=m,m")
1159         (match_operand:DI 3 "aarch64_reg_or_zero" "rZ,*w"))]
1160   "rtx_equal_p (XEXP (operands[2], 0),
1161                 plus_constant (Pmode,
1162                                XEXP (operands[0], 0),
1163                                GET_MODE_SIZE (DImode)))"
1164   "@
1165    stp\\t%x1, %x3, %0
1166    stp\\t%d1, %d3, %0"
1167   [(set_attr "type" "store2,neon_store1_2reg")
1168    (set_attr "fp" "*,yes")]
1171 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1172 ;; fairly lax checking on the second memory operation.
1173 (define_insn "load_pairsf"
1174   [(set (match_operand:SF 0 "register_operand" "=w,*r")
1175         (match_operand:SF 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1176    (set (match_operand:SF 2 "register_operand" "=w,*r")
1177         (match_operand:SF 3 "memory_operand" "m,m"))]
1178   "rtx_equal_p (XEXP (operands[3], 0),
1179                 plus_constant (Pmode,
1180                                XEXP (operands[1], 0),
1181                                GET_MODE_SIZE (SFmode)))"
1182   "@
1183    ldp\\t%s0, %s2, %1
1184    ldp\\t%w0, %w2, %1"
1185   [(set_attr "type" "neon_load1_2reg,load2")
1186    (set_attr "fp" "yes,*")]
1189 (define_insn "load_pairdf"
1190   [(set (match_operand:DF 0 "register_operand" "=w,*r")
1191         (match_operand:DF 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1192    (set (match_operand:DF 2 "register_operand" "=w,*r")
1193         (match_operand:DF 3 "memory_operand" "m,m"))]
1194   "rtx_equal_p (XEXP (operands[3], 0),
1195                 plus_constant (Pmode,
1196                                XEXP (operands[1], 0),
1197                                GET_MODE_SIZE (DFmode)))"
1198   "@
1199    ldp\\t%d0, %d2, %1
1200    ldp\\t%x0, %x2, %1"
1201   [(set_attr "type" "neon_load1_2reg,load2")
1202    (set_attr "fp" "yes,*")]
1205 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1206 ;; fairly lax checking on the second memory operation.
1207 (define_insn "store_pairsf"
1208   [(set (match_operand:SF 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1209         (match_operand:SF 1 "register_operand" "w,*r"))
1210    (set (match_operand:SF 2 "memory_operand" "=m,m")
1211         (match_operand:SF 3 "register_operand" "w,*r"))]
1212   "rtx_equal_p (XEXP (operands[2], 0),
1213                 plus_constant (Pmode,
1214                                XEXP (operands[0], 0),
1215                                GET_MODE_SIZE (SFmode)))"
1216   "@
1217    stp\\t%s1, %s3, %0
1218    stp\\t%w1, %w3, %0"
1219   [(set_attr "type" "neon_store1_2reg,store2")
1220    (set_attr "fp" "yes,*")]
1223 (define_insn "store_pairdf"
1224   [(set (match_operand:DF 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1225         (match_operand:DF 1 "register_operand" "w,*r"))
1226    (set (match_operand:DF 2 "memory_operand" "=m,m")
1227         (match_operand:DF 3 "register_operand" "w,*r"))]
1228   "rtx_equal_p (XEXP (operands[2], 0),
1229                 plus_constant (Pmode,
1230                                XEXP (operands[0], 0),
1231                                GET_MODE_SIZE (DFmode)))"
1232   "@
1233    stp\\t%d1, %d3, %0
1234    stp\\t%x1, %x3, %0"
1235   [(set_attr "type" "neon_store1_2reg,store2")
1236    (set_attr "fp" "yes,*")]
1239 ;; Load pair with post-index writeback.  This is primarily used in function
1240 ;; epilogues.
1241 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
1242   [(parallel
1243     [(set (match_operand:P 0 "register_operand" "=k")
1244           (plus:P (match_operand:P 1 "register_operand" "0")
1245                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1246      (set (match_operand:GPI 2 "register_operand" "=r")
1247           (mem:GPI (match_dup 1)))
1248      (set (match_operand:GPI 3 "register_operand" "=r")
1249           (mem:GPI (plus:P (match_dup 1)
1250                    (match_operand:P 5 "const_int_operand" "n"))))])]
1251   "INTVAL (operands[5]) == GET_MODE_SIZE (<GPI:MODE>mode)"
1252   "ldp\\t%<w>2, %<w>3, [%1], %4"
1253   [(set_attr "type" "load2")]
1256 (define_insn "loadwb_pair<GPF:mode>_<P:mode>"
1257   [(parallel
1258     [(set (match_operand:P 0 "register_operand" "=k")
1259           (plus:P (match_operand:P 1 "register_operand" "0")
1260                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1261      (set (match_operand:GPF 2 "register_operand" "=w")
1262           (mem:GPF (match_dup 1)))
1263      (set (match_operand:GPF 3 "register_operand" "=w")
1264           (mem:GPF (plus:P (match_dup 1)
1265                    (match_operand:P 5 "const_int_operand" "n"))))])]
1266   "INTVAL (operands[5]) == GET_MODE_SIZE (<GPF:MODE>mode)"
1267   "ldp\\t%<w>2, %<w>3, [%1], %4"
1268   [(set_attr "type" "neon_load1_2reg")]
1271 ;; Store pair with pre-index writeback.  This is primarily used in function
1272 ;; prologues.
1273 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
1274   [(parallel
1275     [(set (match_operand:P 0 "register_operand" "=&k")
1276           (plus:P (match_operand:P 1 "register_operand" "0")
1277                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1278      (set (mem:GPI (plus:P (match_dup 0)
1279                    (match_dup 4)))
1280           (match_operand:GPI 2 "register_operand" "r"))
1281      (set (mem:GPI (plus:P (match_dup 0)
1282                    (match_operand:P 5 "const_int_operand" "n")))
1283           (match_operand:GPI 3 "register_operand" "r"))])]
1284   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1285   "stp\\t%<w>2, %<w>3, [%0, %4]!"
1286   [(set_attr "type" "store2")]
1289 (define_insn "storewb_pair<GPF:mode>_<P:mode>"
1290   [(parallel
1291     [(set (match_operand:P 0 "register_operand" "=&k")
1292           (plus:P (match_operand:P 1 "register_operand" "0")
1293                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1294      (set (mem:GPF (plus:P (match_dup 0)
1295                    (match_dup 4)))
1296           (match_operand:GPF 2 "register_operand" "w"))
1297      (set (mem:GPF (plus:P (match_dup 0)
1298                    (match_operand:P 5 "const_int_operand" "n")))
1299           (match_operand:GPF 3 "register_operand" "w"))])]
1300   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPF:MODE>mode)"
1301   "stp\\t%<w>2, %<w>3, [%0, %4]!"
1302   [(set_attr "type" "neon_store1_2reg<q>")]
1305 ;; -------------------------------------------------------------------
1306 ;; Sign/Zero extension
1307 ;; -------------------------------------------------------------------
1309 (define_expand "<optab>sidi2"
1310   [(set (match_operand:DI 0 "register_operand")
1311         (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1312   ""
1315 (define_insn "*extendsidi2_aarch64"
1316   [(set (match_operand:DI 0 "register_operand" "=r,r")
1317         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1318   ""
1319   "@
1320    sxtw\t%0, %w1
1321    ldrsw\t%0, %1"
1322   [(set_attr "type" "extend,load1")]
1325 (define_insn "*load_pair_extendsidi2_aarch64"
1326   [(set (match_operand:DI 0 "register_operand" "=r")
1327         (sign_extend:DI (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump")))
1328    (set (match_operand:DI 2 "register_operand" "=r")
1329         (sign_extend:DI (match_operand:SI 3 "memory_operand" "m")))]
1330   "rtx_equal_p (XEXP (operands[3], 0),
1331                 plus_constant (Pmode,
1332                                XEXP (operands[1], 0),
1333                                GET_MODE_SIZE (SImode)))"
1334   "ldpsw\\t%0, %2, %1"
1335   [(set_attr "type" "load2")]
1338 (define_insn "*zero_extendsidi2_aarch64"
1339   [(set (match_operand:DI 0 "register_operand" "=r,r")
1340         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1341   ""
1342   "@
1343    uxtw\t%0, %w1
1344    ldr\t%w0, %1"
1345   [(set_attr "type" "extend,load1")]
1348 (define_insn "*load_pair_zero_extendsidi2_aarch64"
1349   [(set (match_operand:DI 0 "register_operand" "=r")
1350         (zero_extend:DI (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump")))
1351    (set (match_operand:DI 2 "register_operand" "=r")
1352         (zero_extend:DI (match_operand:SI 3 "memory_operand" "m")))]
1353   "rtx_equal_p (XEXP (operands[3], 0),
1354                 plus_constant (Pmode,
1355                                XEXP (operands[1], 0),
1356                                GET_MODE_SIZE (SImode)))"
1357   "ldp\\t%w0, %w2, %1"
1358   [(set_attr "type" "load2")]
1361 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1362   [(set (match_operand:GPI 0 "register_operand")
1363         (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1364   ""
1367 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1368   [(set (match_operand:GPI 0 "register_operand" "=r,r")
1369         (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1370   ""
1371   "@
1372    sxt<SHORT:size>\t%<GPI:w>0, %w1
1373    ldrs<SHORT:size>\t%<GPI:w>0, %1"
1374   [(set_attr "type" "extend,load1")]
1377 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1378   [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1379         (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1380   ""
1381   "@
1382    uxt<SHORT:size>\t%<GPI:w>0, %w1
1383    ldr<SHORT:size>\t%w0, %1
1384    ldr\t%<SHORT:size>0, %1"
1385   [(set_attr "type" "extend,load1,load1")]
1388 (define_expand "<optab>qihi2"
1389   [(set (match_operand:HI 0 "register_operand")
1390         (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1391   ""
1394 (define_insn "*<optab>qihi2_aarch64"
1395   [(set (match_operand:HI 0 "register_operand" "=r,r")
1396         (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1397   ""
1398   "@
1399    <su>xtb\t%w0, %w1
1400    <ldrxt>b\t%w0, %1"
1401   [(set_attr "type" "extend,load1")]
1404 ;; -------------------------------------------------------------------
1405 ;; Simple arithmetic
1406 ;; -------------------------------------------------------------------
1408 (define_expand "add<mode>3"
1409   [(set
1410     (match_operand:GPI 0 "register_operand" "")
1411     (plus:GPI (match_operand:GPI 1 "register_operand" "")
1412               (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1413   ""
1414   "
1415   if (! aarch64_plus_operand (operands[2], VOIDmode))
1416     {
1417       HOST_WIDE_INT imm = INTVAL (operands[2]);
1419       if (aarch64_move_imm (imm, <MODE>mode) && can_create_pseudo_p ())
1420         {
1421           rtx tmp = gen_reg_rtx (<MODE>mode);
1422           emit_move_insn (tmp, operands[2]);
1423           operands[2] = tmp;
1424         }
1425       else
1426         {
1427           rtx subtarget = ((optimize && can_create_pseudo_p ())
1428                            ? gen_reg_rtx (<MODE>mode) : operands[0]);
1430           if (imm < 0)
1431             imm = -(-imm & ~0xfff);
1432           else
1433             imm &= ~0xfff;
1435           emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1436           operands[1] = subtarget;
1437           operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1438         }
1439     }
1440   "
1443 (define_insn "*addsi3_aarch64"
1444   [(set
1445     (match_operand:SI 0 "register_operand" "=rk,rk,w,rk")
1446     (plus:SI
1447      (match_operand:SI 1 "register_operand" "%rk,rk,w,rk")
1448      (match_operand:SI 2 "aarch64_plus_operand" "I,r,w,J")))]
1449   ""
1450   "@
1451   add\\t%w0, %w1, %2
1452   add\\t%w0, %w1, %w2
1453   add\\t%0.2s, %1.2s, %2.2s
1454   sub\\t%w0, %w1, #%n2"
1455   [(set_attr "type" "alu_imm,alu_sreg,neon_add,alu_imm")
1456    (set_attr "simd" "*,*,yes,*")]
1459 ;; zero_extend version of above
1460 (define_insn "*addsi3_aarch64_uxtw"
1461   [(set
1462     (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1463     (zero_extend:DI
1464      (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1465               (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1466   ""
1467   "@
1468   add\\t%w0, %w1, %2
1469   add\\t%w0, %w1, %w2
1470   sub\\t%w0, %w1, #%n2"
1471   [(set_attr "type" "alu_imm,alu_sreg,alu_imm")]
1474 (define_insn "*adddi3_aarch64"
1475   [(set
1476     (match_operand:DI 0 "register_operand" "=rk,rk,rk,w")
1477     (plus:DI
1478      (match_operand:DI 1 "register_operand" "%rk,rk,rk,w")
1479      (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,w")))]
1480   ""
1481   "@
1482   add\\t%x0, %x1, %2
1483   add\\t%x0, %x1, %x2
1484   sub\\t%x0, %x1, #%n2
1485   add\\t%d0, %d1, %d2"
1486   [(set_attr "type" "alu_imm,alu_sreg,alu_imm,neon_add")
1487    (set_attr "simd" "*,*,*,yes")]
1490 (define_expand "addti3"
1491   [(set (match_operand:TI 0 "register_operand" "")
1492         (plus:TI (match_operand:TI 1 "register_operand" "")
1493                  (match_operand:TI 2 "register_operand" "")))]
1494   ""
1496   rtx low = gen_reg_rtx (DImode);
1497   emit_insn (gen_adddi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1498                                   gen_lowpart (DImode, operands[2])));
1500   rtx high = gen_reg_rtx (DImode);
1501   emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]),
1502                                  gen_highpart (DImode, operands[2])));
1504   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1505   emit_move_insn (gen_highpart (DImode, operands[0]), high);
1506   DONE;
1509 (define_insn "add<mode>3_compare0"
1510   [(set (reg:CC_NZ CC_REGNUM)
1511         (compare:CC_NZ
1512          (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1513                    (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1514          (const_int 0)))
1515    (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1516         (plus:GPI (match_dup 1) (match_dup 2)))]
1517   ""
1518   "@
1519   adds\\t%<w>0, %<w>1, %<w>2
1520   adds\\t%<w>0, %<w>1, %<w>2
1521   subs\\t%<w>0, %<w>1, #%n2"
1522   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1525 ;; zero_extend version of above
1526 (define_insn "*addsi3_compare0_uxtw"
1527   [(set (reg:CC_NZ CC_REGNUM)
1528         (compare:CC_NZ
1529          (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1530                   (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1531          (const_int 0)))
1532    (set (match_operand:DI 0 "register_operand" "=r,r,r")
1533         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1534   ""
1535   "@
1536   adds\\t%w0, %w1, %w2
1537   adds\\t%w0, %w1, %w2
1538   subs\\t%w0, %w1, #%n2"
1539   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1542 (define_insn "*adds_shift_imm_<mode>"
1543   [(set (reg:CC_NZ CC_REGNUM)
1544         (compare:CC_NZ
1545          (plus:GPI (ASHIFT:GPI 
1546                     (match_operand:GPI 1 "register_operand" "r")
1547                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1548                    (match_operand:GPI 3 "register_operand" "r"))
1549          (const_int 0)))
1550    (set (match_operand:GPI 0 "register_operand" "=r")
1551         (plus:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))
1552                   (match_dup 3)))]
1553   ""
1554   "adds\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1555   [(set_attr "type" "alus_shift_imm")]
1558 (define_insn "*subs_shift_imm_<mode>"
1559   [(set (reg:CC_NZ CC_REGNUM)
1560         (compare:CC_NZ
1561          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1562                     (ASHIFT:GPI
1563                      (match_operand:GPI 2 "register_operand" "r")
1564                      (match_operand:QI 3 "aarch64_shift_imm_<mode>" "n")))
1565          (const_int 0)))
1566    (set (match_operand:GPI 0 "register_operand" "=r")
1567         (minus:GPI (match_dup 1)
1568                    (ASHIFT:GPI (match_dup 2) (match_dup 3))))]
1569   ""
1570   "subs\\t%<w>0, %<w>1, %<w>2, <shift> %3"
1571   [(set_attr "type" "alus_shift_imm")]
1574 (define_insn "*adds_mul_imm_<mode>"
1575   [(set (reg:CC_NZ CC_REGNUM)
1576         (compare:CC_NZ
1577          (plus:GPI (mult:GPI
1578                     (match_operand:GPI 1 "register_operand" "r")
1579                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1580                    (match_operand:GPI 3 "register_operand" "r"))
1581          (const_int 0)))
1582    (set (match_operand:GPI 0 "register_operand" "=r")
1583         (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1584                   (match_dup 3)))]
1585   ""
1586   "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1587   [(set_attr "type" "alus_shift_imm")]
1590 (define_insn "*subs_mul_imm_<mode>"
1591   [(set (reg:CC_NZ CC_REGNUM)
1592         (compare:CC_NZ
1593          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1594                     (mult:GPI
1595                      (match_operand:GPI 2 "register_operand" "r")
1596                      (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1597          (const_int 0)))
1598    (set (match_operand:GPI 0 "register_operand" "=r")
1599         (minus:GPI (match_dup 1)
1600                    (mult:GPI (match_dup 2) (match_dup 3))))]
1601   ""
1602   "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1603   [(set_attr "type" "alus_shift_imm")]
1606 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1607   [(set (reg:CC_NZ CC_REGNUM)
1608         (compare:CC_NZ
1609          (plus:GPI
1610           (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1611           (match_operand:GPI 2 "register_operand" "r"))
1612         (const_int 0)))
1613    (set (match_operand:GPI 0 "register_operand" "=r")
1614         (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1615   ""
1616   "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1617   [(set_attr "type" "alus_ext")]
1620 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1621   [(set (reg:CC_NZ CC_REGNUM)
1622         (compare:CC_NZ
1623          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1624                     (ANY_EXTEND:GPI
1625                      (match_operand:ALLX 2 "register_operand" "r")))
1626         (const_int 0)))
1627    (set (match_operand:GPI 0 "register_operand" "=r")
1628         (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1629   ""
1630   "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1631   [(set_attr "type" "alus_ext")]
1634 (define_insn "*adds_<optab><ALLX:mode>_shift_<GPI:mode>"
1635   [(set (reg:CC_NZ CC_REGNUM)
1636         (compare:CC_NZ
1637          (plus:GPI (ashift:GPI 
1638                     (ANY_EXTEND:GPI 
1639                      (match_operand:ALLX 1 "register_operand" "r"))
1640                     (match_operand 2 "aarch64_imm3" "Ui3"))
1641                    (match_operand:GPI 3 "register_operand" "r"))
1642          (const_int 0)))
1643    (set (match_operand:GPI 0 "register_operand" "=rk")
1644         (plus:GPI (ashift:GPI (ANY_EXTEND:GPI (match_dup 1))
1645                               (match_dup 2))
1646                   (match_dup 3)))]
1647   ""
1648   "adds\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1649   [(set_attr "type" "alus_ext")]
1652 (define_insn "*subs_<optab><ALLX:mode>_shift_<GPI:mode>"
1653   [(set (reg:CC_NZ CC_REGNUM)
1654         (compare:CC_NZ
1655          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1656                     (ashift:GPI 
1657                      (ANY_EXTEND:GPI
1658                       (match_operand:ALLX 2 "register_operand" "r"))
1659                      (match_operand 3 "aarch64_imm3" "Ui3")))
1660          (const_int 0)))
1661    (set (match_operand:GPI 0 "register_operand" "=rk")
1662         (minus:GPI (match_dup 1)
1663                    (ashift:GPI (ANY_EXTEND:GPI (match_dup 2))
1664                                (match_dup 3))))]
1665   ""
1666   "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1667   [(set_attr "type" "alus_ext")]
1670 (define_insn "*adds_<optab><mode>_multp2"
1671   [(set (reg:CC_NZ CC_REGNUM)
1672         (compare:CC_NZ
1673          (plus:GPI (ANY_EXTRACT:GPI
1674                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1675                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1676                     (match_operand 3 "const_int_operand" "n")
1677                     (const_int 0))
1678                    (match_operand:GPI 4 "register_operand" "r"))
1679         (const_int 0)))
1680    (set (match_operand:GPI 0 "register_operand" "=r")
1681         (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1682                                    (match_dup 3)
1683                                    (const_int 0))
1684                   (match_dup 4)))]
1685   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1686   "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1687   [(set_attr "type" "alus_ext")]
1690 (define_insn "*subs_<optab><mode>_multp2"
1691   [(set (reg:CC_NZ CC_REGNUM)
1692         (compare:CC_NZ
1693          (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1694                     (ANY_EXTRACT:GPI
1695                      (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1696                                (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1697                      (match_operand 3 "const_int_operand" "n")
1698                      (const_int 0)))
1699         (const_int 0)))
1700    (set (match_operand:GPI 0 "register_operand" "=r")
1701         (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1702                                   (mult:GPI (match_dup 1) (match_dup 2))
1703                                   (match_dup 3)
1704                                   (const_int 0))))]
1705   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1706   "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1707   [(set_attr "type" "alus_ext")]
1710 (define_insn "*add<mode>3nr_compare0"
1711   [(set (reg:CC_NZ CC_REGNUM)
1712         (compare:CC_NZ
1713          (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1714                    (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1715          (const_int 0)))]
1716   ""
1717   "@
1718   cmn\\t%<w>0, %<w>1
1719   cmn\\t%<w>0, %<w>1
1720   cmp\\t%<w>0, #%n1"
1721   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1724 (define_insn "*compare_neg<mode>"
1725   [(set (reg:CC_Z CC_REGNUM)
1726         (compare:CC_Z
1727          (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1728          (match_operand:GPI 1 "register_operand" "r")))]
1729   ""
1730   "cmn\\t%<w>1, %<w>0"
1731   [(set_attr "type" "alus_sreg")]
1734 (define_insn "*add_<shift>_<mode>"
1735   [(set (match_operand:GPI 0 "register_operand" "=r")
1736         (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1737                               (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1738                   (match_operand:GPI 3 "register_operand" "r")))]
1739   ""
1740   "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1741   [(set_attr "type" "alu_shift_imm")]
1744 ;; zero_extend version of above
1745 (define_insn "*add_<shift>_si_uxtw"
1746   [(set (match_operand:DI 0 "register_operand" "=r")
1747         (zero_extend:DI
1748          (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1749                              (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1750                   (match_operand:SI 3 "register_operand" "r"))))]
1751   ""
1752   "add\\t%w0, %w3, %w1, <shift> %2"
1753   [(set_attr "type" "alu_shift_imm")]
1756 (define_insn "*add_mul_imm_<mode>"
1757   [(set (match_operand:GPI 0 "register_operand" "=r")
1758         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1759                             (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1760                   (match_operand:GPI 3 "register_operand" "r")))]
1761   ""
1762   "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1763   [(set_attr "type" "alu_shift_imm")]
1766 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1767   [(set (match_operand:GPI 0 "register_operand" "=rk")
1768         (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1769                   (match_operand:GPI 2 "register_operand" "r")))]
1770   ""
1771   "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1772   [(set_attr "type" "alu_ext")]
1775 ;; zero_extend version of above
1776 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1777   [(set (match_operand:DI 0 "register_operand" "=rk")
1778         (zero_extend:DI
1779          (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1780                   (match_operand:GPI 2 "register_operand" "r"))))]
1781   ""
1782   "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1783   [(set_attr "type" "alu_ext")]
1786 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1787   [(set (match_operand:GPI 0 "register_operand" "=rk")
1788         (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1789                                (match_operand:ALLX 1 "register_operand" "r"))
1790                               (match_operand 2 "aarch64_imm3" "Ui3"))
1791                   (match_operand:GPI 3 "register_operand" "r")))]
1792   ""
1793   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1794   [(set_attr "type" "alu_ext")]
1797 ;; zero_extend version of above
1798 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1799   [(set (match_operand:DI 0 "register_operand" "=rk")
1800         (zero_extend:DI
1801          (plus:SI (ashift:SI (ANY_EXTEND:SI
1802                               (match_operand:SHORT 1 "register_operand" "r"))
1803                              (match_operand 2 "aarch64_imm3" "Ui3"))
1804                   (match_operand:SI 3 "register_operand" "r"))))]
1805   ""
1806   "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1807   [(set_attr "type" "alu_ext")]
1810 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1811   [(set (match_operand:GPI 0 "register_operand" "=rk")
1812         (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1813                              (match_operand:ALLX 1 "register_operand" "r"))
1814                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1815                   (match_operand:GPI 3 "register_operand" "r")))]
1816   ""
1817   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1818   [(set_attr "type" "alu_ext")]
1821 ;; zero_extend version of above
1822 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1823   [(set (match_operand:DI 0 "register_operand" "=rk")
1824         (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1825                              (match_operand:SHORT 1 "register_operand" "r"))
1826                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1827                   (match_operand:SI 3 "register_operand" "r"))))]
1828   ""
1829   "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1830   [(set_attr "type" "alu_ext")]
1833 (define_insn "*add_<optab><mode>_multp2"
1834   [(set (match_operand:GPI 0 "register_operand" "=rk")
1835         (plus:GPI (ANY_EXTRACT:GPI
1836                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1837                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1838                    (match_operand 3 "const_int_operand" "n")
1839                    (const_int 0))
1840                   (match_operand:GPI 4 "register_operand" "r")))]
1841   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1842   "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1843   [(set_attr "type" "alu_ext")]
1846 ;; zero_extend version of above
1847 (define_insn "*add_<optab>si_multp2_uxtw"
1848   [(set (match_operand:DI 0 "register_operand" "=rk")
1849         (zero_extend:DI
1850          (plus:SI (ANY_EXTRACT:SI
1851                    (mult:SI (match_operand:SI 1 "register_operand" "r")
1852                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1853                    (match_operand 3 "const_int_operand" "n")
1854                    (const_int 0))
1855                   (match_operand:SI 4 "register_operand" "r"))))]
1856   "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1857   "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1858   [(set_attr "type" "alu_ext")]
1861 (define_insn "add<mode>3_carryin"
1862   [(set
1863     (match_operand:GPI 0 "register_operand" "=r")
1864     (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1865               (plus:GPI
1866                 (match_operand:GPI 1 "register_operand" "r")
1867                 (match_operand:GPI 2 "register_operand" "r"))))]
1868    ""
1869    "adc\\t%<w>0, %<w>1, %<w>2"
1870   [(set_attr "type" "adc_reg")]
1873 ;; zero_extend version of above
1874 (define_insn "*addsi3_carryin_uxtw"
1875   [(set
1876     (match_operand:DI 0 "register_operand" "=r")
1877     (zero_extend:DI
1878      (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1879               (plus:SI
1880                (match_operand:SI 1 "register_operand" "r")
1881                (match_operand:SI 2 "register_operand" "r")))))]
1882    ""
1883    "adc\\t%w0, %w1, %w2"
1884   [(set_attr "type" "adc_reg")]
1887 (define_insn "*add<mode>3_carryin_alt1"
1888   [(set
1889     (match_operand:GPI 0 "register_operand" "=r")
1890     (plus:GPI (plus:GPI
1891                 (match_operand:GPI 1 "register_operand" "r")
1892                 (match_operand:GPI 2 "register_operand" "r"))
1893               (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1894    ""
1895    "adc\\t%<w>0, %<w>1, %<w>2"
1896   [(set_attr "type" "adc_reg")]
1899 ;; zero_extend version of above
1900 (define_insn "*addsi3_carryin_alt1_uxtw"
1901   [(set
1902     (match_operand:DI 0 "register_operand" "=r")
1903     (zero_extend:DI
1904      (plus:SI (plus:SI
1905                (match_operand:SI 1 "register_operand" "r")
1906                (match_operand:SI 2 "register_operand" "r"))
1907               (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1908    ""
1909    "adc\\t%w0, %w1, %w2"
1910   [(set_attr "type" "adc_reg")]
1913 (define_insn "*add<mode>3_carryin_alt2"
1914   [(set
1915     (match_operand:GPI 0 "register_operand" "=r")
1916     (plus:GPI (plus:GPI
1917                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1918                 (match_operand:GPI 1 "register_operand" "r"))
1919               (match_operand:GPI 2 "register_operand" "r")))]
1920    ""
1921    "adc\\t%<w>0, %<w>1, %<w>2"
1922   [(set_attr "type" "adc_reg")]
1925 ;; zero_extend version of above
1926 (define_insn "*addsi3_carryin_alt2_uxtw"
1927   [(set
1928     (match_operand:DI 0 "register_operand" "=r")
1929     (zero_extend:DI
1930      (plus:SI (plus:SI
1931                (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1932                (match_operand:SI 1 "register_operand" "r"))
1933               (match_operand:SI 2 "register_operand" "r"))))]
1934    ""
1935    "adc\\t%w0, %w1, %w2"
1936   [(set_attr "type" "adc_reg")]
1939 (define_insn "*add<mode>3_carryin_alt3"
1940   [(set
1941     (match_operand:GPI 0 "register_operand" "=r")
1942     (plus:GPI (plus:GPI
1943                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1944                 (match_operand:GPI 2 "register_operand" "r"))
1945               (match_operand:GPI 1 "register_operand" "r")))]
1946    ""
1947    "adc\\t%<w>0, %<w>1, %<w>2"
1948   [(set_attr "type" "adc_reg")]
1951 ;; zero_extend version of above
1952 (define_insn "*addsi3_carryin_alt3_uxtw"
1953   [(set
1954     (match_operand:DI 0 "register_operand" "=r")
1955     (zero_extend:DI
1956      (plus:SI (plus:SI
1957                (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1958                (match_operand:SI 2 "register_operand" "r"))
1959               (match_operand:SI 1 "register_operand" "r"))))]
1960    ""
1961    "adc\\t%w0, %w1, %w2"
1962   [(set_attr "type" "adc_reg")]
1965 (define_insn "*add_uxt<mode>_shift2"
1966   [(set (match_operand:GPI 0 "register_operand" "=rk")
1967         (plus:GPI (and:GPI
1968                    (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
1969                                (match_operand 2 "aarch64_imm3" "Ui3"))
1970                    (match_operand 3 "const_int_operand" "n"))
1971                   (match_operand:GPI 4 "register_operand" "r")))]
1972   "aarch64_uxt_size (INTVAL (operands[2]), INTVAL (operands[3])) != 0"
1973   "*
1974   operands[3] = GEN_INT (aarch64_uxt_size (INTVAL(operands[2]),
1975                                            INTVAL (operands[3])));
1976   return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %2\";"
1977   [(set_attr "type" "alu_ext")]
1980 ;; zero_extend version of above
1981 (define_insn "*add_uxtsi_shift2_uxtw"
1982   [(set (match_operand:DI 0 "register_operand" "=rk")
1983         (zero_extend:DI
1984          (plus:SI (and:SI
1985                    (ashift:SI (match_operand:SI 1 "register_operand" "r")
1986                               (match_operand 2 "aarch64_imm3" "Ui3"))
1987                    (match_operand 3 "const_int_operand" "n"))
1988                   (match_operand:SI 4 "register_operand" "r"))))]
1989   "aarch64_uxt_size (INTVAL (operands[2]), INTVAL (operands[3])) != 0"
1990   "*
1991   operands[3] = GEN_INT (aarch64_uxt_size (INTVAL (operands[2]),
1992                                            INTVAL (operands[3])));
1993   return \"add\t%w0, %w4, %w1, uxt%e3 %2\";"
1994   [(set_attr "type" "alu_ext")]
1997 (define_insn "*add_uxt<mode>_multp2"
1998   [(set (match_operand:GPI 0 "register_operand" "=rk")
1999         (plus:GPI (and:GPI
2000                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2001                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2002                    (match_operand 3 "const_int_operand" "n"))
2003                   (match_operand:GPI 4 "register_operand" "r")))]
2004   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
2005   "*
2006   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2007                                            INTVAL (operands[3])));
2008   return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
2009   [(set_attr "type" "alu_ext")]
2012 ;; zero_extend version of above
2013 (define_insn "*add_uxtsi_multp2_uxtw"
2014   [(set (match_operand:DI 0 "register_operand" "=rk")
2015         (zero_extend:DI
2016          (plus:SI (and:SI
2017                    (mult:SI (match_operand:SI 1 "register_operand" "r")
2018                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2019                    (match_operand 3 "const_int_operand" "n"))
2020                   (match_operand:SI 4 "register_operand" "r"))))]
2021   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
2022   "*
2023   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2024                                            INTVAL (operands[3])));
2025   return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
2026   [(set_attr "type" "alu_ext")]
2029 (define_insn "subsi3"
2030   [(set (match_operand:SI 0 "register_operand" "=rk")
2031         (minus:SI (match_operand:SI 1 "register_operand" "rk")
2032                   (match_operand:SI 2 "register_operand" "r")))]
2033   ""
2034   "sub\\t%w0, %w1, %w2"
2035   [(set_attr "type" "alu_sreg")]
2038 ;; zero_extend version of above
2039 (define_insn "*subsi3_uxtw"
2040   [(set (match_operand:DI 0 "register_operand" "=rk")
2041         (zero_extend:DI
2042          (minus:SI (match_operand:SI 1 "register_operand" "rk")
2043                    (match_operand:SI 2 "register_operand" "r"))))]
2044   ""
2045   "sub\\t%w0, %w1, %w2"
2046   [(set_attr "type" "alu_sreg")]
2049 (define_insn "subdi3"
2050   [(set (match_operand:DI 0 "register_operand" "=rk,w")
2051         (minus:DI (match_operand:DI 1 "register_operand" "rk,w")
2052                   (match_operand:DI 2 "register_operand" "r,w")))]
2053   ""
2054   "@
2055    sub\\t%x0, %x1, %x2
2056    sub\\t%d0, %d1, %d2"
2057   [(set_attr "type" "alu_sreg, neon_sub")
2058    (set_attr "simd" "*,yes")]
2061 (define_expand "subti3"
2062   [(set (match_operand:TI 0 "register_operand" "")
2063         (minus:TI (match_operand:TI 1 "register_operand" "")
2064                   (match_operand:TI 2 "register_operand" "")))]
2065   ""
2067   rtx low = gen_reg_rtx (DImode);
2068   emit_insn (gen_subdi3_compare0 (low, gen_lowpart (DImode, operands[1]),
2069                                   gen_lowpart (DImode, operands[2])));
2071   rtx high = gen_reg_rtx (DImode);
2072   emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]),
2073                                  gen_highpart (DImode, operands[2])));
2075   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2076   emit_move_insn (gen_highpart (DImode, operands[0]), high);
2077   DONE;
2080 (define_insn "sub<mode>3_compare0"
2081   [(set (reg:CC_NZ CC_REGNUM)
2082         (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
2083                                   (match_operand:GPI 2 "register_operand" "r"))
2084                        (const_int 0)))
2085    (set (match_operand:GPI 0 "register_operand" "=r")
2086         (minus:GPI (match_dup 1) (match_dup 2)))]
2087   ""
2088   "subs\\t%<w>0, %<w>1, %<w>2"
2089   [(set_attr "type" "alus_sreg")]
2092 ;; zero_extend version of above
2093 (define_insn "*subsi3_compare0_uxtw"
2094   [(set (reg:CC_NZ CC_REGNUM)
2095         (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
2096                                  (match_operand:SI 2 "register_operand" "r"))
2097                        (const_int 0)))
2098    (set (match_operand:DI 0 "register_operand" "=r")
2099         (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
2100   ""
2101   "subs\\t%w0, %w1, %w2"
2102   [(set_attr "type" "alus_sreg")]
2105 (define_insn "*sub_<shift>_<mode>"
2106   [(set (match_operand:GPI 0 "register_operand" "=r")
2107         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2108                    (ASHIFT:GPI
2109                     (match_operand:GPI 1 "register_operand" "r")
2110                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2111   ""
2112   "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
2113   [(set_attr "type" "alu_shift_imm")]
2116 ;; zero_extend version of above
2117 (define_insn "*sub_<shift>_si_uxtw"
2118   [(set (match_operand:DI 0 "register_operand" "=r")
2119         (zero_extend:DI
2120          (minus:SI (match_operand:SI 3 "register_operand" "r")
2121                    (ASHIFT:SI
2122                     (match_operand:SI 1 "register_operand" "r")
2123                     (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2124   ""
2125   "sub\\t%w0, %w3, %w1, <shift> %2"
2126   [(set_attr "type" "alu_shift_imm")]
2129 (define_insn "*sub_mul_imm_<mode>"
2130   [(set (match_operand:GPI 0 "register_operand" "=r")
2131         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2132                    (mult:GPI
2133                     (match_operand:GPI 1 "register_operand" "r")
2134                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2135   ""
2136   "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
2137   [(set_attr "type" "alu_shift_imm")]
2140 ;; zero_extend version of above
2141 (define_insn "*sub_mul_imm_si_uxtw"
2142   [(set (match_operand:DI 0 "register_operand" "=r")
2143         (zero_extend:DI
2144          (minus:SI (match_operand:SI 3 "register_operand" "r")
2145                    (mult:SI
2146                     (match_operand:SI 1 "register_operand" "r")
2147                     (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2148   ""
2149   "sub\\t%w0, %w3, %w1, lsl %p2"
2150   [(set_attr "type" "alu_shift_imm")]
2153 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
2154   [(set (match_operand:GPI 0 "register_operand" "=rk")
2155         (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
2156                    (ANY_EXTEND:GPI
2157                     (match_operand:ALLX 2 "register_operand" "r"))))]
2158   ""
2159   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
2160   [(set_attr "type" "alu_ext")]
2163 ;; zero_extend version of above
2164 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
2165   [(set (match_operand:DI 0 "register_operand" "=rk")
2166         (zero_extend:DI
2167          (minus:SI (match_operand:SI 1 "register_operand" "rk")
2168                    (ANY_EXTEND:SI
2169                     (match_operand:SHORT 2 "register_operand" "r")))))]
2170   ""
2171   "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
2172   [(set_attr "type" "alu_ext")]
2175 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
2176   [(set (match_operand:GPI 0 "register_operand" "=rk")
2177         (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
2178                    (ashift:GPI (ANY_EXTEND:GPI
2179                                 (match_operand:ALLX 2 "register_operand" "r"))
2180                                (match_operand 3 "aarch64_imm3" "Ui3"))))]
2181   ""
2182   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
2183   [(set_attr "type" "alu_ext")]
2186 ;; zero_extend version of above
2187 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
2188   [(set (match_operand:DI 0 "register_operand" "=rk")
2189         (zero_extend:DI
2190          (minus:SI (match_operand:SI 1 "register_operand" "rk")
2191                    (ashift:SI (ANY_EXTEND:SI
2192                                (match_operand:SHORT 2 "register_operand" "r"))
2193                               (match_operand 3 "aarch64_imm3" "Ui3")))))]
2194   ""
2195   "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
2196   [(set_attr "type" "alu_ext")]
2199 (define_insn "*sub_<optab><mode>_multp2"
2200   [(set (match_operand:GPI 0 "register_operand" "=rk")
2201         (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
2202                    (ANY_EXTRACT:GPI
2203                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2204                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2205                     (match_operand 3 "const_int_operand" "n")
2206                     (const_int 0))))]
2207   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
2208   "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
2209   [(set_attr "type" "alu_ext")]
2212 ;; zero_extend version of above
2213 (define_insn "*sub_<optab>si_multp2_uxtw"
2214   [(set (match_operand:DI 0 "register_operand" "=rk")
2215         (zero_extend:DI
2216          (minus:SI (match_operand:SI 4 "register_operand" "rk")
2217                    (ANY_EXTRACT:SI
2218                     (mult:SI (match_operand:SI 1 "register_operand" "r")
2219                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2220                     (match_operand 3 "const_int_operand" "n")
2221                     (const_int 0)))))]
2222   "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
2223   "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
2224   [(set_attr "type" "alu_ext")]
2227 (define_insn "sub<mode>3_carryin"
2228   [(set
2229     (match_operand:GPI 0 "register_operand" "=r")
2230     (minus:GPI (minus:GPI
2231                 (match_operand:GPI 1 "register_operand" "r")
2232                 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2233                (match_operand:GPI 2 "register_operand" "r")))]
2234    ""
2235    "sbc\\t%<w>0, %<w>1, %<w>2"
2236   [(set_attr "type" "adc_reg")]
2239 ;; zero_extend version of the above
2240 (define_insn "*subsi3_carryin_uxtw"
2241   [(set
2242     (match_operand:DI 0 "register_operand" "=r")
2243     (zero_extend:DI
2244      (minus:SI (minus:SI
2245                 (match_operand:SI 1 "register_operand" "r")
2246                 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2247                (match_operand:SI 2 "register_operand" "r"))))]
2248    ""
2249    "sbc\\t%w0, %w1, %w2"
2250   [(set_attr "type" "adc_reg")]
2253 (define_insn "*sub_uxt<mode>_shift2"
2254   [(set (match_operand:GPI 0 "register_operand" "=rk")
2255         (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
2256                    (and:GPI
2257                     (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
2258                                 (match_operand 2 "aarch64_imm3" "Ui3"))
2259                     (match_operand 3 "const_int_operand" "n"))))]
2260   "aarch64_uxt_size (INTVAL (operands[2]),INTVAL (operands[3])) != 0"
2261   "*
2262   operands[3] = GEN_INT (aarch64_uxt_size (INTVAL (operands[2]),
2263                                            INTVAL (operands[3])));
2264   return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %2\";"
2265   [(set_attr "type" "alu_ext")]
2268 ;; zero_extend version of above
2269 (define_insn "*sub_uxtsi_shift2_uxtw"
2270   [(set (match_operand:DI 0 "register_operand" "=rk")
2271         (zero_extend:DI
2272          (minus:SI (match_operand:SI 4 "register_operand" "rk")
2273                    (and:SI
2274                     (ashift:SI (match_operand:SI 1 "register_operand" "r")
2275                                (match_operand 2 "aarch64_imm3" "Ui3"))
2276                     (match_operand 3 "const_int_operand" "n")))))]
2277   "aarch64_uxt_size (INTVAL (operands[2]),INTVAL (operands[3])) != 0"
2278   "*
2279   operands[3] = GEN_INT (aarch64_uxt_size (INTVAL (operands[2]),
2280                                            INTVAL (operands[3])));
2281   return \"sub\t%w0, %w4, %w1, uxt%e3 %2\";"
2282   [(set_attr "type" "alu_ext")]
2285 (define_insn "*sub_uxt<mode>_multp2"
2286   [(set (match_operand:GPI 0 "register_operand" "=rk")
2287         (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
2288                    (and:GPI
2289                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2290                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2291                     (match_operand 3 "const_int_operand" "n"))))]
2292   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2293   "*
2294   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2295                                            INTVAL (operands[3])));
2296   return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
2297   [(set_attr "type" "alu_ext")]
2300 ;; zero_extend version of above
2301 (define_insn "*sub_uxtsi_multp2_uxtw"
2302   [(set (match_operand:DI 0 "register_operand" "=rk")
2303         (zero_extend:DI
2304          (minus:SI (match_operand:SI 4 "register_operand" "rk")
2305                    (and:SI
2306                     (mult:SI (match_operand:SI 1 "register_operand" "r")
2307                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2308                     (match_operand 3 "const_int_operand" "n")))))]
2309   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2310   "*
2311   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2312                                            INTVAL (operands[3])));
2313   return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
2314   [(set_attr "type" "alu_ext")]
2317 (define_expand "abs<mode>2"
2318   [(match_operand:GPI 0 "register_operand" "")
2319    (match_operand:GPI 1 "register_operand" "")]
2320   ""
2321   {
2322     rtx ccreg = aarch64_gen_compare_reg (LT, operands[1], const0_rtx);
2323     rtx x = gen_rtx_LT (VOIDmode, ccreg, const0_rtx);
2324     emit_insn (gen_csneg3<mode>_insn (operands[0], x, operands[1], operands[1]));
2325     DONE;
2326   }
2329 (define_insn "neg<mode>2"
2330   [(set (match_operand:GPI 0 "register_operand" "=r,w")
2331         (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
2332   ""
2333   "@
2334    neg\\t%<w>0, %<w>1
2335    neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
2336   [(set_attr "type" "alu_sreg, neon_neg<q>")
2337    (set_attr "simd" "*,yes")]
2340 ;; zero_extend version of above
2341 (define_insn "*negsi2_uxtw"
2342   [(set (match_operand:DI 0 "register_operand" "=r")
2343         (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
2344   ""
2345   "neg\\t%w0, %w1"
2346   [(set_attr "type" "alu_sreg")]
2349 (define_insn "*ngc<mode>"
2350   [(set (match_operand:GPI 0 "register_operand" "=r")
2351         (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2352                    (match_operand:GPI 1 "register_operand" "r")))]
2353   ""
2354   "ngc\\t%<w>0, %<w>1"
2355   [(set_attr "type" "adc_reg")]
2358 (define_insn "*ngcsi_uxtw"
2359   [(set (match_operand:DI 0 "register_operand" "=r")
2360         (zero_extend:DI
2361          (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2362                    (match_operand:SI 1 "register_operand" "r"))))]
2363   ""
2364   "ngc\\t%w0, %w1"
2365   [(set_attr "type" "adc_reg")]
2368 (define_insn "*neg<mode>2_compare0"
2369   [(set (reg:CC_NZ CC_REGNUM)
2370         (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2371                        (const_int 0)))
2372    (set (match_operand:GPI 0 "register_operand" "=r")
2373         (neg:GPI (match_dup 1)))]
2374   ""
2375   "negs\\t%<w>0, %<w>1"
2376   [(set_attr "type" "alus_sreg")]
2379 ;; zero_extend version of above
2380 (define_insn "*negsi2_compare0_uxtw"
2381   [(set (reg:CC_NZ CC_REGNUM)
2382         (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
2383                        (const_int 0)))
2384    (set (match_operand:DI 0 "register_operand" "=r")
2385         (zero_extend:DI (neg:SI (match_dup 1))))]
2386   ""
2387   "negs\\t%w0, %w1"
2388   [(set_attr "type" "alus_sreg")]
2391 (define_insn "*neg_<shift><mode>3_compare0"
2392   [(set (reg:CC_NZ CC_REGNUM)
2393         (compare:CC_NZ
2394          (neg:GPI (ASHIFT:GPI
2395                    (match_operand:GPI 1 "register_operand" "r")
2396                    (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2397          (const_int 0)))
2398    (set (match_operand:GPI 0 "register_operand" "=r")
2399         (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2400   ""
2401   "negs\\t%<w>0, %<w>1, <shift> %2"
2402   [(set_attr "type" "alus_shift_imm")]
2405 (define_insn "*neg_<shift>_<mode>2"
2406   [(set (match_operand:GPI 0 "register_operand" "=r")
2407         (neg:GPI (ASHIFT:GPI
2408                   (match_operand:GPI 1 "register_operand" "r")
2409                   (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2410   ""
2411   "neg\\t%<w>0, %<w>1, <shift> %2"
2412   [(set_attr "type" "alu_shift_imm")]
2415 ;; zero_extend version of above
2416 (define_insn "*neg_<shift>_si2_uxtw"
2417   [(set (match_operand:DI 0 "register_operand" "=r")
2418         (zero_extend:DI
2419          (neg:SI (ASHIFT:SI
2420                   (match_operand:SI 1 "register_operand" "r")
2421                   (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2422   ""
2423   "neg\\t%w0, %w1, <shift> %2"
2424   [(set_attr "type" "alu_shift_imm")]
2427 (define_insn "*neg_mul_imm_<mode>2"
2428   [(set (match_operand:GPI 0 "register_operand" "=r")
2429         (neg:GPI (mult:GPI
2430                   (match_operand:GPI 1 "register_operand" "r")
2431                   (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2432   ""
2433   "neg\\t%<w>0, %<w>1, lsl %p2"
2434   [(set_attr "type" "alu_shift_imm")]
2437 ;; zero_extend version of above
2438 (define_insn "*neg_mul_imm_si2_uxtw"
2439   [(set (match_operand:DI 0 "register_operand" "=r")
2440         (zero_extend:DI
2441          (neg:SI (mult:SI
2442                   (match_operand:SI 1 "register_operand" "r")
2443                   (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2444   ""
2445   "neg\\t%w0, %w1, lsl %p2"
2446   [(set_attr "type" "alu_shift_imm")]
2449 (define_insn "mul<mode>3"
2450   [(set (match_operand:GPI 0 "register_operand" "=r")
2451         (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2452                   (match_operand:GPI 2 "register_operand" "r")))]
2453   ""
2454   "mul\\t%<w>0, %<w>1, %<w>2"
2455   [(set_attr "type" "mul")]
2458 ;; zero_extend version of above
2459 (define_insn "*mulsi3_uxtw"
2460   [(set (match_operand:DI 0 "register_operand" "=r")
2461         (zero_extend:DI
2462          (mult:SI (match_operand:SI 1 "register_operand" "r")
2463                   (match_operand:SI 2 "register_operand" "r"))))]
2464   ""
2465   "mul\\t%w0, %w1, %w2"
2466   [(set_attr "type" "mul")]
2469 (define_insn "madd<mode>"
2470   [(set (match_operand:GPI 0 "register_operand" "=r")
2471         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2472                             (match_operand:GPI 2 "register_operand" "r"))
2473                   (match_operand:GPI 3 "register_operand" "r")))]
2474   ""
2475   "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2476   [(set_attr "type" "mla")]
2479 ;; zero_extend version of above
2480 (define_insn "*maddsi_uxtw"
2481   [(set (match_operand:DI 0 "register_operand" "=r")
2482         (zero_extend:DI
2483          (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2484                            (match_operand:SI 2 "register_operand" "r"))
2485                   (match_operand:SI 3 "register_operand" "r"))))]
2486   ""
2487   "madd\\t%w0, %w1, %w2, %w3"
2488   [(set_attr "type" "mla")]
2491 (define_insn "*msub<mode>"
2492   [(set (match_operand:GPI 0 "register_operand" "=r")
2493         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2494                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2495                              (match_operand:GPI 2 "register_operand" "r"))))]
2497   ""
2498   "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2499   [(set_attr "type" "mla")]
2502 ;; zero_extend version of above
2503 (define_insn "*msubsi_uxtw"
2504   [(set (match_operand:DI 0 "register_operand" "=r")
2505         (zero_extend:DI
2506          (minus:SI (match_operand:SI 3 "register_operand" "r")
2507                    (mult:SI (match_operand:SI 1 "register_operand" "r")
2508                             (match_operand:SI 2 "register_operand" "r")))))]
2510   ""
2511   "msub\\t%w0, %w1, %w2, %w3"
2512   [(set_attr "type" "mla")]
2515 (define_insn "*mul<mode>_neg"
2516   [(set (match_operand:GPI 0 "register_operand" "=r")
2517         (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2518                   (match_operand:GPI 2 "register_operand" "r")))]
2520   ""
2521   "mneg\\t%<w>0, %<w>1, %<w>2"
2522   [(set_attr "type" "mul")]
2525 ;; zero_extend version of above
2526 (define_insn "*mulsi_neg_uxtw"
2527   [(set (match_operand:DI 0 "register_operand" "=r")
2528         (zero_extend:DI
2529          (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2530                   (match_operand:SI 2 "register_operand" "r"))))]
2532   ""
2533   "mneg\\t%w0, %w1, %w2"
2534   [(set_attr "type" "mul")]
2537 (define_insn "<su_optab>mulsidi3"
2538   [(set (match_operand:DI 0 "register_operand" "=r")
2539         (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2540                  (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2541   ""
2542   "<su>mull\\t%0, %w1, %w2"
2543   [(set_attr "type" "<su>mull")]
2546 (define_insn "<su_optab>maddsidi4"
2547   [(set (match_operand:DI 0 "register_operand" "=r")
2548         (plus:DI (mult:DI
2549                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2550                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2551                  (match_operand:DI 3 "register_operand" "r")))]
2552   ""
2553   "<su>maddl\\t%0, %w1, %w2, %3"
2554   [(set_attr "type" "<su>mlal")]
2557 (define_insn "<su_optab>msubsidi4"
2558   [(set (match_operand:DI 0 "register_operand" "=r")
2559         (minus:DI
2560          (match_operand:DI 3 "register_operand" "r")
2561          (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2562                   (ANY_EXTEND:DI
2563                    (match_operand:SI 2 "register_operand" "r")))))]
2564   ""
2565   "<su>msubl\\t%0, %w1, %w2, %3"
2566   [(set_attr "type" "<su>mlal")]
2569 (define_insn "*<su_optab>mulsidi_neg"
2570   [(set (match_operand:DI 0 "register_operand" "=r")
2571         (mult:DI (neg:DI
2572                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2573                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2574   ""
2575   "<su>mnegl\\t%0, %w1, %w2"
2576   [(set_attr "type" "<su>mull")]
2579 (define_expand "<su_optab>mulditi3"
2580   [(set (match_operand:TI 0 "register_operand")
2581         (mult:TI (ANY_EXTEND:TI (match_operand:DI 1 "register_operand"))
2582                  (ANY_EXTEND:TI (match_operand:DI 2 "register_operand"))))]
2583   ""
2585   rtx low = gen_reg_rtx (DImode);
2586   emit_insn (gen_muldi3 (low, operands[1], operands[2]));
2588   rtx high = gen_reg_rtx (DImode);
2589   emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2]));
2591   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2592   emit_move_insn (gen_highpart (DImode, operands[0]), high);
2593   DONE;
2596 ;; The default expansion of multi3 using umuldi3_highpart will perform
2597 ;; the additions in an order that fails to combine into two madd insns.
2598 (define_expand "multi3"
2599   [(set (match_operand:TI 0 "register_operand")
2600         (mult:TI (match_operand:TI 1 "register_operand")
2601                  (match_operand:TI 2 "register_operand")))]
2602   ""
2604   rtx l0 = gen_reg_rtx (DImode);
2605   rtx l1 = gen_lowpart (DImode, operands[1]);
2606   rtx l2 = gen_lowpart (DImode, operands[2]);
2607   rtx h0 = gen_reg_rtx (DImode);
2608   rtx h1 = gen_highpart (DImode, operands[1]);
2609   rtx h2 = gen_highpart (DImode, operands[2]);
2611   emit_insn (gen_muldi3 (l0, l1, l2));
2612   emit_insn (gen_umuldi3_highpart (h0, l1, l2));
2613   emit_insn (gen_madddi (h0, h1, l2, h0));
2614   emit_insn (gen_madddi (h0, l1, h2, h0));
2616   emit_move_insn (gen_lowpart (DImode, operands[0]), l0);
2617   emit_move_insn (gen_highpart (DImode, operands[0]), h0);
2618   DONE;
2621 (define_insn "<su>muldi3_highpart"
2622   [(set (match_operand:DI 0 "register_operand" "=r")
2623         (truncate:DI
2624          (lshiftrt:TI
2625           (mult:TI
2626            (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2627            (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2628           (const_int 64))))]
2629   ""
2630   "<su>mulh\\t%0, %1, %2"
2631   [(set_attr "type" "<su>mull")]
2634 (define_insn "<su_optab>div<mode>3"
2635   [(set (match_operand:GPI 0 "register_operand" "=r")
2636         (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2637                      (match_operand:GPI 2 "register_operand" "r")))]
2638   ""
2639   "<su>div\\t%<w>0, %<w>1, %<w>2"
2640   [(set_attr "type" "<su>div")]
2643 ;; zero_extend version of above
2644 (define_insn "*<su_optab>divsi3_uxtw"
2645   [(set (match_operand:DI 0 "register_operand" "=r")
2646         (zero_extend:DI
2647          (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2648                      (match_operand:SI 2 "register_operand" "r"))))]
2649   ""
2650   "<su>div\\t%w0, %w1, %w2"
2651   [(set_attr "type" "<su>div")]
2654 ;; -------------------------------------------------------------------
2655 ;; Comparison insns
2656 ;; -------------------------------------------------------------------
2658 (define_insn "*cmp<mode>"
2659   [(set (reg:CC CC_REGNUM)
2660         (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2661                     (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2662   ""
2663   "@
2664    cmp\\t%<w>0, %<w>1
2665    cmp\\t%<w>0, %<w>1
2666    cmn\\t%<w>0, #%n1"
2667   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
2670 (define_insn "*cmp<mode>"
2671   [(set (reg:CCFP CC_REGNUM)
2672         (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2673                       (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2674    "TARGET_FLOAT"
2675    "@
2676     fcmp\\t%<s>0, #0.0
2677     fcmp\\t%<s>0, %<s>1"
2678   [(set_attr "type" "fcmp<s>")]
2681 (define_insn "*cmpe<mode>"
2682   [(set (reg:CCFPE CC_REGNUM)
2683         (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2684                        (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2685    "TARGET_FLOAT"
2686    "@
2687     fcmpe\\t%<s>0, #0.0
2688     fcmpe\\t%<s>0, %<s>1"
2689   [(set_attr "type" "fcmp<s>")]
2692 (define_insn "*cmp_swp_<shift>_reg<mode>"
2693   [(set (reg:CC_SWP CC_REGNUM)
2694         (compare:CC_SWP (ASHIFT:GPI
2695                          (match_operand:GPI 0 "register_operand" "r")
2696                          (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2697                         (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2698   ""
2699   "cmp\\t%<w>2, %<w>0, <shift> %1"
2700   [(set_attr "type" "alus_shift_imm")]
2703 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2704   [(set (reg:CC_SWP CC_REGNUM)
2705         (compare:CC_SWP (ANY_EXTEND:GPI
2706                          (match_operand:ALLX 0 "register_operand" "r"))
2707                         (match_operand:GPI 1 "register_operand" "r")))]
2708   ""
2709   "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2710   [(set_attr "type" "alus_ext")]
2713 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2714   [(set (reg:CC_SWP CC_REGNUM)
2715         (compare:CC_SWP (ashift:GPI
2716                          (ANY_EXTEND:GPI
2717                           (match_operand:ALLX 0 "register_operand" "r"))
2718                          (match_operand 1 "aarch64_imm3" "Ui3"))
2719         (match_operand:GPI 2 "register_operand" "r")))]
2720   ""
2721   "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2722   [(set_attr "type" "alus_ext")]
2725 ;; -------------------------------------------------------------------
2726 ;; Store-flag and conditional select insns
2727 ;; -------------------------------------------------------------------
2729 (define_expand "cstore<mode>4"
2730   [(set (match_operand:SI 0 "register_operand" "")
2731         (match_operator:SI 1 "aarch64_comparison_operator"
2732          [(match_operand:GPI 2 "register_operand" "")
2733           (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2734   ""
2735   "
2736   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2737                                       operands[3]);
2738   operands[3] = const0_rtx;
2739   "
2742 (define_expand "cstorecc4"
2743   [(set (match_operand:SI 0 "register_operand")
2744        (match_operator 1 "aarch64_comparison_operator"
2745         [(match_operand 2 "ccmp_cc_register")
2746          (match_operand 3 "const0_operand")]))]
2747   ""
2749   emit_insn (gen_rtx_SET (operands[0], operands[1]));
2750   DONE;
2754 (define_expand "cstore<mode>4"
2755   [(set (match_operand:SI 0 "register_operand" "")
2756         (match_operator:SI 1 "aarch64_comparison_operator"
2757          [(match_operand:GPF 2 "register_operand" "")
2758           (match_operand:GPF 3 "register_operand" "")]))]
2759   ""
2760   "
2761   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2762                                       operands[3]);
2763   operands[3] = const0_rtx;
2764   "
2767 (define_insn "*cstore<mode>_insn"
2768   [(set (match_operand:ALLI 0 "register_operand" "=r")
2769         (match_operator:ALLI 1 "aarch64_comparison_operator"
2770          [(match_operand 2 "cc_register" "") (const_int 0)]))]
2771   ""
2772   "cset\\t%<w>0, %m1"
2773   [(set_attr "type" "csel")]
2776 ;; zero_extend version of the above
2777 (define_insn "*cstoresi_insn_uxtw"
2778   [(set (match_operand:DI 0 "register_operand" "=r")
2779         (zero_extend:DI
2780          (match_operator:SI 1 "aarch64_comparison_operator"
2781           [(match_operand 2 "cc_register" "") (const_int 0)])))]
2782   ""
2783   "cset\\t%w0, %m1"
2784   [(set_attr "type" "csel")]
2787 (define_insn "cstore<mode>_neg"
2788   [(set (match_operand:ALLI 0 "register_operand" "=r")
2789         (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2790                   [(match_operand 2 "cc_register" "") (const_int 0)])))]
2791   ""
2792   "csetm\\t%<w>0, %m1"
2793   [(set_attr "type" "csel")]
2796 ;; zero_extend version of the above
2797 (define_insn "*cstoresi_neg_uxtw"
2798   [(set (match_operand:DI 0 "register_operand" "=r")
2799         (zero_extend:DI
2800          (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2801                   [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2802   ""
2803   "csetm\\t%w0, %m1"
2804   [(set_attr "type" "csel")]
2807 (define_expand "cmov<mode>6"
2808   [(set (match_operand:GPI 0 "register_operand" "")
2809         (if_then_else:GPI
2810          (match_operator 1 "aarch64_comparison_operator"
2811           [(match_operand:GPI 2 "register_operand" "")
2812            (match_operand:GPI 3 "aarch64_plus_operand" "")])
2813          (match_operand:GPI 4 "register_operand" "")
2814          (match_operand:GPI 5 "register_operand" "")))]
2815   ""
2816   "
2817   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2818                                       operands[3]);
2819   operands[3] = const0_rtx;
2820   "
2823 (define_expand "cmov<mode>6"
2824   [(set (match_operand:GPF 0 "register_operand" "")
2825         (if_then_else:GPF
2826          (match_operator 1 "aarch64_comparison_operator"
2827           [(match_operand:GPF 2 "register_operand" "")
2828            (match_operand:GPF 3 "register_operand" "")])
2829          (match_operand:GPF 4 "register_operand" "")
2830          (match_operand:GPF 5 "register_operand" "")))]
2831   ""
2832   "
2833   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2834                                       operands[3]);
2835   operands[3] = const0_rtx;
2836   "
2839 (define_insn "*cmov<mode>_insn"
2840   [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2841         (if_then_else:ALLI
2842          (match_operator 1 "aarch64_comparison_operator"
2843           [(match_operand 2 "cc_register" "") (const_int 0)])
2844          (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2845          (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2846   "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2847      || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2848   ;; Final two alternatives should be unreachable, but included for completeness
2849   "@
2850    csel\\t%<w>0, %<w>3, %<w>4, %m1
2851    csinv\\t%<w>0, %<w>3, <w>zr, %m1
2852    csinv\\t%<w>0, %<w>4, <w>zr, %M1
2853    csinc\\t%<w>0, %<w>3, <w>zr, %m1
2854    csinc\\t%<w>0, %<w>4, <w>zr, %M1
2855    mov\\t%<w>0, -1
2856    mov\\t%<w>0, 1"
2857   [(set_attr "type" "csel")]
2860 ;; zero_extend version of above
2861 (define_insn "*cmovsi_insn_uxtw"
2862   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2863         (zero_extend:DI
2864          (if_then_else:SI
2865           (match_operator 1 "aarch64_comparison_operator"
2866            [(match_operand 2 "cc_register" "") (const_int 0)])
2867           (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2868           (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2869   "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2870      || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2871   ;; Final two alternatives should be unreachable, but included for completeness
2872   "@
2873    csel\\t%w0, %w3, %w4, %m1
2874    csinv\\t%w0, %w3, wzr, %m1
2875    csinv\\t%w0, %w4, wzr, %M1
2876    csinc\\t%w0, %w3, wzr, %m1
2877    csinc\\t%w0, %w4, wzr, %M1
2878    mov\\t%w0, -1
2879    mov\\t%w0, 1"
2880   [(set_attr "type" "csel")]
2883 (define_insn "*cmov<mode>_insn"
2884   [(set (match_operand:GPF 0 "register_operand" "=w")
2885         (if_then_else:GPF
2886          (match_operator 1 "aarch64_comparison_operator"
2887           [(match_operand 2 "cc_register" "") (const_int 0)])
2888          (match_operand:GPF 3 "register_operand" "w")
2889          (match_operand:GPF 4 "register_operand" "w")))]
2890   "TARGET_FLOAT"
2891   "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2892   [(set_attr "type" "fcsel")]
2895 (define_expand "mov<mode>cc"
2896   [(set (match_operand:ALLI 0 "register_operand" "")
2897         (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2898                            (match_operand:ALLI 2 "register_operand" "")
2899                            (match_operand:ALLI 3 "register_operand" "")))]
2900   ""
2901   {
2902     enum rtx_code code = GET_CODE (operands[1]);
2904     if (code == UNEQ || code == LTGT)
2905       FAIL;
2907     if (!ccmp_cc_register (XEXP (operands[1], 0),
2908                            GET_MODE (XEXP (operands[1], 0))))
2909       {
2910         rtx ccreg;
2911         ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2912                                          XEXP (operands[1], 1));
2913         operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2914       }
2915   }
2918 (define_expand "mov<GPF:mode><GPI:mode>cc"
2919   [(set (match_operand:GPI 0 "register_operand" "")
2920         (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2921                           (match_operand:GPF 2 "register_operand" "")
2922                           (match_operand:GPF 3 "register_operand" "")))]
2923   ""
2924   {
2925     rtx ccreg;
2926     enum rtx_code code = GET_CODE (operands[1]);
2928     if (code == UNEQ || code == LTGT)
2929       FAIL;
2931     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2932                                   XEXP (operands[1], 1));
2933     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2934   }
2937 (define_expand "mov<mode>cc"
2938   [(set (match_operand:GPF 0 "register_operand" "")
2939         (if_then_else:GPF (match_operand 1 "aarch64_comparison_operator" "")
2940                           (match_operand:GPF 2 "register_operand" "")
2941                           (match_operand:GPF 3 "register_operand" "")))]
2942   ""
2943   {
2944     rtx ccreg;
2945     enum rtx_code code = GET_CODE (operands[1]);
2947     if (code == UNEQ || code == LTGT)
2948       FAIL;
2950     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2951                                   XEXP (operands[1], 1));
2952     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2953   }
2957 ;; CRC32 instructions.
2958 (define_insn "aarch64_<crc_variant>"
2959   [(set (match_operand:SI 0 "register_operand" "=r")
2960         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2961                     (match_operand:<crc_mode> 2 "register_operand" "r")]
2962          CRC))]
2963   "TARGET_CRC32"
2964   {
2965     if (GET_MODE_BITSIZE (GET_MODE (operands[2])) >= 64)
2966       return "<crc_variant>\\t%w0, %w1, %x2";
2967     else
2968       return "<crc_variant>\\t%w0, %w1, %w2";
2969   }
2970   [(set_attr "type" "crc")]
2973 (define_insn "*csinc2<mode>_insn"
2974   [(set (match_operand:GPI 0 "register_operand" "=r")
2975         (plus:GPI (match_operand 2 "aarch64_comparison_operation" "")
2976                   (match_operand:GPI 1 "register_operand" "r")))]
2977   ""
2978   "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2979   [(set_attr "type" "csel")]
2982 (define_insn "csinc3<mode>_insn"
2983   [(set (match_operand:GPI 0 "register_operand" "=r")
2984         (if_then_else:GPI
2985           (match_operand 1 "aarch64_comparison_operation" "")
2986           (plus:GPI (match_operand:GPI 2 "register_operand" "r")
2987                     (const_int 1))
2988           (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2989   ""
2990   "csinc\\t%<w>0, %<w>3, %<w>2, %M1"
2991   [(set_attr "type" "csel")]
2994 (define_insn "*csinv3<mode>_insn"
2995   [(set (match_operand:GPI 0 "register_operand" "=r")
2996         (if_then_else:GPI
2997           (match_operand 1 "aarch64_comparison_operation" "")
2998           (not:GPI (match_operand:GPI 2 "register_operand" "r"))
2999           (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
3000   ""
3001   "csinv\\t%<w>0, %<w>3, %<w>2, %M1"
3002   [(set_attr "type" "csel")]
3005 (define_insn "csneg3<mode>_insn"
3006   [(set (match_operand:GPI 0 "register_operand" "=r")
3007         (if_then_else:GPI
3008           (match_operand 1 "aarch64_comparison_operation" "")
3009           (neg:GPI (match_operand:GPI 2 "register_operand" "r"))
3010           (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
3011   ""
3012   "csneg\\t%<w>0, %<w>3, %<w>2, %M1"
3013   [(set_attr "type" "csel")]
3016 ;; -------------------------------------------------------------------
3017 ;; Logical operations
3018 ;; -------------------------------------------------------------------
3020 (define_insn "<optab><mode>3"
3021   [(set (match_operand:GPI 0 "register_operand" "=r,rk,w")
3022         (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r,w")
3023                      (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>,w")))]
3024   ""
3025   "@
3026   <logical>\\t%<w>0, %<w>1, %<w>2
3027   <logical>\\t%<w>0, %<w>1, %<w>2
3028   <logical>\\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
3029   [(set_attr "type" "logic_reg,logic_imm,neon_logic")
3030    (set_attr "simd" "*,*,yes")]
3033 ;; zero_extend version of above
3034 (define_insn "*<optab>si3_uxtw"
3035   [(set (match_operand:DI 0 "register_operand" "=r,rk")
3036         (zero_extend:DI
3037          (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
3038                      (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
3039   ""
3040   "<logical>\\t%w0, %w1, %w2"
3041   [(set_attr "type" "logic_reg,logic_imm")]
3044 (define_insn "*and<mode>3_compare0"
3045   [(set (reg:CC_NZ CC_REGNUM)
3046         (compare:CC_NZ
3047          (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
3048                   (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
3049          (const_int 0)))
3050    (set (match_operand:GPI 0 "register_operand" "=r,r")
3051         (and:GPI (match_dup 1) (match_dup 2)))]
3052   ""
3053   "ands\\t%<w>0, %<w>1, %<w>2"
3054   [(set_attr "type" "logics_reg,logics_imm")]
3057 ;; zero_extend version of above
3058 (define_insn "*andsi3_compare0_uxtw"
3059   [(set (reg:CC_NZ CC_REGNUM)
3060         (compare:CC_NZ
3061          (and:SI (match_operand:SI 1 "register_operand" "%r,r")
3062                  (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
3063          (const_int 0)))
3064    (set (match_operand:DI 0 "register_operand" "=r,r")
3065         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
3066   ""
3067   "ands\\t%w0, %w1, %w2"
3068   [(set_attr "type" "logics_reg,logics_imm")]
3071 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
3072   [(set (reg:CC_NZ CC_REGNUM)
3073         (compare:CC_NZ
3074          (and:GPI (SHIFT:GPI
3075                    (match_operand:GPI 1 "register_operand" "r")
3076                    (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3077                   (match_operand:GPI 3 "register_operand" "r"))
3078          (const_int 0)))
3079    (set (match_operand:GPI 0 "register_operand" "=r")
3080         (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
3081   ""
3082   "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3083   [(set_attr "type" "logics_shift_imm")]
3086 ;; zero_extend version of above
3087 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
3088   [(set (reg:CC_NZ CC_REGNUM)
3089         (compare:CC_NZ
3090          (and:SI (SHIFT:SI
3091                   (match_operand:SI 1 "register_operand" "r")
3092                   (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3093                  (match_operand:SI 3 "register_operand" "r"))
3094          (const_int 0)))
3095    (set (match_operand:DI 0 "register_operand" "=r")
3096         (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
3097                                 (match_dup 3))))]
3098   ""
3099   "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3100   [(set_attr "type" "logics_shift_imm")]
3103 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
3104   [(set (match_operand:GPI 0 "register_operand" "=r")
3105         (LOGICAL:GPI (SHIFT:GPI
3106                       (match_operand:GPI 1 "register_operand" "r")
3107                       (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3108                      (match_operand:GPI 3 "register_operand" "r")))]
3109   ""
3110   "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3111   [(set_attr "type" "logic_shift_imm")]
3114 (define_insn "*<optab>_rol<mode>3"
3115   [(set (match_operand:GPI 0 "register_operand" "=r")
3116         (LOGICAL:GPI (rotate:GPI
3117                       (match_operand:GPI 1 "register_operand" "r")
3118                       (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3119                      (match_operand:GPI 3 "register_operand" "r")))]
3120   ""
3121   "<logical>\\t%<w>0, %<w>3, %<w>1, ror (<sizen> - %2)"
3122   [(set_attr "type" "logic_shift_imm")]
3125 ;; zero_extend versions of above
3126 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
3127   [(set (match_operand:DI 0 "register_operand" "=r")
3128         (zero_extend:DI
3129          (LOGICAL:SI (SHIFT:SI
3130                       (match_operand:SI 1 "register_operand" "r")
3131                       (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3132                      (match_operand:SI 3 "register_operand" "r"))))]
3133   ""
3134   "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3135   [(set_attr "type" "logic_shift_imm")]
3138 (define_insn "*<optab>_rolsi3_uxtw"
3139   [(set (match_operand:DI 0 "register_operand" "=r")
3140         (zero_extend:DI
3141          (LOGICAL:SI (rotate:SI
3142                       (match_operand:SI 1 "register_operand" "r")
3143                       (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3144                      (match_operand:SI 3 "register_operand" "r"))))]
3145   ""
3146   "<logical>\\t%w0, %w3, %w1, ror (32 - %2)"
3147   [(set_attr "type" "logic_shift_imm")]
3150 (define_insn "one_cmpl<mode>2"
3151   [(set (match_operand:GPI 0 "register_operand" "=r,w")
3152         (not:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
3153   ""
3154   "@
3155   mvn\\t%<w>0, %<w>1
3156   mvn\\t%0.8b, %1.8b"
3157   [(set_attr "type" "logic_reg,neon_logic")
3158    (set_attr "simd" "*,yes")]
3161 (define_insn "*one_cmpl_<optab><mode>2"
3162   [(set (match_operand:GPI 0 "register_operand" "=r")
3163         (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
3164                             (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
3165   ""
3166   "mvn\\t%<w>0, %<w>1, <shift> %2"
3167   [(set_attr "type" "logic_shift_imm")]
3170 ;; Binary logical operators negating one operand, i.e. (a & !b), (a | !b).
3172 (define_insn "*<NLOGICAL:optab>_one_cmpl<mode>3"
3173   [(set (match_operand:GPI 0 "register_operand" "=r,w")
3174         (NLOGICAL:GPI (not:GPI (match_operand:GPI 1 "register_operand" "r,w"))
3175                      (match_operand:GPI 2 "register_operand" "r,w")))]
3176   ""
3177   "@
3178   <NLOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1
3179   <NLOGICAL:nlogical>\\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>"
3180   [(set_attr "type" "logic_reg,neon_logic")
3181    (set_attr "simd" "*,yes")]
3184 (define_insn "*<NLOGICAL:optab>_one_cmplsidi3_ze"
3185   [(set (match_operand:DI 0 "register_operand" "=r")
3186         (zero_extend:DI
3187           (NLOGICAL:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3188                        (match_operand:SI 2 "register_operand" "r"))))]
3189   ""
3190   "<NLOGICAL:nlogical>\\t%w0, %w2, %w1"
3191   [(set_attr "type" "logic_reg")]
3194 (define_insn "*xor_one_cmplsidi3_ze"
3195   [(set (match_operand:DI 0 "register_operand" "=r")
3196         (zero_extend:DI
3197           (not:SI (xor:SI (match_operand:SI 1 "register_operand" "r")
3198                           (match_operand:SI 2 "register_operand" "r")))))]
3199   ""
3200   "eon\\t%w0, %w1, %w2"
3201   [(set_attr "type" "logic_reg")]
3204 ;; (xor (not a) b) is simplify_rtx-ed down to (not (xor a b)).
3205 ;; eon does not operate on SIMD registers so the vector variant must be split.
3206 (define_insn_and_split "*xor_one_cmpl<mode>3"
3207   [(set (match_operand:GPI 0 "register_operand" "=r,w")
3208         (not:GPI (xor:GPI (match_operand:GPI 1 "register_operand" "r,?w")
3209                           (match_operand:GPI 2 "register_operand" "r,w"))))]
3210   ""
3211   "@
3212   eon\\t%<w>0, %<w>1, %<w>2
3213   #"
3214   "reload_completed && FP_REGNUM_P (REGNO (operands[0]))" ;; For SIMD registers.
3215   [(set (match_operand:GPI 0 "register_operand" "=w")
3216         (xor:GPI (match_operand:GPI 1 "register_operand" "w")
3217                  (match_operand:GPI 2 "register_operand" "w")))
3218    (set (match_dup 0) (not:GPI (match_dup 0)))]
3219   ""
3220   [(set_attr "type" "logic_reg,multiple")
3221    (set_attr "simd" "*,yes")]
3224 (define_insn "*and_one_cmpl<mode>3_compare0"
3225   [(set (reg:CC_NZ CC_REGNUM)
3226         (compare:CC_NZ
3227          (and:GPI (not:GPI
3228                    (match_operand:GPI 1 "register_operand" "r"))
3229                   (match_operand:GPI 2 "register_operand" "r"))
3230          (const_int 0)))
3231    (set (match_operand:GPI 0 "register_operand" "=r")
3232         (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
3233   ""
3234   "bics\\t%<w>0, %<w>2, %<w>1"
3235   [(set_attr "type" "logics_reg")]
3238 ;; zero_extend version of above
3239 (define_insn "*and_one_cmplsi3_compare0_uxtw"
3240   [(set (reg:CC_NZ CC_REGNUM)
3241         (compare:CC_NZ
3242          (and:SI (not:SI
3243                   (match_operand:SI 1 "register_operand" "r"))
3244                  (match_operand:SI 2 "register_operand" "r"))
3245          (const_int 0)))
3246    (set (match_operand:DI 0 "register_operand" "=r")
3247         (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
3248   ""
3249   "bics\\t%w0, %w2, %w1"
3250   [(set_attr "type" "logics_reg")]
3253 (define_insn "*and_one_cmpl<mode>3_compare0_no_reuse"
3254   [(set (reg:CC_NZ CC_REGNUM)
3255     (compare:CC_NZ
3256      (and:GPI (not:GPI
3257            (match_operand:GPI 0 "register_operand" "r"))
3258           (match_operand:GPI 1 "register_operand" "r"))
3259      (const_int 0)))]
3260   ""
3261   "bics\\t<w>zr, %<w>1, %<w>0"
3262   [(set_attr "type" "logics_reg")]
3265 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
3266   [(set (match_operand:GPI 0 "register_operand" "=r")
3267         (LOGICAL:GPI (not:GPI
3268                       (SHIFT:GPI
3269                        (match_operand:GPI 1 "register_operand" "r")
3270                        (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
3271                      (match_operand:GPI 3 "register_operand" "r")))]
3272   ""
3273   "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3274   [(set_attr "type" "logic_shift_imm")]
3277 (define_insn "*eor_one_cmpl_<SHIFT:optab><mode>3_alt"
3278   [(set (match_operand:GPI 0 "register_operand" "=r")
3279         (not:GPI (xor:GPI
3280                       (SHIFT:GPI
3281                        (match_operand:GPI 1 "register_operand" "r")
3282                        (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3283                      (match_operand:GPI 3 "register_operand" "r"))))]
3284   ""
3285   "eon\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3286   [(set_attr "type" "logic_shift_imm")]
3289 ;; Zero-extend version of the above.
3290 (define_insn "*eor_one_cmpl_<SHIFT:optab>sidi3_alt_ze"
3291   [(set (match_operand:DI 0 "register_operand" "=r")
3292         (zero_extend:DI
3293           (not:SI (xor:SI
3294                     (SHIFT:SI
3295                       (match_operand:SI 1 "register_operand" "r")
3296                       (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3297                     (match_operand:SI 3 "register_operand" "r")))))]
3298   ""
3299   "eon\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3300   [(set_attr "type" "logic_shift_imm")]
3303 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
3304   [(set (reg:CC_NZ CC_REGNUM)
3305         (compare:CC_NZ
3306          (and:GPI (not:GPI
3307                    (SHIFT:GPI
3308                     (match_operand:GPI 1 "register_operand" "r")
3309                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
3310                   (match_operand:GPI 3 "register_operand" "r"))
3311          (const_int 0)))
3312    (set (match_operand:GPI 0 "register_operand" "=r")
3313         (and:GPI (not:GPI
3314                   (SHIFT:GPI
3315                    (match_dup 1) (match_dup 2))) (match_dup 3)))]
3316   ""
3317   "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3318   [(set_attr "type" "logics_shift_imm")]
3321 ;; zero_extend version of above
3322 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
3323   [(set (reg:CC_NZ CC_REGNUM)
3324         (compare:CC_NZ
3325          (and:SI (not:SI
3326                   (SHIFT:SI
3327                    (match_operand:SI 1 "register_operand" "r")
3328                    (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
3329                  (match_operand:SI 3 "register_operand" "r"))
3330          (const_int 0)))
3331    (set (match_operand:DI 0 "register_operand" "=r")
3332         (zero_extend:DI (and:SI
3333                          (not:SI
3334                           (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
3335   ""
3336   "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3337   [(set_attr "type" "logics_shift_imm")]
3340 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0_no_reuse"
3341   [(set (reg:CC_NZ CC_REGNUM)
3342     (compare:CC_NZ
3343      (and:GPI (not:GPI
3344            (SHIFT:GPI
3345             (match_operand:GPI 0 "register_operand" "r")
3346             (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n")))
3347           (match_operand:GPI 2 "register_operand" "r"))
3348      (const_int 0)))]
3349   ""
3350   "bics\\t<w>zr, %<w>2, %<w>0, <SHIFT:shift> %1"
3351   [(set_attr "type" "logics_shift_imm")]
3354 (define_insn "clz<mode>2"
3355   [(set (match_operand:GPI 0 "register_operand" "=r")
3356         (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
3357   ""
3358   "clz\\t%<w>0, %<w>1"
3359   [(set_attr "type" "clz")]
3362 (define_expand "ffs<mode>2"
3363   [(match_operand:GPI 0 "register_operand")
3364    (match_operand:GPI 1 "register_operand")]
3365   ""
3366   {
3367     rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
3368     rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
3370     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3371     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3372     emit_insn (gen_csinc3<mode>_insn (operands[0], x, operands[0], const0_rtx));
3373     DONE;
3374   }
3377 (define_insn "clrsb<mode>2"
3378   [(set (match_operand:GPI 0 "register_operand" "=r")
3379         (clrsb:GPI (match_operand:GPI 1 "register_operand" "r")))]
3380   ""
3381   "cls\\t%<w>0, %<w>1"
3382   [(set_attr "type" "clz")]
3385 (define_insn "rbit<mode>2"
3386   [(set (match_operand:GPI 0 "register_operand" "=r")
3387         (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
3388   ""
3389   "rbit\\t%<w>0, %<w>1"
3390   [(set_attr "type" "rbit")]
3393 (define_expand "ctz<mode>2"
3394   [(match_operand:GPI 0 "register_operand")
3395    (match_operand:GPI 1 "register_operand")]
3396   ""
3397   {
3398     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3399     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3400     DONE;
3401   }
3404 (define_insn "*and<mode>3nr_compare0"
3405   [(set (reg:CC_NZ CC_REGNUM)
3406         (compare:CC_NZ
3407          (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
3408                   (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
3409          (const_int 0)))]
3410   ""
3411   "tst\\t%<w>0, %<w>1"
3412   [(set_attr "type" "logics_reg")]
3415 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
3416   [(set (reg:CC_NZ CC_REGNUM)
3417         (compare:CC_NZ
3418          (and:GPI (SHIFT:GPI
3419                    (match_operand:GPI 0 "register_operand" "r")
3420                    (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
3421                   (match_operand:GPI 2 "register_operand" "r"))
3422         (const_int 0)))]
3423   ""
3424   "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
3425   [(set_attr "type" "logics_shift_imm")]
3428 ;; -------------------------------------------------------------------
3429 ;; Shifts
3430 ;; -------------------------------------------------------------------
3432 (define_expand "<optab><mode>3"
3433   [(set (match_operand:GPI 0 "register_operand")
3434         (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
3435                     (match_operand:QI 2 "nonmemory_operand")))]
3436   ""
3437   {
3438     if (CONST_INT_P (operands[2]))
3439       {
3440         operands[2] = GEN_INT (INTVAL (operands[2])
3441                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3443         if (operands[2] == const0_rtx)
3444           {
3445             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3446             DONE;
3447           }
3448       }
3449   }
3452 (define_expand "ashl<mode>3"
3453   [(set (match_operand:SHORT 0 "register_operand")
3454         (ashift:SHORT (match_operand:SHORT 1 "register_operand")
3455                       (match_operand:QI 2 "nonmemory_operand")))]
3456   ""
3457   {
3458     if (CONST_INT_P (operands[2]))
3459       {
3460         operands[2] = GEN_INT (INTVAL (operands[2])
3461                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3463         if (operands[2] == const0_rtx)
3464           {
3465             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3466             DONE;
3467           }
3468       }
3469     else
3470       FAIL;
3471   }
3474 (define_expand "rotr<mode>3"
3475   [(set (match_operand:GPI 0 "register_operand")
3476         (rotatert:GPI (match_operand:GPI 1 "register_operand")
3477                       (match_operand:QI 2 "nonmemory_operand")))]
3478   ""
3479   {
3480     if (CONST_INT_P (operands[2]))
3481       {
3482         operands[2] = GEN_INT (INTVAL (operands[2])
3483                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3485         if (operands[2] == const0_rtx)
3486           {
3487             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3488             DONE;
3489           }
3490       }
3491   }
3494 (define_expand "rotl<mode>3"
3495   [(set (match_operand:GPI 0 "register_operand")
3496         (rotatert:GPI (match_operand:GPI 1 "register_operand")
3497                       (match_operand:QI 2 "nonmemory_operand")))]
3498   ""
3499   {
3500     /* (SZ - cnt) % SZ == -cnt % SZ */
3501     if (CONST_INT_P (operands[2]))
3502       {
3503         operands[2] = GEN_INT ((-INTVAL (operands[2]))
3504                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3505         if (operands[2] == const0_rtx)
3506           {
3507             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3508             DONE;
3509           }
3510       }
3511     else
3512       operands[2] = expand_simple_unop (QImode, NEG, operands[2],
3513                                         NULL_RTX, 1);
3514   }
3517 ;; Logical left shift using SISD or Integer instruction
3518 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
3519   [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3520         (ashift:GPI
3521           (match_operand:GPI 1 "register_operand" "w,w,r")
3522           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3523   ""
3524   "@
3525    shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3526    ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
3527    lsl\t%<w>0, %<w>1, %<w>2"
3528   [(set_attr "simd" "yes,yes,no")
3529    (set_attr "type" "neon_shift_imm<q>, neon_shift_reg<q>,shift_reg")]
3532 ;; Logical right shift using SISD or Integer instruction
3533 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3534   [(set (match_operand:GPI 0 "register_operand" "=w,&w,r")
3535         (lshiftrt:GPI
3536           (match_operand:GPI 1 "register_operand" "w,w,r")
3537           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3538   ""
3539   "@
3540    ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3541    #
3542    lsr\t%<w>0, %<w>1, %<w>2"
3543   [(set_attr "simd" "yes,yes,no")
3544    (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")]
3547 (define_split
3548   [(set (match_operand:DI 0 "aarch64_simd_register")
3549         (lshiftrt:DI
3550            (match_operand:DI 1 "aarch64_simd_register")
3551            (match_operand:QI 2 "aarch64_simd_register")))]
3552   "TARGET_SIMD && reload_completed"
3553   [(set (match_dup 3)
3554         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3555    (set (match_dup 0)
3556         (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_USHL))]
3557   {
3558     operands[3] = gen_lowpart (QImode, operands[0]);
3559   }
3562 (define_split
3563   [(set (match_operand:SI 0 "aarch64_simd_register")
3564         (lshiftrt:SI
3565            (match_operand:SI 1 "aarch64_simd_register")
3566            (match_operand:QI 2 "aarch64_simd_register")))]
3567   "TARGET_SIMD && reload_completed"
3568   [(set (match_dup 3)
3569         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3570    (set (match_dup 0)
3571         (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_USHL_2S))]
3572   {
3573     operands[3] = gen_lowpart (QImode, operands[0]);
3574   }
3577 ;; Arithmetic right shift using SISD or Integer instruction
3578 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3579   [(set (match_operand:GPI 0 "register_operand" "=w,&w,&w,r")
3580         (ashiftrt:GPI
3581           (match_operand:GPI 1 "register_operand" "w,w,w,r")
3582           (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,0,rUs<cmode>")))]
3583   ""
3584   "@
3585    sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3586    #
3587    #
3588    asr\t%<w>0, %<w>1, %<w>2"
3589   [(set_attr "simd" "yes,yes,yes,no")
3590    (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>,shift_reg")]
3593 (define_split
3594   [(set (match_operand:DI 0 "aarch64_simd_register")
3595         (ashiftrt:DI
3596            (match_operand:DI 1 "aarch64_simd_register")
3597            (match_operand:QI 2 "aarch64_simd_register")))]
3598   "TARGET_SIMD && reload_completed"
3599   [(set (match_dup 3)
3600         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3601    (set (match_dup 0)
3602         (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_SSHL))]
3604   operands[3] = gen_lowpart (QImode, operands[0]);
3608 (define_split
3609   [(set (match_operand:SI 0 "aarch64_simd_register")
3610         (ashiftrt:SI
3611            (match_operand:SI 1 "aarch64_simd_register")
3612            (match_operand:QI 2 "aarch64_simd_register")))]
3613   "TARGET_SIMD && reload_completed"
3614   [(set (match_dup 3)
3615         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3616    (set (match_dup 0)
3617         (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_SSHL_2S))]
3619   operands[3] = gen_lowpart (QImode, operands[0]);
3623 (define_insn "*aarch64_sisd_ushl"
3624   [(set (match_operand:DI 0 "register_operand" "=w")
3625         (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3626                     (match_operand:QI 2 "register_operand" "w")]
3627                    UNSPEC_SISD_USHL))]
3628   "TARGET_SIMD"
3629   "ushl\t%d0, %d1, %d2"
3630   [(set_attr "simd" "yes")
3631    (set_attr "type" "neon_shift_reg")]
3634 (define_insn "*aarch64_ushl_2s"
3635   [(set (match_operand:SI 0 "register_operand" "=w")
3636         (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3637                     (match_operand:QI 2 "register_operand" "w")]
3638                    UNSPEC_USHL_2S))]
3639   "TARGET_SIMD"
3640   "ushl\t%0.2s, %1.2s, %2.2s"
3641   [(set_attr "simd" "yes")
3642    (set_attr "type" "neon_shift_reg")]
3645 (define_insn "*aarch64_sisd_sshl"
3646   [(set (match_operand:DI 0 "register_operand" "=w")
3647         (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3648                     (match_operand:QI 2 "register_operand" "w")]
3649                    UNSPEC_SISD_SSHL))]
3650   "TARGET_SIMD"
3651   "sshl\t%d0, %d1, %d2"
3652   [(set_attr "simd" "yes")
3653    (set_attr "type" "neon_shift_reg")]
3656 (define_insn "*aarch64_sshl_2s"
3657   [(set (match_operand:SI 0 "register_operand" "=w")
3658         (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3659                     (match_operand:QI 2 "register_operand" "w")]
3660                    UNSPEC_SSHL_2S))]
3661   "TARGET_SIMD"
3662   "sshl\t%0.2s, %1.2s, %2.2s"
3663   [(set_attr "simd" "yes")
3664    (set_attr "type" "neon_shift_reg")]
3667 (define_insn "*aarch64_sisd_neg_qi"
3668   [(set (match_operand:QI 0 "register_operand" "=w")
3669         (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3670                    UNSPEC_SISD_NEG))]
3671   "TARGET_SIMD"
3672   "neg\t%d0, %d1"
3673   [(set_attr "simd" "yes")
3674    (set_attr "type" "neon_neg")]
3677 ;; Rotate right
3678 (define_insn "*ror<mode>3_insn"
3679   [(set (match_operand:GPI 0 "register_operand" "=r")
3680         (rotatert:GPI
3681           (match_operand:GPI 1 "register_operand" "r")
3682           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3683   ""
3684   "ror\\t%<w>0, %<w>1, %<w>2"
3685   [(set_attr "type" "shift_reg")]
3688 ;; zero_extend version of above
3689 (define_insn "*<optab>si3_insn_uxtw"
3690   [(set (match_operand:DI 0 "register_operand" "=r")
3691         (zero_extend:DI (SHIFT:SI
3692          (match_operand:SI 1 "register_operand" "r")
3693          (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3694   ""
3695   "<shift>\\t%w0, %w1, %w2"
3696   [(set_attr "type" "shift_reg")]
3699 (define_insn "*<optab><mode>3_insn"
3700   [(set (match_operand:SHORT 0 "register_operand" "=r")
3701         (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3702                       (match_operand 2 "const_int_operand" "n")))]
3703   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3705   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3706   return "<bfshift>\t%w0, %w1, %2, %3";
3708   [(set_attr "type" "bfm")]
3711 (define_insn "*extr<mode>5_insn"
3712   [(set (match_operand:GPI 0 "register_operand" "=r")
3713         (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3714                              (match_operand 3 "const_int_operand" "n"))
3715                  (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3716                                (match_operand 4 "const_int_operand" "n"))))]
3717   "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3718    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3719   "extr\\t%<w>0, %<w>1, %<w>2, %4"
3720   [(set_attr "type" "shift_imm")]
3723 ;; There are no canonicalisation rules for ashift and lshiftrt inside an ior
3724 ;; so we have to match both orderings.
3725 (define_insn "*extr<mode>5_insn_alt"
3726   [(set (match_operand:GPI 0 "register_operand" "=r")
3727         (ior:GPI  (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3728                                 (match_operand 4 "const_int_operand" "n"))
3729                   (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3730                               (match_operand 3 "const_int_operand" "n"))))]
3731   "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode)
3732    && (UINTVAL (operands[3]) + UINTVAL (operands[4])
3733        == GET_MODE_BITSIZE (<MODE>mode))"
3734   "extr\\t%<w>0, %<w>1, %<w>2, %4"
3735   [(set_attr "type" "shift_imm")]
3738 ;; zero_extend version of the above
3739 (define_insn "*extrsi5_insn_uxtw"
3740   [(set (match_operand:DI 0 "register_operand" "=r")
3741         (zero_extend:DI
3742          (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3743                             (match_operand 3 "const_int_operand" "n"))
3744                  (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3745                               (match_operand 4 "const_int_operand" "n")))))]
3746   "UINTVAL (operands[3]) < 32 &&
3747    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3748   "extr\\t%w0, %w1, %w2, %4"
3749   [(set_attr "type" "shift_imm")]
3752 (define_insn "*extrsi5_insn_uxtw_alt"
3753   [(set (match_operand:DI 0 "register_operand" "=r")
3754         (zero_extend:DI
3755          (ior:SI (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3756                                (match_operand 4 "const_int_operand" "n"))
3757                  (ashift:SI (match_operand:SI 1 "register_operand" "r")
3758                             (match_operand 3 "const_int_operand" "n")))))]
3759   "UINTVAL (operands[3]) < 32 &&
3760    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3761   "extr\\t%w0, %w1, %w2, %4"
3762   [(set_attr "type" "shift_imm")]
3765 (define_insn "*ror<mode>3_insn"
3766   [(set (match_operand:GPI 0 "register_operand" "=r")
3767         (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3768                     (match_operand 2 "const_int_operand" "n")))]
3769   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3771   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3772   return "ror\\t%<w>0, %<w>1, %3";
3774   [(set_attr "type" "shift_imm")]
3777 ;; zero_extend version of the above
3778 (define_insn "*rorsi3_insn_uxtw"
3779   [(set (match_operand:DI 0 "register_operand" "=r")
3780         (zero_extend:DI
3781          (rotate:SI (match_operand:SI 1 "register_operand" "r")
3782                     (match_operand 2 "const_int_operand" "n"))))]
3783   "UINTVAL (operands[2]) < 32"
3785   operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3786   return "ror\\t%w0, %w1, %3";
3788   [(set_attr "type" "shift_imm")]
3791 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3792   [(set (match_operand:GPI 0 "register_operand" "=r")
3793         (ANY_EXTEND:GPI
3794          (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3795                        (match_operand 2 "const_int_operand" "n"))))]
3796   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3798   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3799   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3801   [(set_attr "type" "bfm")]
3804 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3805   [(set (match_operand:GPI 0 "register_operand" "=r")
3806         (zero_extend:GPI
3807          (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3808                          (match_operand 2 "const_int_operand" "n"))))]
3809   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3811   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3812   return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3814   [(set_attr "type" "bfm")]
3817 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3818   [(set (match_operand:GPI 0 "register_operand" "=r")
3819         (sign_extend:GPI
3820          (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3821                          (match_operand 2 "const_int_operand" "n"))))]
3822   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3824   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3825   return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3827   [(set_attr "type" "bfm")]
3830 ;; -------------------------------------------------------------------
3831 ;; Bitfields
3832 ;; -------------------------------------------------------------------
3834 (define_expand "<optab>"
3835   [(set (match_operand:DI 0 "register_operand" "=r")
3836         (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3837                         (match_operand 2 "const_int_operand" "n")
3838                         (match_operand 3 "const_int_operand" "n")))]
3839   ""
3840   ""
3843 (define_insn "*<optab><mode>"
3844   [(set (match_operand:GPI 0 "register_operand" "=r")
3845         (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3846                          (match_operand 2 "const_int_operand" "n")
3847                          (match_operand 3 "const_int_operand" "n")))]
3848   ""
3849   "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3850   [(set_attr "type" "bfm")]
3853 ;; Bitfield Insert (insv)
3854 (define_expand "insv<mode>"
3855   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3856                           (match_operand 1 "const_int_operand")
3857                           (match_operand 2 "const_int_operand"))
3858         (match_operand:GPI 3 "general_operand"))]
3859   ""
3861   unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3862   unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3863   rtx value = operands[3];
3865   if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3866     FAIL;
3868   if (CONST_INT_P (value))
3869     {
3870       unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3872       /* Prefer AND/OR for inserting all zeros or all ones.  */
3873       if ((UINTVAL (value) & mask) == 0
3874            || (UINTVAL (value) & mask) == mask)
3875         FAIL;
3877       /* 16-bit aligned 16-bit wide insert is handled by insv_imm.  */
3878       if (width == 16 && (pos % 16) == 0)
3879         DONE;
3880     }
3881   operands[3] = force_reg (<MODE>mode, value);
3884 (define_insn "*insv_reg<mode>"
3885   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3886                           (match_operand 1 "const_int_operand" "n")
3887                           (match_operand 2 "const_int_operand" "n"))
3888         (match_operand:GPI 3 "register_operand" "r"))]
3889   "!(UINTVAL (operands[1]) == 0
3890      || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3891          > GET_MODE_BITSIZE (<MODE>mode)))"
3892   "bfi\\t%<w>0, %<w>3, %2, %1"
3893   [(set_attr "type" "bfm")]
3896 (define_insn "*extr_insv_lower_reg<mode>"
3897   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3898                           (match_operand 1 "const_int_operand" "n")
3899                           (const_int 0))
3900         (zero_extract:GPI (match_operand:GPI 2 "register_operand" "r")
3901                           (match_dup 1)
3902                           (match_operand 3 "const_int_operand" "n")))]
3903   "!(UINTVAL (operands[1]) == 0
3904      || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3905          > GET_MODE_BITSIZE (<MODE>mode)))"
3906   "bfxil\\t%<w>0, %<w>2, %3, %1"
3907   [(set_attr "type" "bfm")]
3910 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3911   [(set (match_operand:GPI 0 "register_operand" "=r")
3912         (ashift:GPI (ANY_EXTEND:GPI
3913                      (match_operand:ALLX 1 "register_operand" "r"))
3914                     (match_operand 2 "const_int_operand" "n")))]
3915   "UINTVAL (operands[2]) < <GPI:sizen>"
3917   operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3918               ? GEN_INT (<ALLX:sizen>)
3919               : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3920   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3922   [(set_attr "type" "bfm")]
3925 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3927 (define_insn "*andim_ashift<mode>_bfiz"
3928   [(set (match_operand:GPI 0 "register_operand" "=r")
3929         (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3930                              (match_operand 2 "const_int_operand" "n"))
3931                  (match_operand 3 "const_int_operand" "n")))]
3932   "(INTVAL (operands[2]) < (<GPI:sizen>))
3933    && exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3934    && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3935   "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3936   [(set_attr "type" "bfm")]
3939 (define_insn "bswap<mode>2"
3940   [(set (match_operand:GPI 0 "register_operand" "=r")
3941         (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3942   ""
3943   "rev\\t%<w>0, %<w>1"
3944   [(set_attr "type" "rev")]
3947 (define_insn "bswaphi2"
3948   [(set (match_operand:HI 0 "register_operand" "=r")
3949         (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3950   ""
3951   "rev16\\t%w0, %w1"
3952   [(set_attr "type" "rev")]
3955 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
3956 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
3957 ;; each valid permutation.
3959 (define_insn "rev16<mode>2"
3960   [(set (match_operand:GPI 0 "register_operand" "=r")
3961         (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3962                                       (const_int 8))
3963                           (match_operand:GPI 3 "const_int_operand" "n"))
3964                  (and:GPI (lshiftrt:GPI (match_dup 1)
3965                                         (const_int 8))
3966                           (match_operand:GPI 2 "const_int_operand" "n"))))]
3967   "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3968    && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3969   "rev16\\t%<w>0, %<w>1"
3970   [(set_attr "type" "rev")]
3973 (define_insn "rev16<mode>2_alt"
3974   [(set (match_operand:GPI 0 "register_operand" "=r")
3975         (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r")
3976                                         (const_int 8))
3977                           (match_operand:GPI 2 "const_int_operand" "n"))
3978                  (and:GPI (ashift:GPI (match_dup 1)
3979                                       (const_int 8))
3980                           (match_operand:GPI 3 "const_int_operand" "n"))))]
3981   "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3982    && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3983   "rev16\\t%<w>0, %<w>1"
3984   [(set_attr "type" "rev")]
3987 ;; zero_extend version of above
3988 (define_insn "*bswapsi2_uxtw"
3989   [(set (match_operand:DI 0 "register_operand" "=r")
3990         (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3991   ""
3992   "rev\\t%w0, %w1"
3993   [(set_attr "type" "rev")]
3996 ;; -------------------------------------------------------------------
3997 ;; Floating-point intrinsics
3998 ;; -------------------------------------------------------------------
4000 ;; frint floating-point round to integral standard patterns.
4001 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round, frintn.
4003 (define_insn "<frint_pattern><mode>2"
4004   [(set (match_operand:GPF 0 "register_operand" "=w")
4005         (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
4006          FRINT))]
4007   "TARGET_FLOAT"
4008   "frint<frint_suffix>\\t%<s>0, %<s>1"
4009   [(set_attr "type" "f_rint<s>")]
4012 ;; frcvt floating-point round to integer and convert standard patterns.
4013 ;; Expands to lbtrunc, lceil, lfloor, lround.
4014 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
4015   [(set (match_operand:GPI 0 "register_operand" "=r")
4016         (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
4017                       FCVT)))]
4018   "TARGET_FLOAT"
4019   "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
4020   [(set_attr "type" "f_cvtf2i")]
4023 ;; fma - no throw
4025 (define_insn "fma<mode>4"
4026   [(set (match_operand:GPF 0 "register_operand" "=w")
4027         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
4028                  (match_operand:GPF 2 "register_operand" "w")
4029                  (match_operand:GPF 3 "register_operand" "w")))]
4030   "TARGET_FLOAT"
4031   "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
4032   [(set_attr "type" "fmac<s>")]
4035 (define_insn "fnma<mode>4"
4036   [(set (match_operand:GPF 0 "register_operand" "=w")
4037         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
4038                  (match_operand:GPF 2 "register_operand" "w")
4039                  (match_operand:GPF 3 "register_operand" "w")))]
4040   "TARGET_FLOAT"
4041   "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
4042   [(set_attr "type" "fmac<s>")]
4045 (define_insn "fms<mode>4"
4046   [(set (match_operand:GPF 0 "register_operand" "=w")
4047         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
4048                  (match_operand:GPF 2 "register_operand" "w")
4049                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
4050   "TARGET_FLOAT"
4051   "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
4052   [(set_attr "type" "fmac<s>")]
4055 (define_insn "fnms<mode>4"
4056   [(set (match_operand:GPF 0 "register_operand" "=w")
4057         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
4058                  (match_operand:GPF 2 "register_operand" "w")
4059                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
4060   "TARGET_FLOAT"
4061   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
4062   [(set_attr "type" "fmac<s>")]
4065 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
4066 (define_insn "*fnmadd<mode>4"
4067   [(set (match_operand:GPF 0 "register_operand" "=w")
4068         (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
4069                           (match_operand:GPF 2 "register_operand" "w")
4070                           (match_operand:GPF 3 "register_operand" "w"))))]
4071   "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
4072   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
4073   [(set_attr "type" "fmac<s>")]
4076 ;; -------------------------------------------------------------------
4077 ;; Floating-point conversions
4078 ;; -------------------------------------------------------------------
4080 (define_insn "extendsfdf2"
4081   [(set (match_operand:DF 0 "register_operand" "=w")
4082         (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
4083   "TARGET_FLOAT"
4084   "fcvt\\t%d0, %s1"
4085   [(set_attr "type" "f_cvt")]
4088 (define_insn "truncdfsf2"
4089   [(set (match_operand:SF 0 "register_operand" "=w")
4090         (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
4091   "TARGET_FLOAT"
4092   "fcvt\\t%s0, %d1"
4093   [(set_attr "type" "f_cvt")]
4096 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
4097   [(set (match_operand:GPI 0 "register_operand" "=r")
4098         (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
4099   "TARGET_FLOAT"
4100   "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
4101   [(set_attr "type" "f_cvtf2i")]
4104 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
4105   [(set (match_operand:GPI 0 "register_operand" "=r")
4106         (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
4107   "TARGET_FLOAT"
4108   "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
4109   [(set_attr "type" "f_cvtf2i")]
4112 (define_insn "<optab><fcvt_target><GPF:mode>2"
4113   [(set (match_operand:GPF 0 "register_operand" "=w,w")
4114         (FLOATUORS:GPF (match_operand:<FCVT_TARGET> 1 "register_operand" "w,r")))]
4115   ""
4116   "@
4117    <su_optab>cvtf\t%<GPF:s>0, %<s>1
4118    <su_optab>cvtf\t%<GPF:s>0, %<w1>1"
4119   [(set_attr "simd" "yes,no")
4120    (set_attr "fp" "no,yes")
4121    (set_attr "type" "neon_int_to_fp_<Vetype>,f_cvti2f")]
4124 (define_insn "<optab><fcvt_iesize><GPF:mode>2"
4125   [(set (match_operand:GPF 0 "register_operand" "=w")
4126         (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand" "r")))]
4127   "TARGET_FLOAT"
4128   "<su_optab>cvtf\t%<GPF:s>0, %<w2>1"
4129   [(set_attr "type" "f_cvti2f")]
4132 ;; -------------------------------------------------------------------
4133 ;; Floating-point arithmetic
4134 ;; -------------------------------------------------------------------
4136 (define_insn "add<mode>3"
4137   [(set (match_operand:GPF 0 "register_operand" "=w")
4138         (plus:GPF
4139          (match_operand:GPF 1 "register_operand" "w")
4140          (match_operand:GPF 2 "register_operand" "w")))]
4141   "TARGET_FLOAT"
4142   "fadd\\t%<s>0, %<s>1, %<s>2"
4143   [(set_attr "type" "fadd<s>")]
4146 (define_insn "sub<mode>3"
4147   [(set (match_operand:GPF 0 "register_operand" "=w")
4148         (minus:GPF
4149          (match_operand:GPF 1 "register_operand" "w")
4150          (match_operand:GPF 2 "register_operand" "w")))]
4151   "TARGET_FLOAT"
4152   "fsub\\t%<s>0, %<s>1, %<s>2"
4153   [(set_attr "type" "fadd<s>")]
4156 (define_insn "mul<mode>3"
4157   [(set (match_operand:GPF 0 "register_operand" "=w")
4158         (mult:GPF
4159          (match_operand:GPF 1 "register_operand" "w")
4160          (match_operand:GPF 2 "register_operand" "w")))]
4161   "TARGET_FLOAT"
4162   "fmul\\t%<s>0, %<s>1, %<s>2"
4163   [(set_attr "type" "fmul<s>")]
4166 (define_insn "*fnmul<mode>3"
4167   [(set (match_operand:GPF 0 "register_operand" "=w")
4168         (mult:GPF
4169                  (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
4170                  (match_operand:GPF 2 "register_operand" "w")))]
4171   "TARGET_FLOAT"
4172   "fnmul\\t%<s>0, %<s>1, %<s>2"
4173   [(set_attr "type" "fmul<s>")]
4176 (define_insn "div<mode>3"
4177   [(set (match_operand:GPF 0 "register_operand" "=w")
4178         (div:GPF
4179          (match_operand:GPF 1 "register_operand" "w")
4180          (match_operand:GPF 2 "register_operand" "w")))]
4181   "TARGET_FLOAT"
4182   "fdiv\\t%<s>0, %<s>1, %<s>2"
4183   [(set_attr "type" "fdiv<s>")]
4186 (define_insn "neg<mode>2"
4187   [(set (match_operand:GPF 0 "register_operand" "=w")
4188         (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
4189   "TARGET_FLOAT"
4190   "fneg\\t%<s>0, %<s>1"
4191   [(set_attr "type" "ffarith<s>")]
4194 (define_insn "sqrt<mode>2"
4195   [(set (match_operand:GPF 0 "register_operand" "=w")
4196         (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
4197   "TARGET_FLOAT"
4198   "fsqrt\\t%<s>0, %<s>1"
4199   [(set_attr "type" "fsqrt<s>")]
4202 (define_insn "abs<mode>2"
4203   [(set (match_operand:GPF 0 "register_operand" "=w")
4204         (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
4205   "TARGET_FLOAT"
4206   "fabs\\t%<s>0, %<s>1"
4207   [(set_attr "type" "ffarith<s>")]
4210 ;; Given that smax/smin do not specify the result when either input is NaN,
4211 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
4212 ;; for smin.
4214 (define_insn "smax<mode>3"
4215   [(set (match_operand:GPF 0 "register_operand" "=w")
4216         (smax:GPF (match_operand:GPF 1 "register_operand" "w")
4217                   (match_operand:GPF 2 "register_operand" "w")))]
4218   "TARGET_FLOAT"
4219   "fmaxnm\\t%<s>0, %<s>1, %<s>2"
4220   [(set_attr "type" "f_minmax<s>")]
4223 (define_insn "smin<mode>3"
4224   [(set (match_operand:GPF 0 "register_operand" "=w")
4225         (smin:GPF (match_operand:GPF 1 "register_operand" "w")
4226                   (match_operand:GPF 2 "register_operand" "w")))]
4227   "TARGET_FLOAT"
4228   "fminnm\\t%<s>0, %<s>1, %<s>2"
4229   [(set_attr "type" "f_minmax<s>")]
4232 ;; -------------------------------------------------------------------
4233 ;; Reload support
4234 ;; -------------------------------------------------------------------
4236 (define_expand "aarch64_reload_mov<mode>"
4237   [(set (match_operand:TX 0 "register_operand" "=w")
4238         (match_operand:TX 1 "register_operand" "w"))
4239    (clobber (match_operand:DI 2 "register_operand" "=&r"))
4240   ]
4241   "TARGET_FLOAT"
4242   {
4243     rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
4244     rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
4245     gen_aarch64_movtilow_tilow (op0, op1);
4246     gen_aarch64_movdi_tihigh (operands[2], op1);
4247     gen_aarch64_movtihigh_di (op0, operands[2]);
4248     DONE;
4249   }
4252 ;; The following secondary reload helpers patterns are invoked
4253 ;; after or during reload as we don't want these patterns to start
4254 ;; kicking in during the combiner.
4256 (define_insn "aarch64_movdi_<mode>low"
4257   [(set (match_operand:DI 0 "register_operand" "=r")
4258         (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
4259   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4260   "fmov\\t%x0, %d1"
4261   [(set_attr "type" "f_mrc")
4262    (set_attr "length" "4")
4263   ])
4265 (define_insn "aarch64_movdi_<mode>high"
4266   [(set (match_operand:DI 0 "register_operand" "=r")
4267         (truncate:DI
4268           (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
4269                        (const_int 64))))]
4270   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4271   "fmov\\t%x0, %1.d[1]"
4272   [(set_attr "type" "f_mrc")
4273    (set_attr "length" "4")
4274   ])
4276 (define_insn "aarch64_mov<mode>high_di"
4277   [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
4278                          (const_int 64) (const_int 64))
4279         (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4280   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4281   "fmov\\t%0.d[1], %x1"
4282   [(set_attr "type" "f_mcr")
4283    (set_attr "length" "4")
4284   ])
4286 (define_insn "aarch64_mov<mode>low_di"
4287   [(set (match_operand:TX 0 "register_operand" "=w")
4288         (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4289   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4290   "fmov\\t%d0, %x1"
4291   [(set_attr "type" "f_mcr")
4292    (set_attr "length" "4")
4293   ])
4295 (define_insn "aarch64_movtilow_tilow"
4296   [(set (match_operand:TI 0 "register_operand" "=w")
4297         (zero_extend:TI
4298           (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
4299   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4300   "fmov\\t%d0, %d1"
4301   [(set_attr "type" "fmov")
4302    (set_attr "length" "4")
4303   ])
4305 ;; There is a deliberate reason why the parameters of high and lo_sum's
4306 ;; don't have modes for ADRP and ADD instructions.  This is to allow high
4307 ;; and lo_sum's to be used with the labels defining the jump tables in
4308 ;; rodata section.
4310 (define_expand "add_losym"
4311   [(set (match_operand 0 "register_operand" "=r")
4312         (lo_sum (match_operand 1 "register_operand" "r")
4313                 (match_operand 2 "aarch64_valid_symref" "S")))]
4314   ""
4316   machine_mode mode = GET_MODE (operands[0]);
4318   emit_insn ((mode == DImode
4319               ? gen_add_losym_di
4320               : gen_add_losym_si) (operands[0],
4321                                    operands[1],
4322                                    operands[2]));
4323   DONE;
4326 (define_insn "add_losym_<mode>"
4327   [(set (match_operand:P 0 "register_operand" "=r")
4328         (lo_sum:P (match_operand:P 1 "register_operand" "r")
4329                   (match_operand 2 "aarch64_valid_symref" "S")))]
4330   ""
4331   "add\\t%<w>0, %<w>1, :lo12:%a2"
4332   [(set_attr "type" "alu_imm")]
4335 (define_insn "ldr_got_small_<mode>"
4336   [(set (match_operand:PTR 0 "register_operand" "=r")
4337         (unspec:PTR [(mem:PTR (lo_sum:PTR
4338                               (match_operand:PTR 1 "register_operand" "r")
4339                               (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
4340                     UNSPEC_GOTSMALLPIC))]
4341   ""
4342   "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
4343   [(set_attr "type" "load1")]
4346 (define_insn "ldr_got_small_sidi"
4347   [(set (match_operand:DI 0 "register_operand" "=r")
4348         (zero_extend:DI
4349          (unspec:SI [(mem:SI (lo_sum:DI
4350                              (match_operand:DI 1 "register_operand" "r")
4351                              (match_operand:DI 2 "aarch64_valid_symref" "S")))]
4352                     UNSPEC_GOTSMALLPIC)))]
4353   "TARGET_ILP32"
4354   "ldr\\t%w0, [%1, #:got_lo12:%a2]"
4355   [(set_attr "type" "load1")]
4358 (define_insn "ldr_got_tiny"
4359   [(set (match_operand:DI 0 "register_operand" "=r")
4360         (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
4361                    UNSPEC_GOTTINYPIC))]
4362   ""
4363   "ldr\\t%0, %L1"
4364   [(set_attr "type" "load1")]
4367 (define_insn "aarch64_load_tp_hard"
4368   [(set (match_operand:DI 0 "register_operand" "=r")
4369         (unspec:DI [(const_int 0)] UNSPEC_TLS))]
4370   ""
4371   "mrs\\t%0, tpidr_el0"
4372   [(set_attr "type" "mrs")]
4375 ;; The TLS ABI specifically requires that the compiler does not schedule
4376 ;; instructions in the TLS stubs, in order to enable linker relaxation.
4377 ;; Therefore we treat the stubs as an atomic sequence.
4378 (define_expand "tlsgd_small"
4379  [(parallel [(set (match_operand 0 "register_operand" "")
4380                   (call (mem:DI (match_dup 2)) (const_int 1)))
4381              (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
4382              (clobber (reg:DI LR_REGNUM))])]
4383  ""
4385   operands[2] = aarch64_tls_get_addr ();
4388 (define_insn "*tlsgd_small"
4389   [(set (match_operand 0 "register_operand" "")
4390         (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
4391    (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
4392    (clobber (reg:DI LR_REGNUM))
4393   ]
4394   ""
4395   "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
4396   [(set_attr "type" "call")
4397    (set_attr "length" "16")])
4399 (define_insn "tlsie_small_<mode>"
4400   [(set (match_operand:PTR 0 "register_operand" "=r")
4401         (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
4402                    UNSPEC_GOTSMALLTLS))]
4403   ""
4404   "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
4405   [(set_attr "type" "load1")
4406    (set_attr "length" "8")]
4409 (define_insn "tlsie_small_sidi"
4410   [(set (match_operand:DI 0 "register_operand" "=r")
4411         (zero_extend:DI
4412           (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")]
4413                       UNSPEC_GOTSMALLTLS)))]
4414   ""
4415   "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
4416   [(set_attr "type" "load1")
4417    (set_attr "length" "8")]
4420 (define_expand "tlsle_small"
4421   [(set (match_operand 0 "register_operand" "=r")
4422         (unspec [(match_operand 1 "register_operand" "r")
4423                    (match_operand 2 "aarch64_tls_le_symref" "S")]
4424                    UNSPEC_GOTSMALLTLS))]
4425   ""
4427   machine_mode mode = GET_MODE (operands[0]);
4428   emit_insn ((mode == DImode
4429               ? gen_tlsle_small_di
4430               : gen_tlsle_small_si) (operands[0],
4431                                      operands[1],
4432                                      operands[2]));
4433   DONE;
4436 (define_insn "tlsle_small_<mode>"
4437   [(set (match_operand:P 0 "register_operand" "=r")
4438         (unspec:P [(match_operand:P 1 "register_operand" "r")
4439                    (match_operand 2 "aarch64_tls_le_symref" "S")]
4440                    UNSPEC_GOTSMALLTLS))]
4441   ""
4442   "add\\t%<w>0, %<w>1, #%G2, lsl #12\;add\\t%<w>0, %<w>0, #%L2"
4443   [(set_attr "type" "alu_sreg")
4444    (set_attr "length" "8")]
4447 (define_insn "tlsdesc_small_<mode>"
4448   [(set (reg:PTR R0_REGNUM)
4449         (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
4450                    UNSPEC_TLSDESC))
4451    (clobber (reg:DI LR_REGNUM))
4452    (clobber (reg:CC CC_REGNUM))
4453    (clobber (match_scratch:DI 1 "=r"))]
4454   "TARGET_TLS_DESC"
4455   "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
4456   [(set_attr "type" "call")
4457    (set_attr "length" "16")])
4459 (define_insn "stack_tie"
4460   [(set (mem:BLK (scratch))
4461         (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
4462                      (match_operand:DI 1 "register_operand" "rk")]
4463                     UNSPEC_PRLG_STK))]
4464   ""
4465   ""
4466   [(set_attr "length" "0")]
4469 ;; Named pattern for expanding thread pointer reference.
4470 (define_expand "get_thread_pointerdi"
4471   [(match_operand:DI 0 "register_operand" "=r")]
4472   ""
4474   rtx tmp = aarch64_load_tp (operands[0]);
4475   if (tmp != operands[0])
4476     emit_move_insn (operands[0], tmp);
4477   DONE;
4480 ;; Named patterns for stack smashing protection.
4481 (define_expand "stack_protect_set"
4482   [(match_operand 0 "memory_operand")
4483    (match_operand 1 "memory_operand")]
4484   ""
4486   machine_mode mode = GET_MODE (operands[0]);
4488   emit_insn ((mode == DImode
4489               ? gen_stack_protect_set_di
4490               : gen_stack_protect_set_si) (operands[0], operands[1]));
4491   DONE;
4494 (define_insn "stack_protect_set_<mode>"
4495   [(set (match_operand:PTR 0 "memory_operand" "=m")
4496         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
4497          UNSPEC_SP_SET))
4498    (set (match_scratch:PTR 2 "=&r") (const_int 0))]
4499   ""
4500   "ldr\\t%<w>2, %1\;str\\t%<w>2, %0\;mov\t%<w>2,0"
4501   [(set_attr "length" "12")
4502    (set_attr "type" "multiple")])
4504 (define_expand "stack_protect_test"
4505   [(match_operand 0 "memory_operand")
4506    (match_operand 1 "memory_operand")
4507    (match_operand 2)]
4508   ""
4510   rtx result;
4511   machine_mode mode = GET_MODE (operands[0]);
4513   result = gen_reg_rtx(mode);
4515   emit_insn ((mode == DImode
4516               ? gen_stack_protect_test_di
4517               : gen_stack_protect_test_si) (result,
4518                                             operands[0],
4519                                             operands[1]));
4521   if (mode == DImode)
4522     emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4523                                     result, const0_rtx, operands[2]));
4524   else
4525     emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4526                                     result, const0_rtx, operands[2]));
4527   DONE;
4530 (define_insn "stack_protect_test_<mode>"
4531   [(set (match_operand:PTR 0 "register_operand" "=r")
4532         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
4533                      (match_operand:PTR 2 "memory_operand" "m")]
4534          UNSPEC_SP_TEST))
4535    (clobber (match_scratch:PTR 3 "=&r"))]
4536   ""
4537   "ldr\t%<w>3, %x1\;ldr\t%<w>0, %x2\;eor\t%<w>0, %<w>3, %<w>0"
4538   [(set_attr "length" "12")
4539    (set_attr "type" "multiple")])
4541 ;; Write Floating-point Control Register.
4542 (define_insn "set_fpcr"
4543   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
4544   ""
4545   "msr\\tfpcr, %0"
4546   [(set_attr "type" "mrs")])
4548 ;; Read Floating-point Control Register.
4549 (define_insn "get_fpcr"
4550   [(set (match_operand:SI 0 "register_operand" "=r")
4551         (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
4552   ""
4553   "mrs\\t%0, fpcr"
4554   [(set_attr "type" "mrs")])
4556 ;; Write Floating-point Status Register.
4557 (define_insn "set_fpsr"
4558   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
4559   ""
4560   "msr\\tfpsr, %0"
4561   [(set_attr "type" "mrs")])
4563 ;; Read Floating-point Status Register.
4564 (define_insn "get_fpsr"
4565   [(set (match_operand:SI 0 "register_operand" "=r")
4566         (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
4567   ""
4568   "mrs\\t%0, fpsr"
4569   [(set_attr "type" "mrs")])
4572 ;; Define the subtract-one-and-jump insns so loop.c
4573 ;; knows what to generate.
4574 (define_expand "doloop_end"
4575   [(use (match_operand 0 "" ""))      ; loop pseudo
4576    (use (match_operand 1 "" ""))]     ; label
4577   "optimize > 0 && flag_modulo_sched"
4579   rtx s0;
4580   rtx bcomp;
4581   rtx loc_ref;
4582   rtx cc_reg;
4583   rtx insn;
4584   rtx cmp;
4586   /* Currently SMS relies on the do-loop pattern to recognize loops
4587      where (1) the control part consists of all insns defining and/or
4588      using a certain 'count' register and (2) the loop count can be
4589      adjusted by modifying this register prior to the loop.
4590      ??? The possible introduction of a new block to initialize the
4591      new IV can potentially affect branch optimizations.  */
4593   if (GET_MODE (operands[0]) != DImode)
4594     FAIL;
4596   s0 = operands [0];
4597   insn = emit_insn (gen_adddi3_compare0 (s0, s0, GEN_INT (-1)));
4599   cmp = XVECEXP (PATTERN (insn), 0, 0);
4600   cc_reg = SET_DEST (cmp);
4601   bcomp = gen_rtx_NE (VOIDmode, cc_reg, const0_rtx);
4602   loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
4603   emit_jump_insn (gen_rtx_SET (pc_rtx,
4604                                gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
4605                                                      loc_ref, pc_rtx)));
4606   DONE;
4609 ;; AdvSIMD Stuff
4610 (include "aarch64-simd.md")
4612 ;; Atomic Operations
4613 (include "atomics.md")
4615 ;; ldp/stp peephole patterns
4616 (include "aarch64-ldpstp.md")