[AArch64] Properly handle mvn-register and add EON+shift pattern and cost appropriately
[official-gcc.git] / gcc / config / aarch64 / aarch64.md
blob194bfd3d2bdd4bda69402d28a8af4b641b4fa9f2
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       rtx subtarget = ((optimize && can_create_pseudo_p ())
1418                        ? gen_reg_rtx (<MODE>mode) : operands[0]);
1419       HOST_WIDE_INT imm = INTVAL (operands[2]);
1421       if (imm < 0)
1422         imm = -(-imm & ~0xfff);
1423       else
1424         imm &= ~0xfff;
1426       emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1427       operands[1] = subtarget;
1428       operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1429     }
1430   "
1433 (define_insn "*addsi3_aarch64"
1434   [(set
1435     (match_operand:SI 0 "register_operand" "=rk,rk,w,rk")
1436     (plus:SI
1437      (match_operand:SI 1 "register_operand" "%rk,rk,w,rk")
1438      (match_operand:SI 2 "aarch64_plus_operand" "I,r,w,J")))]
1439   ""
1440   "@
1441   add\\t%w0, %w1, %2
1442   add\\t%w0, %w1, %w2
1443   add\\t%0.2s, %1.2s, %2.2s
1444   sub\\t%w0, %w1, #%n2"
1445   [(set_attr "type" "alu_imm,alu_sreg,neon_add,alu_imm")
1446    (set_attr "simd" "*,*,yes,*")]
1449 ;; zero_extend version of above
1450 (define_insn "*addsi3_aarch64_uxtw"
1451   [(set
1452     (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1453     (zero_extend:DI
1454      (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1455               (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1456   ""
1457   "@
1458   add\\t%w0, %w1, %2
1459   add\\t%w0, %w1, %w2
1460   sub\\t%w0, %w1, #%n2"
1461   [(set_attr "type" "alu_imm,alu_sreg,alu_imm")]
1464 (define_insn "*adddi3_aarch64"
1465   [(set
1466     (match_operand:DI 0 "register_operand" "=rk,rk,rk,w")
1467     (plus:DI
1468      (match_operand:DI 1 "register_operand" "%rk,rk,rk,w")
1469      (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,w")))]
1470   ""
1471   "@
1472   add\\t%x0, %x1, %2
1473   add\\t%x0, %x1, %x2
1474   sub\\t%x0, %x1, #%n2
1475   add\\t%d0, %d1, %d2"
1476   [(set_attr "type" "alu_imm,alu_sreg,alu_imm,neon_add")
1477    (set_attr "simd" "*,*,*,yes")]
1480 (define_expand "addti3"
1481   [(set (match_operand:TI 0 "register_operand" "")
1482         (plus:TI (match_operand:TI 1 "register_operand" "")
1483                  (match_operand:TI 2 "register_operand" "")))]
1484   ""
1486   rtx low = gen_reg_rtx (DImode);
1487   emit_insn (gen_adddi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1488                                   gen_lowpart (DImode, operands[2])));
1490   rtx high = gen_reg_rtx (DImode);
1491   emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]),
1492                                  gen_highpart (DImode, operands[2])));
1494   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1495   emit_move_insn (gen_highpart (DImode, operands[0]), high);
1496   DONE;
1499 (define_insn "add<mode>3_compare0"
1500   [(set (reg:CC_NZ CC_REGNUM)
1501         (compare:CC_NZ
1502          (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1503                    (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1504          (const_int 0)))
1505    (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1506         (plus:GPI (match_dup 1) (match_dup 2)))]
1507   ""
1508   "@
1509   adds\\t%<w>0, %<w>1, %<w>2
1510   adds\\t%<w>0, %<w>1, %<w>2
1511   subs\\t%<w>0, %<w>1, #%n2"
1512   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1515 ;; zero_extend version of above
1516 (define_insn "*addsi3_compare0_uxtw"
1517   [(set (reg:CC_NZ CC_REGNUM)
1518         (compare:CC_NZ
1519          (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1520                   (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1521          (const_int 0)))
1522    (set (match_operand:DI 0 "register_operand" "=r,r,r")
1523         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1524   ""
1525   "@
1526   adds\\t%w0, %w1, %w2
1527   adds\\t%w0, %w1, %w2
1528   subs\\t%w0, %w1, #%n2"
1529   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1532 (define_insn "*adds_mul_imm_<mode>"
1533   [(set (reg:CC_NZ CC_REGNUM)
1534         (compare:CC_NZ
1535          (plus:GPI (mult:GPI
1536                     (match_operand:GPI 1 "register_operand" "r")
1537                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1538                    (match_operand:GPI 3 "register_operand" "r"))
1539          (const_int 0)))
1540    (set (match_operand:GPI 0 "register_operand" "=r")
1541         (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1542                   (match_dup 3)))]
1543   ""
1544   "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1545   [(set_attr "type" "alus_shift_imm")]
1548 (define_insn "*subs_mul_imm_<mode>"
1549   [(set (reg:CC_NZ CC_REGNUM)
1550         (compare:CC_NZ
1551          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1552                     (mult:GPI
1553                      (match_operand:GPI 2 "register_operand" "r")
1554                      (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1555          (const_int 0)))
1556    (set (match_operand:GPI 0 "register_operand" "=r")
1557         (minus:GPI (match_dup 1)
1558                    (mult:GPI (match_dup 2) (match_dup 3))))]
1559   ""
1560   "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1561   [(set_attr "type" "alus_shift_imm")]
1564 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1565   [(set (reg:CC_NZ CC_REGNUM)
1566         (compare:CC_NZ
1567          (plus:GPI
1568           (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1569           (match_operand:GPI 2 "register_operand" "r"))
1570         (const_int 0)))
1571    (set (match_operand:GPI 0 "register_operand" "=r")
1572         (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1573   ""
1574   "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1575   [(set_attr "type" "alus_ext")]
1578 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1579   [(set (reg:CC_NZ CC_REGNUM)
1580         (compare:CC_NZ
1581          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1582                     (ANY_EXTEND:GPI
1583                      (match_operand:ALLX 2 "register_operand" "r")))
1584         (const_int 0)))
1585    (set (match_operand:GPI 0 "register_operand" "=r")
1586         (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1587   ""
1588   "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1589   [(set_attr "type" "alus_ext")]
1592 (define_insn "*adds_<optab><mode>_multp2"
1593   [(set (reg:CC_NZ CC_REGNUM)
1594         (compare:CC_NZ
1595          (plus:GPI (ANY_EXTRACT:GPI
1596                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1597                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1598                     (match_operand 3 "const_int_operand" "n")
1599                     (const_int 0))
1600                    (match_operand:GPI 4 "register_operand" "r"))
1601         (const_int 0)))
1602    (set (match_operand:GPI 0 "register_operand" "=r")
1603         (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1604                                    (match_dup 3)
1605                                    (const_int 0))
1606                   (match_dup 4)))]
1607   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1608   "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1609   [(set_attr "type" "alus_ext")]
1612 (define_insn "*subs_<optab><mode>_multp2"
1613   [(set (reg:CC_NZ CC_REGNUM)
1614         (compare:CC_NZ
1615          (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1616                     (ANY_EXTRACT:GPI
1617                      (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1618                                (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1619                      (match_operand 3 "const_int_operand" "n")
1620                      (const_int 0)))
1621         (const_int 0)))
1622    (set (match_operand:GPI 0 "register_operand" "=r")
1623         (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1624                                   (mult:GPI (match_dup 1) (match_dup 2))
1625                                   (match_dup 3)
1626                                   (const_int 0))))]
1627   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1628   "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1629   [(set_attr "type" "alus_ext")]
1632 (define_insn "*add<mode>3nr_compare0"
1633   [(set (reg:CC_NZ CC_REGNUM)
1634         (compare:CC_NZ
1635          (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1636                    (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1637          (const_int 0)))]
1638   ""
1639   "@
1640   cmn\\t%<w>0, %<w>1
1641   cmn\\t%<w>0, %<w>1
1642   cmp\\t%<w>0, #%n1"
1643   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1646 (define_insn "*compare_neg<mode>"
1647   [(set (reg:CC_Z CC_REGNUM)
1648         (compare:CC_Z
1649          (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1650          (match_operand:GPI 1 "register_operand" "r")))]
1651   ""
1652   "cmn\\t%<w>1, %<w>0"
1653   [(set_attr "type" "alus_sreg")]
1656 (define_insn "*add_<shift>_<mode>"
1657   [(set (match_operand:GPI 0 "register_operand" "=r")
1658         (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1659                               (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1660                   (match_operand:GPI 3 "register_operand" "r")))]
1661   ""
1662   "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1663   [(set_attr "type" "alu_shift_imm")]
1666 ;; zero_extend version of above
1667 (define_insn "*add_<shift>_si_uxtw"
1668   [(set (match_operand:DI 0 "register_operand" "=r")
1669         (zero_extend:DI
1670          (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1671                              (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1672                   (match_operand:SI 3 "register_operand" "r"))))]
1673   ""
1674   "add\\t%w0, %w3, %w1, <shift> %2"
1675   [(set_attr "type" "alu_shift_imm")]
1678 (define_insn "*add_mul_imm_<mode>"
1679   [(set (match_operand:GPI 0 "register_operand" "=r")
1680         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1681                             (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1682                   (match_operand:GPI 3 "register_operand" "r")))]
1683   ""
1684   "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1685   [(set_attr "type" "alu_shift_imm")]
1688 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1689   [(set (match_operand:GPI 0 "register_operand" "=rk")
1690         (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1691                   (match_operand:GPI 2 "register_operand" "r")))]
1692   ""
1693   "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1694   [(set_attr "type" "alu_ext")]
1697 ;; zero_extend version of above
1698 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1699   [(set (match_operand:DI 0 "register_operand" "=rk")
1700         (zero_extend:DI
1701          (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1702                   (match_operand:GPI 2 "register_operand" "r"))))]
1703   ""
1704   "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1705   [(set_attr "type" "alu_ext")]
1708 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1709   [(set (match_operand:GPI 0 "register_operand" "=rk")
1710         (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1711                                (match_operand:ALLX 1 "register_operand" "r"))
1712                               (match_operand 2 "aarch64_imm3" "Ui3"))
1713                   (match_operand:GPI 3 "register_operand" "r")))]
1714   ""
1715   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1716   [(set_attr "type" "alu_ext")]
1719 ;; zero_extend version of above
1720 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1721   [(set (match_operand:DI 0 "register_operand" "=rk")
1722         (zero_extend:DI
1723          (plus:SI (ashift:SI (ANY_EXTEND:SI
1724                               (match_operand:SHORT 1 "register_operand" "r"))
1725                              (match_operand 2 "aarch64_imm3" "Ui3"))
1726                   (match_operand:SI 3 "register_operand" "r"))))]
1727   ""
1728   "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1729   [(set_attr "type" "alu_ext")]
1732 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1733   [(set (match_operand:GPI 0 "register_operand" "=rk")
1734         (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1735                              (match_operand:ALLX 1 "register_operand" "r"))
1736                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1737                   (match_operand:GPI 3 "register_operand" "r")))]
1738   ""
1739   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1740   [(set_attr "type" "alu_ext")]
1743 ;; zero_extend version of above
1744 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1745   [(set (match_operand:DI 0 "register_operand" "=rk")
1746         (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1747                              (match_operand:SHORT 1 "register_operand" "r"))
1748                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1749                   (match_operand:SI 3 "register_operand" "r"))))]
1750   ""
1751   "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1752   [(set_attr "type" "alu_ext")]
1755 (define_insn "*add_<optab><mode>_multp2"
1756   [(set (match_operand:GPI 0 "register_operand" "=rk")
1757         (plus:GPI (ANY_EXTRACT:GPI
1758                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1759                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1760                    (match_operand 3 "const_int_operand" "n")
1761                    (const_int 0))
1762                   (match_operand:GPI 4 "register_operand" "r")))]
1763   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1764   "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1765   [(set_attr "type" "alu_ext")]
1768 ;; zero_extend version of above
1769 (define_insn "*add_<optab>si_multp2_uxtw"
1770   [(set (match_operand:DI 0 "register_operand" "=rk")
1771         (zero_extend:DI
1772          (plus:SI (ANY_EXTRACT:SI
1773                    (mult:SI (match_operand:SI 1 "register_operand" "r")
1774                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1775                    (match_operand 3 "const_int_operand" "n")
1776                    (const_int 0))
1777                   (match_operand:SI 4 "register_operand" "r"))))]
1778   "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1779   "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1780   [(set_attr "type" "alu_ext")]
1783 (define_insn "add<mode>3_carryin"
1784   [(set
1785     (match_operand:GPI 0 "register_operand" "=r")
1786     (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1787               (plus:GPI
1788                 (match_operand:GPI 1 "register_operand" "r")
1789                 (match_operand:GPI 2 "register_operand" "r"))))]
1790    ""
1791    "adc\\t%<w>0, %<w>1, %<w>2"
1792   [(set_attr "type" "adc_reg")]
1795 ;; zero_extend version of above
1796 (define_insn "*addsi3_carryin_uxtw"
1797   [(set
1798     (match_operand:DI 0 "register_operand" "=r")
1799     (zero_extend:DI
1800      (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1801               (plus:SI
1802                (match_operand:SI 1 "register_operand" "r")
1803                (match_operand:SI 2 "register_operand" "r")))))]
1804    ""
1805    "adc\\t%w0, %w1, %w2"
1806   [(set_attr "type" "adc_reg")]
1809 (define_insn "*add<mode>3_carryin_alt1"
1810   [(set
1811     (match_operand:GPI 0 "register_operand" "=r")
1812     (plus:GPI (plus:GPI
1813                 (match_operand:GPI 1 "register_operand" "r")
1814                 (match_operand:GPI 2 "register_operand" "r"))
1815               (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1816    ""
1817    "adc\\t%<w>0, %<w>1, %<w>2"
1818   [(set_attr "type" "adc_reg")]
1821 ;; zero_extend version of above
1822 (define_insn "*addsi3_carryin_alt1_uxtw"
1823   [(set
1824     (match_operand:DI 0 "register_operand" "=r")
1825     (zero_extend:DI
1826      (plus:SI (plus:SI
1827                (match_operand:SI 1 "register_operand" "r")
1828                (match_operand:SI 2 "register_operand" "r"))
1829               (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1830    ""
1831    "adc\\t%w0, %w1, %w2"
1832   [(set_attr "type" "adc_reg")]
1835 (define_insn "*add<mode>3_carryin_alt2"
1836   [(set
1837     (match_operand:GPI 0 "register_operand" "=r")
1838     (plus:GPI (plus:GPI
1839                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1840                 (match_operand:GPI 1 "register_operand" "r"))
1841               (match_operand:GPI 2 "register_operand" "r")))]
1842    ""
1843    "adc\\t%<w>0, %<w>1, %<w>2"
1844   [(set_attr "type" "adc_reg")]
1847 ;; zero_extend version of above
1848 (define_insn "*addsi3_carryin_alt2_uxtw"
1849   [(set
1850     (match_operand:DI 0 "register_operand" "=r")
1851     (zero_extend:DI
1852      (plus:SI (plus:SI
1853                (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1854                (match_operand:SI 1 "register_operand" "r"))
1855               (match_operand:SI 2 "register_operand" "r"))))]
1856    ""
1857    "adc\\t%w0, %w1, %w2"
1858   [(set_attr "type" "adc_reg")]
1861 (define_insn "*add<mode>3_carryin_alt3"
1862   [(set
1863     (match_operand:GPI 0 "register_operand" "=r")
1864     (plus:GPI (plus:GPI
1865                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1866                 (match_operand:GPI 2 "register_operand" "r"))
1867               (match_operand:GPI 1 "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_alt3_uxtw"
1875   [(set
1876     (match_operand:DI 0 "register_operand" "=r")
1877     (zero_extend:DI
1878      (plus:SI (plus:SI
1879                (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1880                (match_operand:SI 2 "register_operand" "r"))
1881               (match_operand:SI 1 "register_operand" "r"))))]
1882    ""
1883    "adc\\t%w0, %w1, %w2"
1884   [(set_attr "type" "adc_reg")]
1887 (define_insn "*add_uxt<mode>_multp2"
1888   [(set (match_operand:GPI 0 "register_operand" "=rk")
1889         (plus:GPI (and:GPI
1890                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1891                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1892                    (match_operand 3 "const_int_operand" "n"))
1893                   (match_operand:GPI 4 "register_operand" "r")))]
1894   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1895   "*
1896   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1897                                            INTVAL (operands[3])));
1898   return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1899   [(set_attr "type" "alu_ext")]
1902 ;; zero_extend version of above
1903 (define_insn "*add_uxtsi_multp2_uxtw"
1904   [(set (match_operand:DI 0 "register_operand" "=rk")
1905         (zero_extend:DI
1906          (plus:SI (and:SI
1907                    (mult:SI (match_operand:SI 1 "register_operand" "r")
1908                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1909                    (match_operand 3 "const_int_operand" "n"))
1910                   (match_operand:SI 4 "register_operand" "r"))))]
1911   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1912   "*
1913   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1914                                            INTVAL (operands[3])));
1915   return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1916   [(set_attr "type" "alu_ext")]
1919 (define_insn "subsi3"
1920   [(set (match_operand:SI 0 "register_operand" "=rk")
1921         (minus:SI (match_operand:SI 1 "register_operand" "rk")
1922                   (match_operand:SI 2 "register_operand" "r")))]
1923   ""
1924   "sub\\t%w0, %w1, %w2"
1925   [(set_attr "type" "alu_sreg")]
1928 ;; zero_extend version of above
1929 (define_insn "*subsi3_uxtw"
1930   [(set (match_operand:DI 0 "register_operand" "=rk")
1931         (zero_extend:DI
1932          (minus:SI (match_operand:SI 1 "register_operand" "rk")
1933                    (match_operand:SI 2 "register_operand" "r"))))]
1934   ""
1935   "sub\\t%w0, %w1, %w2"
1936   [(set_attr "type" "alu_sreg")]
1939 (define_insn "subdi3"
1940   [(set (match_operand:DI 0 "register_operand" "=rk,w")
1941         (minus:DI (match_operand:DI 1 "register_operand" "rk,w")
1942                   (match_operand:DI 2 "register_operand" "r,w")))]
1943   ""
1944   "@
1945    sub\\t%x0, %x1, %x2
1946    sub\\t%d0, %d1, %d2"
1947   [(set_attr "type" "alu_sreg, neon_sub")
1948    (set_attr "simd" "*,yes")]
1951 (define_expand "subti3"
1952   [(set (match_operand:TI 0 "register_operand" "")
1953         (minus:TI (match_operand:TI 1 "register_operand" "")
1954                   (match_operand:TI 2 "register_operand" "")))]
1955   ""
1957   rtx low = gen_reg_rtx (DImode);
1958   emit_insn (gen_subdi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1959                                   gen_lowpart (DImode, operands[2])));
1961   rtx high = gen_reg_rtx (DImode);
1962   emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]),
1963                                  gen_highpart (DImode, operands[2])));
1965   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1966   emit_move_insn (gen_highpart (DImode, operands[0]), high);
1967   DONE;
1970 (define_insn "sub<mode>3_compare0"
1971   [(set (reg:CC_NZ CC_REGNUM)
1972         (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1973                                   (match_operand:GPI 2 "register_operand" "r"))
1974                        (const_int 0)))
1975    (set (match_operand:GPI 0 "register_operand" "=r")
1976         (minus:GPI (match_dup 1) (match_dup 2)))]
1977   ""
1978   "subs\\t%<w>0, %<w>1, %<w>2"
1979   [(set_attr "type" "alus_sreg")]
1982 ;; zero_extend version of above
1983 (define_insn "*subsi3_compare0_uxtw"
1984   [(set (reg:CC_NZ CC_REGNUM)
1985         (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1986                                  (match_operand:SI 2 "register_operand" "r"))
1987                        (const_int 0)))
1988    (set (match_operand:DI 0 "register_operand" "=r")
1989         (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1990   ""
1991   "subs\\t%w0, %w1, %w2"
1992   [(set_attr "type" "alus_sreg")]
1995 (define_insn "*sub_<shift>_<mode>"
1996   [(set (match_operand:GPI 0 "register_operand" "=r")
1997         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1998                    (ASHIFT:GPI
1999                     (match_operand:GPI 1 "register_operand" "r")
2000                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2001   ""
2002   "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
2003   [(set_attr "type" "alu_shift_imm")]
2006 ;; zero_extend version of above
2007 (define_insn "*sub_<shift>_si_uxtw"
2008   [(set (match_operand:DI 0 "register_operand" "=r")
2009         (zero_extend:DI
2010          (minus:SI (match_operand:SI 3 "register_operand" "r")
2011                    (ASHIFT:SI
2012                     (match_operand:SI 1 "register_operand" "r")
2013                     (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2014   ""
2015   "sub\\t%w0, %w3, %w1, <shift> %2"
2016   [(set_attr "type" "alu_shift_imm")]
2019 (define_insn "*sub_mul_imm_<mode>"
2020   [(set (match_operand:GPI 0 "register_operand" "=r")
2021         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2022                    (mult:GPI
2023                     (match_operand:GPI 1 "register_operand" "r")
2024                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2025   ""
2026   "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
2027   [(set_attr "type" "alu_shift_imm")]
2030 ;; zero_extend version of above
2031 (define_insn "*sub_mul_imm_si_uxtw"
2032   [(set (match_operand:DI 0 "register_operand" "=r")
2033         (zero_extend:DI
2034          (minus:SI (match_operand:SI 3 "register_operand" "r")
2035                    (mult:SI
2036                     (match_operand:SI 1 "register_operand" "r")
2037                     (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2038   ""
2039   "sub\\t%w0, %w3, %w1, lsl %p2"
2040   [(set_attr "type" "alu_shift_imm")]
2043 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
2044   [(set (match_operand:GPI 0 "register_operand" "=rk")
2045         (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
2046                    (ANY_EXTEND:GPI
2047                     (match_operand:ALLX 2 "register_operand" "r"))))]
2048   ""
2049   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
2050   [(set_attr "type" "alu_ext")]
2053 ;; zero_extend version of above
2054 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
2055   [(set (match_operand:DI 0 "register_operand" "=rk")
2056         (zero_extend:DI
2057          (minus:SI (match_operand:SI 1 "register_operand" "rk")
2058                    (ANY_EXTEND:SI
2059                     (match_operand:SHORT 2 "register_operand" "r")))))]
2060   ""
2061   "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
2062   [(set_attr "type" "alu_ext")]
2065 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
2066   [(set (match_operand:GPI 0 "register_operand" "=rk")
2067         (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
2068                    (ashift:GPI (ANY_EXTEND:GPI
2069                                 (match_operand:ALLX 2 "register_operand" "r"))
2070                                (match_operand 3 "aarch64_imm3" "Ui3"))))]
2071   ""
2072   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
2073   [(set_attr "type" "alu_ext")]
2076 ;; zero_extend version of above
2077 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
2078   [(set (match_operand:DI 0 "register_operand" "=rk")
2079         (zero_extend:DI
2080          (minus:SI (match_operand:SI 1 "register_operand" "rk")
2081                    (ashift:SI (ANY_EXTEND:SI
2082                                (match_operand:SHORT 2 "register_operand" "r"))
2083                               (match_operand 3 "aarch64_imm3" "Ui3")))))]
2084   ""
2085   "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
2086   [(set_attr "type" "alu_ext")]
2089 (define_insn "*sub_<optab><mode>_multp2"
2090   [(set (match_operand:GPI 0 "register_operand" "=rk")
2091         (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
2092                    (ANY_EXTRACT:GPI
2093                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2094                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2095                     (match_operand 3 "const_int_operand" "n")
2096                     (const_int 0))))]
2097   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
2098   "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
2099   [(set_attr "type" "alu_ext")]
2102 ;; zero_extend version of above
2103 (define_insn "*sub_<optab>si_multp2_uxtw"
2104   [(set (match_operand:DI 0 "register_operand" "=rk")
2105         (zero_extend:DI
2106          (minus:SI (match_operand:SI 4 "register_operand" "rk")
2107                    (ANY_EXTRACT:SI
2108                     (mult:SI (match_operand:SI 1 "register_operand" "r")
2109                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2110                     (match_operand 3 "const_int_operand" "n")
2111                     (const_int 0)))))]
2112   "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
2113   "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
2114   [(set_attr "type" "alu_ext")]
2117 (define_insn "sub<mode>3_carryin"
2118   [(set
2119     (match_operand:GPI 0 "register_operand" "=r")
2120     (minus:GPI (minus:GPI
2121                 (match_operand:GPI 1 "register_operand" "r")
2122                 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2123                (match_operand:GPI 2 "register_operand" "r")))]
2124    ""
2125    "sbc\\t%<w>0, %<w>1, %<w>2"
2126   [(set_attr "type" "adc_reg")]
2129 ;; zero_extend version of the above
2130 (define_insn "*subsi3_carryin_uxtw"
2131   [(set
2132     (match_operand:DI 0 "register_operand" "=r")
2133     (zero_extend:DI
2134      (minus:SI (minus:SI
2135                 (match_operand:SI 1 "register_operand" "r")
2136                 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2137                (match_operand:SI 2 "register_operand" "r"))))]
2138    ""
2139    "sbc\\t%w0, %w1, %w2"
2140   [(set_attr "type" "adc_reg")]
2143 (define_insn "*sub_uxt<mode>_multp2"
2144   [(set (match_operand:GPI 0 "register_operand" "=rk")
2145         (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
2146                    (and:GPI
2147                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2148                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2149                     (match_operand 3 "const_int_operand" "n"))))]
2150   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2151   "*
2152   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2153                                            INTVAL (operands[3])));
2154   return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
2155   [(set_attr "type" "alu_ext")]
2158 ;; zero_extend version of above
2159 (define_insn "*sub_uxtsi_multp2_uxtw"
2160   [(set (match_operand:DI 0 "register_operand" "=rk")
2161         (zero_extend:DI
2162          (minus:SI (match_operand:SI 4 "register_operand" "rk")
2163                    (and:SI
2164                     (mult:SI (match_operand:SI 1 "register_operand" "r")
2165                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2166                     (match_operand 3 "const_int_operand" "n")))))]
2167   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2168   "*
2169   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2170                                            INTVAL (operands[3])));
2171   return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
2172   [(set_attr "type" "alu_ext")]
2175 (define_insn_and_split "absdi2"
2176   [(set (match_operand:DI 0 "register_operand" "=&r,w")
2177         (abs:DI (match_operand:DI 1 "register_operand" "r,w")))]
2178   ""
2179   "@
2180    #
2181    abs\\t%d0, %d1"
2182   "reload_completed
2183    && GP_REGNUM_P (REGNO (operands[0]))
2184    && GP_REGNUM_P (REGNO (operands[1]))"
2185   [(const_int 0)]
2186   {
2187     emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2188                             gen_rtx_XOR (DImode,
2189                                          gen_rtx_ASHIFTRT (DImode,
2190                                                            operands[1],
2191                                                            GEN_INT (63)),
2192                                          operands[1])));
2193     emit_insn (gen_rtx_SET (VOIDmode,
2194                             operands[0],
2195                             gen_rtx_MINUS (DImode,
2196                                            operands[0],
2197                                            gen_rtx_ASHIFTRT (DImode,
2198                                                              operands[1],
2199                                                              GEN_INT (63)))));
2200     DONE;
2201   }
2202   [(set_attr "type" "alu_sreg")
2203    (set_attr "simd" "no,yes")]
2206 (define_insn "neg<mode>2"
2207   [(set (match_operand:GPI 0 "register_operand" "=r,w")
2208         (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
2209   ""
2210   "@
2211    neg\\t%<w>0, %<w>1
2212    neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
2213   [(set_attr "type" "alu_sreg, neon_neg<q>")
2214    (set_attr "simd" "*,yes")]
2217 ;; zero_extend version of above
2218 (define_insn "*negsi2_uxtw"
2219   [(set (match_operand:DI 0 "register_operand" "=r")
2220         (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
2221   ""
2222   "neg\\t%w0, %w1"
2223   [(set_attr "type" "alu_sreg")]
2226 (define_insn "*ngc<mode>"
2227   [(set (match_operand:GPI 0 "register_operand" "=r")
2228         (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2229                    (match_operand:GPI 1 "register_operand" "r")))]
2230   ""
2231   "ngc\\t%<w>0, %<w>1"
2232   [(set_attr "type" "adc_reg")]
2235 (define_insn "*ngcsi_uxtw"
2236   [(set (match_operand:DI 0 "register_operand" "=r")
2237         (zero_extend:DI
2238          (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2239                    (match_operand:SI 1 "register_operand" "r"))))]
2240   ""
2241   "ngc\\t%w0, %w1"
2242   [(set_attr "type" "adc_reg")]
2245 (define_insn "*neg<mode>2_compare0"
2246   [(set (reg:CC_NZ CC_REGNUM)
2247         (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2248                        (const_int 0)))
2249    (set (match_operand:GPI 0 "register_operand" "=r")
2250         (neg:GPI (match_dup 1)))]
2251   ""
2252   "negs\\t%<w>0, %<w>1"
2253   [(set_attr "type" "alus_sreg")]
2256 ;; zero_extend version of above
2257 (define_insn "*negsi2_compare0_uxtw"
2258   [(set (reg:CC_NZ CC_REGNUM)
2259         (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
2260                        (const_int 0)))
2261    (set (match_operand:DI 0 "register_operand" "=r")
2262         (zero_extend:DI (neg:SI (match_dup 1))))]
2263   ""
2264   "negs\\t%w0, %w1"
2265   [(set_attr "type" "alus_sreg")]
2268 (define_insn "*neg_<shift><mode>3_compare0"
2269   [(set (reg:CC_NZ CC_REGNUM)
2270         (compare:CC_NZ
2271          (neg:GPI (ASHIFT:GPI
2272                    (match_operand:GPI 1 "register_operand" "r")
2273                    (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2274          (const_int 0)))
2275    (set (match_operand:GPI 0 "register_operand" "=r")
2276         (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2277   ""
2278   "negs\\t%<w>0, %<w>1, <shift> %2"
2279   [(set_attr "type" "alus_shift_imm")]
2282 (define_insn "*neg_<shift>_<mode>2"
2283   [(set (match_operand:GPI 0 "register_operand" "=r")
2284         (neg:GPI (ASHIFT:GPI
2285                   (match_operand:GPI 1 "register_operand" "r")
2286                   (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2287   ""
2288   "neg\\t%<w>0, %<w>1, <shift> %2"
2289   [(set_attr "type" "alu_shift_imm")]
2292 ;; zero_extend version of above
2293 (define_insn "*neg_<shift>_si2_uxtw"
2294   [(set (match_operand:DI 0 "register_operand" "=r")
2295         (zero_extend:DI
2296          (neg:SI (ASHIFT:SI
2297                   (match_operand:SI 1 "register_operand" "r")
2298                   (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2299   ""
2300   "neg\\t%w0, %w1, <shift> %2"
2301   [(set_attr "type" "alu_shift_imm")]
2304 (define_insn "*neg_mul_imm_<mode>2"
2305   [(set (match_operand:GPI 0 "register_operand" "=r")
2306         (neg:GPI (mult:GPI
2307                   (match_operand:GPI 1 "register_operand" "r")
2308                   (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2309   ""
2310   "neg\\t%<w>0, %<w>1, lsl %p2"
2311   [(set_attr "type" "alu_shift_imm")]
2314 ;; zero_extend version of above
2315 (define_insn "*neg_mul_imm_si2_uxtw"
2316   [(set (match_operand:DI 0 "register_operand" "=r")
2317         (zero_extend:DI
2318          (neg:SI (mult:SI
2319                   (match_operand:SI 1 "register_operand" "r")
2320                   (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2321   ""
2322   "neg\\t%w0, %w1, lsl %p2"
2323   [(set_attr "type" "alu_shift_imm")]
2326 (define_insn "mul<mode>3"
2327   [(set (match_operand:GPI 0 "register_operand" "=r")
2328         (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2329                   (match_operand:GPI 2 "register_operand" "r")))]
2330   ""
2331   "mul\\t%<w>0, %<w>1, %<w>2"
2332   [(set_attr "type" "mul")]
2335 ;; zero_extend version of above
2336 (define_insn "*mulsi3_uxtw"
2337   [(set (match_operand:DI 0 "register_operand" "=r")
2338         (zero_extend:DI
2339          (mult:SI (match_operand:SI 1 "register_operand" "r")
2340                   (match_operand:SI 2 "register_operand" "r"))))]
2341   ""
2342   "mul\\t%w0, %w1, %w2"
2343   [(set_attr "type" "mul")]
2346 (define_insn "madd<mode>"
2347   [(set (match_operand:GPI 0 "register_operand" "=r")
2348         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2349                             (match_operand:GPI 2 "register_operand" "r"))
2350                   (match_operand:GPI 3 "register_operand" "r")))]
2351   ""
2352   "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2353   [(set_attr "type" "mla")]
2356 ;; zero_extend version of above
2357 (define_insn "*maddsi_uxtw"
2358   [(set (match_operand:DI 0 "register_operand" "=r")
2359         (zero_extend:DI
2360          (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2361                            (match_operand:SI 2 "register_operand" "r"))
2362                   (match_operand:SI 3 "register_operand" "r"))))]
2363   ""
2364   "madd\\t%w0, %w1, %w2, %w3"
2365   [(set_attr "type" "mla")]
2368 (define_insn "*msub<mode>"
2369   [(set (match_operand:GPI 0 "register_operand" "=r")
2370         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2371                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2372                              (match_operand:GPI 2 "register_operand" "r"))))]
2374   ""
2375   "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2376   [(set_attr "type" "mla")]
2379 ;; zero_extend version of above
2380 (define_insn "*msubsi_uxtw"
2381   [(set (match_operand:DI 0 "register_operand" "=r")
2382         (zero_extend:DI
2383          (minus:SI (match_operand:SI 3 "register_operand" "r")
2384                    (mult:SI (match_operand:SI 1 "register_operand" "r")
2385                             (match_operand:SI 2 "register_operand" "r")))))]
2387   ""
2388   "msub\\t%w0, %w1, %w2, %w3"
2389   [(set_attr "type" "mla")]
2392 (define_insn "*mul<mode>_neg"
2393   [(set (match_operand:GPI 0 "register_operand" "=r")
2394         (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2395                   (match_operand:GPI 2 "register_operand" "r")))]
2397   ""
2398   "mneg\\t%<w>0, %<w>1, %<w>2"
2399   [(set_attr "type" "mul")]
2402 ;; zero_extend version of above
2403 (define_insn "*mulsi_neg_uxtw"
2404   [(set (match_operand:DI 0 "register_operand" "=r")
2405         (zero_extend:DI
2406          (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2407                   (match_operand:SI 2 "register_operand" "r"))))]
2409   ""
2410   "mneg\\t%w0, %w1, %w2"
2411   [(set_attr "type" "mul")]
2414 (define_insn "<su_optab>mulsidi3"
2415   [(set (match_operand:DI 0 "register_operand" "=r")
2416         (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2417                  (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2418   ""
2419   "<su>mull\\t%0, %w1, %w2"
2420   [(set_attr "type" "<su>mull")]
2423 (define_insn "<su_optab>maddsidi4"
2424   [(set (match_operand:DI 0 "register_operand" "=r")
2425         (plus:DI (mult:DI
2426                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2427                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2428                  (match_operand:DI 3 "register_operand" "r")))]
2429   ""
2430   "<su>maddl\\t%0, %w1, %w2, %3"
2431   [(set_attr "type" "<su>mlal")]
2434 (define_insn "<su_optab>msubsidi4"
2435   [(set (match_operand:DI 0 "register_operand" "=r")
2436         (minus:DI
2437          (match_operand:DI 3 "register_operand" "r")
2438          (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2439                   (ANY_EXTEND:DI
2440                    (match_operand:SI 2 "register_operand" "r")))))]
2441   ""
2442   "<su>msubl\\t%0, %w1, %w2, %3"
2443   [(set_attr "type" "<su>mlal")]
2446 (define_insn "*<su_optab>mulsidi_neg"
2447   [(set (match_operand:DI 0 "register_operand" "=r")
2448         (mult:DI (neg:DI
2449                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2450                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2451   ""
2452   "<su>mnegl\\t%0, %w1, %w2"
2453   [(set_attr "type" "<su>mull")]
2456 (define_expand "<su_optab>mulditi3"
2457   [(set (match_operand:TI 0 "register_operand")
2458         (mult:TI (ANY_EXTEND:TI (match_operand:DI 1 "register_operand"))
2459                  (ANY_EXTEND:TI (match_operand:DI 2 "register_operand"))))]
2460   ""
2462   rtx low = gen_reg_rtx (DImode);
2463   emit_insn (gen_muldi3 (low, operands[1], operands[2]));
2465   rtx high = gen_reg_rtx (DImode);
2466   emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2]));
2468   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2469   emit_move_insn (gen_highpart (DImode, operands[0]), high);
2470   DONE;
2473 ;; The default expansion of multi3 using umuldi3_highpart will perform
2474 ;; the additions in an order that fails to combine into two madd insns.
2475 (define_expand "multi3"
2476   [(set (match_operand:TI 0 "register_operand")
2477         (mult:TI (match_operand:TI 1 "register_operand")
2478                  (match_operand:TI 2 "register_operand")))]
2479   ""
2481   rtx l0 = gen_reg_rtx (DImode);
2482   rtx l1 = gen_lowpart (DImode, operands[1]);
2483   rtx l2 = gen_lowpart (DImode, operands[2]);
2484   rtx h0 = gen_reg_rtx (DImode);
2485   rtx h1 = gen_highpart (DImode, operands[1]);
2486   rtx h2 = gen_highpart (DImode, operands[2]);
2488   emit_insn (gen_muldi3 (l0, l1, l2));
2489   emit_insn (gen_umuldi3_highpart (h0, l1, l2));
2490   emit_insn (gen_madddi (h0, h1, l2, h0));
2491   emit_insn (gen_madddi (h0, l1, h2, h0));
2493   emit_move_insn (gen_lowpart (DImode, operands[0]), l0);
2494   emit_move_insn (gen_highpart (DImode, operands[0]), h0);
2495   DONE;
2498 (define_insn "<su>muldi3_highpart"
2499   [(set (match_operand:DI 0 "register_operand" "=r")
2500         (truncate:DI
2501          (lshiftrt:TI
2502           (mult:TI
2503            (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2504            (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2505           (const_int 64))))]
2506   ""
2507   "<su>mulh\\t%0, %1, %2"
2508   [(set_attr "type" "<su>mull")]
2511 (define_insn "<su_optab>div<mode>3"
2512   [(set (match_operand:GPI 0 "register_operand" "=r")
2513         (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2514                      (match_operand:GPI 2 "register_operand" "r")))]
2515   ""
2516   "<su>div\\t%<w>0, %<w>1, %<w>2"
2517   [(set_attr "type" "<su>div")]
2520 ;; zero_extend version of above
2521 (define_insn "*<su_optab>divsi3_uxtw"
2522   [(set (match_operand:DI 0 "register_operand" "=r")
2523         (zero_extend:DI
2524          (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2525                      (match_operand:SI 2 "register_operand" "r"))))]
2526   ""
2527   "<su>div\\t%w0, %w1, %w2"
2528   [(set_attr "type" "<su>div")]
2531 ;; -------------------------------------------------------------------
2532 ;; Comparison insns
2533 ;; -------------------------------------------------------------------
2535 (define_insn "*cmp<mode>"
2536   [(set (reg:CC CC_REGNUM)
2537         (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2538                     (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2539   ""
2540   "@
2541    cmp\\t%<w>0, %<w>1
2542    cmp\\t%<w>0, %<w>1
2543    cmn\\t%<w>0, #%n1"
2544   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
2547 (define_insn "*cmp<mode>"
2548   [(set (reg:CCFP CC_REGNUM)
2549         (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2550                       (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2551    "TARGET_FLOAT"
2552    "@
2553     fcmp\\t%<s>0, #0.0
2554     fcmp\\t%<s>0, %<s>1"
2555   [(set_attr "type" "fcmp<s>")]
2558 (define_insn "*cmpe<mode>"
2559   [(set (reg:CCFPE CC_REGNUM)
2560         (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2561                        (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2562    "TARGET_FLOAT"
2563    "@
2564     fcmpe\\t%<s>0, #0.0
2565     fcmpe\\t%<s>0, %<s>1"
2566   [(set_attr "type" "fcmp<s>")]
2569 (define_insn "*cmp_swp_<shift>_reg<mode>"
2570   [(set (reg:CC_SWP CC_REGNUM)
2571         (compare:CC_SWP (ASHIFT:GPI
2572                          (match_operand:GPI 0 "register_operand" "r")
2573                          (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2574                         (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2575   ""
2576   "cmp\\t%<w>2, %<w>0, <shift> %1"
2577   [(set_attr "type" "alus_shift_imm")]
2580 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2581   [(set (reg:CC_SWP CC_REGNUM)
2582         (compare:CC_SWP (ANY_EXTEND:GPI
2583                          (match_operand:ALLX 0 "register_operand" "r"))
2584                         (match_operand:GPI 1 "register_operand" "r")))]
2585   ""
2586   "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2587   [(set_attr "type" "alus_ext")]
2590 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2591   [(set (reg:CC_SWP CC_REGNUM)
2592         (compare:CC_SWP (ashift:GPI
2593                          (ANY_EXTEND:GPI
2594                           (match_operand:ALLX 0 "register_operand" "r"))
2595                          (match_operand 1 "aarch64_imm3" "Ui3"))
2596         (match_operand:GPI 2 "register_operand" "r")))]
2597   ""
2598   "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2599   [(set_attr "type" "alus_ext")]
2602 ;; -------------------------------------------------------------------
2603 ;; Store-flag and conditional select insns
2604 ;; -------------------------------------------------------------------
2606 (define_expand "cstore<mode>4"
2607   [(set (match_operand:SI 0 "register_operand" "")
2608         (match_operator:SI 1 "aarch64_comparison_operator"
2609          [(match_operand:GPI 2 "register_operand" "")
2610           (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2611   ""
2612   "
2613   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2614                                       operands[3]);
2615   operands[3] = const0_rtx;
2616   "
2619 (define_expand "cstorecc4"
2620   [(set (match_operand:SI 0 "register_operand")
2621        (match_operator 1 "aarch64_comparison_operator"
2622         [(match_operand 2 "ccmp_cc_register")
2623          (match_operand 3 "const0_operand")]))]
2624   ""
2626   emit_insn (gen_rtx_SET (SImode, operands[0], operands[1]));
2627   DONE;
2631 (define_expand "cstore<mode>4"
2632   [(set (match_operand:SI 0 "register_operand" "")
2633         (match_operator:SI 1 "aarch64_comparison_operator"
2634          [(match_operand:GPF 2 "register_operand" "")
2635           (match_operand:GPF 3 "register_operand" "")]))]
2636   ""
2637   "
2638   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2639                                       operands[3]);
2640   operands[3] = const0_rtx;
2641   "
2644 (define_insn "*cstore<mode>_insn"
2645   [(set (match_operand:ALLI 0 "register_operand" "=r")
2646         (match_operator:ALLI 1 "aarch64_comparison_operator"
2647          [(match_operand 2 "cc_register" "") (const_int 0)]))]
2648   ""
2649   "cset\\t%<w>0, %m1"
2650   [(set_attr "type" "csel")]
2653 ;; zero_extend version of the above
2654 (define_insn "*cstoresi_insn_uxtw"
2655   [(set (match_operand:DI 0 "register_operand" "=r")
2656         (zero_extend:DI
2657          (match_operator:SI 1 "aarch64_comparison_operator"
2658           [(match_operand 2 "cc_register" "") (const_int 0)])))]
2659   ""
2660   "cset\\t%w0, %m1"
2661   [(set_attr "type" "csel")]
2664 (define_insn "cstore<mode>_neg"
2665   [(set (match_operand:ALLI 0 "register_operand" "=r")
2666         (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2667                   [(match_operand 2 "cc_register" "") (const_int 0)])))]
2668   ""
2669   "csetm\\t%<w>0, %m1"
2670   [(set_attr "type" "csel")]
2673 ;; zero_extend version of the above
2674 (define_insn "*cstoresi_neg_uxtw"
2675   [(set (match_operand:DI 0 "register_operand" "=r")
2676         (zero_extend:DI
2677          (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2678                   [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2679   ""
2680   "csetm\\t%w0, %m1"
2681   [(set_attr "type" "csel")]
2684 (define_expand "cmov<mode>6"
2685   [(set (match_operand:GPI 0 "register_operand" "")
2686         (if_then_else:GPI
2687          (match_operator 1 "aarch64_comparison_operator"
2688           [(match_operand:GPI 2 "register_operand" "")
2689            (match_operand:GPI 3 "aarch64_plus_operand" "")])
2690          (match_operand:GPI 4 "register_operand" "")
2691          (match_operand:GPI 5 "register_operand" "")))]
2692   ""
2693   "
2694   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2695                                       operands[3]);
2696   operands[3] = const0_rtx;
2697   "
2700 (define_expand "cmov<mode>6"
2701   [(set (match_operand:GPF 0 "register_operand" "")
2702         (if_then_else:GPF
2703          (match_operator 1 "aarch64_comparison_operator"
2704           [(match_operand:GPF 2 "register_operand" "")
2705            (match_operand:GPF 3 "register_operand" "")])
2706          (match_operand:GPF 4 "register_operand" "")
2707          (match_operand:GPF 5 "register_operand" "")))]
2708   ""
2709   "
2710   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2711                                       operands[3]);
2712   operands[3] = const0_rtx;
2713   "
2716 (define_insn "*cmov<mode>_insn"
2717   [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2718         (if_then_else:ALLI
2719          (match_operator 1 "aarch64_comparison_operator"
2720           [(match_operand 2 "cc_register" "") (const_int 0)])
2721          (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2722          (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2723   "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2724      || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2725   ;; Final two alternatives should be unreachable, but included for completeness
2726   "@
2727    csel\\t%<w>0, %<w>3, %<w>4, %m1
2728    csinv\\t%<w>0, %<w>3, <w>zr, %m1
2729    csinv\\t%<w>0, %<w>4, <w>zr, %M1
2730    csinc\\t%<w>0, %<w>3, <w>zr, %m1
2731    csinc\\t%<w>0, %<w>4, <w>zr, %M1
2732    mov\\t%<w>0, -1
2733    mov\\t%<w>0, 1"
2734   [(set_attr "type" "csel")]
2737 ;; zero_extend version of above
2738 (define_insn "*cmovsi_insn_uxtw"
2739   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2740         (zero_extend:DI
2741          (if_then_else:SI
2742           (match_operator 1 "aarch64_comparison_operator"
2743            [(match_operand 2 "cc_register" "") (const_int 0)])
2744           (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2745           (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2746   "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2747      || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2748   ;; Final two alternatives should be unreachable, but included for completeness
2749   "@
2750    csel\\t%w0, %w3, %w4, %m1
2751    csinv\\t%w0, %w3, wzr, %m1
2752    csinv\\t%w0, %w4, wzr, %M1
2753    csinc\\t%w0, %w3, wzr, %m1
2754    csinc\\t%w0, %w4, wzr, %M1
2755    mov\\t%w0, -1
2756    mov\\t%w0, 1"
2757   [(set_attr "type" "csel")]
2760 (define_insn "*cmov<mode>_insn"
2761   [(set (match_operand:GPF 0 "register_operand" "=w")
2762         (if_then_else:GPF
2763          (match_operator 1 "aarch64_comparison_operator"
2764           [(match_operand 2 "cc_register" "") (const_int 0)])
2765          (match_operand:GPF 3 "register_operand" "w")
2766          (match_operand:GPF 4 "register_operand" "w")))]
2767   "TARGET_FLOAT"
2768   "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2769   [(set_attr "type" "fcsel")]
2772 (define_expand "mov<mode>cc"
2773   [(set (match_operand:ALLI 0 "register_operand" "")
2774         (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2775                            (match_operand:ALLI 2 "register_operand" "")
2776                            (match_operand:ALLI 3 "register_operand" "")))]
2777   ""
2778   {
2779     enum rtx_code code = GET_CODE (operands[1]);
2781     if (code == UNEQ || code == LTGT)
2782       FAIL;
2784     if (!ccmp_cc_register (XEXP (operands[1], 0),
2785                            GET_MODE (XEXP (operands[1], 0))))
2786       {
2787         rtx ccreg;
2788         ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2789                                          XEXP (operands[1], 1));
2790         operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2791       }
2792   }
2795 (define_expand "mov<GPF:mode><GPI:mode>cc"
2796   [(set (match_operand:GPI 0 "register_operand" "")
2797         (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2798                           (match_operand:GPF 2 "register_operand" "")
2799                           (match_operand:GPF 3 "register_operand" "")))]
2800   ""
2801   {
2802     rtx ccreg;
2803     enum rtx_code code = GET_CODE (operands[1]);
2805     if (code == UNEQ || code == LTGT)
2806       FAIL;
2808     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2809                                   XEXP (operands[1], 1));
2810     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2811   }
2814 (define_expand "mov<mode>cc"
2815   [(set (match_operand:GPF 0 "register_operand" "")
2816         (if_then_else:GPF (match_operand 1 "aarch64_comparison_operator" "")
2817                           (match_operand:GPF 2 "register_operand" "")
2818                           (match_operand:GPF 3 "register_operand" "")))]
2819   ""
2820   {
2821     rtx ccreg;
2822     enum rtx_code code = GET_CODE (operands[1]);
2824     if (code == UNEQ || code == LTGT)
2825       FAIL;
2827     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2828                                   XEXP (operands[1], 1));
2829     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2830   }
2834 ;; CRC32 instructions.
2835 (define_insn "aarch64_<crc_variant>"
2836   [(set (match_operand:SI 0 "register_operand" "=r")
2837         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2838                     (match_operand:<crc_mode> 2 "register_operand" "r")]
2839          CRC))]
2840   "TARGET_CRC32"
2841   {
2842     if (GET_MODE_BITSIZE (GET_MODE (operands[2])) >= 64)
2843       return "<crc_variant>\\t%w0, %w1, %x2";
2844     else
2845       return "<crc_variant>\\t%w0, %w1, %w2";
2846   }
2847   [(set_attr "type" "crc")]
2850 (define_insn "*csinc2<mode>_insn"
2851   [(set (match_operand:GPI 0 "register_operand" "=r")
2852         (plus:GPI (match_operand 2 "aarch64_comparison_operation" "")
2853                   (match_operand:GPI 1 "register_operand" "r")))]
2854   ""
2855   "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2856   [(set_attr "type" "csel")]
2859 (define_insn "csinc3<mode>_insn"
2860   [(set (match_operand:GPI 0 "register_operand" "=r")
2861         (if_then_else:GPI
2862           (match_operand 1 "aarch64_comparison_operation" "")
2863           (plus:GPI (match_operand:GPI 2 "register_operand" "r")
2864                     (const_int 1))
2865           (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2866   ""
2867   "csinc\\t%<w>0, %<w>3, %<w>2, %M1"
2868   [(set_attr "type" "csel")]
2871 (define_insn "*csinv3<mode>_insn"
2872   [(set (match_operand:GPI 0 "register_operand" "=r")
2873         (if_then_else:GPI
2874           (match_operand 1 "aarch64_comparison_operation" "")
2875           (not:GPI (match_operand:GPI 2 "register_operand" "r"))
2876           (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2877   ""
2878   "csinv\\t%<w>0, %<w>3, %<w>2, %M1"
2879   [(set_attr "type" "csel")]
2882 (define_insn "*csneg3<mode>_insn"
2883   [(set (match_operand:GPI 0 "register_operand" "=r")
2884         (if_then_else:GPI
2885           (match_operand 1 "aarch64_comparison_operation" "")
2886           (neg:GPI (match_operand:GPI 2 "register_operand" "r"))
2887           (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2888   ""
2889   "csneg\\t%<w>0, %<w>3, %<w>2, %M1"
2890   [(set_attr "type" "csel")]
2893 ;; -------------------------------------------------------------------
2894 ;; Logical operations
2895 ;; -------------------------------------------------------------------
2897 (define_insn "<optab><mode>3"
2898   [(set (match_operand:GPI 0 "register_operand" "=r,rk,w")
2899         (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r,w")
2900                      (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>,w")))]
2901   ""
2902   "@
2903   <logical>\\t%<w>0, %<w>1, %<w>2
2904   <logical>\\t%<w>0, %<w>1, %<w>2
2905   <logical>\\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
2906   [(set_attr "type" "logic_reg,logic_imm,neon_logic")
2907    (set_attr "simd" "*,*,yes")]
2910 ;; zero_extend version of above
2911 (define_insn "*<optab>si3_uxtw"
2912   [(set (match_operand:DI 0 "register_operand" "=r,rk")
2913         (zero_extend:DI
2914          (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2915                      (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2916   ""
2917   "<logical>\\t%w0, %w1, %w2"
2918   [(set_attr "type" "logic_reg,logic_imm")]
2921 (define_insn "*and<mode>3_compare0"
2922   [(set (reg:CC_NZ CC_REGNUM)
2923         (compare:CC_NZ
2924          (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2925                   (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2926          (const_int 0)))
2927    (set (match_operand:GPI 0 "register_operand" "=r,r")
2928         (and:GPI (match_dup 1) (match_dup 2)))]
2929   ""
2930   "ands\\t%<w>0, %<w>1, %<w>2"
2931   [(set_attr "type" "logics_reg,logics_imm")]
2934 ;; zero_extend version of above
2935 (define_insn "*andsi3_compare0_uxtw"
2936   [(set (reg:CC_NZ CC_REGNUM)
2937         (compare:CC_NZ
2938          (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2939                  (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2940          (const_int 0)))
2941    (set (match_operand:DI 0 "register_operand" "=r,r")
2942         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2943   ""
2944   "ands\\t%w0, %w1, %w2"
2945   [(set_attr "type" "logics_reg,logics_imm")]
2948 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2949   [(set (reg:CC_NZ CC_REGNUM)
2950         (compare:CC_NZ
2951          (and:GPI (SHIFT:GPI
2952                    (match_operand:GPI 1 "register_operand" "r")
2953                    (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2954                   (match_operand:GPI 3 "register_operand" "r"))
2955          (const_int 0)))
2956    (set (match_operand:GPI 0 "register_operand" "=r")
2957         (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2958   ""
2959   "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2960   [(set_attr "type" "logics_shift_imm")]
2963 ;; zero_extend version of above
2964 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2965   [(set (reg:CC_NZ CC_REGNUM)
2966         (compare:CC_NZ
2967          (and:SI (SHIFT:SI
2968                   (match_operand:SI 1 "register_operand" "r")
2969                   (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2970                  (match_operand:SI 3 "register_operand" "r"))
2971          (const_int 0)))
2972    (set (match_operand:DI 0 "register_operand" "=r")
2973         (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2974                                 (match_dup 3))))]
2975   ""
2976   "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2977   [(set_attr "type" "logics_shift_imm")]
2980 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2981   [(set (match_operand:GPI 0 "register_operand" "=r")
2982         (LOGICAL:GPI (SHIFT:GPI
2983                       (match_operand:GPI 1 "register_operand" "r")
2984                       (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2985                      (match_operand:GPI 3 "register_operand" "r")))]
2986   ""
2987   "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2988   [(set_attr "type" "logic_shift_imm")]
2991 (define_insn "*<optab>_rol<mode>3"
2992   [(set (match_operand:GPI 0 "register_operand" "=r")
2993         (LOGICAL:GPI (rotate:GPI
2994                       (match_operand:GPI 1 "register_operand" "r")
2995                       (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2996                      (match_operand:GPI 3 "register_operand" "r")))]
2997   ""
2998   "<logical>\\t%<w>0, %<w>3, %<w>1, ror (<sizen> - %2)"
2999   [(set_attr "type" "logic_shift_imm")]
3002 ;; zero_extend versions of above
3003 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
3004   [(set (match_operand:DI 0 "register_operand" "=r")
3005         (zero_extend:DI
3006          (LOGICAL:SI (SHIFT:SI
3007                       (match_operand:SI 1 "register_operand" "r")
3008                       (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3009                      (match_operand:SI 3 "register_operand" "r"))))]
3010   ""
3011   "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3012   [(set_attr "type" "logic_shift_imm")]
3015 (define_insn "*<optab>_rolsi3_uxtw"
3016   [(set (match_operand:DI 0 "register_operand" "=r")
3017         (zero_extend:DI
3018          (LOGICAL:SI (rotate:SI
3019                       (match_operand:SI 1 "register_operand" "r")
3020                       (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3021                      (match_operand:SI 3 "register_operand" "r"))))]
3022   ""
3023   "<logical>\\t%w0, %w3, %w1, ror (32 - %2)"
3024   [(set_attr "type" "logic_shift_imm")]
3027 (define_insn "one_cmpl<mode>2"
3028   [(set (match_operand:GPI 0 "register_operand" "=r,w")
3029         (not:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
3030   ""
3031   "@
3032   mvn\\t%<w>0, %<w>1
3033   mvn\\t%0.8b, %1.8b"
3034   [(set_attr "type" "logic_reg,neon_logic")
3035    (set_attr "simd" "*,yes")]
3038 (define_insn "*one_cmpl_<optab><mode>2"
3039   [(set (match_operand:GPI 0 "register_operand" "=r")
3040         (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
3041                             (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
3042   ""
3043   "mvn\\t%<w>0, %<w>1, <shift> %2"
3044   [(set_attr "type" "logic_shift_imm")]
3047 ;; Binary logical operators negating one operand, i.e. (a & !b), (a | !b).
3049 (define_insn "*<NLOGICAL:optab>_one_cmpl<mode>3"
3050   [(set (match_operand:GPI 0 "register_operand" "=r,w")
3051         (NLOGICAL:GPI (not:GPI (match_operand:GPI 1 "register_operand" "r,w"))
3052                      (match_operand:GPI 2 "register_operand" "r,w")))]
3053   ""
3054   "@
3055   <NLOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1
3056   <NLOGICAL:nlogical>\\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>"
3057   [(set_attr "type" "logic_reg,neon_logic")
3058    (set_attr "simd" "*,yes")]
3061 (define_insn "*<NLOGICAL:optab>_one_cmplsidi3_ze"
3062   [(set (match_operand:DI 0 "register_operand" "=r")
3063         (zero_extend:DI
3064           (NLOGICAL:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3065                        (match_operand:SI 2 "register_operand" "r"))))]
3066   ""
3067   "<NLOGICAL:nlogical>\\t%w0, %w2, %w1"
3068   [(set_attr "type" "logic_reg")]
3071 (define_insn "*xor_one_cmplsidi3_ze"
3072   [(set (match_operand:DI 0 "register_operand" "=r")
3073         (zero_extend:DI
3074           (not:SI (xor:SI (match_operand:SI 1 "register_operand" "r")
3075                           (match_operand:SI 2 "register_operand" "r")))))]
3076   ""
3077   "eon\\t%w0, %w1, %w2"
3078   [(set_attr "type" "logic_reg")]
3081 ;; (xor (not a) b) is simplify_rtx-ed down to (not (xor a b)).
3082 ;; eon does not operate on SIMD registers so the vector variant must be split.
3083 (define_insn_and_split "*xor_one_cmpl<mode>3"
3084   [(set (match_operand:GPI 0 "register_operand" "=r,w")
3085         (not:GPI (xor:GPI (match_operand:GPI 1 "register_operand" "r,?w")
3086                           (match_operand:GPI 2 "register_operand" "r,w"))))]
3087   ""
3088   "@
3089   eon\\t%<w>0, %<w>1, %<w>2
3090   #"
3091   "reload_completed && FP_REGNUM_P (REGNO (operands[0]))" ;; For SIMD registers.
3092   [(set (match_operand:GPI 0 "register_operand" "=w")
3093         (xor:GPI (match_operand:GPI 1 "register_operand" "w")
3094                  (match_operand:GPI 2 "register_operand" "w")))
3095    (set (match_dup 0) (not:GPI (match_dup 0)))]
3096   ""
3097   [(set_attr "type" "logic_reg,multiple")
3098    (set_attr "simd" "*,yes")]
3101 (define_insn "*and_one_cmpl<mode>3_compare0"
3102   [(set (reg:CC_NZ CC_REGNUM)
3103         (compare:CC_NZ
3104          (and:GPI (not:GPI
3105                    (match_operand:GPI 1 "register_operand" "r"))
3106                   (match_operand:GPI 2 "register_operand" "r"))
3107          (const_int 0)))
3108    (set (match_operand:GPI 0 "register_operand" "=r")
3109         (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
3110   ""
3111   "bics\\t%<w>0, %<w>2, %<w>1"
3112   [(set_attr "type" "logics_reg")]
3115 ;; zero_extend version of above
3116 (define_insn "*and_one_cmplsi3_compare0_uxtw"
3117   [(set (reg:CC_NZ CC_REGNUM)
3118         (compare:CC_NZ
3119          (and:SI (not:SI
3120                   (match_operand:SI 1 "register_operand" "r"))
3121                  (match_operand:SI 2 "register_operand" "r"))
3122          (const_int 0)))
3123    (set (match_operand:DI 0 "register_operand" "=r")
3124         (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
3125   ""
3126   "bics\\t%w0, %w2, %w1"
3127   [(set_attr "type" "logics_reg")]
3130 (define_insn "*and_one_cmpl<mode>3_compare0_no_reuse"
3131   [(set (reg:CC_NZ CC_REGNUM)
3132     (compare:CC_NZ
3133      (and:GPI (not:GPI
3134            (match_operand:GPI 0 "register_operand" "r"))
3135           (match_operand:GPI 1 "register_operand" "r"))
3136      (const_int 0)))]
3137   ""
3138   "bics\\t<w>zr, %<w>1, %<w>0"
3139   [(set_attr "type" "logics_reg")]
3142 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
3143   [(set (match_operand:GPI 0 "register_operand" "=r")
3144         (LOGICAL:GPI (not:GPI
3145                       (SHIFT:GPI
3146                        (match_operand:GPI 1 "register_operand" "r")
3147                        (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
3148                      (match_operand:GPI 3 "register_operand" "r")))]
3149   ""
3150   "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3151   [(set_attr "type" "logics_shift_imm")]
3154 (define_insn "*eor_one_cmpl_<SHIFT:optab><mode>3_alt"
3155   [(set (match_operand:GPI 0 "register_operand" "=r")
3156         (not:GPI (xor:GPI
3157                       (SHIFT:GPI
3158                        (match_operand:GPI 1 "register_operand" "r")
3159                        (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3160                      (match_operand:GPI 3 "register_operand" "r"))))]
3161   ""
3162   "eon\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3163   [(set_attr "type" "logic_shift_imm")]
3166 ;; Zero-extend version of the above.
3167 (define_insn "*eor_one_cmpl_<SHIFT:optab>sidi3_alt_ze"
3168   [(set (match_operand:DI 0 "register_operand" "=r")
3169         (zero_extend:DI
3170           (not:SI (xor:SI
3171                     (SHIFT:SI
3172                       (match_operand:SI 1 "register_operand" "r")
3173                       (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3174                     (match_operand:SI 3 "register_operand" "r")))))]
3175   ""
3176   "eon\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3177   [(set_attr "type" "logic_shift_imm")]
3180 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
3181   [(set (reg:CC_NZ CC_REGNUM)
3182         (compare:CC_NZ
3183          (and:GPI (not:GPI
3184                    (SHIFT:GPI
3185                     (match_operand:GPI 1 "register_operand" "r")
3186                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
3187                   (match_operand:GPI 3 "register_operand" "r"))
3188          (const_int 0)))
3189    (set (match_operand:GPI 0 "register_operand" "=r")
3190         (and:GPI (not:GPI
3191                   (SHIFT:GPI
3192                    (match_dup 1) (match_dup 2))) (match_dup 3)))]
3193   ""
3194   "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3195   [(set_attr "type" "logics_shift_imm")]
3198 ;; zero_extend version of above
3199 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
3200   [(set (reg:CC_NZ CC_REGNUM)
3201         (compare:CC_NZ
3202          (and:SI (not:SI
3203                   (SHIFT:SI
3204                    (match_operand:SI 1 "register_operand" "r")
3205                    (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
3206                  (match_operand:SI 3 "register_operand" "r"))
3207          (const_int 0)))
3208    (set (match_operand:DI 0 "register_operand" "=r")
3209         (zero_extend:DI (and:SI
3210                          (not:SI
3211                           (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
3212   ""
3213   "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3214   [(set_attr "type" "logics_shift_imm")]
3217 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0_no_reuse"
3218   [(set (reg:CC_NZ CC_REGNUM)
3219     (compare:CC_NZ
3220      (and:GPI (not:GPI
3221            (SHIFT:GPI
3222             (match_operand:GPI 0 "register_operand" "r")
3223             (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n")))
3224           (match_operand:GPI 2 "register_operand" "r"))
3225      (const_int 0)))]
3226   ""
3227   "bics\\t<w>zr, %<w>2, %<w>0, <SHIFT:shift> %1"
3228   [(set_attr "type" "logics_shift_imm")]
3231 (define_insn "clz<mode>2"
3232   [(set (match_operand:GPI 0 "register_operand" "=r")
3233         (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
3234   ""
3235   "clz\\t%<w>0, %<w>1"
3236   [(set_attr "type" "clz")]
3239 (define_expand "ffs<mode>2"
3240   [(match_operand:GPI 0 "register_operand")
3241    (match_operand:GPI 1 "register_operand")]
3242   ""
3243   {
3244     rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
3245     rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
3247     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3248     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3249     emit_insn (gen_csinc3<mode>_insn (operands[0], x, operands[0], const0_rtx));
3250     DONE;
3251   }
3254 (define_insn "clrsb<mode>2"
3255   [(set (match_operand:GPI 0 "register_operand" "=r")
3256         (clrsb:GPI (match_operand:GPI 1 "register_operand" "r")))]
3257   ""
3258   "cls\\t%<w>0, %<w>1"
3259   [(set_attr "type" "clz")]
3262 (define_insn "rbit<mode>2"
3263   [(set (match_operand:GPI 0 "register_operand" "=r")
3264         (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
3265   ""
3266   "rbit\\t%<w>0, %<w>1"
3267   [(set_attr "type" "rbit")]
3270 (define_expand "ctz<mode>2"
3271   [(match_operand:GPI 0 "register_operand")
3272    (match_operand:GPI 1 "register_operand")]
3273   ""
3274   {
3275     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3276     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3277     DONE;
3278   }
3281 (define_insn "*and<mode>3nr_compare0"
3282   [(set (reg:CC_NZ CC_REGNUM)
3283         (compare:CC_NZ
3284          (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
3285                   (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
3286          (const_int 0)))]
3287   ""
3288   "tst\\t%<w>0, %<w>1"
3289   [(set_attr "type" "logics_reg")]
3292 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
3293   [(set (reg:CC_NZ CC_REGNUM)
3294         (compare:CC_NZ
3295          (and:GPI (SHIFT:GPI
3296                    (match_operand:GPI 0 "register_operand" "r")
3297                    (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
3298                   (match_operand:GPI 2 "register_operand" "r"))
3299         (const_int 0)))]
3300   ""
3301   "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
3302   [(set_attr "type" "logics_shift_imm")]
3305 ;; -------------------------------------------------------------------
3306 ;; Shifts
3307 ;; -------------------------------------------------------------------
3309 (define_expand "<optab><mode>3"
3310   [(set (match_operand:GPI 0 "register_operand")
3311         (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
3312                     (match_operand:QI 2 "nonmemory_operand")))]
3313   ""
3314   {
3315     if (CONST_INT_P (operands[2]))
3316       {
3317         operands[2] = GEN_INT (INTVAL (operands[2])
3318                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3320         if (operands[2] == const0_rtx)
3321           {
3322             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3323             DONE;
3324           }
3325       }
3326   }
3329 (define_expand "ashl<mode>3"
3330   [(set (match_operand:SHORT 0 "register_operand")
3331         (ashift:SHORT (match_operand:SHORT 1 "register_operand")
3332                       (match_operand:QI 2 "nonmemory_operand")))]
3333   ""
3334   {
3335     if (CONST_INT_P (operands[2]))
3336       {
3337         operands[2] = GEN_INT (INTVAL (operands[2])
3338                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3340         if (operands[2] == const0_rtx)
3341           {
3342             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3343             DONE;
3344           }
3345       }
3346     else
3347       FAIL;
3348   }
3351 (define_expand "rotr<mode>3"
3352   [(set (match_operand:GPI 0 "register_operand")
3353         (rotatert:GPI (match_operand:GPI 1 "register_operand")
3354                       (match_operand:QI 2 "nonmemory_operand")))]
3355   ""
3356   {
3357     if (CONST_INT_P (operands[2]))
3358       {
3359         operands[2] = GEN_INT (INTVAL (operands[2])
3360                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3362         if (operands[2] == const0_rtx)
3363           {
3364             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3365             DONE;
3366           }
3367       }
3368   }
3371 (define_expand "rotl<mode>3"
3372   [(set (match_operand:GPI 0 "register_operand")
3373         (rotatert:GPI (match_operand:GPI 1 "register_operand")
3374                       (match_operand:QI 2 "nonmemory_operand")))]
3375   ""
3376   {
3377     /* (SZ - cnt) % SZ == -cnt % SZ */
3378     if (CONST_INT_P (operands[2]))
3379       {
3380         operands[2] = GEN_INT ((-INTVAL (operands[2]))
3381                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3382         if (operands[2] == const0_rtx)
3383           {
3384             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3385             DONE;
3386           }
3387       }
3388     else
3389       operands[2] = expand_simple_unop (QImode, NEG, operands[2],
3390                                         NULL_RTX, 1);
3391   }
3394 ;; Logical left shift using SISD or Integer instruction
3395 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
3396   [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3397         (ashift:GPI
3398           (match_operand:GPI 1 "register_operand" "w,w,r")
3399           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3400   ""
3401   "@
3402    shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3403    ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
3404    lsl\t%<w>0, %<w>1, %<w>2"
3405   [(set_attr "simd" "yes,yes,no")
3406    (set_attr "type" "neon_shift_imm<q>, neon_shift_reg<q>,shift_reg")]
3409 ;; Logical right shift using SISD or Integer instruction
3410 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3411   [(set (match_operand:GPI 0 "register_operand" "=w,&w,r")
3412         (lshiftrt:GPI
3413           (match_operand:GPI 1 "register_operand" "w,w,r")
3414           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3415   ""
3416   "@
3417    ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3418    #
3419    lsr\t%<w>0, %<w>1, %<w>2"
3420   [(set_attr "simd" "yes,yes,no")
3421    (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")]
3424 (define_split
3425   [(set (match_operand:DI 0 "aarch64_simd_register")
3426         (lshiftrt:DI
3427            (match_operand:DI 1 "aarch64_simd_register")
3428            (match_operand:QI 2 "aarch64_simd_register")))]
3429   "TARGET_SIMD && reload_completed"
3430   [(set (match_dup 3)
3431         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3432    (set (match_dup 0)
3433         (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_USHL))]
3434   {
3435     operands[3] = gen_lowpart (QImode, operands[0]);
3436   }
3439 (define_split
3440   [(set (match_operand:SI 0 "aarch64_simd_register")
3441         (lshiftrt:SI
3442            (match_operand:SI 1 "aarch64_simd_register")
3443            (match_operand:QI 2 "aarch64_simd_register")))]
3444   "TARGET_SIMD && reload_completed"
3445   [(set (match_dup 3)
3446         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3447    (set (match_dup 0)
3448         (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_USHL_2S))]
3449   {
3450     operands[3] = gen_lowpart (QImode, operands[0]);
3451   }
3454 ;; Arithmetic right shift using SISD or Integer instruction
3455 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3456   [(set (match_operand:GPI 0 "register_operand" "=w,&w,&w,r")
3457         (ashiftrt:GPI
3458           (match_operand:GPI 1 "register_operand" "w,w,w,r")
3459           (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,0,rUs<cmode>")))]
3460   ""
3461   "@
3462    sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3463    #
3464    #
3465    asr\t%<w>0, %<w>1, %<w>2"
3466   [(set_attr "simd" "yes,yes,yes,no")
3467    (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>,shift_reg")]
3470 (define_split
3471   [(set (match_operand:DI 0 "aarch64_simd_register")
3472         (ashiftrt:DI
3473            (match_operand:DI 1 "aarch64_simd_register")
3474            (match_operand:QI 2 "aarch64_simd_register")))]
3475   "TARGET_SIMD && reload_completed"
3476   [(set (match_dup 3)
3477         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3478    (set (match_dup 0)
3479         (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_SSHL))]
3481   operands[3] = gen_lowpart (QImode, operands[0]);
3485 (define_split
3486   [(set (match_operand:SI 0 "aarch64_simd_register")
3487         (ashiftrt:SI
3488            (match_operand:SI 1 "aarch64_simd_register")
3489            (match_operand:QI 2 "aarch64_simd_register")))]
3490   "TARGET_SIMD && reload_completed"
3491   [(set (match_dup 3)
3492         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3493    (set (match_dup 0)
3494         (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_SSHL_2S))]
3496   operands[3] = gen_lowpart (QImode, operands[0]);
3500 (define_insn "*aarch64_sisd_ushl"
3501   [(set (match_operand:DI 0 "register_operand" "=w")
3502         (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3503                     (match_operand:QI 2 "register_operand" "w")]
3504                    UNSPEC_SISD_USHL))]
3505   "TARGET_SIMD"
3506   "ushl\t%d0, %d1, %d2"
3507   [(set_attr "simd" "yes")
3508    (set_attr "type" "neon_shift_reg")]
3511 (define_insn "*aarch64_ushl_2s"
3512   [(set (match_operand:SI 0 "register_operand" "=w")
3513         (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3514                     (match_operand:QI 2 "register_operand" "w")]
3515                    UNSPEC_USHL_2S))]
3516   "TARGET_SIMD"
3517   "ushl\t%0.2s, %1.2s, %2.2s"
3518   [(set_attr "simd" "yes")
3519    (set_attr "type" "neon_shift_reg")]
3522 (define_insn "*aarch64_sisd_sshl"
3523   [(set (match_operand:DI 0 "register_operand" "=w")
3524         (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3525                     (match_operand:QI 2 "register_operand" "w")]
3526                    UNSPEC_SISD_SSHL))]
3527   "TARGET_SIMD"
3528   "sshl\t%d0, %d1, %d2"
3529   [(set_attr "simd" "yes")
3530    (set_attr "type" "neon_shift_reg")]
3533 (define_insn "*aarch64_sshl_2s"
3534   [(set (match_operand:SI 0 "register_operand" "=w")
3535         (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3536                     (match_operand:QI 2 "register_operand" "w")]
3537                    UNSPEC_SSHL_2S))]
3538   "TARGET_SIMD"
3539   "sshl\t%0.2s, %1.2s, %2.2s"
3540   [(set_attr "simd" "yes")
3541    (set_attr "type" "neon_shift_reg")]
3544 (define_insn "*aarch64_sisd_neg_qi"
3545   [(set (match_operand:QI 0 "register_operand" "=w")
3546         (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3547                    UNSPEC_SISD_NEG))]
3548   "TARGET_SIMD"
3549   "neg\t%d0, %d1"
3550   [(set_attr "simd" "yes")
3551    (set_attr "type" "neon_neg")]
3554 ;; Rotate right
3555 (define_insn "*ror<mode>3_insn"
3556   [(set (match_operand:GPI 0 "register_operand" "=r")
3557         (rotatert:GPI
3558           (match_operand:GPI 1 "register_operand" "r")
3559           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3560   ""
3561   "ror\\t%<w>0, %<w>1, %<w>2"
3562   [(set_attr "type" "shift_reg")]
3565 ;; zero_extend version of above
3566 (define_insn "*<optab>si3_insn_uxtw"
3567   [(set (match_operand:DI 0 "register_operand" "=r")
3568         (zero_extend:DI (SHIFT:SI
3569          (match_operand:SI 1 "register_operand" "r")
3570          (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3571   ""
3572   "<shift>\\t%w0, %w1, %w2"
3573   [(set_attr "type" "shift_reg")]
3576 (define_insn "*<optab><mode>3_insn"
3577   [(set (match_operand:SHORT 0 "register_operand" "=r")
3578         (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3579                       (match_operand 2 "const_int_operand" "n")))]
3580   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3582   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3583   return "<bfshift>\t%w0, %w1, %2, %3";
3585   [(set_attr "type" "bfm")]
3588 (define_insn "*extr<mode>5_insn"
3589   [(set (match_operand:GPI 0 "register_operand" "=r")
3590         (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3591                              (match_operand 3 "const_int_operand" "n"))
3592                  (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3593                                (match_operand 4 "const_int_operand" "n"))))]
3594   "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3595    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3596   "extr\\t%<w>0, %<w>1, %<w>2, %4"
3597   [(set_attr "type" "shift_imm")]
3600 ;; zero_extend version of the above
3601 (define_insn "*extrsi5_insn_uxtw"
3602   [(set (match_operand:DI 0 "register_operand" "=r")
3603         (zero_extend:DI
3604          (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3605                             (match_operand 3 "const_int_operand" "n"))
3606                  (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3607                               (match_operand 4 "const_int_operand" "n")))))]
3608   "UINTVAL (operands[3]) < 32 &&
3609    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3610   "extr\\t%w0, %w1, %w2, %4"
3611   [(set_attr "type" "shift_imm")]
3614 (define_insn "*ror<mode>3_insn"
3615   [(set (match_operand:GPI 0 "register_operand" "=r")
3616         (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3617                     (match_operand 2 "const_int_operand" "n")))]
3618   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3620   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3621   return "ror\\t%<w>0, %<w>1, %3";
3623   [(set_attr "type" "shift_imm")]
3626 ;; zero_extend version of the above
3627 (define_insn "*rorsi3_insn_uxtw"
3628   [(set (match_operand:DI 0 "register_operand" "=r")
3629         (zero_extend:DI
3630          (rotate:SI (match_operand:SI 1 "register_operand" "r")
3631                     (match_operand 2 "const_int_operand" "n"))))]
3632   "UINTVAL (operands[2]) < 32"
3634   operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3635   return "ror\\t%w0, %w1, %3";
3637   [(set_attr "type" "shift_imm")]
3640 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3641   [(set (match_operand:GPI 0 "register_operand" "=r")
3642         (ANY_EXTEND:GPI
3643          (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3644                        (match_operand 2 "const_int_operand" "n"))))]
3645   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3647   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3648   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3650   [(set_attr "type" "bfm")]
3653 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3654   [(set (match_operand:GPI 0 "register_operand" "=r")
3655         (zero_extend:GPI
3656          (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3657                          (match_operand 2 "const_int_operand" "n"))))]
3658   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3660   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3661   return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3663   [(set_attr "type" "bfm")]
3666 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3667   [(set (match_operand:GPI 0 "register_operand" "=r")
3668         (sign_extend:GPI
3669          (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3670                          (match_operand 2 "const_int_operand" "n"))))]
3671   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3673   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3674   return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3676   [(set_attr "type" "bfm")]
3679 ;; -------------------------------------------------------------------
3680 ;; Bitfields
3681 ;; -------------------------------------------------------------------
3683 (define_expand "<optab>"
3684   [(set (match_operand:DI 0 "register_operand" "=r")
3685         (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3686                         (match_operand 2 "const_int_operand" "n")
3687                         (match_operand 3 "const_int_operand" "n")))]
3688   ""
3689   ""
3692 (define_insn "*<optab><mode>"
3693   [(set (match_operand:GPI 0 "register_operand" "=r")
3694         (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3695                          (match_operand 2 "const_int_operand" "n")
3696                          (match_operand 3 "const_int_operand" "n")))]
3697   ""
3698   "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3699   [(set_attr "type" "bfm")]
3702 ;; Bitfield Insert (insv)
3703 (define_expand "insv<mode>"
3704   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3705                           (match_operand 1 "const_int_operand")
3706                           (match_operand 2 "const_int_operand"))
3707         (match_operand:GPI 3 "general_operand"))]
3708   ""
3710   unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3711   unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3712   rtx value = operands[3];
3714   if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3715     FAIL;
3717   if (CONST_INT_P (value))
3718     {
3719       unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3721       /* Prefer AND/OR for inserting all zeros or all ones.  */
3722       if ((UINTVAL (value) & mask) == 0
3723            || (UINTVAL (value) & mask) == mask)
3724         FAIL;
3726       /* 16-bit aligned 16-bit wide insert is handled by insv_imm.  */
3727       if (width == 16 && (pos % 16) == 0)
3728         DONE;
3729     }
3730   operands[3] = force_reg (<MODE>mode, value);
3733 (define_insn "*insv_reg<mode>"
3734   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3735                           (match_operand 1 "const_int_operand" "n")
3736                           (match_operand 2 "const_int_operand" "n"))
3737         (match_operand:GPI 3 "register_operand" "r"))]
3738   "!(UINTVAL (operands[1]) == 0
3739      || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3740          > GET_MODE_BITSIZE (<MODE>mode)))"
3741   "bfi\\t%<w>0, %<w>3, %2, %1"
3742   [(set_attr "type" "bfm")]
3745 (define_insn "*extr_insv_lower_reg<mode>"
3746   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3747                           (match_operand 1 "const_int_operand" "n")
3748                           (const_int 0))
3749         (zero_extract:GPI (match_operand:GPI 2 "register_operand" "r")
3750                           (match_dup 1)
3751                           (match_operand 3 "const_int_operand" "n")))]
3752   "!(UINTVAL (operands[1]) == 0
3753      || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3754          > GET_MODE_BITSIZE (<MODE>mode)))"
3755   "bfxil\\t%<w>0, %<w>2, %3, %1"
3756   [(set_attr "type" "bfm")]
3759 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3760   [(set (match_operand:GPI 0 "register_operand" "=r")
3761         (ashift:GPI (ANY_EXTEND:GPI
3762                      (match_operand:ALLX 1 "register_operand" "r"))
3763                     (match_operand 2 "const_int_operand" "n")))]
3764   "UINTVAL (operands[2]) < <GPI:sizen>"
3766   operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3767               ? GEN_INT (<ALLX:sizen>)
3768               : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3769   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3771   [(set_attr "type" "bfm")]
3774 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3776 (define_insn "*andim_ashift<mode>_bfiz"
3777   [(set (match_operand:GPI 0 "register_operand" "=r")
3778         (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3779                              (match_operand 2 "const_int_operand" "n"))
3780                  (match_operand 3 "const_int_operand" "n")))]
3781   "(INTVAL (operands[2]) < (<GPI:sizen>))
3782    && exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3783    && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3784   "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3785   [(set_attr "type" "bfm")]
3788 (define_insn "bswap<mode>2"
3789   [(set (match_operand:GPI 0 "register_operand" "=r")
3790         (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3791   ""
3792   "rev\\t%<w>0, %<w>1"
3793   [(set_attr "type" "rev")]
3796 (define_insn "bswaphi2"
3797   [(set (match_operand:HI 0 "register_operand" "=r")
3798         (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3799   ""
3800   "rev16\\t%w0, %w1"
3801   [(set_attr "type" "rev")]
3804 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
3805 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
3806 ;; each valid permutation.
3808 (define_insn "rev16<mode>2"
3809   [(set (match_operand:GPI 0 "register_operand" "=r")
3810         (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3811                                       (const_int 8))
3812                           (match_operand:GPI 3 "const_int_operand" "n"))
3813                  (and:GPI (lshiftrt:GPI (match_dup 1)
3814                                         (const_int 8))
3815                           (match_operand:GPI 2 "const_int_operand" "n"))))]
3816   "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3817    && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3818   "rev16\\t%<w>0, %<w>1"
3819   [(set_attr "type" "rev")]
3822 (define_insn "rev16<mode>2_alt"
3823   [(set (match_operand:GPI 0 "register_operand" "=r")
3824         (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r")
3825                                         (const_int 8))
3826                           (match_operand:GPI 2 "const_int_operand" "n"))
3827                  (and:GPI (ashift:GPI (match_dup 1)
3828                                       (const_int 8))
3829                           (match_operand:GPI 3 "const_int_operand" "n"))))]
3830   "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3831    && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3832   "rev16\\t%<w>0, %<w>1"
3833   [(set_attr "type" "rev")]
3836 ;; zero_extend version of above
3837 (define_insn "*bswapsi2_uxtw"
3838   [(set (match_operand:DI 0 "register_operand" "=r")
3839         (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3840   ""
3841   "rev\\t%w0, %w1"
3842   [(set_attr "type" "rev")]
3845 ;; -------------------------------------------------------------------
3846 ;; Floating-point intrinsics
3847 ;; -------------------------------------------------------------------
3849 ;; frint floating-point round to integral standard patterns.
3850 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round, frintn.
3852 (define_insn "<frint_pattern><mode>2"
3853   [(set (match_operand:GPF 0 "register_operand" "=w")
3854         (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3855          FRINT))]
3856   "TARGET_FLOAT"
3857   "frint<frint_suffix>\\t%<s>0, %<s>1"
3858   [(set_attr "type" "f_rint<s>")]
3861 ;; frcvt floating-point round to integer and convert standard patterns.
3862 ;; Expands to lbtrunc, lceil, lfloor, lround.
3863 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3864   [(set (match_operand:GPI 0 "register_operand" "=r")
3865         (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3866                       FCVT)))]
3867   "TARGET_FLOAT"
3868   "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3869   [(set_attr "type" "f_cvtf2i")]
3872 ;; fma - no throw
3874 (define_insn "fma<mode>4"
3875   [(set (match_operand:GPF 0 "register_operand" "=w")
3876         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3877                  (match_operand:GPF 2 "register_operand" "w")
3878                  (match_operand:GPF 3 "register_operand" "w")))]
3879   "TARGET_FLOAT"
3880   "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3881   [(set_attr "type" "fmac<s>")]
3884 (define_insn "fnma<mode>4"
3885   [(set (match_operand:GPF 0 "register_operand" "=w")
3886         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3887                  (match_operand:GPF 2 "register_operand" "w")
3888                  (match_operand:GPF 3 "register_operand" "w")))]
3889   "TARGET_FLOAT"
3890   "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3891   [(set_attr "type" "fmac<s>")]
3894 (define_insn "fms<mode>4"
3895   [(set (match_operand:GPF 0 "register_operand" "=w")
3896         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3897                  (match_operand:GPF 2 "register_operand" "w")
3898                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3899   "TARGET_FLOAT"
3900   "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3901   [(set_attr "type" "fmac<s>")]
3904 (define_insn "fnms<mode>4"
3905   [(set (match_operand:GPF 0 "register_operand" "=w")
3906         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3907                  (match_operand:GPF 2 "register_operand" "w")
3908                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3909   "TARGET_FLOAT"
3910   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3911   [(set_attr "type" "fmac<s>")]
3914 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3915 (define_insn "*fnmadd<mode>4"
3916   [(set (match_operand:GPF 0 "register_operand" "=w")
3917         (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3918                           (match_operand:GPF 2 "register_operand" "w")
3919                           (match_operand:GPF 3 "register_operand" "w"))))]
3920   "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3921   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3922   [(set_attr "type" "fmac<s>")]
3925 ;; -------------------------------------------------------------------
3926 ;; Floating-point conversions
3927 ;; -------------------------------------------------------------------
3929 (define_insn "extendsfdf2"
3930   [(set (match_operand:DF 0 "register_operand" "=w")
3931         (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3932   "TARGET_FLOAT"
3933   "fcvt\\t%d0, %s1"
3934   [(set_attr "type" "f_cvt")]
3937 (define_insn "truncdfsf2"
3938   [(set (match_operand:SF 0 "register_operand" "=w")
3939         (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3940   "TARGET_FLOAT"
3941   "fcvt\\t%s0, %d1"
3942   [(set_attr "type" "f_cvt")]
3945 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3946   [(set (match_operand:GPI 0 "register_operand" "=r")
3947         (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3948   "TARGET_FLOAT"
3949   "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3950   [(set_attr "type" "f_cvtf2i")]
3953 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3954   [(set (match_operand:GPI 0 "register_operand" "=r")
3955         (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3956   "TARGET_FLOAT"
3957   "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3958   [(set_attr "type" "f_cvtf2i")]
3961 (define_insn "<optab><fcvt_target><GPF:mode>2"
3962   [(set (match_operand:GPF 0 "register_operand" "=w,w")
3963         (FLOATUORS:GPF (match_operand:<FCVT_TARGET> 1 "register_operand" "w,r")))]
3964   ""
3965   "@
3966    <su_optab>cvtf\t%<GPF:s>0, %<s>1
3967    <su_optab>cvtf\t%<GPF:s>0, %<w1>1"
3968   [(set_attr "simd" "yes,no")
3969    (set_attr "fp" "no,yes")
3970    (set_attr "type" "neon_int_to_fp_<Vetype>,f_cvti2f")]
3973 (define_insn "<optab><fcvt_iesize><GPF:mode>2"
3974   [(set (match_operand:GPF 0 "register_operand" "=w")
3975         (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand" "r")))]
3976   "TARGET_FLOAT"
3977   "<su_optab>cvtf\t%<GPF:s>0, %<w2>1"
3978   [(set_attr "type" "f_cvti2f")]
3981 ;; -------------------------------------------------------------------
3982 ;; Floating-point arithmetic
3983 ;; -------------------------------------------------------------------
3985 (define_insn "add<mode>3"
3986   [(set (match_operand:GPF 0 "register_operand" "=w")
3987         (plus:GPF
3988          (match_operand:GPF 1 "register_operand" "w")
3989          (match_operand:GPF 2 "register_operand" "w")))]
3990   "TARGET_FLOAT"
3991   "fadd\\t%<s>0, %<s>1, %<s>2"
3992   [(set_attr "type" "fadd<s>")]
3995 (define_insn "sub<mode>3"
3996   [(set (match_operand:GPF 0 "register_operand" "=w")
3997         (minus:GPF
3998          (match_operand:GPF 1 "register_operand" "w")
3999          (match_operand:GPF 2 "register_operand" "w")))]
4000   "TARGET_FLOAT"
4001   "fsub\\t%<s>0, %<s>1, %<s>2"
4002   [(set_attr "type" "fadd<s>")]
4005 (define_insn "mul<mode>3"
4006   [(set (match_operand:GPF 0 "register_operand" "=w")
4007         (mult:GPF
4008          (match_operand:GPF 1 "register_operand" "w")
4009          (match_operand:GPF 2 "register_operand" "w")))]
4010   "TARGET_FLOAT"
4011   "fmul\\t%<s>0, %<s>1, %<s>2"
4012   [(set_attr "type" "fmul<s>")]
4015 (define_insn "*fnmul<mode>3"
4016   [(set (match_operand:GPF 0 "register_operand" "=w")
4017         (mult:GPF
4018                  (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
4019                  (match_operand:GPF 2 "register_operand" "w")))]
4020   "TARGET_FLOAT"
4021   "fnmul\\t%<s>0, %<s>1, %<s>2"
4022   [(set_attr "type" "fmul<s>")]
4025 (define_insn "div<mode>3"
4026   [(set (match_operand:GPF 0 "register_operand" "=w")
4027         (div:GPF
4028          (match_operand:GPF 1 "register_operand" "w")
4029          (match_operand:GPF 2 "register_operand" "w")))]
4030   "TARGET_FLOAT"
4031   "fdiv\\t%<s>0, %<s>1, %<s>2"
4032   [(set_attr "type" "fdiv<s>")]
4035 (define_insn "neg<mode>2"
4036   [(set (match_operand:GPF 0 "register_operand" "=w")
4037         (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
4038   "TARGET_FLOAT"
4039   "fneg\\t%<s>0, %<s>1"
4040   [(set_attr "type" "ffarith<s>")]
4043 (define_insn "sqrt<mode>2"
4044   [(set (match_operand:GPF 0 "register_operand" "=w")
4045         (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
4046   "TARGET_FLOAT"
4047   "fsqrt\\t%<s>0, %<s>1"
4048   [(set_attr "type" "fsqrt<s>")]
4051 (define_insn "abs<mode>2"
4052   [(set (match_operand:GPF 0 "register_operand" "=w")
4053         (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
4054   "TARGET_FLOAT"
4055   "fabs\\t%<s>0, %<s>1"
4056   [(set_attr "type" "ffarith<s>")]
4059 ;; Given that smax/smin do not specify the result when either input is NaN,
4060 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
4061 ;; for smin.
4063 (define_insn "smax<mode>3"
4064   [(set (match_operand:GPF 0 "register_operand" "=w")
4065         (smax:GPF (match_operand:GPF 1 "register_operand" "w")
4066                   (match_operand:GPF 2 "register_operand" "w")))]
4067   "TARGET_FLOAT"
4068   "fmaxnm\\t%<s>0, %<s>1, %<s>2"
4069   [(set_attr "type" "f_minmax<s>")]
4072 (define_insn "smin<mode>3"
4073   [(set (match_operand:GPF 0 "register_operand" "=w")
4074         (smin:GPF (match_operand:GPF 1 "register_operand" "w")
4075                   (match_operand:GPF 2 "register_operand" "w")))]
4076   "TARGET_FLOAT"
4077   "fminnm\\t%<s>0, %<s>1, %<s>2"
4078   [(set_attr "type" "f_minmax<s>")]
4081 ;; -------------------------------------------------------------------
4082 ;; Reload support
4083 ;; -------------------------------------------------------------------
4085 (define_expand "aarch64_reload_mov<mode>"
4086   [(set (match_operand:TX 0 "register_operand" "=w")
4087         (match_operand:TX 1 "register_operand" "w"))
4088    (clobber (match_operand:DI 2 "register_operand" "=&r"))
4089   ]
4090   "TARGET_FLOAT"
4091   {
4092     rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
4093     rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
4094     gen_aarch64_movtilow_tilow (op0, op1);
4095     gen_aarch64_movdi_tihigh (operands[2], op1);
4096     gen_aarch64_movtihigh_di (op0, operands[2]);
4097     DONE;
4098   }
4101 ;; The following secondary reload helpers patterns are invoked
4102 ;; after or during reload as we don't want these patterns to start
4103 ;; kicking in during the combiner.
4105 (define_insn "aarch64_movdi_<mode>low"
4106   [(set (match_operand:DI 0 "register_operand" "=r")
4107         (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
4108   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4109   "fmov\\t%x0, %d1"
4110   [(set_attr "type" "f_mrc")
4111    (set_attr "length" "4")
4112   ])
4114 (define_insn "aarch64_movdi_<mode>high"
4115   [(set (match_operand:DI 0 "register_operand" "=r")
4116         (truncate:DI
4117           (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
4118                        (const_int 64))))]
4119   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4120   "fmov\\t%x0, %1.d[1]"
4121   [(set_attr "type" "f_mrc")
4122    (set_attr "length" "4")
4123   ])
4125 (define_insn "aarch64_mov<mode>high_di"
4126   [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
4127                          (const_int 64) (const_int 64))
4128         (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4129   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4130   "fmov\\t%0.d[1], %x1"
4131   [(set_attr "type" "f_mcr")
4132    (set_attr "length" "4")
4133   ])
4135 (define_insn "aarch64_mov<mode>low_di"
4136   [(set (match_operand:TX 0 "register_operand" "=w")
4137         (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4138   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4139   "fmov\\t%d0, %x1"
4140   [(set_attr "type" "f_mcr")
4141    (set_attr "length" "4")
4142   ])
4144 (define_insn "aarch64_movtilow_tilow"
4145   [(set (match_operand:TI 0 "register_operand" "=w")
4146         (zero_extend:TI
4147           (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
4148   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4149   "fmov\\t%d0, %d1"
4150   [(set_attr "type" "fmov")
4151    (set_attr "length" "4")
4152   ])
4154 ;; There is a deliberate reason why the parameters of high and lo_sum's
4155 ;; don't have modes for ADRP and ADD instructions.  This is to allow high
4156 ;; and lo_sum's to be used with the labels defining the jump tables in
4157 ;; rodata section.
4159 (define_expand "add_losym"
4160   [(set (match_operand 0 "register_operand" "=r")
4161         (lo_sum (match_operand 1 "register_operand" "r")
4162                 (match_operand 2 "aarch64_valid_symref" "S")))]
4163   ""
4165   machine_mode mode = GET_MODE (operands[0]);
4167   emit_insn ((mode == DImode
4168               ? gen_add_losym_di
4169               : gen_add_losym_si) (operands[0],
4170                                    operands[1],
4171                                    operands[2]));
4172   DONE;
4175 (define_insn "add_losym_<mode>"
4176   [(set (match_operand:P 0 "register_operand" "=r")
4177         (lo_sum:P (match_operand:P 1 "register_operand" "r")
4178                   (match_operand 2 "aarch64_valid_symref" "S")))]
4179   ""
4180   "add\\t%<w>0, %<w>1, :lo12:%a2"
4181   [(set_attr "type" "alu_imm")]
4184 (define_insn "ldr_got_small_<mode>"
4185   [(set (match_operand:PTR 0 "register_operand" "=r")
4186         (unspec:PTR [(mem:PTR (lo_sum:PTR
4187                               (match_operand:PTR 1 "register_operand" "r")
4188                               (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
4189                     UNSPEC_GOTSMALLPIC))]
4190   ""
4191   "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
4192   [(set_attr "type" "load1")]
4195 (define_insn "ldr_got_small_sidi"
4196   [(set (match_operand:DI 0 "register_operand" "=r")
4197         (zero_extend:DI
4198          (unspec:SI [(mem:SI (lo_sum:DI
4199                              (match_operand:DI 1 "register_operand" "r")
4200                              (match_operand:DI 2 "aarch64_valid_symref" "S")))]
4201                     UNSPEC_GOTSMALLPIC)))]
4202   "TARGET_ILP32"
4203   "ldr\\t%w0, [%1, #:got_lo12:%a2]"
4204   [(set_attr "type" "load1")]
4207 (define_insn "ldr_got_tiny"
4208   [(set (match_operand:DI 0 "register_operand" "=r")
4209         (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
4210                    UNSPEC_GOTTINYPIC))]
4211   ""
4212   "ldr\\t%0, %L1"
4213   [(set_attr "type" "load1")]
4216 (define_insn "aarch64_load_tp_hard"
4217   [(set (match_operand:DI 0 "register_operand" "=r")
4218         (unspec:DI [(const_int 0)] UNSPEC_TLS))]
4219   ""
4220   "mrs\\t%0, tpidr_el0"
4221   [(set_attr "type" "mrs")]
4224 ;; The TLS ABI specifically requires that the compiler does not schedule
4225 ;; instructions in the TLS stubs, in order to enable linker relaxation.
4226 ;; Therefore we treat the stubs as an atomic sequence.
4227 (define_expand "tlsgd_small"
4228  [(parallel [(set (match_operand 0 "register_operand" "")
4229                   (call (mem:DI (match_dup 2)) (const_int 1)))
4230              (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
4231              (clobber (reg:DI LR_REGNUM))])]
4232  ""
4234   operands[2] = aarch64_tls_get_addr ();
4237 (define_insn "*tlsgd_small"
4238   [(set (match_operand 0 "register_operand" "")
4239         (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
4240    (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
4241    (clobber (reg:DI LR_REGNUM))
4242   ]
4243   ""
4244   "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
4245   [(set_attr "type" "call")
4246    (set_attr "length" "16")])
4248 (define_insn "tlsie_small_<mode>"
4249   [(set (match_operand:PTR 0 "register_operand" "=r")
4250         (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
4251                    UNSPEC_GOTSMALLTLS))]
4252   ""
4253   "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
4254   [(set_attr "type" "load1")
4255    (set_attr "length" "8")]
4258 (define_insn "tlsie_small_sidi"
4259   [(set (match_operand:DI 0 "register_operand" "=r")
4260         (zero_extend:DI
4261           (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")]
4262                       UNSPEC_GOTSMALLTLS)))]
4263   ""
4264   "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
4265   [(set_attr "type" "load1")
4266    (set_attr "length" "8")]
4269 (define_expand "tlsle_small"
4270   [(set (match_operand 0 "register_operand" "=r")
4271         (unspec [(match_operand 1 "register_operand" "r")
4272                    (match_operand 2 "aarch64_tls_le_symref" "S")]
4273                    UNSPEC_GOTSMALLTLS))]
4274   ""
4276   machine_mode mode = GET_MODE (operands[0]);
4277   emit_insn ((mode == DImode
4278               ? gen_tlsle_small_di
4279               : gen_tlsle_small_si) (operands[0],
4280                                      operands[1],
4281                                      operands[2]));
4282   DONE;
4285 (define_insn "tlsle_small_<mode>"
4286   [(set (match_operand:P 0 "register_operand" "=r")
4287         (unspec:P [(match_operand:P 1 "register_operand" "r")
4288                    (match_operand 2 "aarch64_tls_le_symref" "S")]
4289                    UNSPEC_GOTSMALLTLS))]
4290   ""
4291   "add\\t%<w>0, %<w>1, #%G2, lsl #12\;add\\t%<w>0, %<w>0, #%L2"
4292   [(set_attr "type" "alu_sreg")
4293    (set_attr "length" "8")]
4296 (define_insn "tlsdesc_small_<mode>"
4297   [(set (reg:PTR R0_REGNUM)
4298         (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
4299                    UNSPEC_TLSDESC))
4300    (clobber (reg:DI LR_REGNUM))
4301    (clobber (reg:CC CC_REGNUM))
4302    (clobber (match_scratch:DI 1 "=r"))]
4303   "TARGET_TLS_DESC"
4304   "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
4305   [(set_attr "type" "call")
4306    (set_attr "length" "16")])
4308 (define_insn "stack_tie"
4309   [(set (mem:BLK (scratch))
4310         (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
4311                      (match_operand:DI 1 "register_operand" "rk")]
4312                     UNSPEC_PRLG_STK))]
4313   ""
4314   ""
4315   [(set_attr "length" "0")]
4318 ;; Named pattern for expanding thread pointer reference.
4319 (define_expand "get_thread_pointerdi"
4320   [(match_operand:DI 0 "register_operand" "=r")]
4321   ""
4323   rtx tmp = aarch64_load_tp (operands[0]);
4324   if (tmp != operands[0])
4325     emit_move_insn (operands[0], tmp);
4326   DONE;
4329 ;; Named patterns for stack smashing protection.
4330 (define_expand "stack_protect_set"
4331   [(match_operand 0 "memory_operand")
4332    (match_operand 1 "memory_operand")]
4333   ""
4335   machine_mode mode = GET_MODE (operands[0]);
4337   emit_insn ((mode == DImode
4338               ? gen_stack_protect_set_di
4339               : gen_stack_protect_set_si) (operands[0], operands[1]));
4340   DONE;
4343 (define_insn "stack_protect_set_<mode>"
4344   [(set (match_operand:PTR 0 "memory_operand" "=m")
4345         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
4346          UNSPEC_SP_SET))
4347    (set (match_scratch:PTR 2 "=&r") (const_int 0))]
4348   ""
4349   "ldr\\t%<w>2, %1\;str\\t%<w>2, %0\;mov\t%<w>2,0"
4350   [(set_attr "length" "12")
4351    (set_attr "type" "multiple")])
4353 (define_expand "stack_protect_test"
4354   [(match_operand 0 "memory_operand")
4355    (match_operand 1 "memory_operand")
4356    (match_operand 2)]
4357   ""
4359   rtx result;
4360   machine_mode mode = GET_MODE (operands[0]);
4362   result = gen_reg_rtx(mode);
4364   emit_insn ((mode == DImode
4365               ? gen_stack_protect_test_di
4366               : gen_stack_protect_test_si) (result,
4367                                             operands[0],
4368                                             operands[1]));
4370   if (mode == DImode)
4371     emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4372                                     result, const0_rtx, operands[2]));
4373   else
4374     emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4375                                     result, const0_rtx, operands[2]));
4376   DONE;
4379 (define_insn "stack_protect_test_<mode>"
4380   [(set (match_operand:PTR 0 "register_operand" "=r")
4381         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
4382                      (match_operand:PTR 2 "memory_operand" "m")]
4383          UNSPEC_SP_TEST))
4384    (clobber (match_scratch:PTR 3 "=&r"))]
4385   ""
4386   "ldr\t%<w>3, %x1\;ldr\t%<w>0, %x2\;eor\t%<w>0, %<w>3, %<w>0"
4387   [(set_attr "length" "12")
4388    (set_attr "type" "multiple")])
4390 ;; Write Floating-point Control Register.
4391 (define_insn "set_fpcr"
4392   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
4393   ""
4394   "msr\\tfpcr, %0"
4395   [(set_attr "type" "mrs")])
4397 ;; Read Floating-point Control Register.
4398 (define_insn "get_fpcr"
4399   [(set (match_operand:SI 0 "register_operand" "=r")
4400         (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
4401   ""
4402   "mrs\\t%0, fpcr"
4403   [(set_attr "type" "mrs")])
4405 ;; Write Floating-point Status Register.
4406 (define_insn "set_fpsr"
4407   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
4408   ""
4409   "msr\\tfpsr, %0"
4410   [(set_attr "type" "mrs")])
4412 ;; Read Floating-point Status Register.
4413 (define_insn "get_fpsr"
4414   [(set (match_operand:SI 0 "register_operand" "=r")
4415         (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
4416   ""
4417   "mrs\\t%0, fpsr"
4418   [(set_attr "type" "mrs")])
4421 ;; Define the subtract-one-and-jump insns so loop.c
4422 ;; knows what to generate.
4423 (define_expand "doloop_end"
4424   [(use (match_operand 0 "" ""))      ; loop pseudo
4425    (use (match_operand 1 "" ""))]     ; label
4426   "optimize > 0 && flag_modulo_sched"
4428   rtx s0;
4429   rtx bcomp;
4430   rtx loc_ref;
4431   rtx cc_reg;
4432   rtx insn;
4433   rtx cmp;
4435   /* Currently SMS relies on the do-loop pattern to recognize loops
4436      where (1) the control part consists of all insns defining and/or
4437      using a certain 'count' register and (2) the loop count can be
4438      adjusted by modifying this register prior to the loop.
4439      ??? The possible introduction of a new block to initialize the
4440      new IV can potentially affect branch optimizations.  */
4442   if (GET_MODE (operands[0]) != DImode)
4443     FAIL;
4445   s0 = operands [0];
4446   insn = emit_insn (gen_adddi3_compare0 (s0, s0, GEN_INT (-1)));
4448   cmp = XVECEXP (PATTERN (insn), 0, 0);
4449   cc_reg = SET_DEST (cmp);
4450   bcomp = gen_rtx_NE (VOIDmode, cc_reg, const0_rtx);
4451   loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
4452   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4453                                gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
4454                                                      loc_ref, pc_rtx)));
4455   DONE;
4458 ;; AdvSIMD Stuff
4459 (include "aarch64-simd.md")
4461 ;; Atomic Operations
4462 (include "atomics.md")
4464 ;; ldp/stp peephole patterns
4465 (include "aarch64-ldpstp.md")