[AArch64 1/3] Don't disparage add/sub in SIMD registers
[official-gcc.git] / gcc / config / aarch64 / aarch64.md
blob3e8434602b99527a41875ebeb319787ab875a887
1 ;; Machine description for AArch64 architecture.
2 ;; Copyright (C) 2009-2014 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-a15.md")
192 (include "thunderx.md")
194 ;; -------------------------------------------------------------------
195 ;; Jumps and other miscellaneous insns
196 ;; -------------------------------------------------------------------
198 (define_insn "indirect_jump"
199   [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
200   ""
201   "br\\t%0"
202   [(set_attr "type" "branch")]
205 (define_insn "jump"
206   [(set (pc) (label_ref (match_operand 0 "" "")))]
207   ""
208   "b\\t%l0"
209   [(set_attr "type" "branch")]
212 (define_expand "cbranch<mode>4"
213   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
214                             [(match_operand:GPI 1 "register_operand" "")
215                              (match_operand:GPI 2 "aarch64_plus_operand" "")])
216                            (label_ref (match_operand 3 "" ""))
217                            (pc)))]
218   ""
219   "
220   operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
221                                          operands[2]);
222   operands[2] = const0_rtx;
223   "
226 (define_expand "cbranch<mode>4"
227   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
228                             [(match_operand:GPF 1 "register_operand" "")
229                              (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
230                            (label_ref (match_operand 3 "" ""))
231                            (pc)))]
232   ""
233   "
234   operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
235                                          operands[2]);
236   operands[2] = const0_rtx;
237   "
240 (define_expand "cbranchcc4"
241   [(set (pc) (if_then_else
242               (match_operator 0 "aarch64_comparison_operator"
243                [(match_operand 1 "cc_register" "")
244                 (match_operand 2 "const0_operand")])
245               (label_ref (match_operand 3 "" ""))
246               (pc)))]
247   ""
248   "")
250 (define_insn "*ccmp_and"
251   [(set (match_operand 1 "ccmp_cc_register" "")
252         (compare
253          (and:SI
254           (match_operator 4 "aarch64_comparison_operator"
255            [(match_operand 0 "ccmp_cc_register" "")
256             (const_int 0)])
257           (match_operator 5 "aarch64_comparison_operator"
258            [(match_operand:GPI 2 "register_operand" "r,r,r")
259             (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")]))
260          (const_int 0)))]
261   "aarch64_ccmp_mode_to_code (GET_MODE (operands[1])) == GET_CODE (operands[5])"
262   "@
263    ccmp\\t%<w>2, %<w>3, %k5, %m4
264    ccmp\\t%<w>2, %<w>3, %k5, %m4
265    ccmn\\t%<w>2, #%n3, %k5, %m4"
266   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
269 (define_insn "*ccmp_ior"
270   [(set (match_operand 1 "ccmp_cc_register" "")
271         (compare
272          (ior:SI
273           (match_operator 4 "aarch64_comparison_operator"
274            [(match_operand 0 "ccmp_cc_register" "")
275             (const_int 0)])
276           (match_operator 5 "aarch64_comparison_operator"
277            [(match_operand:GPI 2 "register_operand" "r,r,r")
278             (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")]))
279          (const_int 0)))]
280   "aarch64_ccmp_mode_to_code (GET_MODE (operands[1])) == GET_CODE (operands[5])"
281   "@
282    ccmp\\t%<w>2, %<w>3, %K5, %M4
283    ccmp\\t%<w>2, %<w>3, %K5, %M4
284    ccmn\\t%<w>2, #%n3, %K5, %M4"
285   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
288 (define_insn "*condjump"
289   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
290                             [(match_operand 1 "cc_register" "") (const_int 0)])
291                            (label_ref (match_operand 2 "" ""))
292                            (pc)))]
293   ""
294   "b%m0\\t%l2"
295   [(set_attr "type" "branch")]
298 (define_expand "casesi"
299   [(match_operand:SI 0 "register_operand" "")   ; Index
300    (match_operand:SI 1 "const_int_operand" "")  ; Lower bound
301    (match_operand:SI 2 "const_int_operand" "")  ; Total range
302    (match_operand:DI 3 "" "")                   ; Table label
303    (match_operand:DI 4 "" "")]                  ; Out of range label
304   ""
305   {
306     if (operands[1] != const0_rtx)
307       {
308         rtx reg = gen_reg_rtx (SImode);
310         /* Canonical RTL says that if you have:
312            (minus (X) (CONST))
314            then this should be emitted as:
316            (plus (X) (-CONST))
318            The use of trunc_int_for_mode ensures that the resulting
319            constant can be represented in SImode, this is important
320            for the corner case where operand[1] is INT_MIN.  */
322         operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
324         if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
325               (operands[1], SImode))
326           operands[1] = force_reg (SImode, operands[1]);
327         emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
328         operands[0] = reg;
329       }
331     if (!aarch64_plus_operand (operands[2], SImode))
332       operands[2] = force_reg (SImode, operands[2]);
333     emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
334                                                  const0_rtx),
335                                     operands[0], operands[2], operands[4]));
337     operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
338     emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
339                                          operands[3]));
340     DONE;
341   }
344 (define_insn "casesi_dispatch"
345   [(parallel
346     [(set (pc)
347           (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
348                            (match_operand:SI 1 "register_operand" "r")]
349                         UNSPEC_CASESI)))
350      (clobber (reg:CC CC_REGNUM))
351      (clobber (match_scratch:DI 3 "=r"))
352      (clobber (match_scratch:DI 4 "=r"))
353      (use (label_ref (match_operand 2 "" "")))])]
354   ""
355   "*
356   return aarch64_output_casesi (operands);
357   "
358   [(set_attr "length" "16")
359    (set_attr "type" "branch")]
362 (define_insn "nop"
363   [(unspec[(const_int 0)] UNSPEC_NOP)]
364   ""
365   "nop"
366   [(set_attr "type" "no_insn")]
369 (define_insn "prefetch"
370   [(prefetch (match_operand:DI 0 "address_operand" "r")
371             (match_operand:QI 1 "const_int_operand" "")
372             (match_operand:QI 2 "const_int_operand" ""))]
373   ""
374   {
375     const char * pftype[2][4] = 
376     {
377       {"prfm\\tPLDL1STRM, %a0",
378        "prfm\\tPLDL3KEEP, %a0",
379        "prfm\\tPLDL2KEEP, %a0",
380        "prfm\\tPLDL1KEEP, %a0"},
381       {"prfm\\tPSTL1STRM, %a0",
382        "prfm\\tPSTL3KEEP, %a0",
383        "prfm\\tPSTL2KEEP, %a0",
384        "prfm\\tPSTL1KEEP, %a0"},
385     };
387     int locality = INTVAL (operands[2]);
389     gcc_assert (IN_RANGE (locality, 0, 3));
391     return pftype[INTVAL(operands[1])][locality];
392   }
393   [(set_attr "type" "load1")]
396 (define_insn "trap"
397   [(trap_if (const_int 1) (const_int 8))]
398   ""
399   "brk #1000"
400   [(set_attr "type" "trap")])
402 (define_expand "prologue"
403   [(clobber (const_int 0))]
404   ""
405   "
406   aarch64_expand_prologue ();
407   DONE;
408   "
411 (define_expand "epilogue"
412   [(clobber (const_int 0))]
413   ""
414   "
415   aarch64_expand_epilogue (false);
416   DONE;
417   "
420 (define_expand "sibcall_epilogue"
421   [(clobber (const_int 0))]
422   ""
423   "
424   aarch64_expand_epilogue (true);
425   DONE;
426   "
429 (define_insn "*do_return"
430   [(return)]
431   ""
432   "ret"
433   [(set_attr "type" "branch")]
436 (define_expand "return"
437   [(simple_return)]
438   "aarch64_use_return_insn_p ()"
439   ""
442 (define_insn "simple_return"
443   [(simple_return)]
444   ""
445   "ret"
446   [(set_attr "type" "branch")]
449 (define_insn "eh_return"
450   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
451     UNSPECV_EH_RETURN)]
452   ""
453   "#"
454   [(set_attr "type" "branch")]
458 (define_split
459   [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
460     UNSPECV_EH_RETURN)]
461   "reload_completed"
462   [(set (match_dup 1) (match_dup 0))]
463   {
464     operands[1] = aarch64_final_eh_return_addr ();
465   }
468 (define_insn "*cb<optab><mode>1"
469   [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
470                                 (const_int 0))
471                            (label_ref (match_operand 1 "" ""))
472                            (pc)))]
473   ""
474   "<cbz>\\t%<w>0, %l1"
475   [(set_attr "type" "branch")]
479 (define_insn "*tb<optab><mode>1"
480   [(set (pc) (if_then_else
481               (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
482                                     (const_int 1)
483                                     (match_operand 1 "const_int_operand" "n"))
484                    (const_int 0))
485              (label_ref (match_operand 2 "" ""))
486              (pc)))
487    (clobber (match_scratch:DI 3 "=r"))]
488   ""
489   "*
490   if (get_attr_length (insn) == 8)
491     return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
492   return \"<tbz>\\t%<w>0, %1, %l2\";
493   "
494   [(set_attr "type" "branch")
495    (set (attr "length")
496         (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
497                            (lt (minus (match_dup 2) (pc)) (const_int 32764)))
498                       (const_int 4)
499                       (const_int 8)))]
502 (define_insn "*cb<optab><mode>1"
503   [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
504                                  (const_int 0))
505                            (label_ref (match_operand 1 "" ""))
506                            (pc)))
507    (clobber (match_scratch:DI 2 "=r"))]
508   ""
509   "*
510   if (get_attr_length (insn) == 8)
511     return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
512   return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
513   "
514   [(set_attr "type" "branch")
515    (set (attr "length")
516         (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
517                            (lt (minus (match_dup 1) (pc)) (const_int 32764)))
518                       (const_int 4)
519                       (const_int 8)))]
522 ;; -------------------------------------------------------------------
523 ;; Subroutine calls and sibcalls
524 ;; -------------------------------------------------------------------
526 (define_expand "call_internal"
527   [(parallel [(call (match_operand 0 "memory_operand" "")
528                     (match_operand 1 "general_operand" ""))
529               (use (match_operand 2 "" ""))
530               (clobber (reg:DI LR_REGNUM))])])
532 (define_expand "call"
533   [(parallel [(call (match_operand 0 "memory_operand" "")
534                     (match_operand 1 "general_operand" ""))
535               (use (match_operand 2 "" ""))
536               (clobber (reg:DI LR_REGNUM))])]
537   ""
538   "
539   {
540     rtx callee, pat;
542     /* In an untyped call, we can get NULL for operand 2.  */
543     if (operands[2] == NULL)
544       operands[2] = const0_rtx;
546     /* Decide if we should generate indirect calls by loading the
547        64-bit address of the callee into a register before performing
548        the branch-and-link.  */
549     callee = XEXP (operands[0], 0);
550     if (GET_CODE (callee) == SYMBOL_REF
551         ? aarch64_is_long_call_p (callee)
552         : !REG_P (callee))
553       XEXP (operands[0], 0) = force_reg (Pmode, callee);
555     pat = gen_call_internal (operands[0], operands[1], operands[2]);
556     aarch64_emit_call_insn (pat);
557     DONE;
558   }"
561 (define_insn "*call_reg"
562   [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
563          (match_operand 1 "" ""))
564    (use (match_operand 2 "" ""))
565    (clobber (reg:DI LR_REGNUM))]
566   ""
567   "blr\\t%0"
568   [(set_attr "type" "call")]
571 (define_insn "*call_symbol"
572   [(call (mem:DI (match_operand:DI 0 "" ""))
573          (match_operand 1 "" ""))
574    (use (match_operand 2 "" ""))
575    (clobber (reg:DI LR_REGNUM))]
576   "GET_CODE (operands[0]) == SYMBOL_REF
577    && !aarch64_is_long_call_p (operands[0])"
578   "bl\\t%a0"
579   [(set_attr "type" "call")]
582 (define_expand "call_value_internal"
583   [(parallel [(set (match_operand 0 "" "")
584                    (call (match_operand 1 "memory_operand" "")
585                          (match_operand 2 "general_operand" "")))
586               (use (match_operand 3 "" ""))
587               (clobber (reg:DI LR_REGNUM))])])
589 (define_expand "call_value"
590   [(parallel [(set (match_operand 0 "" "")
591                    (call (match_operand 1 "memory_operand" "")
592                          (match_operand 2 "general_operand" "")))
593               (use (match_operand 3 "" ""))
594               (clobber (reg:DI LR_REGNUM))])]
595   ""
596   "
597   {
598     rtx callee, pat;
600     /* In an untyped call, we can get NULL for operand 3.  */
601     if (operands[3] == NULL)
602       operands[3] = const0_rtx;
604     /* Decide if we should generate indirect calls by loading the
605        64-bit address of the callee into a register before performing
606        the branch-and-link.  */
607     callee = XEXP (operands[1], 0);
608     if (GET_CODE (callee) == SYMBOL_REF
609         ? aarch64_is_long_call_p (callee)
610         : !REG_P (callee))
611       XEXP (operands[1], 0) = force_reg (Pmode, callee);
613     pat = gen_call_value_internal (operands[0], operands[1], operands[2],
614                                    operands[3]);
615     aarch64_emit_call_insn (pat);
616     DONE;
617   }"
620 (define_insn "*call_value_reg"
621   [(set (match_operand 0 "" "")
622         (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
623                       (match_operand 2 "" "")))
624    (use (match_operand 3 "" ""))
625    (clobber (reg:DI LR_REGNUM))]
626   ""
627   "blr\\t%1"
628   [(set_attr "type" "call")]
632 (define_insn "*call_value_symbol"
633   [(set (match_operand 0 "" "")
634         (call (mem:DI (match_operand:DI 1 "" ""))
635               (match_operand 2 "" "")))
636    (use (match_operand 3 "" ""))
637    (clobber (reg:DI LR_REGNUM))]
638   "GET_CODE (operands[1]) == SYMBOL_REF
639    && !aarch64_is_long_call_p (operands[1])"
640   "bl\\t%a1"
641   [(set_attr "type" "call")]
644 (define_expand "sibcall_internal"
645   [(parallel [(call (match_operand 0 "memory_operand" "")
646                     (match_operand 1 "general_operand" ""))
647               (return)
648               (use (match_operand 2 "" ""))])])
650 (define_expand "sibcall"
651   [(parallel [(call (match_operand 0 "memory_operand" "")
652                     (match_operand 1 "general_operand" ""))
653               (return)
654               (use (match_operand 2 "" ""))])]
655   ""
656   {
657     rtx pat;
659     if (!REG_P (XEXP (operands[0], 0))
660        && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
661      XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
663     if (operands[2] == NULL_RTX)
664       operands[2] = const0_rtx;
666     pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
667     aarch64_emit_call_insn (pat);
668     DONE;
669   }
672 (define_expand "sibcall_value_internal"
673   [(parallel [(set (match_operand 0 "" "")
674                    (call (match_operand 1 "memory_operand" "")
675                          (match_operand 2 "general_operand" "")))
676               (return)
677               (use (match_operand 3 "" ""))])])
679 (define_expand "sibcall_value"
680   [(parallel [(set (match_operand 0 "" "")
681                    (call (match_operand 1 "memory_operand" "")
682                          (match_operand 2 "general_operand" "")))
683               (return)
684               (use (match_operand 3 "" ""))])]
685   ""
686   {
687     rtx pat;
689     if (!REG_P (XEXP (operands[1], 0))
690        && (GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF))
691      XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
693     if (operands[3] == NULL_RTX)
694       operands[3] = const0_rtx;
696     pat = gen_sibcall_value_internal (operands[0], operands[1], operands[2],
697                                       operands[3]);
698     aarch64_emit_call_insn (pat);
699     DONE;
700   }
703 (define_insn "*sibcall_insn"
704   [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucs, Usf"))
705          (match_operand 1 "" ""))
706    (return)
707    (use (match_operand 2 "" ""))]
708   "SIBLING_CALL_P (insn)"
709   "@
710    br\\t%0
711    b\\t%a0"
712   [(set_attr "type" "branch, branch")]
715 (define_insn "*sibcall_value_insn"
716   [(set (match_operand 0 "" "")
717         (call (mem:DI
718                 (match_operand:DI 1 "aarch64_call_insn_operand" "Ucs, Usf"))
719               (match_operand 2 "" "")))
720    (return)
721    (use (match_operand 3 "" ""))]
722   "SIBLING_CALL_P (insn)"
723   "@
724    br\\t%1
725    b\\t%a1"
726   [(set_attr "type" "branch, branch")]
729 ;; Call subroutine returning any type.
731 (define_expand "untyped_call"
732   [(parallel [(call (match_operand 0 "")
733                     (const_int 0))
734               (match_operand 1 "")
735               (match_operand 2 "")])]
736   ""
738   int i;
740   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
742   for (i = 0; i < XVECLEN (operands[2], 0); i++)
743     {
744       rtx set = XVECEXP (operands[2], 0, i);
745       emit_move_insn (SET_DEST (set), SET_SRC (set));
746     }
748   /* The optimizer does not know that the call sets the function value
749      registers we stored in the result block.  We avoid problems by
750      claiming that all hard registers are used and clobbered at this
751      point.  */
752   emit_insn (gen_blockage ());
753   DONE;
756 ;; -------------------------------------------------------------------
757 ;; Moves
758 ;; -------------------------------------------------------------------
760 (define_expand "mov<mode>"
761   [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
762         (match_operand:SHORT 1 "general_operand" ""))]
763   ""
764   "
765     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
766       operands[1] = force_reg (<MODE>mode, operands[1]);
767   "
770 (define_insn "*mov<mode>_aarch64"
771   [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r,   *w,r,*w, m, m, r,*w,*w")
772         (match_operand:SHORT 1 "general_operand"      " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
773   "(register_operand (operands[0], <MODE>mode)
774     || aarch64_reg_or_zero (operands[1], <MODE>mode))"
776    switch (which_alternative)
777      {
778      case 0:
779        return "mov\t%w0, %w1";
780      case 1:
781        return "mov\t%w0, %1";
782      case 2:
783        return aarch64_output_scalar_simd_mov_immediate (operands[1],
784                                                         <MODE>mode);
785      case 3:
786        return "ldr<size>\t%w0, %1";
787      case 4:
788        return "ldr\t%<size>0, %1";
789      case 5:
790        return "str<size>\t%w1, %0";
791      case 6:
792        return "str\t%<size>1, %0";
793      case 7:
794        return "umov\t%w0, %1.<v>[0]";
795      case 8:
796        return "dup\t%0.<Vallxd>, %w1";
797      case 9:
798        return "dup\t%<Vetype>0, %1.<v>[0]";
799      default:
800        gcc_unreachable ();
801      }
803   [(set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
804                      neon_from_gp<q>,neon_from_gp<q>, neon_dup")
805    (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")]
808 (define_expand "mov<mode>"
809   [(set (match_operand:GPI 0 "nonimmediate_operand" "")
810         (match_operand:GPI 1 "general_operand" ""))]
811   ""
812   "
813     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
814       operands[1] = force_reg (<MODE>mode, operands[1]);
816     /* FIXME: RR we still need to fix up what we are doing with
817        symbol_refs and other types of constants.  */
818     if (CONSTANT_P (operands[1])
819         && !CONST_INT_P (operands[1]))
820      {
821        aarch64_expand_mov_immediate (operands[0], operands[1]);
822        DONE;
823      }
824   "
827 (define_insn_and_split "*movsi_aarch64"
828   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,r,*w,m,  m,r,r  ,*w, r,*w")
829         (match_operand:SI 1 "aarch64_mov_operand"  " r,r,k,M,n,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
830   "(register_operand (operands[0], SImode)
831     || aarch64_reg_or_zero (operands[1], SImode))"
832   "@
833    mov\\t%w0, %w1
834    mov\\t%w0, %w1
835    mov\\t%w0, %w1
836    mov\\t%w0, %1
837    #
838    ldr\\t%w0, %1
839    ldr\\t%s0, %1
840    str\\t%w1, %0
841    str\\t%s1, %0
842    adr\\t%x0, %a1
843    adrp\\t%x0, %A1
844    fmov\\t%s0, %w1
845    fmov\\t%w0, %s1
846    fmov\\t%s0, %s1"
847    "CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), SImode)"
848    [(const_int 0)]
849    "{
850        aarch64_expand_mov_immediate (operands[0], operands[1]);
851        DONE;
852     }"
853   [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
854                      adr,adr,f_mcr,f_mrc,fmov")
855    (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
858 (define_insn_and_split "*movdi_aarch64"
859   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,r,*w,m,  m,r,r,  *w, r,*w,w")
860         (match_operand:DI 1 "aarch64_mov_operand"  " r,r,k,N,n,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))]
861   "(register_operand (operands[0], DImode)
862     || aarch64_reg_or_zero (operands[1], DImode))"
863   "@
864    mov\\t%x0, %x1
865    mov\\t%0, %x1
866    mov\\t%x0, %1
867    mov\\t%x0, %1
868    #
869    ldr\\t%x0, %1
870    ldr\\t%d0, %1
871    str\\t%x1, %0
872    str\\t%d1, %0
873    adr\\t%x0, %a1
874    adrp\\t%x0, %A1
875    fmov\\t%d0, %x1
876    fmov\\t%x0, %d1
877    fmov\\t%d0, %d1
878    movi\\t%d0, %1"
879    "(CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), DImode))"
880    [(const_int 0)]
881    "{
882        aarch64_expand_mov_immediate (operands[0], operands[1]);
883        DONE;
884     }"
885   [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
886                      adr,adr,f_mcr,f_mrc,fmov,fmov")
887    (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
888    (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
891 (define_insn "insv_imm<mode>"
892   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
893                           (const_int 16)
894                           (match_operand:GPI 1 "const_int_operand" "n"))
895         (match_operand:GPI 2 "const_int_operand" "n"))]
896   "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
897    && UINTVAL (operands[1]) % 16 == 0"
898   "movk\\t%<w>0, %X2, lsl %1"
899   [(set_attr "type" "mov_imm")]
902 (define_expand "movti"
903   [(set (match_operand:TI 0 "nonimmediate_operand" "")
904         (match_operand:TI 1 "general_operand" ""))]
905   ""
906   "
907     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
908       operands[1] = force_reg (TImode, operands[1]);
909   "
912 (define_insn "*movti_aarch64"
913   [(set (match_operand:TI 0
914          "nonimmediate_operand"  "=r, *w,r ,*w,r  ,Ump,Ump,*w,m")
915         (match_operand:TI 1
916          "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r  ,Z  , m,*w"))]
917   "(register_operand (operands[0], TImode)
918     || aarch64_reg_or_zero (operands[1], TImode))"
919   "@
920    #
921    #
922    #
923    orr\\t%0.16b, %1.16b, %1.16b
924    ldp\\t%0, %H0, %1
925    stp\\t%1, %H1, %0
926    stp\\txzr, xzr, %0
927    ldr\\t%q0, %1
928    str\\t%q1, %0"
929   [(set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \
930                              load2,store2,store2,f_loadd,f_stored")
931    (set_attr "length" "8,8,8,4,4,4,4,4,4")
932    (set_attr "simd" "*,*,*,yes,*,*,*,*,*")
933    (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
936 ;; Split a TImode register-register or register-immediate move into
937 ;; its component DImode pieces, taking care to handle overlapping
938 ;; source and dest registers.
939 (define_split
940    [(set (match_operand:TI 0 "register_operand" "")
941          (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
942   "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
943   [(const_int 0)]
945   aarch64_split_128bit_move (operands[0], operands[1]);
946   DONE;
949 (define_expand "mov<mode>"
950   [(set (match_operand:GPF 0 "nonimmediate_operand" "")
951         (match_operand:GPF 1 "general_operand" ""))]
952   ""
953   "
954     if (!TARGET_FLOAT)
955      {
956         sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
957         FAIL;
958      }
960     if (GET_CODE (operands[0]) == MEM)
961       operands[1] = force_reg (<MODE>mode, operands[1]);
962   "
965 (define_insn "*movsf_aarch64"
966   [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w  ,w,m,r,m ,r")
967         (match_operand:SF 1 "general_operand"      "?rY, w,w,Ufc,m,w,m,rY,r"))]
968   "TARGET_FLOAT && (register_operand (operands[0], SFmode)
969     || register_operand (operands[1], SFmode))"
970   "@
971    fmov\\t%s0, %w1
972    fmov\\t%w0, %s1
973    fmov\\t%s0, %s1
974    fmov\\t%s0, %1
975    ldr\\t%s0, %1
976    str\\t%s1, %0
977    ldr\\t%w0, %1
978    str\\t%w1, %0
979    mov\\t%w0, %w1"
980   [(set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
981                      f_loads,f_stores,f_loads,f_stores,mov_reg")]
984 (define_insn "*movdf_aarch64"
985   [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w  ,w,m,r,m ,r")
986         (match_operand:DF 1 "general_operand"      "?rY, w,w,Ufc,m,w,m,rY,r"))]
987   "TARGET_FLOAT && (register_operand (operands[0], DFmode)
988     || register_operand (operands[1], DFmode))"
989   "@
990    fmov\\t%d0, %x1
991    fmov\\t%x0, %d1
992    fmov\\t%d0, %d1
993    fmov\\t%d0, %1
994    ldr\\t%d0, %1
995    str\\t%d1, %0
996    ldr\\t%x0, %1
997    str\\t%x1, %0
998    mov\\t%x0, %x1"
999   [(set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
1000                      f_loadd,f_stored,f_loadd,f_stored,mov_reg")]
1003 (define_expand "movtf"
1004   [(set (match_operand:TF 0 "nonimmediate_operand" "")
1005         (match_operand:TF 1 "general_operand" ""))]
1006   ""
1007   "
1008     if (!TARGET_FLOAT)
1009      {
1010         sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
1011         FAIL;
1012      }
1014     if (GET_CODE (operands[0]) == MEM)
1015       operands[1] = force_reg (TFmode, operands[1]);
1016   "
1019 (define_insn "*movtf_aarch64"
1020   [(set (match_operand:TF 0
1021          "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
1022         (match_operand:TF 1
1023          "general_operand"      " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
1024   "TARGET_FLOAT && (register_operand (operands[0], TFmode)
1025     || register_operand (operands[1], TFmode))"
1026   "@
1027    orr\\t%0.16b, %1.16b, %1.16b
1028    #
1029    #
1030    #
1031    movi\\t%0.2d, #0
1032    fmov\\t%s0, wzr
1033    ldr\\t%q0, %1
1034    str\\t%q1, %0
1035    ldp\\t%0, %H0, %1
1036    stp\\t%1, %H1, %0"
1037   [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,fconstd,fconstd,\
1038                      f_loadd,f_stored,neon_load1_2reg,neon_store1_2reg")
1039    (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
1040    (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
1041    (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
1044 (define_split
1045    [(set (match_operand:TF 0 "register_operand" "")
1046          (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
1047   "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
1048   [(const_int 0)]
1049   {
1050     aarch64_split_128bit_move (operands[0], operands[1]);
1051     DONE;
1052   }
1055 ;; 0 is dst
1056 ;; 1 is src
1057 ;; 2 is size of move in bytes
1058 ;; 3 is alignment
1060 (define_expand "movmemdi"
1061   [(match_operand:BLK 0 "memory_operand")
1062    (match_operand:BLK 1 "memory_operand")
1063    (match_operand:DI 2 "immediate_operand")
1064    (match_operand:DI 3 "immediate_operand")]
1065    "!STRICT_ALIGNMENT"
1067   if (aarch64_expand_movmem (operands))
1068     DONE;
1069   FAIL;
1073 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1074 ;; fairly lax checking on the second memory operation.
1075 (define_insn "load_pairsi"
1076   [(set (match_operand:SI 0 "register_operand" "=r,*w")
1077         (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1078    (set (match_operand:SI 2 "register_operand" "=r,*w")
1079         (match_operand:SI 3 "memory_operand" "m,m"))]
1080   "rtx_equal_p (XEXP (operands[3], 0),
1081                 plus_constant (Pmode,
1082                                XEXP (operands[1], 0),
1083                                GET_MODE_SIZE (SImode)))"
1084   "@
1085    ldp\\t%w0, %w2, %1
1086    ldp\\t%s0, %s2, %1"
1087   [(set_attr "type" "load2,neon_load1_2reg")
1088    (set_attr "fp" "*,yes")]
1091 (define_insn "load_pairdi"
1092   [(set (match_operand:DI 0 "register_operand" "=r,*w")
1093         (match_operand:DI 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1094    (set (match_operand:DI 2 "register_operand" "=r,*w")
1095         (match_operand:DI 3 "memory_operand" "m,m"))]
1096   "rtx_equal_p (XEXP (operands[3], 0),
1097                 plus_constant (Pmode,
1098                                XEXP (operands[1], 0),
1099                                GET_MODE_SIZE (DImode)))"
1100   "@
1101    ldp\\t%x0, %x2, %1
1102    ldp\\t%d0, %d2, %1"
1103   [(set_attr "type" "load2,neon_load1_2reg")
1104    (set_attr "fp" "*,yes")]
1108 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1109 ;; fairly lax checking on the second memory operation.
1110 (define_insn "store_pairsi"
1111   [(set (match_operand:SI 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1112         (match_operand:SI 1 "aarch64_reg_or_zero" "rZ,*w"))
1113    (set (match_operand:SI 2 "memory_operand" "=m,m")
1114         (match_operand:SI 3 "aarch64_reg_or_zero" "rZ,*w"))]
1115   "rtx_equal_p (XEXP (operands[2], 0),
1116                 plus_constant (Pmode,
1117                                XEXP (operands[0], 0),
1118                                GET_MODE_SIZE (SImode)))"
1119   "@
1120    stp\\t%w1, %w3, %0
1121    stp\\t%s1, %s3, %0"
1122   [(set_attr "type" "store2,neon_store1_2reg")
1123    (set_attr "fp" "*,yes")]
1126 (define_insn "store_pairdi"
1127   [(set (match_operand:DI 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1128         (match_operand:DI 1 "aarch64_reg_or_zero" "rZ,*w"))
1129    (set (match_operand:DI 2 "memory_operand" "=m,m")
1130         (match_operand:DI 3 "aarch64_reg_or_zero" "rZ,*w"))]
1131   "rtx_equal_p (XEXP (operands[2], 0),
1132                 plus_constant (Pmode,
1133                                XEXP (operands[0], 0),
1134                                GET_MODE_SIZE (DImode)))"
1135   "@
1136    stp\\t%x1, %x3, %0
1137    stp\\t%d1, %d3, %0"
1138   [(set_attr "type" "store2,neon_store1_2reg")
1139    (set_attr "fp" "*,yes")]
1142 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1143 ;; fairly lax checking on the second memory operation.
1144 (define_insn "load_pairsf"
1145   [(set (match_operand:SF 0 "register_operand" "=w,*r")
1146         (match_operand:SF 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1147    (set (match_operand:SF 2 "register_operand" "=w,*r")
1148         (match_operand:SF 3 "memory_operand" "m,m"))]
1149   "rtx_equal_p (XEXP (operands[3], 0),
1150                 plus_constant (Pmode,
1151                                XEXP (operands[1], 0),
1152                                GET_MODE_SIZE (SFmode)))"
1153   "@
1154    ldp\\t%s0, %s2, %1
1155    ldp\\t%w0, %w2, %1"
1156   [(set_attr "type" "neon_load1_2reg,load2")
1157    (set_attr "fp" "yes,*")]
1160 (define_insn "load_pairdf"
1161   [(set (match_operand:DF 0 "register_operand" "=w,*r")
1162         (match_operand:DF 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1163    (set (match_operand:DF 2 "register_operand" "=w,*r")
1164         (match_operand:DF 3 "memory_operand" "m,m"))]
1165   "rtx_equal_p (XEXP (operands[3], 0),
1166                 plus_constant (Pmode,
1167                                XEXP (operands[1], 0),
1168                                GET_MODE_SIZE (DFmode)))"
1169   "@
1170    ldp\\t%d0, %d2, %1
1171    ldp\\t%x0, %x2, %1"
1172   [(set_attr "type" "neon_load1_2reg,load2")
1173    (set_attr "fp" "yes,*")]
1176 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1177 ;; fairly lax checking on the second memory operation.
1178 (define_insn "store_pairsf"
1179   [(set (match_operand:SF 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1180         (match_operand:SF 1 "register_operand" "w,*r"))
1181    (set (match_operand:SF 2 "memory_operand" "=m,m")
1182         (match_operand:SF 3 "register_operand" "w,*r"))]
1183   "rtx_equal_p (XEXP (operands[2], 0),
1184                 plus_constant (Pmode,
1185                                XEXP (operands[0], 0),
1186                                GET_MODE_SIZE (SFmode)))"
1187   "@
1188    stp\\t%s1, %s3, %0
1189    stp\\t%w1, %w3, %0"
1190   [(set_attr "type" "neon_store1_2reg,store2")
1191    (set_attr "fp" "yes,*")]
1194 (define_insn "store_pairdf"
1195   [(set (match_operand:DF 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1196         (match_operand:DF 1 "register_operand" "w,*r"))
1197    (set (match_operand:DF 2 "memory_operand" "=m,m")
1198         (match_operand:DF 3 "register_operand" "w,*r"))]
1199   "rtx_equal_p (XEXP (operands[2], 0),
1200                 plus_constant (Pmode,
1201                                XEXP (operands[0], 0),
1202                                GET_MODE_SIZE (DFmode)))"
1203   "@
1204    stp\\t%d1, %d3, %0
1205    stp\\t%x1, %x3, %0"
1206   [(set_attr "type" "neon_store1_2reg,store2")
1207    (set_attr "fp" "yes,*")]
1210 ;; Load pair with post-index writeback.  This is primarily used in function
1211 ;; epilogues.
1212 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
1213   [(parallel
1214     [(set (match_operand:P 0 "register_operand" "=k")
1215           (plus:P (match_operand:P 1 "register_operand" "0")
1216                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1217      (set (match_operand:GPI 2 "register_operand" "=r")
1218           (mem:GPI (match_dup 1)))
1219      (set (match_operand:GPI 3 "register_operand" "=r")
1220           (mem:GPI (plus:P (match_dup 1)
1221                    (match_operand:P 5 "const_int_operand" "n"))))])]
1222   "INTVAL (operands[5]) == GET_MODE_SIZE (<GPI:MODE>mode)"
1223   "ldp\\t%<w>2, %<w>3, [%1], %4"
1224   [(set_attr "type" "load2")]
1227 (define_insn "loadwb_pair<GPF:mode>_<P:mode>"
1228   [(parallel
1229     [(set (match_operand:P 0 "register_operand" "=k")
1230           (plus:P (match_operand:P 1 "register_operand" "0")
1231                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1232      (set (match_operand:GPF 2 "register_operand" "=w")
1233           (mem:GPF (match_dup 1)))
1234      (set (match_operand:GPF 3 "register_operand" "=w")
1235           (mem:GPF (plus:P (match_dup 1)
1236                    (match_operand:P 5 "const_int_operand" "n"))))])]
1237   "INTVAL (operands[5]) == GET_MODE_SIZE (<GPF:MODE>mode)"
1238   "ldp\\t%<w>2, %<w>3, [%1], %4"
1239   [(set_attr "type" "neon_load1_2reg")]
1242 ;; Store pair with pre-index writeback.  This is primarily used in function
1243 ;; prologues.
1244 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
1245   [(parallel
1246     [(set (match_operand:P 0 "register_operand" "=&k")
1247           (plus:P (match_operand:P 1 "register_operand" "0")
1248                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1249      (set (mem:GPI (plus:P (match_dup 0)
1250                    (match_dup 4)))
1251           (match_operand:GPI 2 "register_operand" "r"))
1252      (set (mem:GPI (plus:P (match_dup 0)
1253                    (match_operand:P 5 "const_int_operand" "n")))
1254           (match_operand:GPI 3 "register_operand" "r"))])]
1255   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1256   "stp\\t%<w>2, %<w>3, [%0, %4]!"
1257   [(set_attr "type" "store2")]
1260 (define_insn "storewb_pair<GPF:mode>_<P:mode>"
1261   [(parallel
1262     [(set (match_operand:P 0 "register_operand" "=&k")
1263           (plus:P (match_operand:P 1 "register_operand" "0")
1264                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1265      (set (mem:GPF (plus:P (match_dup 0)
1266                    (match_dup 4)))
1267           (match_operand:GPF 2 "register_operand" "w"))
1268      (set (mem:GPF (plus:P (match_dup 0)
1269                    (match_operand:P 5 "const_int_operand" "n")))
1270           (match_operand:GPF 3 "register_operand" "w"))])]
1271   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPF:MODE>mode)"
1272   "stp\\t%<w>2, %<w>3, [%0, %4]!"
1273   [(set_attr "type" "neon_store1_2reg<q>")]
1276 ;; -------------------------------------------------------------------
1277 ;; Sign/Zero extension
1278 ;; -------------------------------------------------------------------
1280 (define_expand "<optab>sidi2"
1281   [(set (match_operand:DI 0 "register_operand")
1282         (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1283   ""
1286 (define_insn "*extendsidi2_aarch64"
1287   [(set (match_operand:DI 0 "register_operand" "=r,r")
1288         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1289   ""
1290   "@
1291    sxtw\t%0, %w1
1292    ldrsw\t%0, %1"
1293   [(set_attr "type" "extend,load1")]
1296 (define_insn "*load_pair_extendsidi2_aarch64"
1297   [(set (match_operand:DI 0 "register_operand" "=r")
1298         (sign_extend:DI (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump")))
1299    (set (match_operand:DI 2 "register_operand" "=r")
1300         (sign_extend:DI (match_operand:SI 3 "memory_operand" "m")))]
1301   "rtx_equal_p (XEXP (operands[3], 0),
1302                 plus_constant (Pmode,
1303                                XEXP (operands[1], 0),
1304                                GET_MODE_SIZE (SImode)))"
1305   "ldpsw\\t%0, %2, %1"
1306   [(set_attr "type" "load2")]
1309 (define_insn "*zero_extendsidi2_aarch64"
1310   [(set (match_operand:DI 0 "register_operand" "=r,r")
1311         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1312   ""
1313   "@
1314    uxtw\t%0, %w1
1315    ldr\t%w0, %1"
1316   [(set_attr "type" "extend,load1")]
1319 (define_insn "*load_pair_zero_extendsidi2_aarch64"
1320   [(set (match_operand:DI 0 "register_operand" "=r")
1321         (zero_extend:DI (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump")))
1322    (set (match_operand:DI 2 "register_operand" "=r")
1323         (zero_extend:DI (match_operand:SI 3 "memory_operand" "m")))]
1324   "rtx_equal_p (XEXP (operands[3], 0),
1325                 plus_constant (Pmode,
1326                                XEXP (operands[1], 0),
1327                                GET_MODE_SIZE (SImode)))"
1328   "ldp\\t%w0, %w2, %1"
1329   [(set_attr "type" "load2")]
1332 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1333   [(set (match_operand:GPI 0 "register_operand")
1334         (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1335   ""
1338 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1339   [(set (match_operand:GPI 0 "register_operand" "=r,r")
1340         (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1341   ""
1342   "@
1343    sxt<SHORT:size>\t%<GPI:w>0, %w1
1344    ldrs<SHORT:size>\t%<GPI:w>0, %1"
1345   [(set_attr "type" "extend,load1")]
1348 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1349   [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1350         (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1351   ""
1352   "@
1353    uxt<SHORT:size>\t%<GPI:w>0, %w1
1354    ldr<SHORT:size>\t%w0, %1
1355    ldr\t%<SHORT:size>0, %1"
1356   [(set_attr "type" "extend,load1,load1")]
1359 (define_expand "<optab>qihi2"
1360   [(set (match_operand:HI 0 "register_operand")
1361         (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1362   ""
1365 (define_insn "*<optab>qihi2_aarch64"
1366   [(set (match_operand:HI 0 "register_operand" "=r,r")
1367         (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1368   ""
1369   "@
1370    <su>xtb\t%w0, %w1
1371    <ldrxt>b\t%w0, %1"
1372   [(set_attr "type" "extend,load1")]
1375 ;; -------------------------------------------------------------------
1376 ;; Simple arithmetic
1377 ;; -------------------------------------------------------------------
1379 (define_expand "add<mode>3"
1380   [(set
1381     (match_operand:GPI 0 "register_operand" "")
1382     (plus:GPI (match_operand:GPI 1 "register_operand" "")
1383               (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1384   ""
1385   "
1386   if (! aarch64_plus_operand (operands[2], VOIDmode))
1387     {
1388       rtx subtarget = ((optimize && can_create_pseudo_p ())
1389                        ? gen_reg_rtx (<MODE>mode) : operands[0]);
1390       HOST_WIDE_INT imm = INTVAL (operands[2]);
1392       if (imm < 0)
1393         imm = -(-imm & ~0xfff);
1394       else
1395         imm &= ~0xfff;
1397       emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1398       operands[1] = subtarget;
1399       operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1400     }
1401   "
1404 (define_insn "*addsi3_aarch64"
1405   [(set
1406     (match_operand:SI 0 "register_operand" "=rk,rk,w,rk")
1407     (plus:SI
1408      (match_operand:SI 1 "register_operand" "%rk,rk,w,rk")
1409      (match_operand:SI 2 "aarch64_plus_operand" "I,r,w,J")))]
1410   ""
1411   "@
1412   add\\t%w0, %w1, %2
1413   add\\t%w0, %w1, %w2
1414   add\\t%0.2s, %1.2s, %2.2s
1415   sub\\t%w0, %w1, #%n2"
1416   [(set_attr "type" "alu_imm,alu_sreg,neon_add,alu_imm")
1417    (set_attr "simd" "*,*,yes,*")]
1420 ;; zero_extend version of above
1421 (define_insn "*addsi3_aarch64_uxtw"
1422   [(set
1423     (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1424     (zero_extend:DI
1425      (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1426               (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1427   ""
1428   "@
1429   add\\t%w0, %w1, %2
1430   add\\t%w0, %w1, %w2
1431   sub\\t%w0, %w1, #%n2"
1432   [(set_attr "type" "alu_imm,alu_sreg,alu_imm")]
1435 (define_insn "*adddi3_aarch64"
1436   [(set
1437     (match_operand:DI 0 "register_operand" "=rk,rk,rk,w")
1438     (plus:DI
1439      (match_operand:DI 1 "register_operand" "%rk,rk,rk,w")
1440      (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,w")))]
1441   ""
1442   "@
1443   add\\t%x0, %x1, %2
1444   add\\t%x0, %x1, %x2
1445   sub\\t%x0, %x1, #%n2
1446   add\\t%d0, %d1, %d2"
1447   [(set_attr "type" "alu_imm,alu_sreg,alu_imm,neon_add")
1448    (set_attr "simd" "*,*,*,yes")]
1451 (define_expand "addti3"
1452   [(set (match_operand:TI 0 "register_operand" "")
1453         (plus:TI (match_operand:TI 1 "register_operand" "")
1454                  (match_operand:TI 2 "register_operand" "")))]
1455   ""
1457   rtx low = gen_reg_rtx (DImode);
1458   emit_insn (gen_adddi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1459                                   gen_lowpart (DImode, operands[2])));
1461   rtx high = gen_reg_rtx (DImode);
1462   emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]),
1463                                  gen_highpart (DImode, operands[2])));
1465   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1466   emit_move_insn (gen_highpart (DImode, operands[0]), high);
1467   DONE;
1470 (define_insn "add<mode>3_compare0"
1471   [(set (reg:CC_NZ CC_REGNUM)
1472         (compare:CC_NZ
1473          (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1474                    (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1475          (const_int 0)))
1476    (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1477         (plus:GPI (match_dup 1) (match_dup 2)))]
1478   ""
1479   "@
1480   adds\\t%<w>0, %<w>1, %<w>2
1481   adds\\t%<w>0, %<w>1, %<w>2
1482   subs\\t%<w>0, %<w>1, #%n2"
1483   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1486 ;; zero_extend version of above
1487 (define_insn "*addsi3_compare0_uxtw"
1488   [(set (reg:CC_NZ CC_REGNUM)
1489         (compare:CC_NZ
1490          (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1491                   (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1492          (const_int 0)))
1493    (set (match_operand:DI 0 "register_operand" "=r,r,r")
1494         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1495   ""
1496   "@
1497   adds\\t%w0, %w1, %w2
1498   adds\\t%w0, %w1, %w2
1499   subs\\t%w0, %w1, #%n2"
1500   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1503 (define_insn "*adds_mul_imm_<mode>"
1504   [(set (reg:CC_NZ CC_REGNUM)
1505         (compare:CC_NZ
1506          (plus:GPI (mult:GPI
1507                     (match_operand:GPI 1 "register_operand" "r")
1508                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1509                    (match_operand:GPI 3 "register_operand" "r"))
1510          (const_int 0)))
1511    (set (match_operand:GPI 0 "register_operand" "=r")
1512         (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1513                   (match_dup 3)))]
1514   ""
1515   "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1516   [(set_attr "type" "alus_shift_imm")]
1519 (define_insn "*subs_mul_imm_<mode>"
1520   [(set (reg:CC_NZ CC_REGNUM)
1521         (compare:CC_NZ
1522          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1523                     (mult:GPI
1524                      (match_operand:GPI 2 "register_operand" "r")
1525                      (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1526          (const_int 0)))
1527    (set (match_operand:GPI 0 "register_operand" "=r")
1528         (minus:GPI (match_dup 1)
1529                    (mult:GPI (match_dup 2) (match_dup 3))))]
1530   ""
1531   "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1532   [(set_attr "type" "alus_shift_imm")]
1535 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1536   [(set (reg:CC_NZ CC_REGNUM)
1537         (compare:CC_NZ
1538          (plus:GPI
1539           (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1540           (match_operand:GPI 2 "register_operand" "r"))
1541         (const_int 0)))
1542    (set (match_operand:GPI 0 "register_operand" "=r")
1543         (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1544   ""
1545   "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1546   [(set_attr "type" "alus_ext")]
1549 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1550   [(set (reg:CC_NZ CC_REGNUM)
1551         (compare:CC_NZ
1552          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1553                     (ANY_EXTEND:GPI
1554                      (match_operand:ALLX 2 "register_operand" "r")))
1555         (const_int 0)))
1556    (set (match_operand:GPI 0 "register_operand" "=r")
1557         (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1558   ""
1559   "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1560   [(set_attr "type" "alus_ext")]
1563 (define_insn "*adds_<optab><mode>_multp2"
1564   [(set (reg:CC_NZ CC_REGNUM)
1565         (compare:CC_NZ
1566          (plus:GPI (ANY_EXTRACT:GPI
1567                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1568                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1569                     (match_operand 3 "const_int_operand" "n")
1570                     (const_int 0))
1571                    (match_operand:GPI 4 "register_operand" "r"))
1572         (const_int 0)))
1573    (set (match_operand:GPI 0 "register_operand" "=r")
1574         (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1575                                    (match_dup 3)
1576                                    (const_int 0))
1577                   (match_dup 4)))]
1578   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1579   "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1580   [(set_attr "type" "alus_ext")]
1583 (define_insn "*subs_<optab><mode>_multp2"
1584   [(set (reg:CC_NZ CC_REGNUM)
1585         (compare:CC_NZ
1586          (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1587                     (ANY_EXTRACT:GPI
1588                      (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1589                                (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1590                      (match_operand 3 "const_int_operand" "n")
1591                      (const_int 0)))
1592         (const_int 0)))
1593    (set (match_operand:GPI 0 "register_operand" "=r")
1594         (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1595                                   (mult:GPI (match_dup 1) (match_dup 2))
1596                                   (match_dup 3)
1597                                   (const_int 0))))]
1598   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1599   "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1600   [(set_attr "type" "alus_ext")]
1603 (define_insn "*add<mode>3nr_compare0"
1604   [(set (reg:CC_NZ CC_REGNUM)
1605         (compare:CC_NZ
1606          (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1607                    (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1608          (const_int 0)))]
1609   ""
1610   "@
1611   cmn\\t%<w>0, %<w>1
1612   cmn\\t%<w>0, %<w>1
1613   cmp\\t%<w>0, #%n1"
1614   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1617 (define_insn "*compare_neg<mode>"
1618   [(set (reg:CC_Z CC_REGNUM)
1619         (compare:CC_Z
1620          (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1621          (match_operand:GPI 1 "register_operand" "r")))]
1622   ""
1623   "cmn\\t%<w>1, %<w>0"
1624   [(set_attr "type" "alus_sreg")]
1627 (define_insn "*add_<shift>_<mode>"
1628   [(set (match_operand:GPI 0 "register_operand" "=r")
1629         (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1630                               (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1631                   (match_operand:GPI 3 "register_operand" "r")))]
1632   ""
1633   "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1634   [(set_attr "type" "alu_shift_imm")]
1637 ;; zero_extend version of above
1638 (define_insn "*add_<shift>_si_uxtw"
1639   [(set (match_operand:DI 0 "register_operand" "=r")
1640         (zero_extend:DI
1641          (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1642                              (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1643                   (match_operand:SI 3 "register_operand" "r"))))]
1644   ""
1645   "add\\t%w0, %w3, %w1, <shift> %2"
1646   [(set_attr "type" "alu_shift_imm")]
1649 (define_insn "*add_mul_imm_<mode>"
1650   [(set (match_operand:GPI 0 "register_operand" "=r")
1651         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1652                             (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1653                   (match_operand:GPI 3 "register_operand" "r")))]
1654   ""
1655   "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1656   [(set_attr "type" "alu_shift_imm")]
1659 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1660   [(set (match_operand:GPI 0 "register_operand" "=rk")
1661         (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1662                   (match_operand:GPI 2 "register_operand" "r")))]
1663   ""
1664   "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1665   [(set_attr "type" "alu_ext")]
1668 ;; zero_extend version of above
1669 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1670   [(set (match_operand:DI 0 "register_operand" "=rk")
1671         (zero_extend:DI
1672          (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1673                   (match_operand:GPI 2 "register_operand" "r"))))]
1674   ""
1675   "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1676   [(set_attr "type" "alu_ext")]
1679 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1680   [(set (match_operand:GPI 0 "register_operand" "=rk")
1681         (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1682                                (match_operand:ALLX 1 "register_operand" "r"))
1683                               (match_operand 2 "aarch64_imm3" "Ui3"))
1684                   (match_operand:GPI 3 "register_operand" "r")))]
1685   ""
1686   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1687   [(set_attr "type" "alu_ext")]
1690 ;; zero_extend version of above
1691 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1692   [(set (match_operand:DI 0 "register_operand" "=rk")
1693         (zero_extend:DI
1694          (plus:SI (ashift:SI (ANY_EXTEND:SI
1695                               (match_operand:SHORT 1 "register_operand" "r"))
1696                              (match_operand 2 "aarch64_imm3" "Ui3"))
1697                   (match_operand:SI 3 "register_operand" "r"))))]
1698   ""
1699   "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1700   [(set_attr "type" "alu_ext")]
1703 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1704   [(set (match_operand:GPI 0 "register_operand" "=rk")
1705         (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1706                              (match_operand:ALLX 1 "register_operand" "r"))
1707                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1708                   (match_operand:GPI 3 "register_operand" "r")))]
1709   ""
1710   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1711   [(set_attr "type" "alu_ext")]
1714 ;; zero_extend version of above
1715 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1716   [(set (match_operand:DI 0 "register_operand" "=rk")
1717         (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1718                              (match_operand:SHORT 1 "register_operand" "r"))
1719                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1720                   (match_operand:SI 3 "register_operand" "r"))))]
1721   ""
1722   "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1723   [(set_attr "type" "alu_ext")]
1726 (define_insn "*add_<optab><mode>_multp2"
1727   [(set (match_operand:GPI 0 "register_operand" "=rk")
1728         (plus:GPI (ANY_EXTRACT:GPI
1729                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1730                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1731                    (match_operand 3 "const_int_operand" "n")
1732                    (const_int 0))
1733                   (match_operand:GPI 4 "register_operand" "r")))]
1734   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1735   "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1736   [(set_attr "type" "alu_ext")]
1739 ;; zero_extend version of above
1740 (define_insn "*add_<optab>si_multp2_uxtw"
1741   [(set (match_operand:DI 0 "register_operand" "=rk")
1742         (zero_extend:DI
1743          (plus:SI (ANY_EXTRACT:SI
1744                    (mult:SI (match_operand:SI 1 "register_operand" "r")
1745                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1746                    (match_operand 3 "const_int_operand" "n")
1747                    (const_int 0))
1748                   (match_operand:SI 4 "register_operand" "r"))))]
1749   "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1750   "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1751   [(set_attr "type" "alu_ext")]
1754 (define_insn "add<mode>3_carryin"
1755   [(set
1756     (match_operand:GPI 0 "register_operand" "=r")
1757     (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1758               (plus:GPI
1759                 (match_operand:GPI 1 "register_operand" "r")
1760                 (match_operand:GPI 2 "register_operand" "r"))))]
1761    ""
1762    "adc\\t%<w>0, %<w>1, %<w>2"
1763   [(set_attr "type" "adc_reg")]
1766 ;; zero_extend version of above
1767 (define_insn "*addsi3_carryin_uxtw"
1768   [(set
1769     (match_operand:DI 0 "register_operand" "=r")
1770     (zero_extend:DI
1771      (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1772               (plus:SI
1773                (match_operand:SI 1 "register_operand" "r")
1774                (match_operand:SI 2 "register_operand" "r")))))]
1775    ""
1776    "adc\\t%w0, %w1, %w2"
1777   [(set_attr "type" "adc_reg")]
1780 (define_insn "*add<mode>3_carryin_alt1"
1781   [(set
1782     (match_operand:GPI 0 "register_operand" "=r")
1783     (plus:GPI (plus:GPI
1784                 (match_operand:GPI 1 "register_operand" "r")
1785                 (match_operand:GPI 2 "register_operand" "r"))
1786               (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1787    ""
1788    "adc\\t%<w>0, %<w>1, %<w>2"
1789   [(set_attr "type" "adc_reg")]
1792 ;; zero_extend version of above
1793 (define_insn "*addsi3_carryin_alt1_uxtw"
1794   [(set
1795     (match_operand:DI 0 "register_operand" "=r")
1796     (zero_extend:DI
1797      (plus:SI (plus:SI
1798                (match_operand:SI 1 "register_operand" "r")
1799                (match_operand:SI 2 "register_operand" "r"))
1800               (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1801    ""
1802    "adc\\t%w0, %w1, %w2"
1803   [(set_attr "type" "adc_reg")]
1806 (define_insn "*add<mode>3_carryin_alt2"
1807   [(set
1808     (match_operand:GPI 0 "register_operand" "=r")
1809     (plus:GPI (plus:GPI
1810                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1811                 (match_operand:GPI 1 "register_operand" "r"))
1812               (match_operand:GPI 2 "register_operand" "r")))]
1813    ""
1814    "adc\\t%<w>0, %<w>1, %<w>2"
1815   [(set_attr "type" "adc_reg")]
1818 ;; zero_extend version of above
1819 (define_insn "*addsi3_carryin_alt2_uxtw"
1820   [(set
1821     (match_operand:DI 0 "register_operand" "=r")
1822     (zero_extend:DI
1823      (plus:SI (plus:SI
1824                (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1825                (match_operand:SI 1 "register_operand" "r"))
1826               (match_operand:SI 2 "register_operand" "r"))))]
1827    ""
1828    "adc\\t%w0, %w1, %w2"
1829   [(set_attr "type" "adc_reg")]
1832 (define_insn "*add<mode>3_carryin_alt3"
1833   [(set
1834     (match_operand:GPI 0 "register_operand" "=r")
1835     (plus:GPI (plus:GPI
1836                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1837                 (match_operand:GPI 2 "register_operand" "r"))
1838               (match_operand:GPI 1 "register_operand" "r")))]
1839    ""
1840    "adc\\t%<w>0, %<w>1, %<w>2"
1841   [(set_attr "type" "adc_reg")]
1844 ;; zero_extend version of above
1845 (define_insn "*addsi3_carryin_alt3_uxtw"
1846   [(set
1847     (match_operand:DI 0 "register_operand" "=r")
1848     (zero_extend:DI
1849      (plus:SI (plus:SI
1850                (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1851                (match_operand:SI 2 "register_operand" "r"))
1852               (match_operand:SI 1 "register_operand" "r"))))]
1853    ""
1854    "adc\\t%w0, %w1, %w2"
1855   [(set_attr "type" "adc_reg")]
1858 (define_insn "*add_uxt<mode>_multp2"
1859   [(set (match_operand:GPI 0 "register_operand" "=rk")
1860         (plus:GPI (and:GPI
1861                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1862                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1863                    (match_operand 3 "const_int_operand" "n"))
1864                   (match_operand:GPI 4 "register_operand" "r")))]
1865   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1866   "*
1867   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1868                                            INTVAL (operands[3])));
1869   return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1870   [(set_attr "type" "alu_ext")]
1873 ;; zero_extend version of above
1874 (define_insn "*add_uxtsi_multp2_uxtw"
1875   [(set (match_operand:DI 0 "register_operand" "=rk")
1876         (zero_extend:DI
1877          (plus:SI (and:SI
1878                    (mult:SI (match_operand:SI 1 "register_operand" "r")
1879                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1880                    (match_operand 3 "const_int_operand" "n"))
1881                   (match_operand:SI 4 "register_operand" "r"))))]
1882   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1883   "*
1884   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1885                                            INTVAL (operands[3])));
1886   return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1887   [(set_attr "type" "alu_ext")]
1890 (define_insn "subsi3"
1891   [(set (match_operand:SI 0 "register_operand" "=rk")
1892         (minus:SI (match_operand:SI 1 "register_operand" "r")
1893                    (match_operand:SI 2 "register_operand" "r")))]
1894   ""
1895   "sub\\t%w0, %w1, %w2"
1896   [(set_attr "type" "alu_sreg")]
1899 ;; zero_extend version of above
1900 (define_insn "*subsi3_uxtw"
1901   [(set (match_operand:DI 0 "register_operand" "=rk")
1902         (zero_extend:DI
1903          (minus:SI (match_operand:SI 1 "register_operand" "r")
1904                    (match_operand:SI 2 "register_operand" "r"))))]
1905   ""
1906   "sub\\t%w0, %w1, %w2"
1907   [(set_attr "type" "alu_sreg")]
1910 (define_insn "subdi3"
1911   [(set (match_operand:DI 0 "register_operand" "=rk,w")
1912         (minus:DI (match_operand:DI 1 "register_operand" "r,w")
1913                    (match_operand:DI 2 "register_operand" "r,w")))]
1914   ""
1915   "@
1916    sub\\t%x0, %x1, %x2
1917    sub\\t%d0, %d1, %d2"
1918   [(set_attr "type" "alu_sreg, neon_sub")
1919    (set_attr "simd" "*,yes")]
1922 (define_expand "subti3"
1923   [(set (match_operand:TI 0 "register_operand" "")
1924         (minus:TI (match_operand:TI 1 "register_operand" "")
1925                   (match_operand:TI 2 "register_operand" "")))]
1926   ""
1928   rtx low = gen_reg_rtx (DImode);
1929   emit_insn (gen_subdi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1930                                   gen_lowpart (DImode, operands[2])));
1932   rtx high = gen_reg_rtx (DImode);
1933   emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]),
1934                                  gen_highpart (DImode, operands[2])));
1936   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1937   emit_move_insn (gen_highpart (DImode, operands[0]), high);
1938   DONE;
1941 (define_insn "sub<mode>3_compare0"
1942   [(set (reg:CC_NZ CC_REGNUM)
1943         (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1944                                   (match_operand:GPI 2 "register_operand" "r"))
1945                        (const_int 0)))
1946    (set (match_operand:GPI 0 "register_operand" "=r")
1947         (minus:GPI (match_dup 1) (match_dup 2)))]
1948   ""
1949   "subs\\t%<w>0, %<w>1, %<w>2"
1950   [(set_attr "type" "alus_sreg")]
1953 ;; zero_extend version of above
1954 (define_insn "*subsi3_compare0_uxtw"
1955   [(set (reg:CC_NZ CC_REGNUM)
1956         (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1957                                  (match_operand:SI 2 "register_operand" "r"))
1958                        (const_int 0)))
1959    (set (match_operand:DI 0 "register_operand" "=r")
1960         (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1961   ""
1962   "subs\\t%w0, %w1, %w2"
1963   [(set_attr "type" "alus_sreg")]
1966 (define_insn "*sub_<shift>_<mode>"
1967   [(set (match_operand:GPI 0 "register_operand" "=r")
1968         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1969                    (ASHIFT:GPI
1970                     (match_operand:GPI 1 "register_operand" "r")
1971                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1972   ""
1973   "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1974   [(set_attr "type" "alu_shift_imm")]
1977 ;; zero_extend version of above
1978 (define_insn "*sub_<shift>_si_uxtw"
1979   [(set (match_operand:DI 0 "register_operand" "=r")
1980         (zero_extend:DI
1981          (minus:SI (match_operand:SI 3 "register_operand" "r")
1982                    (ASHIFT:SI
1983                     (match_operand:SI 1 "register_operand" "r")
1984                     (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1985   ""
1986   "sub\\t%w0, %w3, %w1, <shift> %2"
1987   [(set_attr "type" "alu_shift_imm")]
1990 (define_insn "*sub_mul_imm_<mode>"
1991   [(set (match_operand:GPI 0 "register_operand" "=r")
1992         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1993                    (mult:GPI
1994                     (match_operand:GPI 1 "register_operand" "r")
1995                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1996   ""
1997   "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1998   [(set_attr "type" "alu_shift_imm")]
2001 ;; zero_extend version of above
2002 (define_insn "*sub_mul_imm_si_uxtw"
2003   [(set (match_operand:DI 0 "register_operand" "=r")
2004         (zero_extend:DI
2005          (minus:SI (match_operand:SI 3 "register_operand" "r")
2006                    (mult:SI
2007                     (match_operand:SI 1 "register_operand" "r")
2008                     (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2009   ""
2010   "sub\\t%w0, %w3, %w1, lsl %p2"
2011   [(set_attr "type" "alu_shift_imm")]
2014 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
2015   [(set (match_operand:GPI 0 "register_operand" "=rk")
2016         (minus:GPI (match_operand:GPI 1 "register_operand" "r")
2017                    (ANY_EXTEND:GPI
2018                     (match_operand:ALLX 2 "register_operand" "r"))))]
2019   ""
2020   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
2021   [(set_attr "type" "alu_ext")]
2024 ;; zero_extend version of above
2025 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
2026   [(set (match_operand:DI 0 "register_operand" "=rk")
2027         (zero_extend:DI
2028          (minus:SI (match_operand:SI 1 "register_operand" "r")
2029                    (ANY_EXTEND:SI
2030                     (match_operand:SHORT 2 "register_operand" "r")))))]
2031   ""
2032   "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
2033   [(set_attr "type" "alu_ext")]
2036 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
2037   [(set (match_operand:GPI 0 "register_operand" "=rk")
2038         (minus:GPI (match_operand:GPI 1 "register_operand" "r")
2039                    (ashift:GPI (ANY_EXTEND:GPI
2040                                 (match_operand:ALLX 2 "register_operand" "r"))
2041                                (match_operand 3 "aarch64_imm3" "Ui3"))))]
2042   ""
2043   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
2044   [(set_attr "type" "alu_ext")]
2047 ;; zero_extend version of above
2048 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
2049   [(set (match_operand:DI 0 "register_operand" "=rk")
2050         (zero_extend:DI
2051          (minus:SI (match_operand:SI 1 "register_operand" "r")
2052                    (ashift:SI (ANY_EXTEND:SI
2053                                (match_operand:SHORT 2 "register_operand" "r"))
2054                               (match_operand 3 "aarch64_imm3" "Ui3")))))]
2055   ""
2056   "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
2057   [(set_attr "type" "alu_ext")]
2060 (define_insn "*sub_<optab><mode>_multp2"
2061   [(set (match_operand:GPI 0 "register_operand" "=rk")
2062         (minus:GPI (match_operand:GPI 4 "register_operand" "r")
2063                    (ANY_EXTRACT:GPI
2064                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2065                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2066                     (match_operand 3 "const_int_operand" "n")
2067                     (const_int 0))))]
2068   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
2069   "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
2070   [(set_attr "type" "alu_ext")]
2073 ;; zero_extend version of above
2074 (define_insn "*sub_<optab>si_multp2_uxtw"
2075   [(set (match_operand:DI 0 "register_operand" "=rk")
2076         (zero_extend:DI
2077          (minus:SI (match_operand:SI 4 "register_operand" "r")
2078                    (ANY_EXTRACT:SI
2079                     (mult:SI (match_operand:SI 1 "register_operand" "r")
2080                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2081                     (match_operand 3 "const_int_operand" "n")
2082                     (const_int 0)))))]
2083   "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
2084   "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
2085   [(set_attr "type" "alu_ext")]
2088 (define_insn "sub<mode>3_carryin"
2089   [(set
2090     (match_operand:GPI 0 "register_operand" "=r")
2091     (minus:GPI (minus:GPI
2092                 (match_operand:GPI 1 "register_operand" "r")
2093                 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2094                (match_operand:GPI 2 "register_operand" "r")))]
2095    ""
2096    "sbc\\t%<w>0, %<w>1, %<w>2"
2097   [(set_attr "type" "adc_reg")]
2100 ;; zero_extend version of the above
2101 (define_insn "*subsi3_carryin_uxtw"
2102   [(set
2103     (match_operand:DI 0 "register_operand" "=r")
2104     (zero_extend:DI
2105      (minus:SI (minus:SI
2106                 (match_operand:SI 1 "register_operand" "r")
2107                 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2108                (match_operand:SI 2 "register_operand" "r"))))]
2109    ""
2110    "sbc\\t%w0, %w1, %w2"
2111   [(set_attr "type" "adc_reg")]
2114 (define_insn "*sub_uxt<mode>_multp2"
2115   [(set (match_operand:GPI 0 "register_operand" "=rk")
2116         (minus:GPI (match_operand:GPI 4 "register_operand" "r")
2117                    (and:GPI
2118                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2119                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2120                     (match_operand 3 "const_int_operand" "n"))))]
2121   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2122   "*
2123   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2124                                            INTVAL (operands[3])));
2125   return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
2126   [(set_attr "type" "alu_ext")]
2129 ;; zero_extend version of above
2130 (define_insn "*sub_uxtsi_multp2_uxtw"
2131   [(set (match_operand:DI 0 "register_operand" "=rk")
2132         (zero_extend:DI
2133          (minus:SI (match_operand:SI 4 "register_operand" "r")
2134                    (and:SI
2135                     (mult:SI (match_operand:SI 1 "register_operand" "r")
2136                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2137                     (match_operand 3 "const_int_operand" "n")))))]
2138   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2139   "*
2140   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2141                                            INTVAL (operands[3])));
2142   return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
2143   [(set_attr "type" "alu_ext")]
2146 (define_insn_and_split "absdi2"
2147   [(set (match_operand:DI 0 "register_operand" "=&r,w")
2148         (abs:DI (match_operand:DI 1 "register_operand" "r,w")))]
2149   ""
2150   "@
2151    #
2152    abs\\t%d0, %d1"
2153   "reload_completed
2154    && GP_REGNUM_P (REGNO (operands[0]))
2155    && GP_REGNUM_P (REGNO (operands[1]))"
2156   [(const_int 0)]
2157   {
2158     emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2159                             gen_rtx_XOR (DImode,
2160                                          gen_rtx_ASHIFTRT (DImode,
2161                                                            operands[1],
2162                                                            GEN_INT (63)),
2163                                          operands[1])));
2164     emit_insn (gen_rtx_SET (VOIDmode,
2165                             operands[0],
2166                             gen_rtx_MINUS (DImode,
2167                                            operands[0],
2168                                            gen_rtx_ASHIFTRT (DImode,
2169                                                              operands[1],
2170                                                              GEN_INT (63)))));
2171     DONE;
2172   }
2173   [(set_attr "type" "alu_sreg")
2174    (set_attr "simd" "no,yes")]
2177 (define_insn "neg<mode>2"
2178   [(set (match_operand:GPI 0 "register_operand" "=r,w")
2179         (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
2180   ""
2181   "@
2182    neg\\t%<w>0, %<w>1
2183    neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
2184   [(set_attr "type" "alu_sreg, neon_neg<q>")
2185    (set_attr "simd" "*,yes")]
2188 ;; zero_extend version of above
2189 (define_insn "*negsi2_uxtw"
2190   [(set (match_operand:DI 0 "register_operand" "=r")
2191         (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
2192   ""
2193   "neg\\t%w0, %w1"
2194   [(set_attr "type" "alu_sreg")]
2197 (define_insn "*ngc<mode>"
2198   [(set (match_operand:GPI 0 "register_operand" "=r")
2199         (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2200                    (match_operand:GPI 1 "register_operand" "r")))]
2201   ""
2202   "ngc\\t%<w>0, %<w>1"
2203   [(set_attr "type" "adc_reg")]
2206 (define_insn "*ngcsi_uxtw"
2207   [(set (match_operand:DI 0 "register_operand" "=r")
2208         (zero_extend:DI
2209          (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2210                    (match_operand:SI 1 "register_operand" "r"))))]
2211   ""
2212   "ngc\\t%w0, %w1"
2213   [(set_attr "type" "adc_reg")]
2216 (define_insn "*neg<mode>2_compare0"
2217   [(set (reg:CC_NZ CC_REGNUM)
2218         (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2219                        (const_int 0)))
2220    (set (match_operand:GPI 0 "register_operand" "=r")
2221         (neg:GPI (match_dup 1)))]
2222   ""
2223   "negs\\t%<w>0, %<w>1"
2224   [(set_attr "type" "alus_sreg")]
2227 ;; zero_extend version of above
2228 (define_insn "*negsi2_compare0_uxtw"
2229   [(set (reg:CC_NZ CC_REGNUM)
2230         (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
2231                        (const_int 0)))
2232    (set (match_operand:DI 0 "register_operand" "=r")
2233         (zero_extend:DI (neg:SI (match_dup 1))))]
2234   ""
2235   "negs\\t%w0, %w1"
2236   [(set_attr "type" "alus_sreg")]
2239 (define_insn "*neg_<shift><mode>3_compare0"
2240   [(set (reg:CC_NZ CC_REGNUM)
2241         (compare:CC_NZ
2242          (neg:GPI (ASHIFT:GPI
2243                    (match_operand:GPI 1 "register_operand" "r")
2244                    (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2245          (const_int 0)))
2246    (set (match_operand:GPI 0 "register_operand" "=r")
2247         (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2248   ""
2249   "negs\\t%<w>0, %<w>1, <shift> %2"
2250   [(set_attr "type" "alus_shift_imm")]
2253 (define_insn "*neg_<shift>_<mode>2"
2254   [(set (match_operand:GPI 0 "register_operand" "=r")
2255         (neg:GPI (ASHIFT:GPI
2256                   (match_operand:GPI 1 "register_operand" "r")
2257                   (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2258   ""
2259   "neg\\t%<w>0, %<w>1, <shift> %2"
2260   [(set_attr "type" "alu_shift_imm")]
2263 ;; zero_extend version of above
2264 (define_insn "*neg_<shift>_si2_uxtw"
2265   [(set (match_operand:DI 0 "register_operand" "=r")
2266         (zero_extend:DI
2267          (neg:SI (ASHIFT:SI
2268                   (match_operand:SI 1 "register_operand" "r")
2269                   (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2270   ""
2271   "neg\\t%w0, %w1, <shift> %2"
2272   [(set_attr "type" "alu_shift_imm")]
2275 (define_insn "*neg_mul_imm_<mode>2"
2276   [(set (match_operand:GPI 0 "register_operand" "=r")
2277         (neg:GPI (mult:GPI
2278                   (match_operand:GPI 1 "register_operand" "r")
2279                   (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2280   ""
2281   "neg\\t%<w>0, %<w>1, lsl %p2"
2282   [(set_attr "type" "alu_shift_imm")]
2285 ;; zero_extend version of above
2286 (define_insn "*neg_mul_imm_si2_uxtw"
2287   [(set (match_operand:DI 0 "register_operand" "=r")
2288         (zero_extend:DI
2289          (neg:SI (mult:SI
2290                   (match_operand:SI 1 "register_operand" "r")
2291                   (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2292   ""
2293   "neg\\t%w0, %w1, lsl %p2"
2294   [(set_attr "type" "alu_shift_imm")]
2297 (define_insn "mul<mode>3"
2298   [(set (match_operand:GPI 0 "register_operand" "=r")
2299         (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2300                   (match_operand:GPI 2 "register_operand" "r")))]
2301   ""
2302   "mul\\t%<w>0, %<w>1, %<w>2"
2303   [(set_attr "type" "mul")]
2306 ;; zero_extend version of above
2307 (define_insn "*mulsi3_uxtw"
2308   [(set (match_operand:DI 0 "register_operand" "=r")
2309         (zero_extend:DI
2310          (mult:SI (match_operand:SI 1 "register_operand" "r")
2311                   (match_operand:SI 2 "register_operand" "r"))))]
2312   ""
2313   "mul\\t%w0, %w1, %w2"
2314   [(set_attr "type" "mul")]
2317 (define_insn "madd<mode>"
2318   [(set (match_operand:GPI 0 "register_operand" "=r")
2319         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2320                             (match_operand:GPI 2 "register_operand" "r"))
2321                   (match_operand:GPI 3 "register_operand" "r")))]
2322   ""
2323   "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2324   [(set_attr "type" "mla")]
2327 ;; zero_extend version of above
2328 (define_insn "*maddsi_uxtw"
2329   [(set (match_operand:DI 0 "register_operand" "=r")
2330         (zero_extend:DI
2331          (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2332                            (match_operand:SI 2 "register_operand" "r"))
2333                   (match_operand:SI 3 "register_operand" "r"))))]
2334   ""
2335   "madd\\t%w0, %w1, %w2, %w3"
2336   [(set_attr "type" "mla")]
2339 (define_insn "*msub<mode>"
2340   [(set (match_operand:GPI 0 "register_operand" "=r")
2341         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2342                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2343                              (match_operand:GPI 2 "register_operand" "r"))))]
2345   ""
2346   "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2347   [(set_attr "type" "mla")]
2350 ;; zero_extend version of above
2351 (define_insn "*msubsi_uxtw"
2352   [(set (match_operand:DI 0 "register_operand" "=r")
2353         (zero_extend:DI
2354          (minus:SI (match_operand:SI 3 "register_operand" "r")
2355                    (mult:SI (match_operand:SI 1 "register_operand" "r")
2356                             (match_operand:SI 2 "register_operand" "r")))))]
2358   ""
2359   "msub\\t%w0, %w1, %w2, %w3"
2360   [(set_attr "type" "mla")]
2363 (define_insn "*mul<mode>_neg"
2364   [(set (match_operand:GPI 0 "register_operand" "=r")
2365         (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2366                   (match_operand:GPI 2 "register_operand" "r")))]
2368   ""
2369   "mneg\\t%<w>0, %<w>1, %<w>2"
2370   [(set_attr "type" "mul")]
2373 ;; zero_extend version of above
2374 (define_insn "*mulsi_neg_uxtw"
2375   [(set (match_operand:DI 0 "register_operand" "=r")
2376         (zero_extend:DI
2377          (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2378                   (match_operand:SI 2 "register_operand" "r"))))]
2380   ""
2381   "mneg\\t%w0, %w1, %w2"
2382   [(set_attr "type" "mul")]
2385 (define_insn "<su_optab>mulsidi3"
2386   [(set (match_operand:DI 0 "register_operand" "=r")
2387         (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2388                  (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2389   ""
2390   "<su>mull\\t%0, %w1, %w2"
2391   [(set_attr "type" "<su>mull")]
2394 (define_insn "<su_optab>maddsidi4"
2395   [(set (match_operand:DI 0 "register_operand" "=r")
2396         (plus:DI (mult:DI
2397                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2398                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2399                  (match_operand:DI 3 "register_operand" "r")))]
2400   ""
2401   "<su>maddl\\t%0, %w1, %w2, %3"
2402   [(set_attr "type" "<su>mlal")]
2405 (define_insn "<su_optab>msubsidi4"
2406   [(set (match_operand:DI 0 "register_operand" "=r")
2407         (minus:DI
2408          (match_operand:DI 3 "register_operand" "r")
2409          (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2410                   (ANY_EXTEND:DI
2411                    (match_operand:SI 2 "register_operand" "r")))))]
2412   ""
2413   "<su>msubl\\t%0, %w1, %w2, %3"
2414   [(set_attr "type" "<su>mlal")]
2417 (define_insn "*<su_optab>mulsidi_neg"
2418   [(set (match_operand:DI 0 "register_operand" "=r")
2419         (mult:DI (neg:DI
2420                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2421                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2422   ""
2423   "<su>mnegl\\t%0, %w1, %w2"
2424   [(set_attr "type" "<su>mull")]
2427 (define_expand "<su_optab>mulditi3"
2428   [(set (match_operand:TI 0 "register_operand")
2429         (mult:TI (ANY_EXTEND:TI (match_operand:DI 1 "register_operand"))
2430                  (ANY_EXTEND:TI (match_operand:DI 2 "register_operand"))))]
2431   ""
2433   rtx low = gen_reg_rtx (DImode);
2434   emit_insn (gen_muldi3 (low, operands[1], operands[2]));
2436   rtx high = gen_reg_rtx (DImode);
2437   emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2]));
2439   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2440   emit_move_insn (gen_highpart (DImode, operands[0]), high);
2441   DONE;
2444 ;; The default expansion of multi3 using umuldi3_highpart will perform
2445 ;; the additions in an order that fails to combine into two madd insns.
2446 (define_expand "multi3"
2447   [(set (match_operand:TI 0 "register_operand")
2448         (mult:TI (match_operand:TI 1 "register_operand")
2449                  (match_operand:TI 2 "register_operand")))]
2450   ""
2452   rtx l0 = gen_reg_rtx (DImode);
2453   rtx l1 = gen_lowpart (DImode, operands[1]);
2454   rtx l2 = gen_lowpart (DImode, operands[2]);
2455   rtx h0 = gen_reg_rtx (DImode);
2456   rtx h1 = gen_highpart (DImode, operands[1]);
2457   rtx h2 = gen_highpart (DImode, operands[2]);
2459   emit_insn (gen_muldi3 (l0, l1, l2));
2460   emit_insn (gen_umuldi3_highpart (h0, l1, l2));
2461   emit_insn (gen_madddi (h0, h1, l2, h0));
2462   emit_insn (gen_madddi (h0, l1, h2, h0));
2464   emit_move_insn (gen_lowpart (DImode, operands[0]), l0);
2465   emit_move_insn (gen_highpart (DImode, operands[0]), h0);
2466   DONE;
2469 (define_insn "<su>muldi3_highpart"
2470   [(set (match_operand:DI 0 "register_operand" "=r")
2471         (truncate:DI
2472          (lshiftrt:TI
2473           (mult:TI
2474            (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2475            (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2476           (const_int 64))))]
2477   ""
2478   "<su>mulh\\t%0, %1, %2"
2479   [(set_attr "type" "<su>mull")]
2482 (define_insn "<su_optab>div<mode>3"
2483   [(set (match_operand:GPI 0 "register_operand" "=r")
2484         (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2485                      (match_operand:GPI 2 "register_operand" "r")))]
2486   ""
2487   "<su>div\\t%<w>0, %<w>1, %<w>2"
2488   [(set_attr "type" "<su>div")]
2491 ;; zero_extend version of above
2492 (define_insn "*<su_optab>divsi3_uxtw"
2493   [(set (match_operand:DI 0 "register_operand" "=r")
2494         (zero_extend:DI
2495          (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2496                      (match_operand:SI 2 "register_operand" "r"))))]
2497   ""
2498   "<su>div\\t%w0, %w1, %w2"
2499   [(set_attr "type" "<su>div")]
2502 ;; -------------------------------------------------------------------
2503 ;; Comparison insns
2504 ;; -------------------------------------------------------------------
2506 (define_insn "*cmp<mode>"
2507   [(set (reg:CC CC_REGNUM)
2508         (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2509                     (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2510   ""
2511   "@
2512    cmp\\t%<w>0, %<w>1
2513    cmp\\t%<w>0, %<w>1
2514    cmn\\t%<w>0, #%n1"
2515   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
2518 (define_insn "*cmp<mode>"
2519   [(set (reg:CCFP CC_REGNUM)
2520         (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2521                       (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2522    "TARGET_FLOAT"
2523    "@
2524     fcmp\\t%<s>0, #0.0
2525     fcmp\\t%<s>0, %<s>1"
2526   [(set_attr "type" "fcmp<s>")]
2529 (define_insn "*cmpe<mode>"
2530   [(set (reg:CCFPE CC_REGNUM)
2531         (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2532                        (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2533    "TARGET_FLOAT"
2534    "@
2535     fcmpe\\t%<s>0, #0.0
2536     fcmpe\\t%<s>0, %<s>1"
2537   [(set_attr "type" "fcmp<s>")]
2540 (define_insn "*cmp_swp_<shift>_reg<mode>"
2541   [(set (reg:CC_SWP CC_REGNUM)
2542         (compare:CC_SWP (ASHIFT:GPI
2543                          (match_operand:GPI 0 "register_operand" "r")
2544                          (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2545                         (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2546   ""
2547   "cmp\\t%<w>2, %<w>0, <shift> %1"
2548   [(set_attr "type" "alus_shift_imm")]
2551 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2552   [(set (reg:CC_SWP CC_REGNUM)
2553         (compare:CC_SWP (ANY_EXTEND:GPI
2554                          (match_operand:ALLX 0 "register_operand" "r"))
2555                         (match_operand:GPI 1 "register_operand" "r")))]
2556   ""
2557   "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2558   [(set_attr "type" "alus_ext")]
2561 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2562   [(set (reg:CC_SWP CC_REGNUM)
2563         (compare:CC_SWP (ashift:GPI
2564                          (ANY_EXTEND:GPI
2565                           (match_operand:ALLX 0 "register_operand" "r"))
2566                          (match_operand 1 "aarch64_imm3" "Ui3"))
2567         (match_operand:GPI 2 "register_operand" "r")))]
2568   ""
2569   "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2570   [(set_attr "type" "alus_ext")]
2573 ;; -------------------------------------------------------------------
2574 ;; Store-flag and conditional select insns
2575 ;; -------------------------------------------------------------------
2577 (define_expand "cstore<mode>4"
2578   [(set (match_operand:SI 0 "register_operand" "")
2579         (match_operator:SI 1 "aarch64_comparison_operator"
2580          [(match_operand:GPI 2 "register_operand" "")
2581           (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2582   ""
2583   "
2584   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2585                                       operands[3]);
2586   operands[3] = const0_rtx;
2587   "
2590 (define_expand "cstorecc4"
2591   [(set (match_operand:SI 0 "register_operand")
2592        (match_operator 1 "aarch64_comparison_operator"
2593         [(match_operand 2 "ccmp_cc_register")
2594          (match_operand 3 "const0_operand")]))]
2595   ""
2597   emit_insn (gen_rtx_SET (SImode, operands[0], operands[1]));
2598   DONE;
2602 (define_expand "cstore<mode>4"
2603   [(set (match_operand:SI 0 "register_operand" "")
2604         (match_operator:SI 1 "aarch64_comparison_operator"
2605          [(match_operand:GPF 2 "register_operand" "")
2606           (match_operand:GPF 3 "register_operand" "")]))]
2607   ""
2608   "
2609   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2610                                       operands[3]);
2611   operands[3] = const0_rtx;
2612   "
2615 (define_insn "*cstore<mode>_insn"
2616   [(set (match_operand:ALLI 0 "register_operand" "=r")
2617         (match_operator:ALLI 1 "aarch64_comparison_operator"
2618          [(match_operand 2 "cc_register" "") (const_int 0)]))]
2619   ""
2620   "cset\\t%<w>0, %m1"
2621   [(set_attr "type" "csel")]
2624 ;; zero_extend version of the above
2625 (define_insn "*cstoresi_insn_uxtw"
2626   [(set (match_operand:DI 0 "register_operand" "=r")
2627         (zero_extend:DI
2628          (match_operator:SI 1 "aarch64_comparison_operator"
2629           [(match_operand 2 "cc_register" "") (const_int 0)])))]
2630   ""
2631   "cset\\t%w0, %m1"
2632   [(set_attr "type" "csel")]
2635 (define_insn "cstore<mode>_neg"
2636   [(set (match_operand:ALLI 0 "register_operand" "=r")
2637         (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2638                   [(match_operand 2 "cc_register" "") (const_int 0)])))]
2639   ""
2640   "csetm\\t%<w>0, %m1"
2641   [(set_attr "type" "csel")]
2644 ;; zero_extend version of the above
2645 (define_insn "*cstoresi_neg_uxtw"
2646   [(set (match_operand:DI 0 "register_operand" "=r")
2647         (zero_extend:DI
2648          (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2649                   [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2650   ""
2651   "csetm\\t%w0, %m1"
2652   [(set_attr "type" "csel")]
2655 (define_expand "cmov<mode>6"
2656   [(set (match_operand:GPI 0 "register_operand" "")
2657         (if_then_else:GPI
2658          (match_operator 1 "aarch64_comparison_operator"
2659           [(match_operand:GPI 2 "register_operand" "")
2660            (match_operand:GPI 3 "aarch64_plus_operand" "")])
2661          (match_operand:GPI 4 "register_operand" "")
2662          (match_operand:GPI 5 "register_operand" "")))]
2663   ""
2664   "
2665   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2666                                       operands[3]);
2667   operands[3] = const0_rtx;
2668   "
2671 (define_expand "cmov<mode>6"
2672   [(set (match_operand:GPF 0 "register_operand" "")
2673         (if_then_else:GPF
2674          (match_operator 1 "aarch64_comparison_operator"
2675           [(match_operand:GPF 2 "register_operand" "")
2676            (match_operand:GPF 3 "register_operand" "")])
2677          (match_operand:GPF 4 "register_operand" "")
2678          (match_operand:GPF 5 "register_operand" "")))]
2679   ""
2680   "
2681   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2682                                       operands[3]);
2683   operands[3] = const0_rtx;
2684   "
2687 (define_insn "*cmov<mode>_insn"
2688   [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2689         (if_then_else:ALLI
2690          (match_operator 1 "aarch64_comparison_operator"
2691           [(match_operand 2 "cc_register" "") (const_int 0)])
2692          (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2693          (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2694   "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2695      || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2696   ;; Final two alternatives should be unreachable, but included for completeness
2697   "@
2698    csel\\t%<w>0, %<w>3, %<w>4, %m1
2699    csinv\\t%<w>0, %<w>3, <w>zr, %m1
2700    csinv\\t%<w>0, %<w>4, <w>zr, %M1
2701    csinc\\t%<w>0, %<w>3, <w>zr, %m1
2702    csinc\\t%<w>0, %<w>4, <w>zr, %M1
2703    mov\\t%<w>0, -1
2704    mov\\t%<w>0, 1"
2705   [(set_attr "type" "csel")]
2708 ;; zero_extend version of above
2709 (define_insn "*cmovsi_insn_uxtw"
2710   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2711         (zero_extend:DI
2712          (if_then_else:SI
2713           (match_operator 1 "aarch64_comparison_operator"
2714            [(match_operand 2 "cc_register" "") (const_int 0)])
2715           (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2716           (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2717   "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2718      || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2719   ;; Final two alternatives should be unreachable, but included for completeness
2720   "@
2721    csel\\t%w0, %w3, %w4, %m1
2722    csinv\\t%w0, %w3, wzr, %m1
2723    csinv\\t%w0, %w4, wzr, %M1
2724    csinc\\t%w0, %w3, wzr, %m1
2725    csinc\\t%w0, %w4, wzr, %M1
2726    mov\\t%w0, -1
2727    mov\\t%w0, 1"
2728   [(set_attr "type" "csel")]
2731 (define_insn "*cmov<mode>_insn"
2732   [(set (match_operand:GPF 0 "register_operand" "=w")
2733         (if_then_else:GPF
2734          (match_operator 1 "aarch64_comparison_operator"
2735           [(match_operand 2 "cc_register" "") (const_int 0)])
2736          (match_operand:GPF 3 "register_operand" "w")
2737          (match_operand:GPF 4 "register_operand" "w")))]
2738   "TARGET_FLOAT"
2739   "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2740   [(set_attr "type" "fcsel")]
2743 (define_expand "mov<mode>cc"
2744   [(set (match_operand:ALLI 0 "register_operand" "")
2745         (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2746                            (match_operand:ALLI 2 "register_operand" "")
2747                            (match_operand:ALLI 3 "register_operand" "")))]
2748   ""
2749   {
2750     enum rtx_code code = GET_CODE (operands[1]);
2752     if (code == UNEQ || code == LTGT)
2753       FAIL;
2755     if (!ccmp_cc_register (XEXP (operands[1], 0),
2756                            GET_MODE (XEXP (operands[1], 0))))
2757       {
2758         rtx ccreg;
2759         ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2760                                          XEXP (operands[1], 1));
2761         operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2762       }
2763   }
2766 (define_expand "mov<GPF:mode><GPI:mode>cc"
2767   [(set (match_operand:GPI 0 "register_operand" "")
2768         (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2769                           (match_operand:GPF 2 "register_operand" "")
2770                           (match_operand:GPF 3 "register_operand" "")))]
2771   ""
2772   {
2773     rtx ccreg;
2774     enum rtx_code code = GET_CODE (operands[1]);
2776     if (code == UNEQ || code == LTGT)
2777       FAIL;
2779     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2780                                   XEXP (operands[1], 1));
2781     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2782   }
2785 (define_expand "mov<mode>cc"
2786   [(set (match_operand:GPF 0 "register_operand" "")
2787         (if_then_else:GPF (match_operand 1 "aarch64_comparison_operator" "")
2788                           (match_operand:GPF 2 "register_operand" "")
2789                           (match_operand:GPF 3 "register_operand" "")))]
2790   ""
2791   {
2792     rtx ccreg;
2793     enum rtx_code code = GET_CODE (operands[1]);
2795     if (code == UNEQ || code == LTGT)
2796       FAIL;
2798     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2799                                   XEXP (operands[1], 1));
2800     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2801   }
2805 ;; CRC32 instructions.
2806 (define_insn "aarch64_<crc_variant>"
2807   [(set (match_operand:SI 0 "register_operand" "=r")
2808         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2809                     (match_operand:<crc_mode> 2 "register_operand" "r")]
2810          CRC))]
2811   "TARGET_CRC32"
2812   {
2813     if (GET_MODE_BITSIZE (GET_MODE (operands[2])) >= 64)
2814       return "<crc_variant>\\t%w0, %w1, %x2";
2815     else
2816       return "<crc_variant>\\t%w0, %w1, %w2";
2817   }
2818   [(set_attr "type" "crc")]
2821 (define_insn "*csinc2<mode>_insn"
2822   [(set (match_operand:GPI 0 "register_operand" "=r")
2823         (plus:GPI (match_operand 2 "aarch64_comparison_operation" "")
2824                   (match_operand:GPI 1 "register_operand" "r")))]
2825   ""
2826   "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2827   [(set_attr "type" "csel")]
2830 (define_insn "csinc3<mode>_insn"
2831   [(set (match_operand:GPI 0 "register_operand" "=r")
2832         (if_then_else:GPI
2833           (match_operand 1 "aarch64_comparison_operation" "")
2834           (plus:GPI (match_operand:GPI 2 "register_operand" "r")
2835                     (const_int 1))
2836           (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2837   ""
2838   "csinc\\t%<w>0, %<w>3, %<w>2, %M1"
2839   [(set_attr "type" "csel")]
2842 (define_insn "*csinv3<mode>_insn"
2843   [(set (match_operand:GPI 0 "register_operand" "=r")
2844         (if_then_else:GPI
2845           (match_operand 1 "aarch64_comparison_operation" "")
2846           (not:GPI (match_operand:GPI 2 "register_operand" "r"))
2847           (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2848   ""
2849   "csinv\\t%<w>0, %<w>3, %<w>2, %M1"
2850   [(set_attr "type" "csel")]
2853 (define_insn "*csneg3<mode>_insn"
2854   [(set (match_operand:GPI 0 "register_operand" "=r")
2855         (if_then_else:GPI
2856           (match_operand 1 "aarch64_comparison_operation" "")
2857           (neg:GPI (match_operand:GPI 2 "register_operand" "r"))
2858           (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2859   ""
2860   "csneg\\t%<w>0, %<w>3, %<w>2, %M1"
2861   [(set_attr "type" "csel")]
2864 ;; -------------------------------------------------------------------
2865 ;; Logical operations
2866 ;; -------------------------------------------------------------------
2868 (define_insn "<optab><mode>3"
2869   [(set (match_operand:GPI 0 "register_operand" "=r,rk")
2870         (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2871                      (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
2872   ""
2873   "<logical>\\t%<w>0, %<w>1, %<w>2"
2874   [(set_attr "type" "logic_reg,logic_imm")]
2877 ;; zero_extend version of above
2878 (define_insn "*<optab>si3_uxtw"
2879   [(set (match_operand:DI 0 "register_operand" "=r,rk")
2880         (zero_extend:DI
2881          (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2882                      (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2883   ""
2884   "<logical>\\t%w0, %w1, %w2"
2885   [(set_attr "type" "logic_reg,logic_imm")]
2888 (define_insn "*and<mode>3_compare0"
2889   [(set (reg:CC_NZ CC_REGNUM)
2890         (compare:CC_NZ
2891          (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2892                   (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2893          (const_int 0)))
2894    (set (match_operand:GPI 0 "register_operand" "=r,r")
2895         (and:GPI (match_dup 1) (match_dup 2)))]
2896   ""
2897   "ands\\t%<w>0, %<w>1, %<w>2"
2898   [(set_attr "type" "logics_reg,logics_imm")]
2901 ;; zero_extend version of above
2902 (define_insn "*andsi3_compare0_uxtw"
2903   [(set (reg:CC_NZ CC_REGNUM)
2904         (compare:CC_NZ
2905          (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2906                  (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2907          (const_int 0)))
2908    (set (match_operand:DI 0 "register_operand" "=r,r")
2909         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2910   ""
2911   "ands\\t%w0, %w1, %w2"
2912   [(set_attr "type" "logics_reg,logics_imm")]
2915 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2916   [(set (reg:CC_NZ CC_REGNUM)
2917         (compare:CC_NZ
2918          (and:GPI (SHIFT:GPI
2919                    (match_operand:GPI 1 "register_operand" "r")
2920                    (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2921                   (match_operand:GPI 3 "register_operand" "r"))
2922          (const_int 0)))
2923    (set (match_operand:GPI 0 "register_operand" "=r")
2924         (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2925   ""
2926   "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2927   [(set_attr "type" "logics_shift_imm")]
2930 ;; zero_extend version of above
2931 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2932   [(set (reg:CC_NZ CC_REGNUM)
2933         (compare:CC_NZ
2934          (and:SI (SHIFT:SI
2935                   (match_operand:SI 1 "register_operand" "r")
2936                   (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2937                  (match_operand:SI 3 "register_operand" "r"))
2938          (const_int 0)))
2939    (set (match_operand:DI 0 "register_operand" "=r")
2940         (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2941                                 (match_dup 3))))]
2942   ""
2943   "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2944   [(set_attr "type" "logics_shift_imm")]
2947 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2948   [(set (match_operand:GPI 0 "register_operand" "=r")
2949         (LOGICAL:GPI (SHIFT:GPI
2950                       (match_operand:GPI 1 "register_operand" "r")
2951                       (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2952                      (match_operand:GPI 3 "register_operand" "r")))]
2953   ""
2954   "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2955   [(set_attr "type" "logic_shift_imm")]
2958 (define_insn "*<optab>_rol<mode>3"
2959   [(set (match_operand:GPI 0 "register_operand" "=r")
2960         (LOGICAL:GPI (rotate:GPI
2961                       (match_operand:GPI 1 "register_operand" "r")
2962                       (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2963                      (match_operand:GPI 3 "register_operand" "r")))]
2964   ""
2965   "<logical>\\t%<w>0, %<w>3, %<w>1, ror (<sizen> - %2)"
2966   [(set_attr "type" "logic_shift_imm")]
2969 ;; zero_extend versions of above
2970 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
2971   [(set (match_operand:DI 0 "register_operand" "=r")
2972         (zero_extend:DI
2973          (LOGICAL:SI (SHIFT:SI
2974                       (match_operand:SI 1 "register_operand" "r")
2975                       (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2976                      (match_operand:SI 3 "register_operand" "r"))))]
2977   ""
2978   "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2979   [(set_attr "type" "logic_shift_imm")]
2982 (define_insn "*<optab>_rolsi3_uxtw"
2983   [(set (match_operand:DI 0 "register_operand" "=r")
2984         (zero_extend:DI
2985          (LOGICAL:SI (rotate:SI
2986                       (match_operand:SI 1 "register_operand" "r")
2987                       (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2988                      (match_operand:SI 3 "register_operand" "r"))))]
2989   ""
2990   "<logical>\\t%w0, %w3, %w1, ror (32 - %2)"
2991   [(set_attr "type" "logic_shift_imm")]
2994 (define_insn "one_cmpl<mode>2"
2995   [(set (match_operand:GPI 0 "register_operand" "=r")
2996         (not:GPI (match_operand:GPI 1 "register_operand" "r")))]
2997   ""
2998   "mvn\\t%<w>0, %<w>1"
2999   [(set_attr "type" "logic_reg")]
3002 (define_insn "*one_cmpl_<optab><mode>2"
3003   [(set (match_operand:GPI 0 "register_operand" "=r")
3004         (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
3005                             (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
3006   ""
3007   "mvn\\t%<w>0, %<w>1, <shift> %2"
3008   [(set_attr "type" "logic_shift_imm")]
3011 (define_insn "*<LOGICAL:optab>_one_cmpl<mode>3"
3012   [(set (match_operand:GPI 0 "register_operand" "=r")
3013         (LOGICAL:GPI (not:GPI
3014                       (match_operand:GPI 1 "register_operand" "r"))
3015                      (match_operand:GPI 2 "register_operand" "r")))]
3016   ""
3017   "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1"
3018   [(set_attr "type" "logic_reg")]
3021 (define_insn "*and_one_cmpl<mode>3_compare0"
3022   [(set (reg:CC_NZ CC_REGNUM)
3023         (compare:CC_NZ
3024          (and:GPI (not:GPI
3025                    (match_operand:GPI 1 "register_operand" "r"))
3026                   (match_operand:GPI 2 "register_operand" "r"))
3027          (const_int 0)))
3028    (set (match_operand:GPI 0 "register_operand" "=r")
3029         (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
3030   ""
3031   "bics\\t%<w>0, %<w>2, %<w>1"
3032   [(set_attr "type" "logics_reg")]
3035 ;; zero_extend version of above
3036 (define_insn "*and_one_cmplsi3_compare0_uxtw"
3037   [(set (reg:CC_NZ CC_REGNUM)
3038         (compare:CC_NZ
3039          (and:SI (not:SI
3040                   (match_operand:SI 1 "register_operand" "r"))
3041                  (match_operand:SI 2 "register_operand" "r"))
3042          (const_int 0)))
3043    (set (match_operand:DI 0 "register_operand" "=r")
3044         (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
3045   ""
3046   "bics\\t%w0, %w2, %w1"
3047   [(set_attr "type" "logics_reg")]
3050 (define_insn "*and_one_cmpl<mode>3_compare0_no_reuse"
3051   [(set (reg:CC_NZ CC_REGNUM)
3052     (compare:CC_NZ
3053      (and:GPI (not:GPI
3054            (match_operand:GPI 0 "register_operand" "r"))
3055           (match_operand:GPI 1 "register_operand" "r"))
3056      (const_int 0)))]
3057   ""
3058   "bics\\t<w>zr, %<w>1, %<w>0"
3059   [(set_attr "type" "logics_reg")]
3062 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
3063   [(set (match_operand:GPI 0 "register_operand" "=r")
3064         (LOGICAL:GPI (not:GPI
3065                       (SHIFT:GPI
3066                        (match_operand:GPI 1 "register_operand" "r")
3067                        (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
3068                      (match_operand:GPI 3 "register_operand" "r")))]
3069   ""
3070   "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3071   [(set_attr "type" "logics_shift_imm")]
3074 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
3075   [(set (reg:CC_NZ CC_REGNUM)
3076         (compare:CC_NZ
3077          (and:GPI (not:GPI
3078                    (SHIFT:GPI
3079                     (match_operand:GPI 1 "register_operand" "r")
3080                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
3081                   (match_operand:GPI 3 "register_operand" "r"))
3082          (const_int 0)))
3083    (set (match_operand:GPI 0 "register_operand" "=r")
3084         (and:GPI (not:GPI
3085                   (SHIFT:GPI
3086                    (match_dup 1) (match_dup 2))) (match_dup 3)))]
3087   ""
3088   "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3089   [(set_attr "type" "logics_shift_imm")]
3092 ;; zero_extend version of above
3093 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
3094   [(set (reg:CC_NZ CC_REGNUM)
3095         (compare:CC_NZ
3096          (and:SI (not:SI
3097                   (SHIFT:SI
3098                    (match_operand:SI 1 "register_operand" "r")
3099                    (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
3100                  (match_operand:SI 3 "register_operand" "r"))
3101          (const_int 0)))
3102    (set (match_operand:DI 0 "register_operand" "=r")
3103         (zero_extend:DI (and:SI
3104                          (not:SI
3105                           (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
3106   ""
3107   "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3108   [(set_attr "type" "logics_shift_imm")]
3111 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0_no_reuse"
3112   [(set (reg:CC_NZ CC_REGNUM)
3113     (compare:CC_NZ
3114      (and:GPI (not:GPI
3115            (SHIFT:GPI
3116             (match_operand:GPI 0 "register_operand" "r")
3117             (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n")))
3118           (match_operand:GPI 2 "register_operand" "r"))
3119      (const_int 0)))]
3120   ""
3121   "bics\\t<w>zr, %<w>2, %<w>0, <SHIFT:shift> %1"
3122   [(set_attr "type" "logics_shift_imm")]
3125 (define_insn "clz<mode>2"
3126   [(set (match_operand:GPI 0 "register_operand" "=r")
3127         (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
3128   ""
3129   "clz\\t%<w>0, %<w>1"
3130   [(set_attr "type" "clz")]
3133 (define_expand "ffs<mode>2"
3134   [(match_operand:GPI 0 "register_operand")
3135    (match_operand:GPI 1 "register_operand")]
3136   ""
3137   {
3138     rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
3139     rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
3141     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3142     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3143     emit_insn (gen_csinc3<mode>_insn (operands[0], x, operands[0], const0_rtx));
3144     DONE;
3145   }
3148 (define_insn "clrsb<mode>2"
3149   [(set (match_operand:GPI 0 "register_operand" "=r")
3150         (clrsb:GPI (match_operand:GPI 1 "register_operand" "r")))]
3151   ""
3152   "cls\\t%<w>0, %<w>1"
3153   [(set_attr "type" "clz")]
3156 (define_insn "rbit<mode>2"
3157   [(set (match_operand:GPI 0 "register_operand" "=r")
3158         (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
3159   ""
3160   "rbit\\t%<w>0, %<w>1"
3161   [(set_attr "type" "rbit")]
3164 (define_expand "ctz<mode>2"
3165   [(match_operand:GPI 0 "register_operand")
3166    (match_operand:GPI 1 "register_operand")]
3167   ""
3168   {
3169     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3170     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3171     DONE;
3172   }
3175 (define_insn "*and<mode>3nr_compare0"
3176   [(set (reg:CC_NZ CC_REGNUM)
3177         (compare:CC_NZ
3178          (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
3179                   (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
3180          (const_int 0)))]
3181   ""
3182   "tst\\t%<w>0, %<w>1"
3183   [(set_attr "type" "logics_reg")]
3186 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
3187   [(set (reg:CC_NZ CC_REGNUM)
3188         (compare:CC_NZ
3189          (and:GPI (SHIFT:GPI
3190                    (match_operand:GPI 0 "register_operand" "r")
3191                    (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
3192                   (match_operand:GPI 2 "register_operand" "r"))
3193         (const_int 0)))]
3194   ""
3195   "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
3196   [(set_attr "type" "logics_shift_imm")]
3199 ;; -------------------------------------------------------------------
3200 ;; Shifts
3201 ;; -------------------------------------------------------------------
3203 (define_expand "<optab><mode>3"
3204   [(set (match_operand:GPI 0 "register_operand")
3205         (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
3206                     (match_operand:QI 2 "nonmemory_operand")))]
3207   ""
3208   {
3209     if (CONST_INT_P (operands[2]))
3210       {
3211         operands[2] = GEN_INT (INTVAL (operands[2])
3212                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3214         if (operands[2] == const0_rtx)
3215           {
3216             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3217             DONE;
3218           }
3219       }
3220   }
3223 (define_expand "ashl<mode>3"
3224   [(set (match_operand:SHORT 0 "register_operand")
3225         (ashift:SHORT (match_operand:SHORT 1 "register_operand")
3226                       (match_operand:QI 2 "nonmemory_operand")))]
3227   ""
3228   {
3229     if (CONST_INT_P (operands[2]))
3230       {
3231         operands[2] = GEN_INT (INTVAL (operands[2])
3232                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3234         if (operands[2] == const0_rtx)
3235           {
3236             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3237             DONE;
3238           }
3239       }
3240   }
3243 (define_expand "rotr<mode>3"
3244   [(set (match_operand:GPI 0 "register_operand")
3245         (rotatert:GPI (match_operand:GPI 1 "register_operand")
3246                       (match_operand:QI 2 "nonmemory_operand")))]
3247   ""
3248   {
3249     if (CONST_INT_P (operands[2]))
3250       {
3251         operands[2] = GEN_INT (INTVAL (operands[2])
3252                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3254         if (operands[2] == const0_rtx)
3255           {
3256             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3257             DONE;
3258           }
3259       }
3260   }
3263 (define_expand "rotl<mode>3"
3264   [(set (match_operand:GPI 0 "register_operand")
3265         (rotatert:GPI (match_operand:GPI 1 "register_operand")
3266                       (match_operand:QI 2 "nonmemory_operand")))]
3267   ""
3268   {
3269     /* (SZ - cnt) % SZ == -cnt % SZ */
3270     if (CONST_INT_P (operands[2]))
3271       {
3272         operands[2] = GEN_INT ((-INTVAL (operands[2]))
3273                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3274         if (operands[2] == const0_rtx)
3275           {
3276             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3277             DONE;
3278           }
3279       }
3280     else
3281       operands[2] = expand_simple_unop (QImode, NEG, operands[2],
3282                                         NULL_RTX, 1);
3283   }
3286 ;; Logical left shift using SISD or Integer instruction
3287 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
3288   [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3289         (ashift:GPI
3290           (match_operand:GPI 1 "register_operand" "w,w,r")
3291           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3292   ""
3293   "@
3294    shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3295    ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
3296    lsl\t%<w>0, %<w>1, %<w>2"
3297   [(set_attr "simd" "yes,yes,no")
3298    (set_attr "type" "neon_shift_imm<q>, neon_shift_reg<q>,shift_reg")]
3301 ;; Logical right shift using SISD or Integer instruction
3302 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3303   [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3304         (lshiftrt:GPI
3305           (match_operand:GPI 1 "register_operand" "w,w,r")
3306           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3307   ""
3308   "@
3309    ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3310    #
3311    lsr\t%<w>0, %<w>1, %<w>2"
3312   [(set_attr "simd" "yes,yes,no")
3313    (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")]
3316 (define_split
3317   [(set (match_operand:DI 0 "aarch64_simd_register")
3318         (lshiftrt:DI
3319            (match_operand:DI 1 "aarch64_simd_register")
3320            (match_operand:QI 2 "aarch64_simd_register")))]
3321   "TARGET_SIMD && reload_completed"
3322   [(set (match_dup 2)
3323         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3324    (set (match_dup 0)
3325         (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_USHL))]
3326   ""
3329 (define_split
3330   [(set (match_operand:SI 0 "aarch64_simd_register")
3331         (lshiftrt:SI
3332            (match_operand:SI 1 "aarch64_simd_register")
3333            (match_operand:QI 2 "aarch64_simd_register")))]
3334   "TARGET_SIMD && reload_completed"
3335   [(set (match_dup 2)
3336         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3337    (set (match_dup 0)
3338         (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_USHL_2S))]
3339   ""
3342 ;; Arithmetic right shift using SISD or Integer instruction
3343 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3344   [(set (match_operand:GPI 0 "register_operand" "=w,&w,&w,r")
3345         (ashiftrt:GPI
3346           (match_operand:GPI 1 "register_operand" "w,w,w,r")
3347           (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,0,rUs<cmode>")))]
3348   ""
3349   "@
3350    sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3351    #
3352    #
3353    asr\t%<w>0, %<w>1, %<w>2"
3354   [(set_attr "simd" "yes,yes,yes,no")
3355    (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>,shift_reg")]
3358 (define_split
3359   [(set (match_operand:DI 0 "aarch64_simd_register")
3360         (ashiftrt:DI
3361            (match_operand:DI 1 "aarch64_simd_register")
3362            (match_operand:QI 2 "aarch64_simd_register")))]
3363   "TARGET_SIMD && reload_completed"
3364   [(set (match_dup 3)
3365         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3366    (set (match_dup 0)
3367         (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_SSHL))]
3369   operands[3] = gen_lowpart (QImode, operands[0]);
3373 (define_split
3374   [(set (match_operand:SI 0 "aarch64_simd_register")
3375         (ashiftrt:SI
3376            (match_operand:SI 1 "aarch64_simd_register")
3377            (match_operand:QI 2 "aarch64_simd_register")))]
3378   "TARGET_SIMD && reload_completed"
3379   [(set (match_dup 3)
3380         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3381    (set (match_dup 0)
3382         (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_SSHL_2S))]
3384   operands[3] = gen_lowpart (QImode, operands[0]);
3388 (define_insn "*aarch64_sisd_ushl"
3389   [(set (match_operand:DI 0 "register_operand" "=w")
3390         (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3391                     (match_operand:QI 2 "register_operand" "w")]
3392                    UNSPEC_SISD_USHL))]
3393   "TARGET_SIMD"
3394   "ushl\t%d0, %d1, %d2"
3395   [(set_attr "simd" "yes")
3396    (set_attr "type" "neon_shift_reg")]
3399 (define_insn "*aarch64_ushl_2s"
3400   [(set (match_operand:SI 0 "register_operand" "=w")
3401         (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3402                     (match_operand:QI 2 "register_operand" "w")]
3403                    UNSPEC_USHL_2S))]
3404   "TARGET_SIMD"
3405   "ushl\t%0.2s, %1.2s, %2.2s"
3406   [(set_attr "simd" "yes")
3407    (set_attr "type" "neon_shift_reg")]
3410 (define_insn "*aarch64_sisd_sshl"
3411   [(set (match_operand:DI 0 "register_operand" "=w")
3412         (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3413                     (match_operand:QI 2 "register_operand" "w")]
3414                    UNSPEC_SISD_SSHL))]
3415   "TARGET_SIMD"
3416   "sshl\t%d0, %d1, %d2"
3417   [(set_attr "simd" "yes")
3418    (set_attr "type" "neon_shift_reg")]
3421 (define_insn "*aarch64_sshl_2s"
3422   [(set (match_operand:SI 0 "register_operand" "=w")
3423         (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3424                     (match_operand:QI 2 "register_operand" "w")]
3425                    UNSPEC_SSHL_2S))]
3426   "TARGET_SIMD"
3427   "sshl\t%0.2s, %1.2s, %2.2s"
3428   [(set_attr "simd" "yes")
3429    (set_attr "type" "neon_shift_reg")]
3432 (define_insn "*aarch64_sisd_neg_qi"
3433   [(set (match_operand:QI 0 "register_operand" "=w")
3434         (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3435                    UNSPEC_SISD_NEG))]
3436   "TARGET_SIMD"
3437   "neg\t%d0, %d1"
3438   [(set_attr "simd" "yes")
3439    (set_attr "type" "neon_neg")]
3442 ;; Rotate right
3443 (define_insn "*ror<mode>3_insn"
3444   [(set (match_operand:GPI 0 "register_operand" "=r")
3445         (rotatert:GPI
3446           (match_operand:GPI 1 "register_operand" "r")
3447           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3448   ""
3449   "ror\\t%<w>0, %<w>1, %<w>2"
3450   [(set_attr "type" "shift_reg")]
3453 ;; zero_extend version of above
3454 (define_insn "*<optab>si3_insn_uxtw"
3455   [(set (match_operand:DI 0 "register_operand" "=r")
3456         (zero_extend:DI (SHIFT:SI
3457          (match_operand:SI 1 "register_operand" "r")
3458          (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3459   ""
3460   "<shift>\\t%w0, %w1, %w2"
3461   [(set_attr "type" "shift_reg")]
3464 (define_insn "*ashl<mode>3_insn"
3465   [(set (match_operand:SHORT 0 "register_operand" "=r")
3466         (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3467                       (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
3468   ""
3469   "lsl\\t%<w>0, %<w>1, %<w>2"
3470   [(set_attr "type" "shift_reg")]
3473 (define_insn "*<optab><mode>3_insn"
3474   [(set (match_operand:SHORT 0 "register_operand" "=r")
3475         (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3476                       (match_operand 2 "const_int_operand" "n")))]
3477   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3479   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3480   return "<bfshift>\t%w0, %w1, %2, %3";
3482   [(set_attr "type" "bfm")]
3485 (define_insn "*extr<mode>5_insn"
3486   [(set (match_operand:GPI 0 "register_operand" "=r")
3487         (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3488                              (match_operand 3 "const_int_operand" "n"))
3489                  (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3490                                (match_operand 4 "const_int_operand" "n"))))]
3491   "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3492    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3493   "extr\\t%<w>0, %<w>1, %<w>2, %4"
3494   [(set_attr "type" "shift_imm")]
3497 ;; zero_extend version of the above
3498 (define_insn "*extrsi5_insn_uxtw"
3499   [(set (match_operand:DI 0 "register_operand" "=r")
3500         (zero_extend:DI
3501          (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3502                             (match_operand 3 "const_int_operand" "n"))
3503                  (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3504                               (match_operand 4 "const_int_operand" "n")))))]
3505   "UINTVAL (operands[3]) < 32 &&
3506    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3507   "extr\\t%w0, %w1, %w2, %4"
3508   [(set_attr "type" "shift_imm")]
3511 (define_insn "*ror<mode>3_insn"
3512   [(set (match_operand:GPI 0 "register_operand" "=r")
3513         (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3514                     (match_operand 2 "const_int_operand" "n")))]
3515   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3517   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3518   return "ror\\t%<w>0, %<w>1, %3";
3520   [(set_attr "type" "shift_imm")]
3523 ;; zero_extend version of the above
3524 (define_insn "*rorsi3_insn_uxtw"
3525   [(set (match_operand:DI 0 "register_operand" "=r")
3526         (zero_extend:DI
3527          (rotate:SI (match_operand:SI 1 "register_operand" "r")
3528                     (match_operand 2 "const_int_operand" "n"))))]
3529   "UINTVAL (operands[2]) < 32"
3531   operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3532   return "ror\\t%w0, %w1, %3";
3534   [(set_attr "type" "shift_imm")]
3537 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3538   [(set (match_operand:GPI 0 "register_operand" "=r")
3539         (ANY_EXTEND:GPI
3540          (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3541                        (match_operand 2 "const_int_operand" "n"))))]
3542   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3544   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3545   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3547   [(set_attr "type" "bfm")]
3550 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3551   [(set (match_operand:GPI 0 "register_operand" "=r")
3552         (zero_extend:GPI
3553          (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3554                          (match_operand 2 "const_int_operand" "n"))))]
3555   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3557   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3558   return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3560   [(set_attr "type" "bfm")]
3563 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3564   [(set (match_operand:GPI 0 "register_operand" "=r")
3565         (sign_extend:GPI
3566          (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3567                          (match_operand 2 "const_int_operand" "n"))))]
3568   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3570   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3571   return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3573   [(set_attr "type" "bfm")]
3576 ;; -------------------------------------------------------------------
3577 ;; Bitfields
3578 ;; -------------------------------------------------------------------
3580 (define_expand "<optab>"
3581   [(set (match_operand:DI 0 "register_operand" "=r")
3582         (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3583                         (match_operand 2 "const_int_operand" "n")
3584                         (match_operand 3 "const_int_operand" "n")))]
3585   ""
3586   ""
3589 (define_insn "*<optab><mode>"
3590   [(set (match_operand:GPI 0 "register_operand" "=r")
3591         (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3592                          (match_operand 2 "const_int_operand" "n")
3593                          (match_operand 3 "const_int_operand" "n")))]
3594   ""
3595   "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3596   [(set_attr "type" "bfm")]
3599 ;; Bitfield Insert (insv)
3600 (define_expand "insv<mode>"
3601   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3602                           (match_operand 1 "const_int_operand")
3603                           (match_operand 2 "const_int_operand"))
3604         (match_operand:GPI 3 "general_operand"))]
3605   ""
3607   unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3608   unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3609   rtx value = operands[3];
3611   if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3612     FAIL;
3614   if (CONST_INT_P (value))
3615     {
3616       unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3618       /* Prefer AND/OR for inserting all zeros or all ones.  */
3619       if ((UINTVAL (value) & mask) == 0
3620            || (UINTVAL (value) & mask) == mask)
3621         FAIL;
3623       /* 16-bit aligned 16-bit wide insert is handled by insv_imm.  */
3624       if (width == 16 && (pos % 16) == 0)
3625         DONE;
3626     }
3627   operands[3] = force_reg (<MODE>mode, value);
3630 (define_insn "*insv_reg<mode>"
3631   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3632                           (match_operand 1 "const_int_operand" "n")
3633                           (match_operand 2 "const_int_operand" "n"))
3634         (match_operand:GPI 3 "register_operand" "r"))]
3635   "!(UINTVAL (operands[1]) == 0
3636      || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3637          > GET_MODE_BITSIZE (<MODE>mode)))"
3638   "bfi\\t%<w>0, %<w>3, %2, %1"
3639   [(set_attr "type" "bfm")]
3642 (define_insn "*extr_insv_lower_reg<mode>"
3643   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3644                           (match_operand 1 "const_int_operand" "n")
3645                           (const_int 0))
3646         (zero_extract:GPI (match_operand:GPI 2 "register_operand" "r")
3647                           (match_dup 1)
3648                           (match_operand 3 "const_int_operand" "n")))]
3649   "!(UINTVAL (operands[1]) == 0
3650      || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3651          > GET_MODE_BITSIZE (<MODE>mode)))"
3652   "bfxil\\t%<w>0, %<w>2, %3, %1"
3653   [(set_attr "type" "bfm")]
3656 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3657   [(set (match_operand:GPI 0 "register_operand" "=r")
3658         (ashift:GPI (ANY_EXTEND:GPI
3659                      (match_operand:ALLX 1 "register_operand" "r"))
3660                     (match_operand 2 "const_int_operand" "n")))]
3661   "UINTVAL (operands[2]) < <GPI:sizen>"
3663   operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3664               ? GEN_INT (<ALLX:sizen>)
3665               : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3666   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3668   [(set_attr "type" "bfm")]
3671 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3673 (define_insn "*andim_ashift<mode>_bfiz"
3674   [(set (match_operand:GPI 0 "register_operand" "=r")
3675         (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3676                              (match_operand 2 "const_int_operand" "n"))
3677                  (match_operand 3 "const_int_operand" "n")))]
3678   "(INTVAL (operands[2]) < (<GPI:sizen>))
3679    && exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3680    && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3681   "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3682   [(set_attr "type" "bfm")]
3685 (define_insn "bswap<mode>2"
3686   [(set (match_operand:GPI 0 "register_operand" "=r")
3687         (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3688   ""
3689   "rev\\t%<w>0, %<w>1"
3690   [(set_attr "type" "rev")]
3693 (define_insn "bswaphi2"
3694   [(set (match_operand:HI 0 "register_operand" "=r")
3695         (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3696   ""
3697   "rev16\\t%w0, %w1"
3698   [(set_attr "type" "rev")]
3701 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
3702 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
3703 ;; each valid permutation.
3705 (define_insn "rev16<mode>2"
3706   [(set (match_operand:GPI 0 "register_operand" "=r")
3707         (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3708                                       (const_int 8))
3709                           (match_operand:GPI 3 "const_int_operand" "n"))
3710                  (and:GPI (lshiftrt:GPI (match_dup 1)
3711                                         (const_int 8))
3712                           (match_operand:GPI 2 "const_int_operand" "n"))))]
3713   "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3714    && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3715   "rev16\\t%<w>0, %<w>1"
3716   [(set_attr "type" "rev")]
3719 (define_insn "rev16<mode>2_alt"
3720   [(set (match_operand:GPI 0 "register_operand" "=r")
3721         (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r")
3722                                         (const_int 8))
3723                           (match_operand:GPI 2 "const_int_operand" "n"))
3724                  (and:GPI (ashift:GPI (match_dup 1)
3725                                       (const_int 8))
3726                           (match_operand:GPI 3 "const_int_operand" "n"))))]
3727   "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3728    && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3729   "rev16\\t%<w>0, %<w>1"
3730   [(set_attr "type" "rev")]
3733 ;; zero_extend version of above
3734 (define_insn "*bswapsi2_uxtw"
3735   [(set (match_operand:DI 0 "register_operand" "=r")
3736         (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3737   ""
3738   "rev\\t%w0, %w1"
3739   [(set_attr "type" "rev")]
3742 ;; -------------------------------------------------------------------
3743 ;; Floating-point intrinsics
3744 ;; -------------------------------------------------------------------
3746 ;; frint floating-point round to integral standard patterns.
3747 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round, frintn.
3749 (define_insn "<frint_pattern><mode>2"
3750   [(set (match_operand:GPF 0 "register_operand" "=w")
3751         (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3752          FRINT))]
3753   "TARGET_FLOAT"
3754   "frint<frint_suffix>\\t%<s>0, %<s>1"
3755   [(set_attr "type" "f_rint<s>")]
3758 ;; frcvt floating-point round to integer and convert standard patterns.
3759 ;; Expands to lbtrunc, lceil, lfloor, lround.
3760 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3761   [(set (match_operand:GPI 0 "register_operand" "=r")
3762         (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3763                       FCVT)))]
3764   "TARGET_FLOAT"
3765   "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3766   [(set_attr "type" "f_cvtf2i")]
3769 ;; fma - no throw
3771 (define_insn "fma<mode>4"
3772   [(set (match_operand:GPF 0 "register_operand" "=w")
3773         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3774                  (match_operand:GPF 2 "register_operand" "w")
3775                  (match_operand:GPF 3 "register_operand" "w")))]
3776   "TARGET_FLOAT"
3777   "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3778   [(set_attr "type" "fmac<s>")]
3781 (define_insn "fnma<mode>4"
3782   [(set (match_operand:GPF 0 "register_operand" "=w")
3783         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3784                  (match_operand:GPF 2 "register_operand" "w")
3785                  (match_operand:GPF 3 "register_operand" "w")))]
3786   "TARGET_FLOAT"
3787   "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3788   [(set_attr "type" "fmac<s>")]
3791 (define_insn "fms<mode>4"
3792   [(set (match_operand:GPF 0 "register_operand" "=w")
3793         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3794                  (match_operand:GPF 2 "register_operand" "w")
3795                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3796   "TARGET_FLOAT"
3797   "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3798   [(set_attr "type" "fmac<s>")]
3801 (define_insn "fnms<mode>4"
3802   [(set (match_operand:GPF 0 "register_operand" "=w")
3803         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3804                  (match_operand:GPF 2 "register_operand" "w")
3805                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3806   "TARGET_FLOAT"
3807   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3808   [(set_attr "type" "fmac<s>")]
3811 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3812 (define_insn "*fnmadd<mode>4"
3813   [(set (match_operand:GPF 0 "register_operand" "=w")
3814         (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3815                           (match_operand:GPF 2 "register_operand" "w")
3816                           (match_operand:GPF 3 "register_operand" "w"))))]
3817   "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3818   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3819   [(set_attr "type" "fmac<s>")]
3822 ;; -------------------------------------------------------------------
3823 ;; Floating-point conversions
3824 ;; -------------------------------------------------------------------
3826 (define_insn "extendsfdf2"
3827   [(set (match_operand:DF 0 "register_operand" "=w")
3828         (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3829   "TARGET_FLOAT"
3830   "fcvt\\t%d0, %s1"
3831   [(set_attr "type" "f_cvt")]
3834 (define_insn "truncdfsf2"
3835   [(set (match_operand:SF 0 "register_operand" "=w")
3836         (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3837   "TARGET_FLOAT"
3838   "fcvt\\t%s0, %d1"
3839   [(set_attr "type" "f_cvt")]
3842 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3843   [(set (match_operand:GPI 0 "register_operand" "=r")
3844         (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3845   "TARGET_FLOAT"
3846   "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3847   [(set_attr "type" "f_cvtf2i")]
3850 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3851   [(set (match_operand:GPI 0 "register_operand" "=r")
3852         (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3853   "TARGET_FLOAT"
3854   "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3855   [(set_attr "type" "f_cvtf2i")]
3858 (define_insn "<optab><fcvt_target><GPF:mode>2"
3859   [(set (match_operand:GPF 0 "register_operand" "=w,w")
3860         (FLOATUORS:GPF (match_operand:<FCVT_TARGET> 1 "register_operand" "w,r")))]
3861   ""
3862   "@
3863    <su_optab>cvtf\t%<GPF:s>0, %<s>1
3864    <su_optab>cvtf\t%<GPF:s>0, %<w1>1"
3865   [(set_attr "simd" "yes,no")
3866    (set_attr "fp" "no,yes")
3867    (set_attr "type" "neon_int_to_fp_<Vetype>,f_cvti2f")]
3870 (define_insn "<optab><fcvt_iesize><GPF:mode>2"
3871   [(set (match_operand:GPF 0 "register_operand" "=w")
3872         (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand" "r")))]
3873   "TARGET_FLOAT"
3874   "<su_optab>cvtf\t%<GPF:s>0, %<w2>1"
3875   [(set_attr "type" "f_cvti2f")]
3878 ;; -------------------------------------------------------------------
3879 ;; Floating-point arithmetic
3880 ;; -------------------------------------------------------------------
3882 (define_insn "add<mode>3"
3883   [(set (match_operand:GPF 0 "register_operand" "=w")
3884         (plus:GPF
3885          (match_operand:GPF 1 "register_operand" "w")
3886          (match_operand:GPF 2 "register_operand" "w")))]
3887   "TARGET_FLOAT"
3888   "fadd\\t%<s>0, %<s>1, %<s>2"
3889   [(set_attr "type" "fadd<s>")]
3892 (define_insn "sub<mode>3"
3893   [(set (match_operand:GPF 0 "register_operand" "=w")
3894         (minus:GPF
3895          (match_operand:GPF 1 "register_operand" "w")
3896          (match_operand:GPF 2 "register_operand" "w")))]
3897   "TARGET_FLOAT"
3898   "fsub\\t%<s>0, %<s>1, %<s>2"
3899   [(set_attr "type" "fadd<s>")]
3902 (define_insn "mul<mode>3"
3903   [(set (match_operand:GPF 0 "register_operand" "=w")
3904         (mult:GPF
3905          (match_operand:GPF 1 "register_operand" "w")
3906          (match_operand:GPF 2 "register_operand" "w")))]
3907   "TARGET_FLOAT"
3908   "fmul\\t%<s>0, %<s>1, %<s>2"
3909   [(set_attr "type" "fmul<s>")]
3912 (define_insn "*fnmul<mode>3"
3913   [(set (match_operand:GPF 0 "register_operand" "=w")
3914         (mult:GPF
3915                  (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3916                  (match_operand:GPF 2 "register_operand" "w")))]
3917   "TARGET_FLOAT"
3918   "fnmul\\t%<s>0, %<s>1, %<s>2"
3919   [(set_attr "type" "fmul<s>")]
3922 (define_insn "div<mode>3"
3923   [(set (match_operand:GPF 0 "register_operand" "=w")
3924         (div:GPF
3925          (match_operand:GPF 1 "register_operand" "w")
3926          (match_operand:GPF 2 "register_operand" "w")))]
3927   "TARGET_FLOAT"
3928   "fdiv\\t%<s>0, %<s>1, %<s>2"
3929   [(set_attr "type" "fdiv<s>")]
3932 (define_insn "neg<mode>2"
3933   [(set (match_operand:GPF 0 "register_operand" "=w")
3934         (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
3935   "TARGET_FLOAT"
3936   "fneg\\t%<s>0, %<s>1"
3937   [(set_attr "type" "ffarith<s>")]
3940 (define_insn "sqrt<mode>2"
3941   [(set (match_operand:GPF 0 "register_operand" "=w")
3942         (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
3943   "TARGET_FLOAT"
3944   "fsqrt\\t%<s>0, %<s>1"
3945   [(set_attr "type" "fsqrt<s>")]
3948 (define_insn "abs<mode>2"
3949   [(set (match_operand:GPF 0 "register_operand" "=w")
3950         (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
3951   "TARGET_FLOAT"
3952   "fabs\\t%<s>0, %<s>1"
3953   [(set_attr "type" "ffarith<s>")]
3956 ;; Given that smax/smin do not specify the result when either input is NaN,
3957 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
3958 ;; for smin.
3960 (define_insn "smax<mode>3"
3961   [(set (match_operand:GPF 0 "register_operand" "=w")
3962         (smax:GPF (match_operand:GPF 1 "register_operand" "w")
3963                   (match_operand:GPF 2 "register_operand" "w")))]
3964   "TARGET_FLOAT"
3965   "fmaxnm\\t%<s>0, %<s>1, %<s>2"
3966   [(set_attr "type" "f_minmax<s>")]
3969 (define_insn "smin<mode>3"
3970   [(set (match_operand:GPF 0 "register_operand" "=w")
3971         (smin:GPF (match_operand:GPF 1 "register_operand" "w")
3972                   (match_operand:GPF 2 "register_operand" "w")))]
3973   "TARGET_FLOAT"
3974   "fminnm\\t%<s>0, %<s>1, %<s>2"
3975   [(set_attr "type" "f_minmax<s>")]
3978 ;; -------------------------------------------------------------------
3979 ;; Reload support
3980 ;; -------------------------------------------------------------------
3982 (define_expand "aarch64_reload_mov<mode>"
3983   [(set (match_operand:TX 0 "register_operand" "=w")
3984         (match_operand:TX 1 "register_operand" "w"))
3985    (clobber (match_operand:DI 2 "register_operand" "=&r"))
3986   ]
3987   "TARGET_FLOAT"
3988   {
3989     rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
3990     rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
3991     gen_aarch64_movtilow_tilow (op0, op1);
3992     gen_aarch64_movdi_tihigh (operands[2], op1);
3993     gen_aarch64_movtihigh_di (op0, operands[2]);
3994     DONE;
3995   }
3998 ;; The following secondary reload helpers patterns are invoked
3999 ;; after or during reload as we don't want these patterns to start
4000 ;; kicking in during the combiner.
4002 (define_insn "aarch64_movdi_<mode>low"
4003   [(set (match_operand:DI 0 "register_operand" "=r")
4004         (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
4005   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4006   "fmov\\t%x0, %d1"
4007   [(set_attr "type" "f_mrc")
4008    (set_attr "length" "4")
4009   ])
4011 (define_insn "aarch64_movdi_<mode>high"
4012   [(set (match_operand:DI 0 "register_operand" "=r")
4013         (truncate:DI
4014           (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
4015                        (const_int 64))))]
4016   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4017   "fmov\\t%x0, %1.d[1]"
4018   [(set_attr "type" "f_mrc")
4019    (set_attr "length" "4")
4020   ])
4022 (define_insn "aarch64_mov<mode>high_di"
4023   [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
4024                          (const_int 64) (const_int 64))
4025         (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4026   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4027   "fmov\\t%0.d[1], %x1"
4028   [(set_attr "type" "f_mcr")
4029    (set_attr "length" "4")
4030   ])
4032 (define_insn "aarch64_mov<mode>low_di"
4033   [(set (match_operand:TX 0 "register_operand" "=w")
4034         (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4035   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4036   "fmov\\t%d0, %x1"
4037   [(set_attr "type" "f_mcr")
4038    (set_attr "length" "4")
4039   ])
4041 (define_insn "aarch64_movtilow_tilow"
4042   [(set (match_operand:TI 0 "register_operand" "=w")
4043         (zero_extend:TI
4044           (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
4045   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4046   "fmov\\t%d0, %d1"
4047   [(set_attr "type" "fmov")
4048    (set_attr "length" "4")
4049   ])
4051 ;; There is a deliberate reason why the parameters of high and lo_sum's
4052 ;; don't have modes for ADRP and ADD instructions.  This is to allow high
4053 ;; and lo_sum's to be used with the labels defining the jump tables in
4054 ;; rodata section.
4056 (define_expand "add_losym"
4057   [(set (match_operand 0 "register_operand" "=r")
4058         (lo_sum (match_operand 1 "register_operand" "r")
4059                 (match_operand 2 "aarch64_valid_symref" "S")))]
4060   ""
4062   machine_mode mode = GET_MODE (operands[0]);
4064   emit_insn ((mode == DImode
4065               ? gen_add_losym_di
4066               : gen_add_losym_si) (operands[0],
4067                                    operands[1],
4068                                    operands[2]));
4069   DONE;
4072 (define_insn "add_losym_<mode>"
4073   [(set (match_operand:P 0 "register_operand" "=r")
4074         (lo_sum:P (match_operand:P 1 "register_operand" "r")
4075                   (match_operand 2 "aarch64_valid_symref" "S")))]
4076   ""
4077   "add\\t%<w>0, %<w>1, :lo12:%a2"
4078   [(set_attr "type" "alu_imm")]
4081 (define_insn "ldr_got_small_<mode>"
4082   [(set (match_operand:PTR 0 "register_operand" "=r")
4083         (unspec:PTR [(mem:PTR (lo_sum:PTR
4084                               (match_operand:PTR 1 "register_operand" "r")
4085                               (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
4086                     UNSPEC_GOTSMALLPIC))]
4087   ""
4088   "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
4089   [(set_attr "type" "load1")]
4092 (define_insn "ldr_got_small_sidi"
4093   [(set (match_operand:DI 0 "register_operand" "=r")
4094         (zero_extend:DI
4095          (unspec:SI [(mem:SI (lo_sum:DI
4096                              (match_operand:DI 1 "register_operand" "r")
4097                              (match_operand:DI 2 "aarch64_valid_symref" "S")))]
4098                     UNSPEC_GOTSMALLPIC)))]
4099   "TARGET_ILP32"
4100   "ldr\\t%w0, [%1, #:got_lo12:%a2]"
4101   [(set_attr "type" "load1")]
4104 (define_insn "ldr_got_tiny"
4105   [(set (match_operand:DI 0 "register_operand" "=r")
4106         (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
4107                    UNSPEC_GOTTINYPIC))]
4108   ""
4109   "ldr\\t%0, %L1"
4110   [(set_attr "type" "load1")]
4113 (define_insn "aarch64_load_tp_hard"
4114   [(set (match_operand:DI 0 "register_operand" "=r")
4115         (unspec:DI [(const_int 0)] UNSPEC_TLS))]
4116   ""
4117   "mrs\\t%0, tpidr_el0"
4118   [(set_attr "type" "mrs")]
4121 ;; The TLS ABI specifically requires that the compiler does not schedule
4122 ;; instructions in the TLS stubs, in order to enable linker relaxation.
4123 ;; Therefore we treat the stubs as an atomic sequence.
4124 (define_expand "tlsgd_small"
4125  [(parallel [(set (match_operand 0 "register_operand" "")
4126                   (call (mem:DI (match_dup 2)) (const_int 1)))
4127              (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
4128              (clobber (reg:DI LR_REGNUM))])]
4129  ""
4131   operands[2] = aarch64_tls_get_addr ();
4134 (define_insn "*tlsgd_small"
4135   [(set (match_operand 0 "register_operand" "")
4136         (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
4137    (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
4138    (clobber (reg:DI LR_REGNUM))
4139   ]
4140   ""
4141   "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
4142   [(set_attr "type" "call")
4143    (set_attr "length" "16")])
4145 (define_insn "tlsie_small_<mode>"
4146   [(set (match_operand:PTR 0 "register_operand" "=r")
4147         (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
4148                    UNSPEC_GOTSMALLTLS))]
4149   ""
4150   "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
4151   [(set_attr "type" "load1")
4152    (set_attr "length" "8")]
4155 (define_insn "tlsie_small_sidi"
4156   [(set (match_operand:DI 0 "register_operand" "=r")
4157         (zero_extend:DI
4158           (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")]
4159                       UNSPEC_GOTSMALLTLS)))]
4160   ""
4161   "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
4162   [(set_attr "type" "load1")
4163    (set_attr "length" "8")]
4166 (define_expand "tlsle_small"
4167   [(set (match_operand 0 "register_operand" "=r")
4168         (unspec [(match_operand 1 "register_operand" "r")
4169                    (match_operand 2 "aarch64_tls_le_symref" "S")]
4170                    UNSPEC_GOTSMALLTLS))]
4171   ""
4173   machine_mode mode = GET_MODE (operands[0]);
4174   emit_insn ((mode == DImode
4175               ? gen_tlsle_small_di
4176               : gen_tlsle_small_si) (operands[0],
4177                                      operands[1],
4178                                      operands[2]));
4179   DONE;
4182 (define_insn "tlsle_small_<mode>"
4183   [(set (match_operand:P 0 "register_operand" "=r")
4184         (unspec:P [(match_operand:P 1 "register_operand" "r")
4185                    (match_operand 2 "aarch64_tls_le_symref" "S")]
4186                    UNSPEC_GOTSMALLTLS))]
4187   ""
4188   "add\\t%<w>0, %<w>1, #%G2\;add\\t%<w>0, %<w>0, #%L2"
4189   [(set_attr "type" "alu_sreg")
4190    (set_attr "length" "8")]
4193 (define_insn "tlsdesc_small_<mode>"
4194   [(set (reg:PTR R0_REGNUM)
4195         (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
4196                    UNSPEC_TLSDESC))
4197    (clobber (reg:DI LR_REGNUM))
4198    (clobber (reg:CC CC_REGNUM))
4199    (clobber (match_scratch:DI 1 "=r"))]
4200   "TARGET_TLS_DESC"
4201   "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
4202   [(set_attr "type" "call")
4203    (set_attr "length" "16")])
4205 (define_insn "stack_tie"
4206   [(set (mem:BLK (scratch))
4207         (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
4208                      (match_operand:DI 1 "register_operand" "rk")]
4209                     UNSPEC_PRLG_STK))]
4210   ""
4211   ""
4212   [(set_attr "length" "0")]
4215 ;; Named pattern for expanding thread pointer reference.
4216 (define_expand "get_thread_pointerdi"
4217   [(match_operand:DI 0 "register_operand" "=r")]
4218   ""
4220   rtx tmp = aarch64_load_tp (operands[0]);
4221   if (tmp != operands[0])
4222     emit_move_insn (operands[0], tmp);
4223   DONE;
4226 ;; Named patterns for stack smashing protection.
4227 (define_expand "stack_protect_set"
4228   [(match_operand 0 "memory_operand")
4229    (match_operand 1 "memory_operand")]
4230   ""
4232   machine_mode mode = GET_MODE (operands[0]);
4234   emit_insn ((mode == DImode
4235               ? gen_stack_protect_set_di
4236               : gen_stack_protect_set_si) (operands[0], operands[1]));
4237   DONE;
4240 (define_insn "stack_protect_set_<mode>"
4241   [(set (match_operand:PTR 0 "memory_operand" "=m")
4242         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
4243          UNSPEC_SP_SET))
4244    (set (match_scratch:PTR 2 "=&r") (const_int 0))]
4245   ""
4246   "ldr\\t%<w>2, %1\;str\\t%<w>2, %0\;mov\t%<w>2,0"
4247   [(set_attr "length" "12")
4248    (set_attr "type" "multiple")])
4250 (define_expand "stack_protect_test"
4251   [(match_operand 0 "memory_operand")
4252    (match_operand 1 "memory_operand")
4253    (match_operand 2)]
4254   ""
4256   rtx result;
4257   machine_mode mode = GET_MODE (operands[0]);
4259   result = gen_reg_rtx(mode);
4261   emit_insn ((mode == DImode
4262               ? gen_stack_protect_test_di
4263               : gen_stack_protect_test_si) (result,
4264                                             operands[0],
4265                                             operands[1]));
4267   if (mode == DImode)
4268     emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4269                                     result, const0_rtx, operands[2]));
4270   else
4271     emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4272                                     result, const0_rtx, operands[2]));
4273   DONE;
4276 (define_insn "stack_protect_test_<mode>"
4277   [(set (match_operand:PTR 0 "register_operand" "=r")
4278         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
4279                      (match_operand:PTR 2 "memory_operand" "m")]
4280          UNSPEC_SP_TEST))
4281    (clobber (match_scratch:PTR 3 "=&r"))]
4282   ""
4283   "ldr\t%<w>3, %x1\;ldr\t%<w>0, %x2\;eor\t%<w>0, %<w>3, %<w>0"
4284   [(set_attr "length" "12")
4285    (set_attr "type" "multiple")])
4287 ;; Write Floating-point Control Register.
4288 (define_insn "set_fpcr"
4289   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
4290   ""
4291   "msr\\tfpcr, %0"
4292   [(set_attr "type" "mrs")])
4294 ;; Read Floating-point Control Register.
4295 (define_insn "get_fpcr"
4296   [(set (match_operand:SI 0 "register_operand" "=r")
4297         (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
4298   ""
4299   "mrs\\t%0, fpcr"
4300   [(set_attr "type" "mrs")])
4302 ;; Write Floating-point Status Register.
4303 (define_insn "set_fpsr"
4304   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
4305   ""
4306   "msr\\tfpsr, %0"
4307   [(set_attr "type" "mrs")])
4309 ;; Read Floating-point Status Register.
4310 (define_insn "get_fpsr"
4311   [(set (match_operand:SI 0 "register_operand" "=r")
4312         (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
4313   ""
4314   "mrs\\t%0, fpsr"
4315   [(set_attr "type" "mrs")])
4318 ;; Define the subtract-one-and-jump insns so loop.c
4319 ;; knows what to generate.
4320 (define_expand "doloop_end"
4321   [(use (match_operand 0 "" ""))      ; loop pseudo
4322    (use (match_operand 1 "" ""))]     ; label
4323   "optimize > 0 && flag_modulo_sched"
4325   rtx s0;
4326   rtx bcomp;
4327   rtx loc_ref;
4328   rtx cc_reg;
4329   rtx insn;
4330   rtx cmp;
4332   /* Currently SMS relies on the do-loop pattern to recognize loops
4333      where (1) the control part consists of all insns defining and/or
4334      using a certain 'count' register and (2) the loop count can be
4335      adjusted by modifying this register prior to the loop.
4336      ??? The possible introduction of a new block to initialize the
4337      new IV can potentially affect branch optimizations.  */
4339   if (GET_MODE (operands[0]) != DImode)
4340     FAIL;
4342   s0 = operands [0];
4343   insn = emit_insn (gen_adddi3_compare0 (s0, s0, GEN_INT (-1)));
4345   cmp = XVECEXP (PATTERN (insn), 0, 0);
4346   cc_reg = SET_DEST (cmp);
4347   bcomp = gen_rtx_NE (VOIDmode, cc_reg, const0_rtx);
4348   loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
4349   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4350                                gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
4351                                                      loc_ref, pc_rtx)));
4352   DONE;
4355 ;; AdvSIMD Stuff
4356 (include "aarch64-simd.md")
4358 ;; Atomic Operations
4359 (include "atomics.md")
4361 ;; ldp/stp peephole patterns
4362 (include "aarch64-ldpstp.md")