gcc/ada/
[official-gcc.git] / gcc / config / aarch64 / aarch64.md
blob17570ba026b45df097f8838751eed86d7ce03609
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_FRECPE
79     UNSPEC_FRECPS
80     UNSPEC_FRECPX
81     UNSPEC_FRINTA
82     UNSPEC_FRINTI
83     UNSPEC_FRINTM
84     UNSPEC_FRINTN
85     UNSPEC_FRINTP
86     UNSPEC_FRINTX
87     UNSPEC_FRINTZ
88     UNSPEC_GOTSMALLPIC
89     UNSPEC_GOTSMALLTLS
90     UNSPEC_GOTTINYPIC
91     UNSPEC_LD1
92     UNSPEC_LD2
93     UNSPEC_LD2_DUP
94     UNSPEC_LD3
95     UNSPEC_LD3_DUP
96     UNSPEC_LD4
97     UNSPEC_LD4_DUP
98     UNSPEC_LD2_LANE
99     UNSPEC_LD3_LANE
100     UNSPEC_LD4_LANE
101     UNSPEC_MB
102     UNSPEC_NOP
103     UNSPEC_PRLG_STK
104     UNSPEC_RBIT
105     UNSPEC_SISD_NEG
106     UNSPEC_SISD_SSHL
107     UNSPEC_SISD_USHL
108     UNSPEC_SSHL_2S
109     UNSPEC_SSHR64
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_USHR64
121     UNSPEC_VSTRUCTDUMMY
122     UNSPEC_SP_SET
123     UNSPEC_SP_TEST
126 (define_c_enum "unspecv" [
127     UNSPECV_EH_RETURN           ; Represent EH_RETURN
128     UNSPECV_GET_FPCR            ; Represent fetch of FPCR content.
129     UNSPECV_SET_FPCR            ; Represent assign of FPCR content.
130     UNSPECV_GET_FPSR            ; Represent fetch of FPSR content.
131     UNSPECV_SET_FPSR            ; Represent assign of FPSR content.
132   ]
135 ;; If further include files are added the defintion of MD_INCLUDES
136 ;; must be updated.
138 (include "constraints.md")
139 (include "predicates.md")
140 (include "iterators.md")
142 ;; -------------------------------------------------------------------
143 ;; Instruction types and attributes
144 ;; -------------------------------------------------------------------
146 ; The "type" attribute is is included here from AArch32 backend to be able
147 ; to share pipeline descriptions.
148 (include "../arm/types.md")
150 ;; It is important to set the fp or simd attributes to yes when a pattern
151 ;; alternative uses the FP or SIMD register files, usually signified by use of
152 ;; the 'w' constraint.  This will ensure that the alternative will be
153 ;; disabled when compiling with -mgeneral-regs-only or with the +nofp/+nosimd
154 ;; architecture extensions.  If all the alternatives in a pattern use the
155 ;; FP or SIMD registers then the pattern predicate should include TARGET_FLOAT
156 ;; or TARGET_SIMD.
158 ;; Attribute that specifies whether or not the instruction touches fp
159 ;; registers.  When this is set to yes for an alternative, that alternative
160 ;; will be disabled when !TARGET_FLOAT.
161 (define_attr "fp" "no,yes" (const_string "no"))
163 ;; Attribute that specifies whether or not the instruction touches simd
164 ;; registers.  When this is set to yes for an alternative, that alternative
165 ;; will be disabled when !TARGET_SIMD.
166 (define_attr "simd" "no,yes" (const_string "no"))
168 (define_attr "length" ""
169   (const_int 4))
171 ;; Attribute that controls whether an alternative is enabled or not.
172 ;; Currently it is only used to disable alternatives which touch fp or simd
173 ;; registers when -mgeneral-regs-only is specified.
174 (define_attr "enabled" "no,yes"
175   (cond [(ior
176         (and (eq_attr "fp" "yes")
177              (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
178         (and (eq_attr "simd" "yes")
179              (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
180              (const_string "no")
181         ] (const_string "yes")))
183 ;; -------------------------------------------------------------------
184 ;; Pipeline descriptions and scheduling
185 ;; -------------------------------------------------------------------
187 ;; Processor types.
188 (include "aarch64-tune.md")
190 ;; True if the generic scheduling description should be used.
192 (define_attr "generic_sched" "yes,no"
193   (const (if_then_else
194           (eq_attr "tune" "cortexa53,cortexa15")
195           (const_string "no")
196           (const_string "yes"))))
198 ;; Scheduling
199 (include "../arm/cortex-a53.md")
200 (include "../arm/cortex-a15.md")
202 ;; -------------------------------------------------------------------
203 ;; Jumps and other miscellaneous insns
204 ;; -------------------------------------------------------------------
206 (define_insn "indirect_jump"
207   [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
208   ""
209   "br\\t%0"
210   [(set_attr "type" "branch")]
213 (define_insn "jump"
214   [(set (pc) (label_ref (match_operand 0 "" "")))]
215   ""
216   "b\\t%l0"
217   [(set_attr "type" "branch")]
220 (define_expand "cbranch<mode>4"
221   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
222                             [(match_operand:GPI 1 "register_operand" "")
223                              (match_operand:GPI 2 "aarch64_plus_operand" "")])
224                            (label_ref (match_operand 3 "" ""))
225                            (pc)))]
226   ""
227   "
228   operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
229                                          operands[2]);
230   operands[2] = const0_rtx;
231   "
234 (define_expand "cbranch<mode>4"
235   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
236                             [(match_operand:GPF 1 "register_operand" "")
237                              (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
238                            (label_ref (match_operand 3 "" ""))
239                            (pc)))]
240   ""
241   "
242   operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
243                                          operands[2]);
244   operands[2] = const0_rtx;
245   "
248 (define_insn "*condjump"
249   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
250                             [(match_operand 1 "cc_register" "") (const_int 0)])
251                            (label_ref (match_operand 2 "" ""))
252                            (pc)))]
253   ""
254   "b%m0\\t%l2"
255   [(set_attr "type" "branch")]
258 (define_expand "casesi"
259   [(match_operand:SI 0 "register_operand" "")   ; Index
260    (match_operand:SI 1 "const_int_operand" "")  ; Lower bound
261    (match_operand:SI 2 "const_int_operand" "")  ; Total range
262    (match_operand:DI 3 "" "")                   ; Table label
263    (match_operand:DI 4 "" "")]                  ; Out of range label
264   ""
265   {
266     if (operands[1] != const0_rtx)
267       {
268         rtx reg = gen_reg_rtx (SImode);
270         /* Canonical RTL says that if you have:
272            (minus (X) (CONST))
274            then this should be emitted as:
276            (plus (X) (-CONST))
278            The use of trunc_int_for_mode ensures that the resulting
279            constant can be represented in SImode, this is important
280            for the corner case where operand[1] is INT_MIN.  */
282         operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
284         if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
285               (operands[1], SImode))
286           operands[1] = force_reg (SImode, operands[1]);
287         emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
288         operands[0] = reg;
289       }
291     if (!aarch64_plus_operand (operands[2], SImode))
292       operands[2] = force_reg (SImode, operands[2]);
293     emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
294                                                  const0_rtx),
295                                     operands[0], operands[2], operands[4]));
297     operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
298     emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
299                                          operands[3]));
300     DONE;
301   }
304 (define_insn "casesi_dispatch"
305   [(parallel
306     [(set (pc)
307           (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
308                            (match_operand:SI 1 "register_operand" "r")]
309                         UNSPEC_CASESI)))
310      (clobber (reg:CC CC_REGNUM))
311      (clobber (match_scratch:DI 3 "=r"))
312      (clobber (match_scratch:DI 4 "=r"))
313      (use (label_ref (match_operand 2 "" "")))])]
314   ""
315   "*
316   return aarch64_output_casesi (operands);
317   "
318   [(set_attr "length" "16")
319    (set_attr "type" "branch")]
322 (define_insn "nop"
323   [(unspec[(const_int 0)] UNSPEC_NOP)]
324   ""
325   "nop"
326   [(set_attr "type" "no_insn")]
329 (define_insn "trap"
330   [(trap_if (const_int 1) (const_int 8))]
331   ""
332   "brk #1000"
333   [(set_attr "type" "trap")])
335 (define_expand "prologue"
336   [(clobber (const_int 0))]
337   ""
338   "
339   aarch64_expand_prologue ();
340   DONE;
341   "
344 (define_expand "epilogue"
345   [(clobber (const_int 0))]
346   ""
347   "
348   aarch64_expand_epilogue (false);
349   DONE;
350   "
353 (define_expand "sibcall_epilogue"
354   [(clobber (const_int 0))]
355   ""
356   "
357   aarch64_expand_epilogue (true);
358   DONE;
359   "
362 (define_insn "*do_return"
363   [(return)]
364   ""
365   "ret"
366   [(set_attr "type" "branch")]
369 (define_expand "return"
370   [(simple_return)]
371   "aarch64_use_return_insn_p ()"
372   ""
375 (define_insn "simple_return"
376   [(simple_return)]
377   ""
378   "ret"
379   [(set_attr "type" "branch")]
382 (define_insn "eh_return"
383   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
384     UNSPECV_EH_RETURN)]
385   ""
386   "#"
387   [(set_attr "type" "branch")]
391 (define_split
392   [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
393     UNSPECV_EH_RETURN)]
394   "reload_completed"
395   [(set (match_dup 1) (match_dup 0))]
396   {
397     operands[1] = aarch64_final_eh_return_addr ();
398   }
401 (define_insn "*cb<optab><mode>1"
402   [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
403                                 (const_int 0))
404                            (label_ref (match_operand 1 "" ""))
405                            (pc)))]
406   ""
407   "<cbz>\\t%<w>0, %l1"
408   [(set_attr "type" "branch")]
412 (define_insn "*tb<optab><mode>1"
413   [(set (pc) (if_then_else
414               (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
415                                     (const_int 1)
416                                     (match_operand 1 "const_int_operand" "n"))
417                    (const_int 0))
418              (label_ref (match_operand 2 "" ""))
419              (pc)))
420    (clobber (match_scratch:DI 3 "=r"))]
421   ""
422   "*
423   if (get_attr_length (insn) == 8)
424     return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
425   return \"<tbz>\\t%<w>0, %1, %l2\";
426   "
427   [(set_attr "type" "branch")
428    (set (attr "length")
429         (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
430                            (lt (minus (match_dup 2) (pc)) (const_int 32764)))
431                       (const_int 4)
432                       (const_int 8)))]
435 (define_insn "*cb<optab><mode>1"
436   [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
437                                  (const_int 0))
438                            (label_ref (match_operand 1 "" ""))
439                            (pc)))
440    (clobber (match_scratch:DI 2 "=r"))]
441   ""
442   "*
443   if (get_attr_length (insn) == 8)
444     return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
445   return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
446   "
447   [(set_attr "type" "branch")
448    (set (attr "length")
449         (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
450                            (lt (minus (match_dup 1) (pc)) (const_int 32764)))
451                       (const_int 4)
452                       (const_int 8)))]
455 ;; -------------------------------------------------------------------
456 ;; Subroutine calls and sibcalls
457 ;; -------------------------------------------------------------------
459 (define_expand "call_internal"
460   [(parallel [(call (match_operand 0 "memory_operand" "")
461                     (match_operand 1 "general_operand" ""))
462               (use (match_operand 2 "" ""))
463               (clobber (reg:DI LR_REGNUM))])])
465 (define_expand "call"
466   [(parallel [(call (match_operand 0 "memory_operand" "")
467                     (match_operand 1 "general_operand" ""))
468               (use (match_operand 2 "" ""))
469               (clobber (reg:DI LR_REGNUM))])]
470   ""
471   "
472   {
473     rtx callee, pat;
475     /* In an untyped call, we can get NULL for operand 2.  */
476     if (operands[2] == NULL)
477       operands[2] = const0_rtx;
479     /* Decide if we should generate indirect calls by loading the
480        64-bit address of the callee into a register before performing
481        the branch-and-link.  */
482     callee = XEXP (operands[0], 0);
483     if (GET_CODE (callee) == SYMBOL_REF
484         ? aarch64_is_long_call_p (callee)
485         : !REG_P (callee))
486       XEXP (operands[0], 0) = force_reg (Pmode, callee);
488     pat = gen_call_internal (operands[0], operands[1], operands[2]);
489     aarch64_emit_call_insn (pat);
490     DONE;
491   }"
494 (define_insn "*call_reg"
495   [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
496          (match_operand 1 "" ""))
497    (use (match_operand 2 "" ""))
498    (clobber (reg:DI LR_REGNUM))]
499   ""
500   "blr\\t%0"
501   [(set_attr "type" "call")]
504 (define_insn "*call_symbol"
505   [(call (mem:DI (match_operand:DI 0 "" ""))
506          (match_operand 1 "" ""))
507    (use (match_operand 2 "" ""))
508    (clobber (reg:DI LR_REGNUM))]
509   "GET_CODE (operands[0]) == SYMBOL_REF
510    && !aarch64_is_long_call_p (operands[0])"
511   "bl\\t%a0"
512   [(set_attr "type" "call")]
515 (define_expand "call_value_internal"
516   [(parallel [(set (match_operand 0 "" "")
517                    (call (match_operand 1 "memory_operand" "")
518                          (match_operand 2 "general_operand" "")))
519               (use (match_operand 3 "" ""))
520               (clobber (reg:DI LR_REGNUM))])])
522 (define_expand "call_value"
523   [(parallel [(set (match_operand 0 "" "")
524                    (call (match_operand 1 "memory_operand" "")
525                          (match_operand 2 "general_operand" "")))
526               (use (match_operand 3 "" ""))
527               (clobber (reg:DI LR_REGNUM))])]
528   ""
529   "
530   {
531     rtx callee, pat;
533     /* In an untyped call, we can get NULL for operand 3.  */
534     if (operands[3] == NULL)
535       operands[3] = const0_rtx;
537     /* Decide if we should generate indirect calls by loading the
538        64-bit address of the callee into a register before performing
539        the branch-and-link.  */
540     callee = XEXP (operands[1], 0);
541     if (GET_CODE (callee) == SYMBOL_REF
542         ? aarch64_is_long_call_p (callee)
543         : !REG_P (callee))
544       XEXP (operands[1], 0) = force_reg (Pmode, callee);
546     pat = gen_call_value_internal (operands[0], operands[1], operands[2],
547                                    operands[3]);
548     aarch64_emit_call_insn (pat);
549     DONE;
550   }"
553 (define_insn "*call_value_reg"
554   [(set (match_operand 0 "" "")
555         (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
556                       (match_operand 2 "" "")))
557    (use (match_operand 3 "" ""))
558    (clobber (reg:DI LR_REGNUM))]
559   ""
560   "blr\\t%1"
561   [(set_attr "type" "call")]
565 (define_insn "*call_value_symbol"
566   [(set (match_operand 0 "" "")
567         (call (mem:DI (match_operand:DI 1 "" ""))
568               (match_operand 2 "" "")))
569    (use (match_operand 3 "" ""))
570    (clobber (reg:DI LR_REGNUM))]
571   "GET_CODE (operands[1]) == SYMBOL_REF
572    && !aarch64_is_long_call_p (operands[1])"
573   "bl\\t%a1"
574   [(set_attr "type" "call")]
577 (define_expand "sibcall_internal"
578   [(parallel [(call (match_operand 0 "memory_operand" "")
579                     (match_operand 1 "general_operand" ""))
580               (return)
581               (use (match_operand 2 "" ""))])])
583 (define_expand "sibcall"
584   [(parallel [(call (match_operand 0 "memory_operand" "")
585                     (match_operand 1 "general_operand" ""))
586               (return)
587               (use (match_operand 2 "" ""))])]
588   ""
589   {
590     rtx pat;
592     if (!REG_P (XEXP (operands[0], 0))
593        && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
594      XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
596     if (operands[2] == NULL_RTX)
597       operands[2] = const0_rtx;
599     pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
600     aarch64_emit_call_insn (pat);
601     DONE;
602   }
605 (define_expand "sibcall_value_internal"
606   [(parallel [(set (match_operand 0 "" "")
607                    (call (match_operand 1 "memory_operand" "")
608                          (match_operand 2 "general_operand" "")))
609               (return)
610               (use (match_operand 3 "" ""))])])
612 (define_expand "sibcall_value"
613   [(parallel [(set (match_operand 0 "" "")
614                    (call (match_operand 1 "memory_operand" "")
615                          (match_operand 2 "general_operand" "")))
616               (return)
617               (use (match_operand 3 "" ""))])]
618   ""
619   {
620     rtx pat;
622     if (!REG_P (XEXP (operands[1], 0))
623        && (GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF))
624      XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
626     if (operands[3] == NULL_RTX)
627       operands[3] = const0_rtx;
629     pat = gen_sibcall_value_internal (operands[0], operands[1], operands[2],
630                                       operands[3]);
631     aarch64_emit_call_insn (pat);
632     DONE;
633   }
636 (define_insn "*sibcall_insn"
637   [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucs, Usf"))
638          (match_operand 1 "" ""))
639    (return)
640    (use (match_operand 2 "" ""))]
641   "SIBLING_CALL_P (insn)"
642   "@
643    br\\t%0
644    b\\t%a0"
645   [(set_attr "type" "branch, branch")]
648 (define_insn "*sibcall_value_insn"
649   [(set (match_operand 0 "" "")
650         (call (mem:DI
651                 (match_operand:DI 1 "aarch64_call_insn_operand" "Ucs, Usf"))
652               (match_operand 2 "" "")))
653    (return)
654    (use (match_operand 3 "" ""))]
655   "SIBLING_CALL_P (insn)"
656   "@
657    br\\t%1
658    b\\t%a1"
659   [(set_attr "type" "branch, branch")]
662 ;; Call subroutine returning any type.
664 (define_expand "untyped_call"
665   [(parallel [(call (match_operand 0 "")
666                     (const_int 0))
667               (match_operand 1 "")
668               (match_operand 2 "")])]
669   ""
671   int i;
673   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
675   for (i = 0; i < XVECLEN (operands[2], 0); i++)
676     {
677       rtx set = XVECEXP (operands[2], 0, i);
678       emit_move_insn (SET_DEST (set), SET_SRC (set));
679     }
681   /* The optimizer does not know that the call sets the function value
682      registers we stored in the result block.  We avoid problems by
683      claiming that all hard registers are used and clobbered at this
684      point.  */
685   emit_insn (gen_blockage ());
686   DONE;
689 ;; -------------------------------------------------------------------
690 ;; Moves
691 ;; -------------------------------------------------------------------
693 (define_expand "mov<mode>"
694   [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
695         (match_operand:SHORT 1 "general_operand" ""))]
696   ""
697   "
698     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
699       operands[1] = force_reg (<MODE>mode, operands[1]);
700   "
703 (define_insn "*mov<mode>_aarch64"
704   [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r,   *w,r,*w, m, m, r,*w,*w")
705         (match_operand:SHORT 1 "general_operand"      " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
706   "(register_operand (operands[0], <MODE>mode)
707     || aarch64_reg_or_zero (operands[1], <MODE>mode))"
709    switch (which_alternative)
710      {
711      case 0:
712        return "mov\t%w0, %w1";
713      case 1:
714        return "mov\t%w0, %1";
715      case 2:
716        return aarch64_output_scalar_simd_mov_immediate (operands[1],
717                                                         <MODE>mode);
718      case 3:
719        return "ldr<size>\t%w0, %1";
720      case 4:
721        return "ldr\t%<size>0, %1";
722      case 5:
723        return "str<size>\t%w1, %0";
724      case 6:
725        return "str\t%<size>1, %0";
726      case 7:
727        return "umov\t%w0, %1.<v>[0]";
728      case 8:
729        return "dup\t%0.<Vallxd>, %w1";
730      case 9:
731        return "dup\t%<Vetype>0, %1.<v>[0]";
732      default:
733        gcc_unreachable ();
734      }
736   [(set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
737                      neon_from_gp<q>,neon_from_gp<q>, neon_dup")
738    (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")]
741 (define_expand "mov<mode>"
742   [(set (match_operand:GPI 0 "nonimmediate_operand" "")
743         (match_operand:GPI 1 "general_operand" ""))]
744   ""
745   "
746     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
747       operands[1] = force_reg (<MODE>mode, operands[1]);
749     if (CONSTANT_P (operands[1]))
750       {
751         aarch64_expand_mov_immediate (operands[0], operands[1]);
752         DONE;
753       }
754   "
757 (define_insn "*movsi_aarch64"
758   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m,  m,r,r  ,*w, r,*w")
759         (match_operand:SI 1 "aarch64_mov_operand"  " r,r,k,M,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
760   "(register_operand (operands[0], SImode)
761     || aarch64_reg_or_zero (operands[1], SImode))"
762   "@
763    mov\\t%w0, %w1
764    mov\\t%w0, %w1
765    mov\\t%w0, %w1
766    mov\\t%w0, %1
767    ldr\\t%w0, %1
768    ldr\\t%s0, %1
769    str\\t%w1, %0
770    str\\t%s1, %0
771    adr\\t%x0, %a1
772    adrp\\t%x0, %A1
773    fmov\\t%s0, %w1
774    fmov\\t%w0, %s1
775    fmov\\t%s0, %s1"
776   [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
777                      adr,adr,f_mcr,f_mrc,fmov")
778    (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
781 (define_insn "*movdi_aarch64"
782   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m,  m,r,r,  *w, r,*w,w")
783         (match_operand:DI 1 "aarch64_mov_operand"  " r,r,k,N,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))]
784   "(register_operand (operands[0], DImode)
785     || aarch64_reg_or_zero (operands[1], DImode))"
786   "@
787    mov\\t%x0, %x1
788    mov\\t%0, %x1
789    mov\\t%x0, %1
790    mov\\t%x0, %1
791    ldr\\t%x0, %1
792    ldr\\t%d0, %1
793    str\\t%x1, %0
794    str\\t%d1, %0
795    adr\\t%x0, %a1
796    adrp\\t%x0, %A1
797    fmov\\t%d0, %x1
798    fmov\\t%x0, %d1
799    fmov\\t%d0, %d1
800    movi\\t%d0, %1"
801   [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
802                      adr,adr,f_mcr,f_mrc,fmov,fmov")
803    (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
804    (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
807 (define_insn "insv_imm<mode>"
808   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
809                           (const_int 16)
810                           (match_operand:GPI 1 "const_int_operand" "n"))
811         (match_operand:GPI 2 "const_int_operand" "n"))]
812   "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
813    && UINTVAL (operands[1]) % 16 == 0"
814   "movk\\t%<w>0, %X2, lsl %1"
815   [(set_attr "type" "mov_imm")]
818 (define_expand "movti"
819   [(set (match_operand:TI 0 "nonimmediate_operand" "")
820         (match_operand:TI 1 "general_operand" ""))]
821   ""
822   "
823     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
824       operands[1] = force_reg (TImode, operands[1]);
825   "
828 (define_insn "*movti_aarch64"
829   [(set (match_operand:TI 0
830          "nonimmediate_operand"  "=r, *w,r ,*w,r  ,Ump,Ump,*w,m")
831         (match_operand:TI 1
832          "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r  ,Z  , m,*w"))]
833   "(register_operand (operands[0], TImode)
834     || aarch64_reg_or_zero (operands[1], TImode))"
835   "@
836    #
837    #
838    #
839    orr\\t%0.16b, %1.16b, %1.16b
840    ldp\\t%0, %H0, %1
841    stp\\t%1, %H1, %0
842    stp\\txzr, xzr, %0
843    ldr\\t%q0, %1
844    str\\t%q1, %0"
845   [(set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \
846                              load2,store2,store2,f_loadd,f_stored")
847    (set_attr "length" "8,8,8,4,4,4,4,4,4")
848    (set_attr "simd" "*,*,*,yes,*,*,*,*,*")
849    (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
852 ;; Split a TImode register-register or register-immediate move into
853 ;; its component DImode pieces, taking care to handle overlapping
854 ;; source and dest registers.
855 (define_split
856    [(set (match_operand:TI 0 "register_operand" "")
857          (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
858   "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
859   [(const_int 0)]
861   aarch64_split_128bit_move (operands[0], operands[1]);
862   DONE;
865 (define_expand "mov<mode>"
866   [(set (match_operand:GPF 0 "nonimmediate_operand" "")
867         (match_operand:GPF 1 "general_operand" ""))]
868   ""
869   "
870     if (!TARGET_FLOAT)
871      {
872         sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
873         FAIL;
874      }
876     if (GET_CODE (operands[0]) == MEM)
877       operands[1] = force_reg (<MODE>mode, operands[1]);
878   "
881 (define_insn "*movsf_aarch64"
882   [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w  ,w,m,r,m ,r")
883         (match_operand:SF 1 "general_operand"      "?rY, w,w,Ufc,m,w,m,rY,r"))]
884   "TARGET_FLOAT && (register_operand (operands[0], SFmode)
885     || register_operand (operands[1], SFmode))"
886   "@
887    fmov\\t%s0, %w1
888    fmov\\t%w0, %s1
889    fmov\\t%s0, %s1
890    fmov\\t%s0, %1
891    ldr\\t%s0, %1
892    str\\t%s1, %0
893    ldr\\t%w0, %1
894    str\\t%w1, %0
895    mov\\t%w0, %w1"
896   [(set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
897                      f_loads,f_stores,f_loads,f_stores,mov_reg")]
900 (define_insn "*movdf_aarch64"
901   [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w  ,w,m,r,m ,r")
902         (match_operand:DF 1 "general_operand"      "?rY, w,w,Ufc,m,w,m,rY,r"))]
903   "TARGET_FLOAT && (register_operand (operands[0], DFmode)
904     || register_operand (operands[1], DFmode))"
905   "@
906    fmov\\t%d0, %x1
907    fmov\\t%x0, %d1
908    fmov\\t%d0, %d1
909    fmov\\t%d0, %1
910    ldr\\t%d0, %1
911    str\\t%d1, %0
912    ldr\\t%x0, %1
913    str\\t%x1, %0
914    mov\\t%x0, %x1"
915   [(set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
916                      f_loadd,f_stored,f_loadd,f_stored,mov_reg")]
919 (define_expand "movtf"
920   [(set (match_operand:TF 0 "nonimmediate_operand" "")
921         (match_operand:TF 1 "general_operand" ""))]
922   ""
923   "
924     if (!TARGET_FLOAT)
925      {
926         sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
927         FAIL;
928      }
930     if (GET_CODE (operands[0]) == MEM)
931       operands[1] = force_reg (TFmode, operands[1]);
932   "
935 (define_insn "*movtf_aarch64"
936   [(set (match_operand:TF 0
937          "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
938         (match_operand:TF 1
939          "general_operand"      " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
940   "TARGET_FLOAT && (register_operand (operands[0], TFmode)
941     || register_operand (operands[1], TFmode))"
942   "@
943    orr\\t%0.16b, %1.16b, %1.16b
944    #
945    #
946    #
947    movi\\t%0.2d, #0
948    fmov\\t%s0, wzr
949    ldr\\t%q0, %1
950    str\\t%q1, %0
951    ldp\\t%0, %H0, %1
952    stp\\t%1, %H1, %0"
953   [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,fconstd,fconstd,\
954                      f_loadd,f_stored,neon_load1_2reg,neon_store1_2reg")
955    (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
956    (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
957    (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
960 (define_split
961    [(set (match_operand:TF 0 "register_operand" "")
962          (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
963   "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
964   [(const_int 0)]
965   {
966     aarch64_split_128bit_move (operands[0], operands[1]);
967     DONE;
968   }
971 ;; 0 is dst
972 ;; 1 is src
973 ;; 2 is size of move in bytes
974 ;; 3 is alignment
976 (define_expand "movmemdi"
977   [(match_operand:BLK 0 "memory_operand")
978    (match_operand:BLK 1 "memory_operand")
979    (match_operand:DI 2 "immediate_operand")
980    (match_operand:DI 3 "immediate_operand")]
981    "!STRICT_ALIGNMENT"
983   if (aarch64_expand_movmem (operands))
984     DONE;
985   FAIL;
989 ;; Operands 1 and 3 are tied together by the final condition; so we allow
990 ;; fairly lax checking on the second memory operation.
991 (define_insn "load_pair<mode>"
992   [(set (match_operand:GPI 0 "register_operand" "=r")
993         (match_operand:GPI 1 "aarch64_mem_pair_operand" "Ump"))
994    (set (match_operand:GPI 2 "register_operand" "=r")
995         (match_operand:GPI 3 "memory_operand" "m"))]
996   "rtx_equal_p (XEXP (operands[3], 0),
997                 plus_constant (Pmode,
998                                XEXP (operands[1], 0),
999                                GET_MODE_SIZE (<MODE>mode)))"
1000   "ldp\\t%<w>0, %<w>2, %1"
1001   [(set_attr "type" "load2")]
1004 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1005 ;; fairly lax checking on the second memory operation.
1006 (define_insn "store_pair<mode>"
1007   [(set (match_operand:GPI 0 "aarch64_mem_pair_operand" "=Ump")
1008         (match_operand:GPI 1 "register_operand" "r"))
1009    (set (match_operand:GPI 2 "memory_operand" "=m")
1010         (match_operand:GPI 3 "register_operand" "r"))]
1011   "rtx_equal_p (XEXP (operands[2], 0),
1012                 plus_constant (Pmode,
1013                                XEXP (operands[0], 0),
1014                                GET_MODE_SIZE (<MODE>mode)))"
1015   "stp\\t%<w>1, %<w>3, %0"
1016   [(set_attr "type" "store2")]
1019 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1020 ;; fairly lax checking on the second memory operation.
1021 (define_insn "load_pair<mode>"
1022   [(set (match_operand:GPF 0 "register_operand" "=w")
1023         (match_operand:GPF 1 "aarch64_mem_pair_operand" "Ump"))
1024    (set (match_operand:GPF 2 "register_operand" "=w")
1025         (match_operand:GPF 3 "memory_operand" "m"))]
1026   "rtx_equal_p (XEXP (operands[3], 0),
1027                 plus_constant (Pmode,
1028                                XEXP (operands[1], 0),
1029                                GET_MODE_SIZE (<MODE>mode)))"
1030   "ldp\\t%<w>0, %<w>2, %1"
1031   [(set_attr "type" "neon_load1_2reg<q>")]
1034 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1035 ;; fairly lax checking on the second memory operation.
1036 (define_insn "store_pair<mode>"
1037   [(set (match_operand:GPF 0 "aarch64_mem_pair_operand" "=Ump")
1038         (match_operand:GPF 1 "register_operand" "w"))
1039    (set (match_operand:GPF 2 "memory_operand" "=m")
1040         (match_operand:GPF 3 "register_operand" "w"))]
1041   "rtx_equal_p (XEXP (operands[2], 0),
1042                 plus_constant (Pmode,
1043                                XEXP (operands[0], 0),
1044                                GET_MODE_SIZE (<MODE>mode)))"
1045   "stp\\t%<w>1, %<w>3, %0"
1046   [(set_attr "type" "neon_store1_2reg<q>")]
1049 ;; Load pair with post-index writeback.  This is primarily used in function
1050 ;; epilogues.
1051 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
1052   [(parallel
1053     [(set (match_operand:P 0 "register_operand" "=k")
1054           (plus:P (match_operand:P 1 "register_operand" "0")
1055                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1056      (set (match_operand:GPI 2 "register_operand" "=r")
1057           (mem:GPI (match_dup 1)))
1058      (set (match_operand:GPI 3 "register_operand" "=r")
1059           (mem:GPI (plus:P (match_dup 1)
1060                    (match_operand:P 5 "const_int_operand" "n"))))])]
1061   "INTVAL (operands[5]) == GET_MODE_SIZE (<GPI:MODE>mode)"
1062   "ldp\\t%<w>2, %<w>3, [%1], %4"
1063   [(set_attr "type" "load2")]
1066 (define_insn "loadwb_pair<GPF:mode>_<P:mode>"
1067   [(parallel
1068     [(set (match_operand:P 0 "register_operand" "=k")
1069           (plus:P (match_operand:P 1 "register_operand" "0")
1070                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1071      (set (match_operand:GPF 2 "register_operand" "=w")
1072           (mem:GPF (match_dup 1)))
1073      (set (match_operand:GPF 3 "register_operand" "=w")
1074           (mem:GPF (plus:P (match_dup 1)
1075                    (match_operand:P 5 "const_int_operand" "n"))))])]
1076   "INTVAL (operands[5]) == GET_MODE_SIZE (<GPF:MODE>mode)"
1077   "ldp\\t%<w>2, %<w>3, [%1], %4"
1078   [(set_attr "type" "neon_load1_2reg")]
1081 ;; Store pair with pre-index writeback.  This is primarily used in function
1082 ;; prologues.
1083 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
1084   [(parallel
1085     [(set (match_operand:P 0 "register_operand" "=&k")
1086           (plus:P (match_operand:P 1 "register_operand" "0")
1087                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1088      (set (mem:GPI (plus:P (match_dup 0)
1089                    (match_dup 4)))
1090           (match_operand:GPI 2 "register_operand" "r"))
1091      (set (mem:GPI (plus:P (match_dup 0)
1092                    (match_operand:P 5 "const_int_operand" "n")))
1093           (match_operand:GPI 3 "register_operand" "r"))])]
1094   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1095   "stp\\t%<w>2, %<w>3, [%0, %4]!"
1096   [(set_attr "type" "store2")]
1099 (define_insn "storewb_pair<GPF:mode>_<P:mode>"
1100   [(parallel
1101     [(set (match_operand:P 0 "register_operand" "=&k")
1102           (plus:P (match_operand:P 1 "register_operand" "0")
1103                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1104      (set (mem:GPF (plus:P (match_dup 0)
1105                    (match_dup 4)))
1106           (match_operand:GPF 2 "register_operand" "w"))
1107      (set (mem:GPF (plus:P (match_dup 0)
1108                    (match_operand:P 5 "const_int_operand" "n")))
1109           (match_operand:GPF 3 "register_operand" "w"))])]
1110   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPF:MODE>mode)"
1111   "stp\\t%<w>2, %<w>3, [%0, %4]!"
1112   [(set_attr "type" "neon_store1_2reg<q>")]
1115 ;; -------------------------------------------------------------------
1116 ;; Sign/Zero extension
1117 ;; -------------------------------------------------------------------
1119 (define_expand "<optab>sidi2"
1120   [(set (match_operand:DI 0 "register_operand")
1121         (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1122   ""
1125 (define_insn "*extendsidi2_aarch64"
1126   [(set (match_operand:DI 0 "register_operand" "=r,r")
1127         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1128   ""
1129   "@
1130    sxtw\t%0, %w1
1131    ldrsw\t%0, %1"
1132   [(set_attr "type" "extend,load1")]
1135 (define_insn "*zero_extendsidi2_aarch64"
1136   [(set (match_operand:DI 0 "register_operand" "=r,r")
1137         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1138   ""
1139   "@
1140    uxtw\t%0, %w1
1141    ldr\t%w0, %1"
1142   [(set_attr "type" "extend,load1")]
1145 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1146   [(set (match_operand:GPI 0 "register_operand")
1147         (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1148   ""
1151 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1152   [(set (match_operand:GPI 0 "register_operand" "=r,r")
1153         (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1154   ""
1155   "@
1156    sxt<SHORT:size>\t%<GPI:w>0, %w1
1157    ldrs<SHORT:size>\t%<GPI:w>0, %1"
1158   [(set_attr "type" "extend,load1")]
1161 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1162   [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1163         (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1164   ""
1165   "@
1166    uxt<SHORT:size>\t%<GPI:w>0, %w1
1167    ldr<SHORT:size>\t%w0, %1
1168    ldr\t%<SHORT:size>0, %1"
1169   [(set_attr "type" "extend,load1,load1")]
1172 (define_expand "<optab>qihi2"
1173   [(set (match_operand:HI 0 "register_operand")
1174         (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1175   ""
1178 (define_insn "*<optab>qihi2_aarch64"
1179   [(set (match_operand:HI 0 "register_operand" "=r,r")
1180         (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1181   ""
1182   "@
1183    <su>xtb\t%w0, %w1
1184    <ldrxt>b\t%w0, %1"
1185   [(set_attr "type" "extend,load1")]
1188 ;; -------------------------------------------------------------------
1189 ;; Simple arithmetic
1190 ;; -------------------------------------------------------------------
1192 (define_expand "add<mode>3"
1193   [(set
1194     (match_operand:GPI 0 "register_operand" "")
1195     (plus:GPI (match_operand:GPI 1 "register_operand" "")
1196               (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1197   ""
1198   "
1199   if (! aarch64_plus_operand (operands[2], VOIDmode))
1200     {
1201       rtx subtarget = ((optimize && can_create_pseudo_p ())
1202                        ? gen_reg_rtx (<MODE>mode) : operands[0]);
1203       HOST_WIDE_INT imm = INTVAL (operands[2]);
1205       if (imm < 0)
1206         imm = -(-imm & ~0xfff);
1207       else
1208         imm &= ~0xfff;
1210       emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1211       operands[1] = subtarget;
1212       operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1213     }
1214   "
1217 (define_insn "*addsi3_aarch64"
1218   [(set
1219     (match_operand:SI 0 "register_operand" "=rk,rk,w,rk")
1220     (plus:SI
1221      (match_operand:SI 1 "register_operand" "%rk,rk,w,rk")
1222      (match_operand:SI 2 "aarch64_plus_operand" "I,r,w,J")))]
1223   ""
1224   "@
1225   add\\t%w0, %w1, %2
1226   add\\t%w0, %w1, %w2
1227   add\\t%0.2s, %1.2s, %2.2s
1228   sub\\t%w0, %w1, #%n2"
1229   [(set_attr "type" "alu_imm,alu_sreg,neon_add,alu_imm")
1230    (set_attr "simd" "*,*,yes,*")]
1233 ;; zero_extend version of above
1234 (define_insn "*addsi3_aarch64_uxtw"
1235   [(set
1236     (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1237     (zero_extend:DI
1238      (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1239               (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1240   ""
1241   "@
1242   add\\t%w0, %w1, %2
1243   add\\t%w0, %w1, %w2
1244   sub\\t%w0, %w1, #%n2"
1245   [(set_attr "type" "alu_imm,alu_sreg,alu_imm")]
1248 (define_insn "*adddi3_aarch64"
1249   [(set
1250     (match_operand:DI 0 "register_operand" "=rk,rk,rk,!w")
1251     (plus:DI
1252      (match_operand:DI 1 "register_operand" "%rk,rk,rk,!w")
1253      (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,!w")))]
1254   ""
1255   "@
1256   add\\t%x0, %x1, %2
1257   add\\t%x0, %x1, %x2
1258   sub\\t%x0, %x1, #%n2
1259   add\\t%d0, %d1, %d2"
1260   [(set_attr "type" "alu_imm,alu_sreg,alu_imm,neon_add")
1261    (set_attr "simd" "*,*,*,yes")]
1264 (define_expand "addti3"
1265   [(set (match_operand:TI 0 "register_operand" "")
1266         (plus:TI (match_operand:TI 1 "register_operand" "")
1267                  (match_operand:TI 2 "register_operand" "")))]
1268   ""
1270   rtx low = gen_reg_rtx (DImode);
1271   emit_insn (gen_adddi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1272                                   gen_lowpart (DImode, operands[2])));
1274   rtx high = gen_reg_rtx (DImode);
1275   emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]),
1276                                  gen_highpart (DImode, operands[2])));
1278   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1279   emit_move_insn (gen_highpart (DImode, operands[0]), high);
1280   DONE;
1283 (define_insn "add<mode>3_compare0"
1284   [(set (reg:CC_NZ CC_REGNUM)
1285         (compare:CC_NZ
1286          (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1287                    (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1288          (const_int 0)))
1289    (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1290         (plus:GPI (match_dup 1) (match_dup 2)))]
1291   ""
1292   "@
1293   adds\\t%<w>0, %<w>1, %<w>2
1294   adds\\t%<w>0, %<w>1, %<w>2
1295   subs\\t%<w>0, %<w>1, #%n2"
1296   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1299 ;; zero_extend version of above
1300 (define_insn "*addsi3_compare0_uxtw"
1301   [(set (reg:CC_NZ CC_REGNUM)
1302         (compare:CC_NZ
1303          (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1304                   (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1305          (const_int 0)))
1306    (set (match_operand:DI 0 "register_operand" "=r,r,r")
1307         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1308   ""
1309   "@
1310   adds\\t%w0, %w1, %w2
1311   adds\\t%w0, %w1, %w2
1312   subs\\t%w0, %w1, #%n2"
1313   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1316 (define_insn "*adds_mul_imm_<mode>"
1317   [(set (reg:CC_NZ CC_REGNUM)
1318         (compare:CC_NZ
1319          (plus:GPI (mult:GPI
1320                     (match_operand:GPI 1 "register_operand" "r")
1321                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1322                    (match_operand:GPI 3 "register_operand" "r"))
1323          (const_int 0)))
1324    (set (match_operand:GPI 0 "register_operand" "=r")
1325         (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1326                   (match_dup 3)))]
1327   ""
1328   "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1329   [(set_attr "type" "alus_shift_imm")]
1332 (define_insn "*subs_mul_imm_<mode>"
1333   [(set (reg:CC_NZ CC_REGNUM)
1334         (compare:CC_NZ
1335          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1336                     (mult:GPI
1337                      (match_operand:GPI 2 "register_operand" "r")
1338                      (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1339          (const_int 0)))
1340    (set (match_operand:GPI 0 "register_operand" "=r")
1341         (minus:GPI (match_dup 1)
1342                    (mult:GPI (match_dup 2) (match_dup 3))))]
1343   ""
1344   "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1345   [(set_attr "type" "alus_shift_imm")]
1348 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1349   [(set (reg:CC_NZ CC_REGNUM)
1350         (compare:CC_NZ
1351          (plus:GPI
1352           (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1353           (match_operand:GPI 2 "register_operand" "r"))
1354         (const_int 0)))
1355    (set (match_operand:GPI 0 "register_operand" "=r")
1356         (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1357   ""
1358   "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1359   [(set_attr "type" "alus_ext")]
1362 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1363   [(set (reg:CC_NZ CC_REGNUM)
1364         (compare:CC_NZ
1365          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1366                     (ANY_EXTEND:GPI
1367                      (match_operand:ALLX 2 "register_operand" "r")))
1368         (const_int 0)))
1369    (set (match_operand:GPI 0 "register_operand" "=r")
1370         (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1371   ""
1372   "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1373   [(set_attr "type" "alus_ext")]
1376 (define_insn "*adds_<optab><mode>_multp2"
1377   [(set (reg:CC_NZ CC_REGNUM)
1378         (compare:CC_NZ
1379          (plus:GPI (ANY_EXTRACT:GPI
1380                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1381                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1382                     (match_operand 3 "const_int_operand" "n")
1383                     (const_int 0))
1384                    (match_operand:GPI 4 "register_operand" "r"))
1385         (const_int 0)))
1386    (set (match_operand:GPI 0 "register_operand" "=r")
1387         (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1388                                    (match_dup 3)
1389                                    (const_int 0))
1390                   (match_dup 4)))]
1391   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1392   "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1393   [(set_attr "type" "alus_ext")]
1396 (define_insn "*subs_<optab><mode>_multp2"
1397   [(set (reg:CC_NZ CC_REGNUM)
1398         (compare:CC_NZ
1399          (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1400                     (ANY_EXTRACT:GPI
1401                      (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1402                                (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1403                      (match_operand 3 "const_int_operand" "n")
1404                      (const_int 0)))
1405         (const_int 0)))
1406    (set (match_operand:GPI 0 "register_operand" "=r")
1407         (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1408                                   (mult:GPI (match_dup 1) (match_dup 2))
1409                                   (match_dup 3)
1410                                   (const_int 0))))]
1411   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1412   "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1413   [(set_attr "type" "alus_ext")]
1416 (define_insn "*add<mode>3nr_compare0"
1417   [(set (reg:CC_NZ CC_REGNUM)
1418         (compare:CC_NZ
1419          (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1420                    (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1421          (const_int 0)))]
1422   ""
1423   "@
1424   cmn\\t%<w>0, %<w>1
1425   cmn\\t%<w>0, %<w>1
1426   cmp\\t%<w>0, #%n1"
1427   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1430 (define_insn "*compare_neg<mode>"
1431   [(set (reg:CC_Z CC_REGNUM)
1432         (compare:CC_Z
1433          (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1434          (match_operand:GPI 1 "register_operand" "r")))]
1435   ""
1436   "cmn\\t%<w>1, %<w>0"
1437   [(set_attr "type" "alus_sreg")]
1440 (define_insn "*add_<shift>_<mode>"
1441   [(set (match_operand:GPI 0 "register_operand" "=r")
1442         (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1443                               (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1444                   (match_operand:GPI 3 "register_operand" "r")))]
1445   ""
1446   "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1447   [(set_attr "type" "alu_shift_imm")]
1450 ;; zero_extend version of above
1451 (define_insn "*add_<shift>_si_uxtw"
1452   [(set (match_operand:DI 0 "register_operand" "=r")
1453         (zero_extend:DI
1454          (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1455                              (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1456                   (match_operand:SI 3 "register_operand" "r"))))]
1457   ""
1458   "add\\t%w0, %w3, %w1, <shift> %2"
1459   [(set_attr "type" "alu_shift_imm")]
1462 (define_insn "*add_mul_imm_<mode>"
1463   [(set (match_operand:GPI 0 "register_operand" "=r")
1464         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1465                             (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1466                   (match_operand:GPI 3 "register_operand" "r")))]
1467   ""
1468   "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1469   [(set_attr "type" "alu_shift_imm")]
1472 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1473   [(set (match_operand:GPI 0 "register_operand" "=rk")
1474         (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1475                   (match_operand:GPI 2 "register_operand" "r")))]
1476   ""
1477   "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1478   [(set_attr "type" "alu_ext")]
1481 ;; zero_extend version of above
1482 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1483   [(set (match_operand:DI 0 "register_operand" "=rk")
1484         (zero_extend:DI
1485          (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1486                   (match_operand:GPI 2 "register_operand" "r"))))]
1487   ""
1488   "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1489   [(set_attr "type" "alu_ext")]
1492 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1493   [(set (match_operand:GPI 0 "register_operand" "=rk")
1494         (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1495                                (match_operand:ALLX 1 "register_operand" "r"))
1496                               (match_operand 2 "aarch64_imm3" "Ui3"))
1497                   (match_operand:GPI 3 "register_operand" "r")))]
1498   ""
1499   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1500   [(set_attr "type" "alu_ext")]
1503 ;; zero_extend version of above
1504 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1505   [(set (match_operand:DI 0 "register_operand" "=rk")
1506         (zero_extend:DI
1507          (plus:SI (ashift:SI (ANY_EXTEND:SI
1508                               (match_operand:SHORT 1 "register_operand" "r"))
1509                              (match_operand 2 "aarch64_imm3" "Ui3"))
1510                   (match_operand:SI 3 "register_operand" "r"))))]
1511   ""
1512   "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1513   [(set_attr "type" "alu_ext")]
1516 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1517   [(set (match_operand:GPI 0 "register_operand" "=rk")
1518         (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1519                              (match_operand:ALLX 1 "register_operand" "r"))
1520                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1521                   (match_operand:GPI 3 "register_operand" "r")))]
1522   ""
1523   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1524   [(set_attr "type" "alu_ext")]
1527 ;; zero_extend version of above
1528 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1529   [(set (match_operand:DI 0 "register_operand" "=rk")
1530         (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1531                              (match_operand:SHORT 1 "register_operand" "r"))
1532                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1533                   (match_operand:SI 3 "register_operand" "r"))))]
1534   ""
1535   "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1536   [(set_attr "type" "alu_ext")]
1539 (define_insn "*add_<optab><mode>_multp2"
1540   [(set (match_operand:GPI 0 "register_operand" "=rk")
1541         (plus:GPI (ANY_EXTRACT:GPI
1542                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1543                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1544                    (match_operand 3 "const_int_operand" "n")
1545                    (const_int 0))
1546                   (match_operand:GPI 4 "register_operand" "r")))]
1547   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1548   "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1549   [(set_attr "type" "alu_ext")]
1552 ;; zero_extend version of above
1553 (define_insn "*add_<optab>si_multp2_uxtw"
1554   [(set (match_operand:DI 0 "register_operand" "=rk")
1555         (zero_extend:DI
1556          (plus:SI (ANY_EXTRACT:SI
1557                    (mult:SI (match_operand:SI 1 "register_operand" "r")
1558                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1559                    (match_operand 3 "const_int_operand" "n")
1560                    (const_int 0))
1561                   (match_operand:SI 4 "register_operand" "r"))))]
1562   "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1563   "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1564   [(set_attr "type" "alu_ext")]
1567 (define_insn "add<mode>3_carryin"
1568   [(set
1569     (match_operand:GPI 0 "register_operand" "=r")
1570     (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1571               (plus:GPI
1572                 (match_operand:GPI 1 "register_operand" "r")
1573                 (match_operand:GPI 2 "register_operand" "r"))))]
1574    ""
1575    "adc\\t%<w>0, %<w>1, %<w>2"
1576   [(set_attr "type" "adc_reg")]
1579 ;; zero_extend version of above
1580 (define_insn "*addsi3_carryin_uxtw"
1581   [(set
1582     (match_operand:DI 0 "register_operand" "=r")
1583     (zero_extend:DI
1584      (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1585               (plus:SI
1586                (match_operand:SI 1 "register_operand" "r")
1587                (match_operand:SI 2 "register_operand" "r")))))]
1588    ""
1589    "adc\\t%w0, %w1, %w2"
1590   [(set_attr "type" "adc_reg")]
1593 (define_insn "*add<mode>3_carryin_alt1"
1594   [(set
1595     (match_operand:GPI 0 "register_operand" "=r")
1596     (plus:GPI (plus:GPI
1597                 (match_operand:GPI 1 "register_operand" "r")
1598                 (match_operand:GPI 2 "register_operand" "r"))
1599               (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1600    ""
1601    "adc\\t%<w>0, %<w>1, %<w>2"
1602   [(set_attr "type" "adc_reg")]
1605 ;; zero_extend version of above
1606 (define_insn "*addsi3_carryin_alt1_uxtw"
1607   [(set
1608     (match_operand:DI 0 "register_operand" "=r")
1609     (zero_extend:DI
1610      (plus:SI (plus:SI
1611                (match_operand:SI 1 "register_operand" "r")
1612                (match_operand:SI 2 "register_operand" "r"))
1613               (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1614    ""
1615    "adc\\t%w0, %w1, %w2"
1616   [(set_attr "type" "adc_reg")]
1619 (define_insn "*add<mode>3_carryin_alt2"
1620   [(set
1621     (match_operand:GPI 0 "register_operand" "=r")
1622     (plus:GPI (plus:GPI
1623                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1624                 (match_operand:GPI 1 "register_operand" "r"))
1625               (match_operand:GPI 2 "register_operand" "r")))]
1626    ""
1627    "adc\\t%<w>0, %<w>1, %<w>2"
1628   [(set_attr "type" "adc_reg")]
1631 ;; zero_extend version of above
1632 (define_insn "*addsi3_carryin_alt2_uxtw"
1633   [(set
1634     (match_operand:DI 0 "register_operand" "=r")
1635     (zero_extend:DI
1636      (plus:SI (plus:SI
1637                (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1638                (match_operand:SI 1 "register_operand" "r"))
1639               (match_operand:SI 2 "register_operand" "r"))))]
1640    ""
1641    "adc\\t%w0, %w1, %w2"
1642   [(set_attr "type" "adc_reg")]
1645 (define_insn "*add<mode>3_carryin_alt3"
1646   [(set
1647     (match_operand:GPI 0 "register_operand" "=r")
1648     (plus:GPI (plus:GPI
1649                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1650                 (match_operand:GPI 2 "register_operand" "r"))
1651               (match_operand:GPI 1 "register_operand" "r")))]
1652    ""
1653    "adc\\t%<w>0, %<w>1, %<w>2"
1654   [(set_attr "type" "adc_reg")]
1657 ;; zero_extend version of above
1658 (define_insn "*addsi3_carryin_alt3_uxtw"
1659   [(set
1660     (match_operand:DI 0 "register_operand" "=r")
1661     (zero_extend:DI
1662      (plus:SI (plus:SI
1663                (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1664                (match_operand:SI 2 "register_operand" "r"))
1665               (match_operand:SI 1 "register_operand" "r"))))]
1666    ""
1667    "adc\\t%w0, %w1, %w2"
1668   [(set_attr "type" "adc_reg")]
1671 (define_insn "*add_uxt<mode>_multp2"
1672   [(set (match_operand:GPI 0 "register_operand" "=rk")
1673         (plus:GPI (and:GPI
1674                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1675                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1676                    (match_operand 3 "const_int_operand" "n"))
1677                   (match_operand:GPI 4 "register_operand" "r")))]
1678   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1679   "*
1680   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1681                                            INTVAL (operands[3])));
1682   return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1683   [(set_attr "type" "alu_ext")]
1686 ;; zero_extend version of above
1687 (define_insn "*add_uxtsi_multp2_uxtw"
1688   [(set (match_operand:DI 0 "register_operand" "=rk")
1689         (zero_extend:DI
1690          (plus:SI (and:SI
1691                    (mult:SI (match_operand:SI 1 "register_operand" "r")
1692                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1693                    (match_operand 3 "const_int_operand" "n"))
1694                   (match_operand:SI 4 "register_operand" "r"))))]
1695   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1696   "*
1697   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1698                                            INTVAL (operands[3])));
1699   return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1700   [(set_attr "type" "alu_ext")]
1703 (define_insn "subsi3"
1704   [(set (match_operand:SI 0 "register_operand" "=rk")
1705         (minus:SI (match_operand:SI 1 "register_operand" "r")
1706                    (match_operand:SI 2 "register_operand" "r")))]
1707   ""
1708   "sub\\t%w0, %w1, %w2"
1709   [(set_attr "type" "alu_sreg")]
1712 ;; zero_extend version of above
1713 (define_insn "*subsi3_uxtw"
1714   [(set (match_operand:DI 0 "register_operand" "=rk")
1715         (zero_extend:DI
1716          (minus:SI (match_operand:SI 1 "register_operand" "r")
1717                    (match_operand:SI 2 "register_operand" "r"))))]
1718   ""
1719   "sub\\t%w0, %w1, %w2"
1720   [(set_attr "type" "alu_sreg")]
1723 (define_insn "subdi3"
1724   [(set (match_operand:DI 0 "register_operand" "=rk,!w")
1725         (minus:DI (match_operand:DI 1 "register_operand" "r,!w")
1726                    (match_operand:DI 2 "register_operand" "r,!w")))]
1727   ""
1728   "@
1729    sub\\t%x0, %x1, %x2
1730    sub\\t%d0, %d1, %d2"
1731   [(set_attr "type" "alu_sreg, neon_sub")
1732    (set_attr "simd" "*,yes")]
1735 (define_expand "subti3"
1736   [(set (match_operand:TI 0 "register_operand" "")
1737         (minus:TI (match_operand:TI 1 "register_operand" "")
1738                   (match_operand:TI 2 "register_operand" "")))]
1739   ""
1741   rtx low = gen_reg_rtx (DImode);
1742   emit_insn (gen_subdi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1743                                   gen_lowpart (DImode, operands[2])));
1745   rtx high = gen_reg_rtx (DImode);
1746   emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]),
1747                                  gen_highpart (DImode, operands[2])));
1749   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1750   emit_move_insn (gen_highpart (DImode, operands[0]), high);
1751   DONE;
1754 (define_insn "sub<mode>3_compare0"
1755   [(set (reg:CC_NZ CC_REGNUM)
1756         (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1757                                   (match_operand:GPI 2 "register_operand" "r"))
1758                        (const_int 0)))
1759    (set (match_operand:GPI 0 "register_operand" "=r")
1760         (minus:GPI (match_dup 1) (match_dup 2)))]
1761   ""
1762   "subs\\t%<w>0, %<w>1, %<w>2"
1763   [(set_attr "type" "alus_sreg")]
1766 ;; zero_extend version of above
1767 (define_insn "*subsi3_compare0_uxtw"
1768   [(set (reg:CC_NZ CC_REGNUM)
1769         (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1770                                  (match_operand:SI 2 "register_operand" "r"))
1771                        (const_int 0)))
1772    (set (match_operand:DI 0 "register_operand" "=r")
1773         (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1774   ""
1775   "subs\\t%w0, %w1, %w2"
1776   [(set_attr "type" "alus_sreg")]
1779 (define_insn "*sub_<shift>_<mode>"
1780   [(set (match_operand:GPI 0 "register_operand" "=r")
1781         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1782                    (ASHIFT:GPI
1783                     (match_operand:GPI 1 "register_operand" "r")
1784                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1785   ""
1786   "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1787   [(set_attr "type" "alu_shift_imm")]
1790 ;; zero_extend version of above
1791 (define_insn "*sub_<shift>_si_uxtw"
1792   [(set (match_operand:DI 0 "register_operand" "=r")
1793         (zero_extend:DI
1794          (minus:SI (match_operand:SI 3 "register_operand" "r")
1795                    (ASHIFT:SI
1796                     (match_operand:SI 1 "register_operand" "r")
1797                     (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1798   ""
1799   "sub\\t%w0, %w3, %w1, <shift> %2"
1800   [(set_attr "type" "alu_shift_imm")]
1803 (define_insn "*sub_mul_imm_<mode>"
1804   [(set (match_operand:GPI 0 "register_operand" "=r")
1805         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1806                    (mult:GPI
1807                     (match_operand:GPI 1 "register_operand" "r")
1808                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1809   ""
1810   "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1811   [(set_attr "type" "alu_shift_imm")]
1814 ;; zero_extend version of above
1815 (define_insn "*sub_mul_imm_si_uxtw"
1816   [(set (match_operand:DI 0 "register_operand" "=r")
1817         (zero_extend:DI
1818          (minus:SI (match_operand:SI 3 "register_operand" "r")
1819                    (mult:SI
1820                     (match_operand:SI 1 "register_operand" "r")
1821                     (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
1822   ""
1823   "sub\\t%w0, %w3, %w1, lsl %p2"
1824   [(set_attr "type" "alu_shift_imm")]
1827 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
1828   [(set (match_operand:GPI 0 "register_operand" "=rk")
1829         (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1830                    (ANY_EXTEND:GPI
1831                     (match_operand:ALLX 2 "register_operand" "r"))))]
1832   ""
1833   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1834   [(set_attr "type" "alu_ext")]
1837 ;; zero_extend version of above
1838 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
1839   [(set (match_operand:DI 0 "register_operand" "=rk")
1840         (zero_extend:DI
1841          (minus:SI (match_operand:SI 1 "register_operand" "r")
1842                    (ANY_EXTEND:SI
1843                     (match_operand:SHORT 2 "register_operand" "r")))))]
1844   ""
1845   "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
1846   [(set_attr "type" "alu_ext")]
1849 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
1850   [(set (match_operand:GPI 0 "register_operand" "=rk")
1851         (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1852                    (ashift:GPI (ANY_EXTEND:GPI
1853                                 (match_operand:ALLX 2 "register_operand" "r"))
1854                                (match_operand 3 "aarch64_imm3" "Ui3"))))]
1855   ""
1856   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1857   [(set_attr "type" "alu_ext")]
1860 ;; zero_extend version of above
1861 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
1862   [(set (match_operand:DI 0 "register_operand" "=rk")
1863         (zero_extend:DI
1864          (minus:SI (match_operand:SI 1 "register_operand" "r")
1865                    (ashift:SI (ANY_EXTEND:SI
1866                                (match_operand:SHORT 2 "register_operand" "r"))
1867                               (match_operand 3 "aarch64_imm3" "Ui3")))))]
1868   ""
1869   "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
1870   [(set_attr "type" "alu_ext")]
1873 (define_insn "*sub_<optab><mode>_multp2"
1874   [(set (match_operand:GPI 0 "register_operand" "=rk")
1875         (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1876                    (ANY_EXTRACT:GPI
1877                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1878                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1879                     (match_operand 3 "const_int_operand" "n")
1880                     (const_int 0))))]
1881   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1882   "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1883   [(set_attr "type" "alu_ext")]
1886 ;; zero_extend version of above
1887 (define_insn "*sub_<optab>si_multp2_uxtw"
1888   [(set (match_operand:DI 0 "register_operand" "=rk")
1889         (zero_extend:DI
1890          (minus:SI (match_operand:SI 4 "register_operand" "r")
1891                    (ANY_EXTRACT:SI
1892                     (mult:SI (match_operand:SI 1 "register_operand" "r")
1893                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1894                     (match_operand 3 "const_int_operand" "n")
1895                     (const_int 0)))))]
1896   "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1897   "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1898   [(set_attr "type" "alu_ext")]
1901 (define_insn "sub<mode>3_carryin"
1902   [(set
1903     (match_operand:GPI 0 "register_operand" "=r")
1904     (minus:GPI (minus:GPI
1905                 (match_operand:GPI 1 "register_operand" "r")
1906                 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
1907                (match_operand:GPI 2 "register_operand" "r")))]
1908    ""
1909    "sbc\\t%<w>0, %<w>1, %<w>2"
1910   [(set_attr "type" "adc_reg")]
1913 ;; zero_extend version of the above
1914 (define_insn "*subsi3_carryin_uxtw"
1915   [(set
1916     (match_operand:DI 0 "register_operand" "=r")
1917     (zero_extend:DI
1918      (minus:SI (minus:SI
1919                 (match_operand:SI 1 "register_operand" "r")
1920                 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
1921                (match_operand:SI 2 "register_operand" "r"))))]
1922    ""
1923    "sbc\\t%w0, %w1, %w2"
1924   [(set_attr "type" "adc_reg")]
1927 (define_insn "*sub_uxt<mode>_multp2"
1928   [(set (match_operand:GPI 0 "register_operand" "=rk")
1929         (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1930                    (and:GPI
1931                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1932                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1933                     (match_operand 3 "const_int_operand" "n"))))]
1934   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1935   "*
1936   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1937                                            INTVAL (operands[3])));
1938   return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1939   [(set_attr "type" "alu_ext")]
1942 ;; zero_extend version of above
1943 (define_insn "*sub_uxtsi_multp2_uxtw"
1944   [(set (match_operand:DI 0 "register_operand" "=rk")
1945         (zero_extend:DI
1946          (minus:SI (match_operand:SI 4 "register_operand" "r")
1947                    (and:SI
1948                     (mult:SI (match_operand:SI 1 "register_operand" "r")
1949                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1950                     (match_operand 3 "const_int_operand" "n")))))]
1951   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1952   "*
1953   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1954                                            INTVAL (operands[3])));
1955   return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
1956   [(set_attr "type" "alu_ext")]
1959 (define_insn_and_split "absdi2"
1960   [(set (match_operand:DI 0 "register_operand" "=r,w")
1961         (abs:DI (match_operand:DI 1 "register_operand" "r,w")))
1962    (clobber (match_scratch:DI 2 "=&r,X"))]
1963   ""
1964   "@
1965    #
1966    abs\\t%d0, %d1"
1967   "reload_completed
1968    && GP_REGNUM_P (REGNO (operands[0]))
1969    && GP_REGNUM_P (REGNO (operands[1]))"
1970   [(const_int 0)]
1971   {
1972     emit_insn (gen_rtx_SET (VOIDmode, operands[2],
1973                             gen_rtx_XOR (DImode,
1974                                          gen_rtx_ASHIFTRT (DImode,
1975                                                            operands[1],
1976                                                            GEN_INT (63)),
1977                                          operands[1])));
1978     emit_insn (gen_rtx_SET (VOIDmode,
1979                             operands[0],
1980                             gen_rtx_MINUS (DImode,
1981                                            operands[2],
1982                                            gen_rtx_ASHIFTRT (DImode,
1983                                                              operands[1],
1984                                                              GEN_INT (63)))));
1985     DONE;
1986   }
1987   [(set_attr "type" "alu_sreg")
1988    (set_attr "simd" "no,yes")]
1991 (define_insn "neg<mode>2"
1992   [(set (match_operand:GPI 0 "register_operand" "=r,w")
1993         (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
1994   ""
1995   "@
1996    neg\\t%<w>0, %<w>1
1997    neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
1998   [(set_attr "type" "alu_sreg, neon_neg<q>")
1999    (set_attr "simd" "*,yes")]
2002 ;; zero_extend version of above
2003 (define_insn "*negsi2_uxtw"
2004   [(set (match_operand:DI 0 "register_operand" "=r")
2005         (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
2006   ""
2007   "neg\\t%w0, %w1"
2008   [(set_attr "type" "alu_sreg")]
2011 (define_insn "*ngc<mode>"
2012   [(set (match_operand:GPI 0 "register_operand" "=r")
2013         (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2014                    (match_operand:GPI 1 "register_operand" "r")))]
2015   ""
2016   "ngc\\t%<w>0, %<w>1"
2017   [(set_attr "type" "adc_reg")]
2020 (define_insn "*ngcsi_uxtw"
2021   [(set (match_operand:DI 0 "register_operand" "=r")
2022         (zero_extend:DI
2023          (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2024                    (match_operand:SI 1 "register_operand" "r"))))]
2025   ""
2026   "ngc\\t%w0, %w1"
2027   [(set_attr "type" "adc_reg")]
2030 (define_insn "*neg<mode>2_compare0"
2031   [(set (reg:CC_NZ CC_REGNUM)
2032         (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2033                        (const_int 0)))
2034    (set (match_operand:GPI 0 "register_operand" "=r")
2035         (neg:GPI (match_dup 1)))]
2036   ""
2037   "negs\\t%<w>0, %<w>1"
2038   [(set_attr "type" "alus_sreg")]
2041 ;; zero_extend version of above
2042 (define_insn "*negsi2_compare0_uxtw"
2043   [(set (reg:CC_NZ CC_REGNUM)
2044         (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
2045                        (const_int 0)))
2046    (set (match_operand:DI 0 "register_operand" "=r")
2047         (zero_extend:DI (neg:SI (match_dup 1))))]
2048   ""
2049   "negs\\t%w0, %w1"
2050   [(set_attr "type" "alus_sreg")]
2053 (define_insn "*neg_<shift><mode>3_compare0"
2054   [(set (reg:CC_NZ CC_REGNUM)
2055         (compare:CC_NZ
2056          (neg:GPI (ASHIFT:GPI
2057                    (match_operand:GPI 1 "register_operand" "r")
2058                    (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2059          (const_int 0)))
2060    (set (match_operand:GPI 0 "register_operand" "=r")
2061         (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2062   ""
2063   "negs\\t%<w>0, %<w>1, <shift> %2"
2064   [(set_attr "type" "alus_shift_imm")]
2067 (define_insn "*neg_<shift>_<mode>2"
2068   [(set (match_operand:GPI 0 "register_operand" "=r")
2069         (neg:GPI (ASHIFT:GPI
2070                   (match_operand:GPI 1 "register_operand" "r")
2071                   (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2072   ""
2073   "neg\\t%<w>0, %<w>1, <shift> %2"
2074   [(set_attr "type" "alu_shift_imm")]
2077 ;; zero_extend version of above
2078 (define_insn "*neg_<shift>_si2_uxtw"
2079   [(set (match_operand:DI 0 "register_operand" "=r")
2080         (zero_extend:DI
2081          (neg:SI (ASHIFT:SI
2082                   (match_operand:SI 1 "register_operand" "r")
2083                   (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2084   ""
2085   "neg\\t%w0, %w1, <shift> %2"
2086   [(set_attr "type" "alu_shift_imm")]
2089 (define_insn "*neg_mul_imm_<mode>2"
2090   [(set (match_operand:GPI 0 "register_operand" "=r")
2091         (neg:GPI (mult:GPI
2092                   (match_operand:GPI 1 "register_operand" "r")
2093                   (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2094   ""
2095   "neg\\t%<w>0, %<w>1, lsl %p2"
2096   [(set_attr "type" "alu_shift_imm")]
2099 ;; zero_extend version of above
2100 (define_insn "*neg_mul_imm_si2_uxtw"
2101   [(set (match_operand:DI 0 "register_operand" "=r")
2102         (zero_extend:DI
2103          (neg:SI (mult:SI
2104                   (match_operand:SI 1 "register_operand" "r")
2105                   (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2106   ""
2107   "neg\\t%w0, %w1, lsl %p2"
2108   [(set_attr "type" "alu_shift_imm")]
2111 (define_insn "mul<mode>3"
2112   [(set (match_operand:GPI 0 "register_operand" "=r")
2113         (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2114                   (match_operand:GPI 2 "register_operand" "r")))]
2115   ""
2116   "mul\\t%<w>0, %<w>1, %<w>2"
2117   [(set_attr "type" "mul")]
2120 ;; zero_extend version of above
2121 (define_insn "*mulsi3_uxtw"
2122   [(set (match_operand:DI 0 "register_operand" "=r")
2123         (zero_extend:DI
2124          (mult:SI (match_operand:SI 1 "register_operand" "r")
2125                   (match_operand:SI 2 "register_operand" "r"))))]
2126   ""
2127   "mul\\t%w0, %w1, %w2"
2128   [(set_attr "type" "mul")]
2131 (define_insn "madd<mode>"
2132   [(set (match_operand:GPI 0 "register_operand" "=r")
2133         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2134                             (match_operand:GPI 2 "register_operand" "r"))
2135                   (match_operand:GPI 3 "register_operand" "r")))]
2136   ""
2137   "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2138   [(set_attr "type" "mla")]
2141 ;; zero_extend version of above
2142 (define_insn "*maddsi_uxtw"
2143   [(set (match_operand:DI 0 "register_operand" "=r")
2144         (zero_extend:DI
2145          (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2146                            (match_operand:SI 2 "register_operand" "r"))
2147                   (match_operand:SI 3 "register_operand" "r"))))]
2148   ""
2149   "madd\\t%w0, %w1, %w2, %w3"
2150   [(set_attr "type" "mla")]
2153 (define_insn "*msub<mode>"
2154   [(set (match_operand:GPI 0 "register_operand" "=r")
2155         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2156                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2157                              (match_operand:GPI 2 "register_operand" "r"))))]
2159   ""
2160   "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2161   [(set_attr "type" "mla")]
2164 ;; zero_extend version of above
2165 (define_insn "*msubsi_uxtw"
2166   [(set (match_operand:DI 0 "register_operand" "=r")
2167         (zero_extend:DI
2168          (minus:SI (match_operand:SI 3 "register_operand" "r")
2169                    (mult:SI (match_operand:SI 1 "register_operand" "r")
2170                             (match_operand:SI 2 "register_operand" "r")))))]
2172   ""
2173   "msub\\t%w0, %w1, %w2, %w3"
2174   [(set_attr "type" "mla")]
2177 (define_insn "*mul<mode>_neg"
2178   [(set (match_operand:GPI 0 "register_operand" "=r")
2179         (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2180                   (match_operand:GPI 2 "register_operand" "r")))]
2182   ""
2183   "mneg\\t%<w>0, %<w>1, %<w>2"
2184   [(set_attr "type" "mul")]
2187 ;; zero_extend version of above
2188 (define_insn "*mulsi_neg_uxtw"
2189   [(set (match_operand:DI 0 "register_operand" "=r")
2190         (zero_extend:DI
2191          (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2192                   (match_operand:SI 2 "register_operand" "r"))))]
2194   ""
2195   "mneg\\t%w0, %w1, %w2"
2196   [(set_attr "type" "mul")]
2199 (define_insn "<su_optab>mulsidi3"
2200   [(set (match_operand:DI 0 "register_operand" "=r")
2201         (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2202                  (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2203   ""
2204   "<su>mull\\t%0, %w1, %w2"
2205   [(set_attr "type" "<su>mull")]
2208 (define_insn "<su_optab>maddsidi4"
2209   [(set (match_operand:DI 0 "register_operand" "=r")
2210         (plus:DI (mult:DI
2211                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2212                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2213                  (match_operand:DI 3 "register_operand" "r")))]
2214   ""
2215   "<su>maddl\\t%0, %w1, %w2, %3"
2216   [(set_attr "type" "<su>mlal")]
2219 (define_insn "<su_optab>msubsidi4"
2220   [(set (match_operand:DI 0 "register_operand" "=r")
2221         (minus:DI
2222          (match_operand:DI 3 "register_operand" "r")
2223          (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2224                   (ANY_EXTEND:DI
2225                    (match_operand:SI 2 "register_operand" "r")))))]
2226   ""
2227   "<su>msubl\\t%0, %w1, %w2, %3"
2228   [(set_attr "type" "<su>mlal")]
2231 (define_insn "*<su_optab>mulsidi_neg"
2232   [(set (match_operand:DI 0 "register_operand" "=r")
2233         (mult:DI (neg:DI
2234                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2235                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2236   ""
2237   "<su>mnegl\\t%0, %w1, %w2"
2238   [(set_attr "type" "<su>mull")]
2241 (define_expand "<su_optab>mulditi3"
2242   [(set (match_operand:TI 0 "register_operand")
2243         (mult:TI (ANY_EXTEND:TI (match_operand:DI 1 "register_operand"))
2244                  (ANY_EXTEND:TI (match_operand:DI 2 "register_operand"))))]
2245   ""
2247   rtx low = gen_reg_rtx (DImode);
2248   emit_insn (gen_muldi3 (low, operands[1], operands[2]));
2250   rtx high = gen_reg_rtx (DImode);
2251   emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2]));
2253   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2254   emit_move_insn (gen_highpart (DImode, operands[0]), high);
2255   DONE;
2258 ;; The default expansion of multi3 using umuldi3_highpart will perform
2259 ;; the additions in an order that fails to combine into two madd insns.
2260 (define_expand "multi3"
2261   [(set (match_operand:TI 0 "register_operand")
2262         (mult:TI (match_operand:TI 1 "register_operand")
2263                  (match_operand:TI 2 "register_operand")))]
2264   ""
2266   rtx l0 = gen_reg_rtx (DImode);
2267   rtx l1 = gen_lowpart (DImode, operands[1]);
2268   rtx l2 = gen_lowpart (DImode, operands[2]);
2269   rtx h0 = gen_reg_rtx (DImode);
2270   rtx h1 = gen_highpart (DImode, operands[1]);
2271   rtx h2 = gen_highpart (DImode, operands[2]);
2273   emit_insn (gen_muldi3 (l0, l1, l2));
2274   emit_insn (gen_umuldi3_highpart (h0, l1, l2));
2275   emit_insn (gen_madddi (h0, h1, l2, h0));
2276   emit_insn (gen_madddi (h0, l1, h2, h0));
2278   emit_move_insn (gen_lowpart (DImode, operands[0]), l0);
2279   emit_move_insn (gen_highpart (DImode, operands[0]), h0);
2280   DONE;
2283 (define_insn "<su>muldi3_highpart"
2284   [(set (match_operand:DI 0 "register_operand" "=r")
2285         (truncate:DI
2286          (lshiftrt:TI
2287           (mult:TI
2288            (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2289            (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2290           (const_int 64))))]
2291   ""
2292   "<su>mulh\\t%0, %1, %2"
2293   [(set_attr "type" "<su>mull")]
2296 (define_insn "<su_optab>div<mode>3"
2297   [(set (match_operand:GPI 0 "register_operand" "=r")
2298         (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2299                      (match_operand:GPI 2 "register_operand" "r")))]
2300   ""
2301   "<su>div\\t%<w>0, %<w>1, %<w>2"
2302   [(set_attr "type" "<su>div")]
2305 ;; zero_extend version of above
2306 (define_insn "*<su_optab>divsi3_uxtw"
2307   [(set (match_operand:DI 0 "register_operand" "=r")
2308         (zero_extend:DI
2309          (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2310                      (match_operand:SI 2 "register_operand" "r"))))]
2311   ""
2312   "<su>div\\t%w0, %w1, %w2"
2313   [(set_attr "type" "<su>div")]
2316 ;; -------------------------------------------------------------------
2317 ;; Comparison insns
2318 ;; -------------------------------------------------------------------
2320 (define_insn "*cmp<mode>"
2321   [(set (reg:CC CC_REGNUM)
2322         (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2323                     (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2324   ""
2325   "@
2326    cmp\\t%<w>0, %<w>1
2327    cmp\\t%<w>0, %<w>1
2328    cmn\\t%<w>0, #%n1"
2329   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
2332 (define_insn "*cmp<mode>"
2333   [(set (reg:CCFP CC_REGNUM)
2334         (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2335                       (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2336    "TARGET_FLOAT"
2337    "@
2338     fcmp\\t%<s>0, #0.0
2339     fcmp\\t%<s>0, %<s>1"
2340   [(set_attr "type" "fcmp<s>")]
2343 (define_insn "*cmpe<mode>"
2344   [(set (reg:CCFPE CC_REGNUM)
2345         (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2346                        (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2347    "TARGET_FLOAT"
2348    "@
2349     fcmpe\\t%<s>0, #0.0
2350     fcmpe\\t%<s>0, %<s>1"
2351   [(set_attr "type" "fcmp<s>")]
2354 (define_insn "*cmp_swp_<shift>_reg<mode>"
2355   [(set (reg:CC_SWP CC_REGNUM)
2356         (compare:CC_SWP (ASHIFT:GPI
2357                          (match_operand:GPI 0 "register_operand" "r")
2358                          (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2359                         (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2360   ""
2361   "cmp\\t%<w>2, %<w>0, <shift> %1"
2362   [(set_attr "type" "alus_shift_imm")]
2365 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2366   [(set (reg:CC_SWP CC_REGNUM)
2367         (compare:CC_SWP (ANY_EXTEND:GPI
2368                          (match_operand:ALLX 0 "register_operand" "r"))
2369                         (match_operand:GPI 1 "register_operand" "r")))]
2370   ""
2371   "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2372   [(set_attr "type" "alus_ext")]
2375 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2376   [(set (reg:CC_SWP CC_REGNUM)
2377         (compare:CC_SWP (ashift:GPI
2378                          (ANY_EXTEND:GPI
2379                           (match_operand:ALLX 0 "register_operand" "r"))
2380                          (match_operand 1 "aarch64_imm3" "Ui3"))
2381         (match_operand:GPI 2 "register_operand" "r")))]
2382   ""
2383   "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2384   [(set_attr "type" "alus_ext")]
2387 ;; -------------------------------------------------------------------
2388 ;; Store-flag and conditional select insns
2389 ;; -------------------------------------------------------------------
2391 (define_expand "cstore<mode>4"
2392   [(set (match_operand:SI 0 "register_operand" "")
2393         (match_operator:SI 1 "aarch64_comparison_operator"
2394          [(match_operand:GPI 2 "register_operand" "")
2395           (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2396   ""
2397   "
2398   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2399                                       operands[3]);
2400   operands[3] = const0_rtx;
2401   "
2404 (define_expand "cstore<mode>4"
2405   [(set (match_operand:SI 0 "register_operand" "")
2406         (match_operator:SI 1 "aarch64_comparison_operator"
2407          [(match_operand:GPF 2 "register_operand" "")
2408           (match_operand:GPF 3 "register_operand" "")]))]
2409   ""
2410   "
2411   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2412                                       operands[3]);
2413   operands[3] = const0_rtx;
2414   "
2417 (define_insn "*cstore<mode>_insn"
2418   [(set (match_operand:ALLI 0 "register_operand" "=r")
2419         (match_operator:ALLI 1 "aarch64_comparison_operator"
2420          [(match_operand 2 "cc_register" "") (const_int 0)]))]
2421   ""
2422   "cset\\t%<w>0, %m1"
2423   [(set_attr "type" "csel")]
2426 ;; zero_extend version of the above
2427 (define_insn "*cstoresi_insn_uxtw"
2428   [(set (match_operand:DI 0 "register_operand" "=r")
2429         (zero_extend:DI
2430          (match_operator:SI 1 "aarch64_comparison_operator"
2431           [(match_operand 2 "cc_register" "") (const_int 0)])))]
2432   ""
2433   "cset\\t%w0, %m1"
2434   [(set_attr "type" "csel")]
2437 (define_insn "cstore<mode>_neg"
2438   [(set (match_operand:ALLI 0 "register_operand" "=r")
2439         (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2440                   [(match_operand 2 "cc_register" "") (const_int 0)])))]
2441   ""
2442   "csetm\\t%<w>0, %m1"
2443   [(set_attr "type" "csel")]
2446 ;; zero_extend version of the above
2447 (define_insn "*cstoresi_neg_uxtw"
2448   [(set (match_operand:DI 0 "register_operand" "=r")
2449         (zero_extend:DI
2450          (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2451                   [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2452   ""
2453   "csetm\\t%w0, %m1"
2454   [(set_attr "type" "csel")]
2457 (define_expand "cmov<mode>6"
2458   [(set (match_operand:GPI 0 "register_operand" "")
2459         (if_then_else:GPI
2460          (match_operator 1 "aarch64_comparison_operator"
2461           [(match_operand:GPI 2 "register_operand" "")
2462            (match_operand:GPI 3 "aarch64_plus_operand" "")])
2463          (match_operand:GPI 4 "register_operand" "")
2464          (match_operand:GPI 5 "register_operand" "")))]
2465   ""
2466   "
2467   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2468                                       operands[3]);
2469   operands[3] = const0_rtx;
2470   "
2473 (define_expand "cmov<mode>6"
2474   [(set (match_operand:GPF 0 "register_operand" "")
2475         (if_then_else:GPF
2476          (match_operator 1 "aarch64_comparison_operator"
2477           [(match_operand:GPF 2 "register_operand" "")
2478            (match_operand:GPF 3 "register_operand" "")])
2479          (match_operand:GPF 4 "register_operand" "")
2480          (match_operand:GPF 5 "register_operand" "")))]
2481   ""
2482   "
2483   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2484                                       operands[3]);
2485   operands[3] = const0_rtx;
2486   "
2489 (define_insn "*cmov<mode>_insn"
2490   [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2491         (if_then_else:ALLI
2492          (match_operator 1 "aarch64_comparison_operator"
2493           [(match_operand 2 "cc_register" "") (const_int 0)])
2494          (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2495          (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2496   "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2497      || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2498   ;; Final two alternatives should be unreachable, but included for completeness
2499   "@
2500    csel\\t%<w>0, %<w>3, %<w>4, %m1
2501    csinv\\t%<w>0, %<w>3, <w>zr, %m1
2502    csinv\\t%<w>0, %<w>4, <w>zr, %M1
2503    csinc\\t%<w>0, %<w>3, <w>zr, %m1
2504    csinc\\t%<w>0, %<w>4, <w>zr, %M1
2505    mov\\t%<w>0, -1
2506    mov\\t%<w>0, 1"
2507   [(set_attr "type" "csel")]
2510 ;; zero_extend version of above
2511 (define_insn "*cmovsi_insn_uxtw"
2512   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2513         (zero_extend:DI
2514          (if_then_else:SI
2515           (match_operator 1 "aarch64_comparison_operator"
2516            [(match_operand 2 "cc_register" "") (const_int 0)])
2517           (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2518           (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2519   "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2520      || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2521   ;; Final two alternatives should be unreachable, but included for completeness
2522   "@
2523    csel\\t%w0, %w3, %w4, %m1
2524    csinv\\t%w0, %w3, wzr, %m1
2525    csinv\\t%w0, %w4, wzr, %M1
2526    csinc\\t%w0, %w3, wzr, %m1
2527    csinc\\t%w0, %w4, wzr, %M1
2528    mov\\t%w0, -1
2529    mov\\t%w0, 1"
2530   [(set_attr "type" "csel")]
2533 (define_insn "*cmov<mode>_insn"
2534   [(set (match_operand:GPF 0 "register_operand" "=w")
2535         (if_then_else:GPF
2536          (match_operator 1 "aarch64_comparison_operator"
2537           [(match_operand 2 "cc_register" "") (const_int 0)])
2538          (match_operand:GPF 3 "register_operand" "w")
2539          (match_operand:GPF 4 "register_operand" "w")))]
2540   "TARGET_FLOAT"
2541   "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2542   [(set_attr "type" "fcsel")]
2545 (define_expand "mov<mode>cc"
2546   [(set (match_operand:ALLI 0 "register_operand" "")
2547         (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2548                            (match_operand:ALLI 2 "register_operand" "")
2549                            (match_operand:ALLI 3 "register_operand" "")))]
2550   ""
2551   {
2552     rtx ccreg;
2553     enum rtx_code code = GET_CODE (operands[1]);
2555     if (code == UNEQ || code == LTGT)
2556       FAIL;
2558     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2559                                   XEXP (operands[1], 1));
2560     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2561   }
2564 (define_expand "mov<GPF:mode><GPI:mode>cc"
2565   [(set (match_operand:GPI 0 "register_operand" "")
2566         (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2567                           (match_operand:GPF 2 "register_operand" "")
2568                           (match_operand:GPF 3 "register_operand" "")))]
2569   ""
2570   {
2571     rtx ccreg;
2572     enum rtx_code code = GET_CODE (operands[1]);
2574     if (code == UNEQ || code == LTGT)
2575       FAIL;
2577     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2578                                   XEXP (operands[1], 1));
2579     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2580   }
2583 (define_expand "mov<mode>cc"
2584   [(set (match_operand:GPF 0 "register_operand" "")
2585         (if_then_else:GPF (match_operand 1 "aarch64_comparison_operator" "")
2586                           (match_operand:GPF 2 "register_operand" "")
2587                           (match_operand:GPF 3 "register_operand" "")))]
2588   ""
2589   {
2590     rtx ccreg;
2591     enum rtx_code code = GET_CODE (operands[1]);
2593     if (code == UNEQ || code == LTGT)
2594       FAIL;
2596     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2597                                   XEXP (operands[1], 1));
2598     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2599   }
2603 ;; CRC32 instructions.
2604 (define_insn "aarch64_<crc_variant>"
2605   [(set (match_operand:SI 0 "register_operand" "=r")
2606         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2607                     (match_operand:<crc_mode> 2 "register_operand" "r")]
2608          CRC))]
2609   "TARGET_CRC32"
2610   {
2611     if (GET_MODE_BITSIZE (GET_MODE (operands[2])) >= 64)
2612       return "<crc_variant>\\t%w0, %w1, %x2";
2613     else
2614       return "<crc_variant>\\t%w0, %w1, %w2";
2615   }
2616   [(set_attr "type" "crc")]
2619 (define_insn "*csinc2<mode>_insn"
2620   [(set (match_operand:GPI 0 "register_operand" "=r")
2621         (plus:GPI (match_operand 2 "aarch64_comparison_operation" "")
2622                   (match_operand:GPI 1 "register_operand" "r")))]
2623   ""
2624   "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2625   [(set_attr "type" "csel")]
2628 (define_insn "csinc3<mode>_insn"
2629   [(set (match_operand:GPI 0 "register_operand" "=r")
2630         (if_then_else:GPI
2631           (match_operand 1 "aarch64_comparison_operation" "")
2632           (plus:GPI (match_operand:GPI 2 "register_operand" "r")
2633                     (const_int 1))
2634           (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2635   ""
2636   "csinc\\t%<w>0, %<w>3, %<w>2, %M1"
2637   [(set_attr "type" "csel")]
2640 (define_insn "*csinv3<mode>_insn"
2641   [(set (match_operand:GPI 0 "register_operand" "=r")
2642         (if_then_else:GPI
2643           (match_operand 1 "aarch64_comparison_operation" "")
2644           (not:GPI (match_operand:GPI 2 "register_operand" "r"))
2645           (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2646   ""
2647   "csinv\\t%<w>0, %<w>3, %<w>2, %M1"
2648   [(set_attr "type" "csel")]
2651 (define_insn "*csneg3<mode>_insn"
2652   [(set (match_operand:GPI 0 "register_operand" "=r")
2653         (if_then_else:GPI
2654           (match_operand 1 "aarch64_comparison_operation" "")
2655           (neg:GPI (match_operand:GPI 2 "register_operand" "r"))
2656           (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2657   ""
2658   "csneg\\t%<w>0, %<w>3, %<w>2, %M1"
2659   [(set_attr "type" "csel")]
2662 ;; -------------------------------------------------------------------
2663 ;; Logical operations
2664 ;; -------------------------------------------------------------------
2666 (define_insn "<optab><mode>3"
2667   [(set (match_operand:GPI 0 "register_operand" "=r,rk")
2668         (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2669                      (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
2670   ""
2671   "<logical>\\t%<w>0, %<w>1, %<w>2"
2672   [(set_attr "type" "logic_reg,logic_imm")]
2675 ;; zero_extend version of above
2676 (define_insn "*<optab>si3_uxtw"
2677   [(set (match_operand:DI 0 "register_operand" "=r,rk")
2678         (zero_extend:DI
2679          (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2680                      (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2681   ""
2682   "<logical>\\t%w0, %w1, %w2"
2683   [(set_attr "type" "logic_reg,logic_imm")]
2686 (define_insn "*and<mode>3_compare0"
2687   [(set (reg:CC_NZ CC_REGNUM)
2688         (compare:CC_NZ
2689          (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2690                   (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2691          (const_int 0)))
2692    (set (match_operand:GPI 0 "register_operand" "=r,r")
2693         (and:GPI (match_dup 1) (match_dup 2)))]
2694   ""
2695   "ands\\t%<w>0, %<w>1, %<w>2"
2696   [(set_attr "type" "logics_reg,logics_imm")]
2699 ;; zero_extend version of above
2700 (define_insn "*andsi3_compare0_uxtw"
2701   [(set (reg:CC_NZ CC_REGNUM)
2702         (compare:CC_NZ
2703          (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2704                  (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2705          (const_int 0)))
2706    (set (match_operand:DI 0 "register_operand" "=r,r")
2707         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2708   ""
2709   "ands\\t%w0, %w1, %w2"
2710   [(set_attr "type" "logics_reg,logics_imm")]
2713 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2714   [(set (reg:CC_NZ CC_REGNUM)
2715         (compare:CC_NZ
2716          (and:GPI (SHIFT:GPI
2717                    (match_operand:GPI 1 "register_operand" "r")
2718                    (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2719                   (match_operand:GPI 3 "register_operand" "r"))
2720          (const_int 0)))
2721    (set (match_operand:GPI 0 "register_operand" "=r")
2722         (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2723   ""
2724   "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2725   [(set_attr "type" "logics_shift_imm")]
2728 ;; zero_extend version of above
2729 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2730   [(set (reg:CC_NZ CC_REGNUM)
2731         (compare:CC_NZ
2732          (and:SI (SHIFT:SI
2733                   (match_operand:SI 1 "register_operand" "r")
2734                   (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2735                  (match_operand:SI 3 "register_operand" "r"))
2736          (const_int 0)))
2737    (set (match_operand:DI 0 "register_operand" "=r")
2738         (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2739                                 (match_dup 3))))]
2740   ""
2741   "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2742   [(set_attr "type" "logics_shift_imm")]
2745 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2746   [(set (match_operand:GPI 0 "register_operand" "=r")
2747         (LOGICAL:GPI (SHIFT:GPI
2748                       (match_operand:GPI 1 "register_operand" "r")
2749                       (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2750                      (match_operand:GPI 3 "register_operand" "r")))]
2751   ""
2752   "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2753   [(set_attr "type" "logic_shift_imm")]
2756 (define_insn "*<optab>_rol<mode>3"
2757   [(set (match_operand:GPI 0 "register_operand" "=r")
2758         (LOGICAL:GPI (rotate:GPI
2759                       (match_operand:GPI 1 "register_operand" "r")
2760                       (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2761                      (match_operand:GPI 3 "register_operand" "r")))]
2762   ""
2763   "<logical>\\t%<w>0, %<w>3, %<w>1, ror (<sizen> - %2)"
2764   [(set_attr "type" "logic_shift_imm")]
2767 ;; zero_extend versions of above
2768 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
2769   [(set (match_operand:DI 0 "register_operand" "=r")
2770         (zero_extend:DI
2771          (LOGICAL:SI (SHIFT:SI
2772                       (match_operand:SI 1 "register_operand" "r")
2773                       (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2774                      (match_operand:SI 3 "register_operand" "r"))))]
2775   ""
2776   "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2777   [(set_attr "type" "logic_shift_imm")]
2780 (define_insn "*<optab>_rolsi3_uxtw"
2781   [(set (match_operand:DI 0 "register_operand" "=r")
2782         (zero_extend:DI
2783          (LOGICAL:SI (rotate:SI
2784                       (match_operand:SI 1 "register_operand" "r")
2785                       (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2786                      (match_operand:SI 3 "register_operand" "r"))))]
2787   ""
2788   "<logical>\\t%w0, %w3, %w1, ror (32 - %2)"
2789   [(set_attr "type" "logic_shift_imm")]
2792 (define_insn "one_cmpl<mode>2"
2793   [(set (match_operand:GPI 0 "register_operand" "=r")
2794         (not:GPI (match_operand:GPI 1 "register_operand" "r")))]
2795   ""
2796   "mvn\\t%<w>0, %<w>1"
2797   [(set_attr "type" "logic_reg")]
2800 (define_insn "*one_cmpl_<optab><mode>2"
2801   [(set (match_operand:GPI 0 "register_operand" "=r")
2802         (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
2803                             (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2804   ""
2805   "mvn\\t%<w>0, %<w>1, <shift> %2"
2806   [(set_attr "type" "logic_shift_imm")]
2809 (define_insn "*<LOGICAL:optab>_one_cmpl<mode>3"
2810   [(set (match_operand:GPI 0 "register_operand" "=r")
2811         (LOGICAL:GPI (not:GPI
2812                       (match_operand:GPI 1 "register_operand" "r"))
2813                      (match_operand:GPI 2 "register_operand" "r")))]
2814   ""
2815   "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1"
2816   [(set_attr "type" "logic_reg")]
2819 (define_insn "*and_one_cmpl<mode>3_compare0"
2820   [(set (reg:CC_NZ CC_REGNUM)
2821         (compare:CC_NZ
2822          (and:GPI (not:GPI
2823                    (match_operand:GPI 1 "register_operand" "r"))
2824                   (match_operand:GPI 2 "register_operand" "r"))
2825          (const_int 0)))
2826    (set (match_operand:GPI 0 "register_operand" "=r")
2827         (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
2828   ""
2829   "bics\\t%<w>0, %<w>2, %<w>1"
2830   [(set_attr "type" "logics_reg")]
2833 ;; zero_extend version of above
2834 (define_insn "*and_one_cmplsi3_compare0_uxtw"
2835   [(set (reg:CC_NZ CC_REGNUM)
2836         (compare:CC_NZ
2837          (and:SI (not:SI
2838                   (match_operand:SI 1 "register_operand" "r"))
2839                  (match_operand:SI 2 "register_operand" "r"))
2840          (const_int 0)))
2841    (set (match_operand:DI 0 "register_operand" "=r")
2842         (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
2843   ""
2844   "bics\\t%w0, %w2, %w1"
2845   [(set_attr "type" "logics_reg")]
2848 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
2849   [(set (match_operand:GPI 0 "register_operand" "=r")
2850         (LOGICAL:GPI (not:GPI
2851                       (SHIFT:GPI
2852                        (match_operand:GPI 1 "register_operand" "r")
2853                        (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2854                      (match_operand:GPI 3 "register_operand" "r")))]
2855   ""
2856   "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2857   [(set_attr "type" "logics_shift_imm")]
2860 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
2861   [(set (reg:CC_NZ CC_REGNUM)
2862         (compare:CC_NZ
2863          (and:GPI (not:GPI
2864                    (SHIFT:GPI
2865                     (match_operand:GPI 1 "register_operand" "r")
2866                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2867                   (match_operand:GPI 3 "register_operand" "r"))
2868          (const_int 0)))
2869    (set (match_operand:GPI 0 "register_operand" "=r")
2870         (and:GPI (not:GPI
2871                   (SHIFT:GPI
2872                    (match_dup 1) (match_dup 2))) (match_dup 3)))]
2873   ""
2874   "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2875   [(set_attr "type" "logics_shift_imm")]
2878 ;; zero_extend version of above
2879 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
2880   [(set (reg:CC_NZ CC_REGNUM)
2881         (compare:CC_NZ
2882          (and:SI (not:SI
2883                   (SHIFT:SI
2884                    (match_operand:SI 1 "register_operand" "r")
2885                    (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
2886                  (match_operand:SI 3 "register_operand" "r"))
2887          (const_int 0)))
2888    (set (match_operand:DI 0 "register_operand" "=r")
2889         (zero_extend:DI (and:SI
2890                          (not:SI
2891                           (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
2892   ""
2893   "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2894   [(set_attr "type" "logics_shift_imm")]
2897 (define_insn "clz<mode>2"
2898   [(set (match_operand:GPI 0 "register_operand" "=r")
2899         (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
2900   ""
2901   "clz\\t%<w>0, %<w>1"
2902   [(set_attr "type" "clz")]
2905 (define_expand "ffs<mode>2"
2906   [(match_operand:GPI 0 "register_operand")
2907    (match_operand:GPI 1 "register_operand")]
2908   ""
2909   {
2910     rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
2911     rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
2913     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2914     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2915     emit_insn (gen_csinc3<mode>_insn (operands[0], x, operands[0], const0_rtx));
2916     DONE;
2917   }
2920 (define_insn "clrsb<mode>2"
2921   [(set (match_operand:GPI 0 "register_operand" "=r")
2922         (clrsb:GPI (match_operand:GPI 1 "register_operand" "r")))]
2923   ""
2924   "cls\\t%<w>0, %<w>1"
2925   [(set_attr "type" "clz")]
2928 (define_insn "rbit<mode>2"
2929   [(set (match_operand:GPI 0 "register_operand" "=r")
2930         (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
2931   ""
2932   "rbit\\t%<w>0, %<w>1"
2933   [(set_attr "type" "rbit")]
2936 (define_expand "ctz<mode>2"
2937   [(match_operand:GPI 0 "register_operand")
2938    (match_operand:GPI 1 "register_operand")]
2939   ""
2940   {
2941     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2942     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2943     DONE;
2944   }
2947 (define_insn "*and<mode>3nr_compare0"
2948   [(set (reg:CC_NZ CC_REGNUM)
2949         (compare:CC_NZ
2950          (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
2951                   (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
2952          (const_int 0)))]
2953   ""
2954   "tst\\t%<w>0, %<w>1"
2955   [(set_attr "type" "logics_reg")]
2958 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
2959   [(set (reg:CC_NZ CC_REGNUM)
2960         (compare:CC_NZ
2961          (and:GPI (SHIFT:GPI
2962                    (match_operand:GPI 0 "register_operand" "r")
2963                    (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2964                   (match_operand:GPI 2 "register_operand" "r"))
2965         (const_int 0)))]
2966   ""
2967   "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
2968   [(set_attr "type" "logics_shift_imm")]
2971 ;; -------------------------------------------------------------------
2972 ;; Shifts
2973 ;; -------------------------------------------------------------------
2975 (define_expand "<optab><mode>3"
2976   [(set (match_operand:GPI 0 "register_operand")
2977         (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
2978                     (match_operand:QI 2 "nonmemory_operand")))]
2979   ""
2980   {
2981     if (CONST_INT_P (operands[2]))
2982       {
2983         operands[2] = GEN_INT (INTVAL (operands[2])
2984                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2986         if (operands[2] == const0_rtx)
2987           {
2988             emit_insn (gen_mov<mode> (operands[0], operands[1]));
2989             DONE;
2990           }
2991       }
2992   }
2995 (define_expand "ashl<mode>3"
2996   [(set (match_operand:SHORT 0 "register_operand")
2997         (ashift:SHORT (match_operand:SHORT 1 "register_operand")
2998                       (match_operand:QI 2 "nonmemory_operand")))]
2999   ""
3000   {
3001     if (CONST_INT_P (operands[2]))
3002       {
3003         operands[2] = GEN_INT (INTVAL (operands[2])
3004                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3006         if (operands[2] == const0_rtx)
3007           {
3008             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3009             DONE;
3010           }
3011       }
3012   }
3015 (define_expand "rotr<mode>3"
3016   [(set (match_operand:GPI 0 "register_operand")
3017         (rotatert:GPI (match_operand:GPI 1 "register_operand")
3018                       (match_operand:QI 2 "nonmemory_operand")))]
3019   ""
3020   {
3021     if (CONST_INT_P (operands[2]))
3022       {
3023         operands[2] = GEN_INT (INTVAL (operands[2])
3024                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3026         if (operands[2] == const0_rtx)
3027           {
3028             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3029             DONE;
3030           }
3031       }
3032   }
3035 (define_expand "rotl<mode>3"
3036   [(set (match_operand:GPI 0 "register_operand")
3037         (rotatert:GPI (match_operand:GPI 1 "register_operand")
3038                       (match_operand:QI 2 "nonmemory_operand")))]
3039   ""
3040   {
3041     /* (SZ - cnt) % SZ == -cnt % SZ */
3042     if (CONST_INT_P (operands[2]))
3043       {
3044         operands[2] = GEN_INT ((-INTVAL (operands[2]))
3045                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3046         if (operands[2] == const0_rtx)
3047           {
3048             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3049             DONE;
3050           }
3051       }
3052     else
3053       operands[2] = expand_simple_unop (QImode, NEG, operands[2],
3054                                         NULL_RTX, 1);
3055   }
3058 ;; Logical left shift using SISD or Integer instruction
3059 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
3060   [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3061         (ashift:GPI
3062           (match_operand:GPI 1 "register_operand" "w,w,r")
3063           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3064   ""
3065   "@
3066    shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3067    ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
3068    lsl\t%<w>0, %<w>1, %<w>2"
3069   [(set_attr "simd" "yes,yes,no")
3070    (set_attr "type" "neon_shift_imm<q>, neon_shift_reg<q>,shift_reg")]
3073 ;; Logical right shift using SISD or Integer instruction
3074 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3075   [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3076         (lshiftrt:GPI
3077           (match_operand:GPI 1 "register_operand" "w,w,r")
3078           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3079   ""
3080   "@
3081    ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3082    #
3083    lsr\t%<w>0, %<w>1, %<w>2"
3084   [(set_attr "simd" "yes,yes,no")
3085    (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")]
3088 (define_split
3089   [(set (match_operand:DI 0 "aarch64_simd_register")
3090         (lshiftrt:DI
3091            (match_operand:DI 1 "aarch64_simd_register")
3092            (match_operand:QI 2 "aarch64_simd_register")))]
3093   "TARGET_SIMD && reload_completed"
3094   [(set (match_dup 2)
3095         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3096    (set (match_dup 0)
3097         (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_USHL))]
3098   ""
3101 (define_split
3102   [(set (match_operand:SI 0 "aarch64_simd_register")
3103         (lshiftrt:SI
3104            (match_operand:SI 1 "aarch64_simd_register")
3105            (match_operand:QI 2 "aarch64_simd_register")))]
3106   "TARGET_SIMD && reload_completed"
3107   [(set (match_dup 2)
3108         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3109    (set (match_dup 0)
3110         (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_USHL_2S))]
3111   ""
3114 ;; Arithmetic right shift using SISD or Integer instruction
3115 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3116   [(set (match_operand:GPI 0 "register_operand" "=w,&w,&w,r")
3117         (ashiftrt:GPI
3118           (match_operand:GPI 1 "register_operand" "w,w,w,r")
3119           (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,0,rUs<cmode>")))]
3120   ""
3121   "@
3122    sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3123    #
3124    #
3125    asr\t%<w>0, %<w>1, %<w>2"
3126   [(set_attr "simd" "yes,yes,yes,no")
3127    (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>,shift_reg")]
3130 (define_split
3131   [(set (match_operand:DI 0 "aarch64_simd_register")
3132         (ashiftrt:DI
3133            (match_operand:DI 1 "aarch64_simd_register")
3134            (match_operand:QI 2 "aarch64_simd_register")))]
3135   "TARGET_SIMD && reload_completed"
3136   [(set (match_dup 3)
3137         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3138    (set (match_dup 0)
3139         (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_SSHL))]
3141   operands[3] = gen_lowpart (QImode, operands[0]);
3145 (define_split
3146   [(set (match_operand:SI 0 "aarch64_simd_register")
3147         (ashiftrt:SI
3148            (match_operand:SI 1 "aarch64_simd_register")
3149            (match_operand:QI 2 "aarch64_simd_register")))]
3150   "TARGET_SIMD && reload_completed"
3151   [(set (match_dup 3)
3152         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3153    (set (match_dup 0)
3154         (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_SSHL_2S))]
3156   operands[3] = gen_lowpart (QImode, operands[0]);
3160 (define_insn "*aarch64_sisd_ushl"
3161   [(set (match_operand:DI 0 "register_operand" "=w")
3162         (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3163                     (match_operand:QI 2 "register_operand" "w")]
3164                    UNSPEC_SISD_USHL))]
3165   "TARGET_SIMD"
3166   "ushl\t%d0, %d1, %d2"
3167   [(set_attr "simd" "yes")
3168    (set_attr "type" "neon_shift_reg")]
3171 (define_insn "*aarch64_ushl_2s"
3172   [(set (match_operand:SI 0 "register_operand" "=w")
3173         (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3174                     (match_operand:QI 2 "register_operand" "w")]
3175                    UNSPEC_USHL_2S))]
3176   "TARGET_SIMD"
3177   "ushl\t%0.2s, %1.2s, %2.2s"
3178   [(set_attr "simd" "yes")
3179    (set_attr "type" "neon_shift_reg")]
3182 (define_insn "*aarch64_sisd_sshl"
3183   [(set (match_operand:DI 0 "register_operand" "=w")
3184         (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3185                     (match_operand:QI 2 "register_operand" "w")]
3186                    UNSPEC_SISD_SSHL))]
3187   "TARGET_SIMD"
3188   "sshl\t%d0, %d1, %d2"
3189   [(set_attr "simd" "yes")
3190    (set_attr "type" "neon_shift_reg")]
3193 (define_insn "*aarch64_sshl_2s"
3194   [(set (match_operand:SI 0 "register_operand" "=w")
3195         (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3196                     (match_operand:QI 2 "register_operand" "w")]
3197                    UNSPEC_SSHL_2S))]
3198   "TARGET_SIMD"
3199   "sshl\t%0.2s, %1.2s, %2.2s"
3200   [(set_attr "simd" "yes")
3201    (set_attr "type" "neon_shift_reg")]
3204 (define_insn "*aarch64_sisd_neg_qi"
3205   [(set (match_operand:QI 0 "register_operand" "=w")
3206         (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3207                    UNSPEC_SISD_NEG))]
3208   "TARGET_SIMD"
3209   "neg\t%d0, %d1"
3210   [(set_attr "simd" "yes")
3211    (set_attr "type" "neon_neg")]
3214 ;; Rotate right
3215 (define_insn "*ror<mode>3_insn"
3216   [(set (match_operand:GPI 0 "register_operand" "=r")
3217         (rotatert:GPI
3218           (match_operand:GPI 1 "register_operand" "r")
3219           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3220   ""
3221   "ror\\t%<w>0, %<w>1, %<w>2"
3222   [(set_attr "type" "shift_reg")]
3225 ;; zero_extend version of above
3226 (define_insn "*<optab>si3_insn_uxtw"
3227   [(set (match_operand:DI 0 "register_operand" "=r")
3228         (zero_extend:DI (SHIFT:SI
3229          (match_operand:SI 1 "register_operand" "r")
3230          (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3231   ""
3232   "<shift>\\t%w0, %w1, %w2"
3233   [(set_attr "type" "shift_reg")]
3236 (define_insn "*ashl<mode>3_insn"
3237   [(set (match_operand:SHORT 0 "register_operand" "=r")
3238         (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3239                       (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
3240   ""
3241   "lsl\\t%<w>0, %<w>1, %<w>2"
3242   [(set_attr "type" "shift_reg")]
3245 (define_insn "*<optab><mode>3_insn"
3246   [(set (match_operand:SHORT 0 "register_operand" "=r")
3247         (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3248                       (match_operand 2 "const_int_operand" "n")))]
3249   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3251   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3252   return "<bfshift>\t%w0, %w1, %2, %3";
3254   [(set_attr "type" "bfm")]
3257 (define_insn "*extr<mode>5_insn"
3258   [(set (match_operand:GPI 0 "register_operand" "=r")
3259         (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3260                              (match_operand 3 "const_int_operand" "n"))
3261                  (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3262                                (match_operand 4 "const_int_operand" "n"))))]
3263   "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3264    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3265   "extr\\t%<w>0, %<w>1, %<w>2, %4"
3266   [(set_attr "type" "shift_imm")]
3269 ;; zero_extend version of the above
3270 (define_insn "*extrsi5_insn_uxtw"
3271   [(set (match_operand:DI 0 "register_operand" "=r")
3272         (zero_extend:DI
3273          (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3274                             (match_operand 3 "const_int_operand" "n"))
3275                  (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3276                               (match_operand 4 "const_int_operand" "n")))))]
3277   "UINTVAL (operands[3]) < 32 &&
3278    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3279   "extr\\t%w0, %w1, %w2, %4"
3280   [(set_attr "type" "shift_imm")]
3283 (define_insn "*ror<mode>3_insn"
3284   [(set (match_operand:GPI 0 "register_operand" "=r")
3285         (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3286                     (match_operand 2 "const_int_operand" "n")))]
3287   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3289   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3290   return "ror\\t%<w>0, %<w>1, %3";
3292   [(set_attr "type" "shift_imm")]
3295 ;; zero_extend version of the above
3296 (define_insn "*rorsi3_insn_uxtw"
3297   [(set (match_operand:DI 0 "register_operand" "=r")
3298         (zero_extend:DI
3299          (rotate:SI (match_operand:SI 1 "register_operand" "r")
3300                     (match_operand 2 "const_int_operand" "n"))))]
3301   "UINTVAL (operands[2]) < 32"
3303   operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3304   return "ror\\t%w0, %w1, %3";
3306   [(set_attr "type" "shift_imm")]
3309 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3310   [(set (match_operand:GPI 0 "register_operand" "=r")
3311         (ANY_EXTEND:GPI
3312          (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3313                        (match_operand 2 "const_int_operand" "n"))))]
3314   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3316   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3317   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3319   [(set_attr "type" "bfm")]
3322 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3323   [(set (match_operand:GPI 0 "register_operand" "=r")
3324         (zero_extend:GPI
3325          (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3326                          (match_operand 2 "const_int_operand" "n"))))]
3327   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3329   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3330   return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3332   [(set_attr "type" "bfm")]
3335 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3336   [(set (match_operand:GPI 0 "register_operand" "=r")
3337         (sign_extend:GPI
3338          (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3339                          (match_operand 2 "const_int_operand" "n"))))]
3340   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3342   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3343   return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3345   [(set_attr "type" "bfm")]
3348 ;; -------------------------------------------------------------------
3349 ;; Bitfields
3350 ;; -------------------------------------------------------------------
3352 (define_expand "<optab>"
3353   [(set (match_operand:DI 0 "register_operand" "=r")
3354         (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3355                         (match_operand 2 "const_int_operand" "n")
3356                         (match_operand 3 "const_int_operand" "n")))]
3357   ""
3358   ""
3361 (define_insn "*<optab><mode>"
3362   [(set (match_operand:GPI 0 "register_operand" "=r")
3363         (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3364                          (match_operand 2 "const_int_operand" "n")
3365                          (match_operand 3 "const_int_operand" "n")))]
3366   ""
3367   "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3368   [(set_attr "type" "bfm")]
3371 ;; Bitfield Insert (insv)
3372 (define_expand "insv<mode>"
3373   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3374                           (match_operand 1 "const_int_operand")
3375                           (match_operand 2 "const_int_operand"))
3376         (match_operand:GPI 3 "general_operand"))]
3377   ""
3379   unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3380   unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3381   rtx value = operands[3];
3383   if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3384     FAIL;
3386   if (CONST_INT_P (value))
3387     {
3388       unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3390       /* Prefer AND/OR for inserting all zeros or all ones.  */
3391       if ((UINTVAL (value) & mask) == 0
3392            || (UINTVAL (value) & mask) == mask)
3393         FAIL;
3395       /* 16-bit aligned 16-bit wide insert is handled by insv_imm.  */
3396       if (width == 16 && (pos % 16) == 0)
3397         DONE;
3398     }
3399   operands[3] = force_reg (<MODE>mode, value);
3402 (define_insn "*insv_reg<mode>"
3403   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3404                           (match_operand 1 "const_int_operand" "n")
3405                           (match_operand 2 "const_int_operand" "n"))
3406         (match_operand:GPI 3 "register_operand" "r"))]
3407   "!(UINTVAL (operands[1]) == 0
3408      || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3409          > GET_MODE_BITSIZE (<MODE>mode)))"
3410   "bfi\\t%<w>0, %<w>3, %2, %1"
3411   [(set_attr "type" "bfm")]
3414 (define_insn "*extr_insv_lower_reg<mode>"
3415   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3416                           (match_operand 1 "const_int_operand" "n")
3417                           (const_int 0))
3418         (zero_extract:GPI (match_operand:GPI 2 "register_operand" "r")
3419                           (match_dup 1)
3420                           (match_operand 3 "const_int_operand" "n")))]
3421   "!(UINTVAL (operands[1]) == 0
3422      || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3423          > GET_MODE_BITSIZE (<MODE>mode)))"
3424   "bfxil\\t%<w>0, %<w>2, %3, %1"
3425   [(set_attr "type" "bfm")]
3428 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3429   [(set (match_operand:GPI 0 "register_operand" "=r")
3430         (ashift:GPI (ANY_EXTEND:GPI
3431                      (match_operand:ALLX 1 "register_operand" "r"))
3432                     (match_operand 2 "const_int_operand" "n")))]
3433   "UINTVAL (operands[2]) < <GPI:sizen>"
3435   operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3436               ? GEN_INT (<ALLX:sizen>)
3437               : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3438   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3440   [(set_attr "type" "bfm")]
3443 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3445 (define_insn "*andim_ashift<mode>_bfiz"
3446   [(set (match_operand:GPI 0 "register_operand" "=r")
3447         (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3448                              (match_operand 2 "const_int_operand" "n"))
3449                  (match_operand 3 "const_int_operand" "n")))]
3450   "(INTVAL (operands[2]) < (<GPI:sizen>))
3451    && exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3452    && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3453   "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3454   [(set_attr "type" "bfm")]
3457 (define_insn "bswap<mode>2"
3458   [(set (match_operand:GPI 0 "register_operand" "=r")
3459         (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3460   ""
3461   "rev\\t%<w>0, %<w>1"
3462   [(set_attr "type" "rev")]
3465 (define_insn "bswaphi2"
3466   [(set (match_operand:HI 0 "register_operand" "=r")
3467         (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3468   ""
3469   "rev16\\t%w0, %w1"
3470   [(set_attr "type" "rev")]
3473 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
3474 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
3475 ;; each valid permutation.
3477 (define_insn "rev16<mode>2"
3478   [(set (match_operand:GPI 0 "register_operand" "=r")
3479         (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3480                                       (const_int 8))
3481                           (match_operand:GPI 3 "const_int_operand" "n"))
3482                  (and:GPI (lshiftrt:GPI (match_dup 1)
3483                                         (const_int 8))
3484                           (match_operand:GPI 2 "const_int_operand" "n"))))]
3485   "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3486    && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3487   "rev16\\t%<w>0, %<w>1"
3488   [(set_attr "type" "rev")]
3491 (define_insn "rev16<mode>2_alt"
3492   [(set (match_operand:GPI 0 "register_operand" "=r")
3493         (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r")
3494                                         (const_int 8))
3495                           (match_operand:GPI 2 "const_int_operand" "n"))
3496                  (and:GPI (ashift:GPI (match_dup 1)
3497                                       (const_int 8))
3498                           (match_operand:GPI 3 "const_int_operand" "n"))))]
3499   "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3500    && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3501   "rev16\\t%<w>0, %<w>1"
3502   [(set_attr "type" "rev")]
3505 ;; zero_extend version of above
3506 (define_insn "*bswapsi2_uxtw"
3507   [(set (match_operand:DI 0 "register_operand" "=r")
3508         (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3509   ""
3510   "rev\\t%w0, %w1"
3511   [(set_attr "type" "rev")]
3514 ;; -------------------------------------------------------------------
3515 ;; Floating-point intrinsics
3516 ;; -------------------------------------------------------------------
3518 ;; frint floating-point round to integral standard patterns.
3519 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round, frintn.
3521 (define_insn "<frint_pattern><mode>2"
3522   [(set (match_operand:GPF 0 "register_operand" "=w")
3523         (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3524          FRINT))]
3525   "TARGET_FLOAT"
3526   "frint<frint_suffix>\\t%<s>0, %<s>1"
3527   [(set_attr "type" "f_rint<s>")]
3530 ;; frcvt floating-point round to integer and convert standard patterns.
3531 ;; Expands to lbtrunc, lceil, lfloor, lround.
3532 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3533   [(set (match_operand:GPI 0 "register_operand" "=r")
3534         (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3535                       FCVT)))]
3536   "TARGET_FLOAT"
3537   "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3538   [(set_attr "type" "f_cvtf2i")]
3541 ;; fma - no throw
3543 (define_insn "fma<mode>4"
3544   [(set (match_operand:GPF 0 "register_operand" "=w")
3545         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3546                  (match_operand:GPF 2 "register_operand" "w")
3547                  (match_operand:GPF 3 "register_operand" "w")))]
3548   "TARGET_FLOAT"
3549   "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3550   [(set_attr "type" "fmac<s>")]
3553 (define_insn "fnma<mode>4"
3554   [(set (match_operand:GPF 0 "register_operand" "=w")
3555         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3556                  (match_operand:GPF 2 "register_operand" "w")
3557                  (match_operand:GPF 3 "register_operand" "w")))]
3558   "TARGET_FLOAT"
3559   "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3560   [(set_attr "type" "fmac<s>")]
3563 (define_insn "fms<mode>4"
3564   [(set (match_operand:GPF 0 "register_operand" "=w")
3565         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3566                  (match_operand:GPF 2 "register_operand" "w")
3567                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3568   "TARGET_FLOAT"
3569   "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3570   [(set_attr "type" "fmac<s>")]
3573 (define_insn "fnms<mode>4"
3574   [(set (match_operand:GPF 0 "register_operand" "=w")
3575         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3576                  (match_operand:GPF 2 "register_operand" "w")
3577                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3578   "TARGET_FLOAT"
3579   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3580   [(set_attr "type" "fmac<s>")]
3583 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3584 (define_insn "*fnmadd<mode>4"
3585   [(set (match_operand:GPF 0 "register_operand" "=w")
3586         (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3587                           (match_operand:GPF 2 "register_operand" "w")
3588                           (match_operand:GPF 3 "register_operand" "w"))))]
3589   "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3590   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3591   [(set_attr "type" "fmac<s>")]
3594 ;; -------------------------------------------------------------------
3595 ;; Floating-point conversions
3596 ;; -------------------------------------------------------------------
3598 (define_insn "extendsfdf2"
3599   [(set (match_operand:DF 0 "register_operand" "=w")
3600         (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3601   "TARGET_FLOAT"
3602   "fcvt\\t%d0, %s1"
3603   [(set_attr "type" "f_cvt")]
3606 (define_insn "truncdfsf2"
3607   [(set (match_operand:SF 0 "register_operand" "=w")
3608         (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3609   "TARGET_FLOAT"
3610   "fcvt\\t%s0, %d1"
3611   [(set_attr "type" "f_cvt")]
3614 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3615   [(set (match_operand:GPI 0 "register_operand" "=r")
3616         (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3617   "TARGET_FLOAT"
3618   "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3619   [(set_attr "type" "f_cvtf2i")]
3622 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3623   [(set (match_operand:GPI 0 "register_operand" "=r")
3624         (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3625   "TARGET_FLOAT"
3626   "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3627   [(set_attr "type" "f_cvtf2i")]
3630 (define_insn "<optab><fcvt_target><GPF:mode>2"
3631   [(set (match_operand:GPF 0 "register_operand" "=w,w")
3632         (FLOATUORS:GPF (match_operand:<FCVT_TARGET> 1 "register_operand" "w,r")))]
3633   ""
3634   "@
3635    <su_optab>cvtf\t%<GPF:s>0, %<s>1
3636    <su_optab>cvtf\t%<GPF:s>0, %<w1>1"
3637   [(set_attr "simd" "yes,no")
3638    (set_attr "fp" "no,yes")
3639    (set_attr "type" "neon_int_to_fp_<Vetype>,f_cvti2f")]
3642 (define_insn "<optab><fcvt_iesize><GPF:mode>2"
3643   [(set (match_operand:GPF 0 "register_operand" "=w")
3644         (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand" "r")))]
3645   "TARGET_FLOAT"
3646   "<su_optab>cvtf\t%<GPF:s>0, %<w2>1"
3647   [(set_attr "type" "f_cvti2f")]
3650 ;; -------------------------------------------------------------------
3651 ;; Floating-point arithmetic
3652 ;; -------------------------------------------------------------------
3654 (define_insn "add<mode>3"
3655   [(set (match_operand:GPF 0 "register_operand" "=w")
3656         (plus:GPF
3657          (match_operand:GPF 1 "register_operand" "w")
3658          (match_operand:GPF 2 "register_operand" "w")))]
3659   "TARGET_FLOAT"
3660   "fadd\\t%<s>0, %<s>1, %<s>2"
3661   [(set_attr "type" "fadd<s>")]
3664 (define_insn "sub<mode>3"
3665   [(set (match_operand:GPF 0 "register_operand" "=w")
3666         (minus:GPF
3667          (match_operand:GPF 1 "register_operand" "w")
3668          (match_operand:GPF 2 "register_operand" "w")))]
3669   "TARGET_FLOAT"
3670   "fsub\\t%<s>0, %<s>1, %<s>2"
3671   [(set_attr "type" "fadd<s>")]
3674 (define_insn "mul<mode>3"
3675   [(set (match_operand:GPF 0 "register_operand" "=w")
3676         (mult:GPF
3677          (match_operand:GPF 1 "register_operand" "w")
3678          (match_operand:GPF 2 "register_operand" "w")))]
3679   "TARGET_FLOAT"
3680   "fmul\\t%<s>0, %<s>1, %<s>2"
3681   [(set_attr "type" "fmul<s>")]
3684 (define_insn "*fnmul<mode>3"
3685   [(set (match_operand:GPF 0 "register_operand" "=w")
3686         (mult:GPF
3687                  (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3688                  (match_operand:GPF 2 "register_operand" "w")))]
3689   "TARGET_FLOAT"
3690   "fnmul\\t%<s>0, %<s>1, %<s>2"
3691   [(set_attr "type" "fmul<s>")]
3694 (define_insn "div<mode>3"
3695   [(set (match_operand:GPF 0 "register_operand" "=w")
3696         (div:GPF
3697          (match_operand:GPF 1 "register_operand" "w")
3698          (match_operand:GPF 2 "register_operand" "w")))]
3699   "TARGET_FLOAT"
3700   "fdiv\\t%<s>0, %<s>1, %<s>2"
3701   [(set_attr "type" "fdiv<s>")]
3704 (define_insn "neg<mode>2"
3705   [(set (match_operand:GPF 0 "register_operand" "=w")
3706         (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
3707   "TARGET_FLOAT"
3708   "fneg\\t%<s>0, %<s>1"
3709   [(set_attr "type" "ffarith<s>")]
3712 (define_insn "sqrt<mode>2"
3713   [(set (match_operand:GPF 0 "register_operand" "=w")
3714         (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
3715   "TARGET_FLOAT"
3716   "fsqrt\\t%<s>0, %<s>1"
3717   [(set_attr "type" "fsqrt<s>")]
3720 (define_insn "abs<mode>2"
3721   [(set (match_operand:GPF 0 "register_operand" "=w")
3722         (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
3723   "TARGET_FLOAT"
3724   "fabs\\t%<s>0, %<s>1"
3725   [(set_attr "type" "ffarith<s>")]
3728 ;; Given that smax/smin do not specify the result when either input is NaN,
3729 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
3730 ;; for smin.
3732 (define_insn "smax<mode>3"
3733   [(set (match_operand:GPF 0 "register_operand" "=w")
3734         (smax:GPF (match_operand:GPF 1 "register_operand" "w")
3735                   (match_operand:GPF 2 "register_operand" "w")))]
3736   "TARGET_FLOAT"
3737   "fmaxnm\\t%<s>0, %<s>1, %<s>2"
3738   [(set_attr "type" "f_minmax<s>")]
3741 (define_insn "smin<mode>3"
3742   [(set (match_operand:GPF 0 "register_operand" "=w")
3743         (smin:GPF (match_operand:GPF 1 "register_operand" "w")
3744                   (match_operand:GPF 2 "register_operand" "w")))]
3745   "TARGET_FLOAT"
3746   "fminnm\\t%<s>0, %<s>1, %<s>2"
3747   [(set_attr "type" "f_minmax<s>")]
3750 ;; -------------------------------------------------------------------
3751 ;; Reload support
3752 ;; -------------------------------------------------------------------
3754 (define_expand "aarch64_reload_mov<mode>"
3755   [(set (match_operand:TX 0 "register_operand" "=w")
3756         (match_operand:TX 1 "register_operand" "w"))
3757    (clobber (match_operand:DI 2 "register_operand" "=&r"))
3758   ]
3759   "TARGET_FLOAT"
3760   {
3761     rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
3762     rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
3763     gen_aarch64_movtilow_tilow (op0, op1);
3764     gen_aarch64_movdi_tihigh (operands[2], op1);
3765     gen_aarch64_movtihigh_di (op0, operands[2]);
3766     DONE;
3767   }
3770 ;; The following secondary reload helpers patterns are invoked
3771 ;; after or during reload as we don't want these patterns to start
3772 ;; kicking in during the combiner.
3774 (define_insn "aarch64_movdi_<mode>low"
3775   [(set (match_operand:DI 0 "register_operand" "=r")
3776         (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
3777   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
3778   "fmov\\t%x0, %d1"
3779   [(set_attr "type" "f_mrc")
3780    (set_attr "length" "4")
3781   ])
3783 (define_insn "aarch64_movdi_<mode>high"
3784   [(set (match_operand:DI 0 "register_operand" "=r")
3785         (truncate:DI
3786           (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
3787                        (const_int 64))))]
3788   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
3789   "fmov\\t%x0, %1.d[1]"
3790   [(set_attr "type" "f_mrc")
3791    (set_attr "length" "4")
3792   ])
3794 (define_insn "aarch64_mov<mode>high_di"
3795   [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
3796                          (const_int 64) (const_int 64))
3797         (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
3798   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
3799   "fmov\\t%0.d[1], %x1"
3800   [(set_attr "type" "f_mcr")
3801    (set_attr "length" "4")
3802   ])
3804 (define_insn "aarch64_mov<mode>low_di"
3805   [(set (match_operand:TX 0 "register_operand" "=w")
3806         (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
3807   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
3808   "fmov\\t%d0, %x1"
3809   [(set_attr "type" "f_mcr")
3810    (set_attr "length" "4")
3811   ])
3813 (define_insn "aarch64_movtilow_tilow"
3814   [(set (match_operand:TI 0 "register_operand" "=w")
3815         (zero_extend:TI
3816           (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
3817   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
3818   "fmov\\t%d0, %d1"
3819   [(set_attr "type" "fmov")
3820    (set_attr "length" "4")
3821   ])
3823 ;; There is a deliberate reason why the parameters of high and lo_sum's
3824 ;; don't have modes for ADRP and ADD instructions.  This is to allow high
3825 ;; and lo_sum's to be used with the labels defining the jump tables in
3826 ;; rodata section.
3828 (define_expand "add_losym"
3829   [(set (match_operand 0 "register_operand" "=r")
3830         (lo_sum (match_operand 1 "register_operand" "r")
3831                 (match_operand 2 "aarch64_valid_symref" "S")))]
3832   ""
3834   machine_mode mode = GET_MODE (operands[0]);
3836   emit_insn ((mode == DImode
3837               ? gen_add_losym_di
3838               : gen_add_losym_si) (operands[0],
3839                                    operands[1],
3840                                    operands[2]));
3841   DONE;
3844 (define_insn "add_losym_<mode>"
3845   [(set (match_operand:P 0 "register_operand" "=r")
3846         (lo_sum:P (match_operand:P 1 "register_operand" "r")
3847                   (match_operand 2 "aarch64_valid_symref" "S")))]
3848   ""
3849   "add\\t%<w>0, %<w>1, :lo12:%a2"
3850   [(set_attr "type" "alu_imm")]
3853 (define_insn "ldr_got_small_<mode>"
3854   [(set (match_operand:PTR 0 "register_operand" "=r")
3855         (unspec:PTR [(mem:PTR (lo_sum:PTR
3856                               (match_operand:PTR 1 "register_operand" "r")
3857                               (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
3858                     UNSPEC_GOTSMALLPIC))]
3859   ""
3860   "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
3861   [(set_attr "type" "load1")]
3864 (define_insn "ldr_got_small_sidi"
3865   [(set (match_operand:DI 0 "register_operand" "=r")
3866         (zero_extend:DI
3867          (unspec:SI [(mem:SI (lo_sum:DI
3868                              (match_operand:DI 1 "register_operand" "r")
3869                              (match_operand:DI 2 "aarch64_valid_symref" "S")))]
3870                     UNSPEC_GOTSMALLPIC)))]
3871   "TARGET_ILP32"
3872   "ldr\\t%w0, [%1, #:got_lo12:%a2]"
3873   [(set_attr "type" "load1")]
3876 (define_insn "ldr_got_tiny"
3877   [(set (match_operand:DI 0 "register_operand" "=r")
3878         (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
3879                    UNSPEC_GOTTINYPIC))]
3880   ""
3881   "ldr\\t%0, %L1"
3882   [(set_attr "type" "load1")]
3885 (define_insn "aarch64_load_tp_hard"
3886   [(set (match_operand:DI 0 "register_operand" "=r")
3887         (unspec:DI [(const_int 0)] UNSPEC_TLS))]
3888   ""
3889   "mrs\\t%0, tpidr_el0"
3890   [(set_attr "type" "mrs")]
3893 ;; The TLS ABI specifically requires that the compiler does not schedule
3894 ;; instructions in the TLS stubs, in order to enable linker relaxation.
3895 ;; Therefore we treat the stubs as an atomic sequence.
3896 (define_expand "tlsgd_small"
3897  [(parallel [(set (match_operand 0 "register_operand" "")
3898                   (call (mem:DI (match_dup 2)) (const_int 1)))
3899              (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
3900              (clobber (reg:DI LR_REGNUM))])]
3901  ""
3903   operands[2] = aarch64_tls_get_addr ();
3906 (define_insn "*tlsgd_small"
3907   [(set (match_operand 0 "register_operand" "")
3908         (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
3909    (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
3910    (clobber (reg:DI LR_REGNUM))
3911   ]
3912   ""
3913   "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
3914   [(set_attr "type" "call")
3915    (set_attr "length" "16")])
3917 (define_insn "tlsie_small_<mode>"
3918   [(set (match_operand:PTR 0 "register_operand" "=r")
3919         (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
3920                    UNSPEC_GOTSMALLTLS))]
3921   ""
3922   "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
3923   [(set_attr "type" "load1")
3924    (set_attr "length" "8")]
3927 (define_insn "tlsie_small_sidi"
3928   [(set (match_operand:DI 0 "register_operand" "=r")
3929         (zero_extend:DI
3930           (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")]
3931                       UNSPEC_GOTSMALLTLS)))]
3932   ""
3933   "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
3934   [(set_attr "type" "load1")
3935    (set_attr "length" "8")]
3938 (define_expand "tlsle_small"
3939   [(set (match_operand 0 "register_operand" "=r")
3940         (unspec [(match_operand 1 "register_operand" "r")
3941                    (match_operand 2 "aarch64_tls_le_symref" "S")]
3942                    UNSPEC_GOTSMALLTLS))]
3943   ""
3945   machine_mode mode = GET_MODE (operands[0]);
3946   emit_insn ((mode == DImode
3947               ? gen_tlsle_small_di
3948               : gen_tlsle_small_si) (operands[0],
3949                                      operands[1],
3950                                      operands[2]));
3951   DONE;
3954 (define_insn "tlsle_small_<mode>"
3955   [(set (match_operand:P 0 "register_operand" "=r")
3956         (unspec:P [(match_operand:P 1 "register_operand" "r")
3957                    (match_operand 2 "aarch64_tls_le_symref" "S")]
3958                    UNSPEC_GOTSMALLTLS))]
3959   ""
3960   "add\\t%<w>0, %<w>1, #%G2\;add\\t%<w>0, %<w>0, #%L2"
3961   [(set_attr "type" "alu_sreg")
3962    (set_attr "length" "8")]
3965 (define_insn "tlsdesc_small_<mode>"
3966   [(set (reg:PTR R0_REGNUM)
3967         (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
3968                    UNSPEC_TLSDESC))
3969    (clobber (reg:DI LR_REGNUM))
3970    (clobber (reg:CC CC_REGNUM))
3971    (clobber (match_scratch:DI 1 "=r"))]
3972   "TARGET_TLS_DESC"
3973   "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
3974   [(set_attr "type" "call")
3975    (set_attr "length" "16")])
3977 (define_insn "stack_tie"
3978   [(set (mem:BLK (scratch))
3979         (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
3980                      (match_operand:DI 1 "register_operand" "rk")]
3981                     UNSPEC_PRLG_STK))]
3982   ""
3983   ""
3984   [(set_attr "length" "0")]
3987 ;; Named pattern for expanding thread pointer reference.
3988 (define_expand "get_thread_pointerdi"
3989   [(match_operand:DI 0 "register_operand" "=r")]
3990   ""
3992   rtx tmp = aarch64_load_tp (operands[0]);
3993   if (tmp != operands[0])
3994     emit_move_insn (operands[0], tmp);
3995   DONE;
3998 ;; Named patterns for stack smashing protection.
3999 (define_expand "stack_protect_set"
4000   [(match_operand 0 "memory_operand")
4001    (match_operand 1 "memory_operand")]
4002   ""
4004   machine_mode mode = GET_MODE (operands[0]);
4006   emit_insn ((mode == DImode
4007               ? gen_stack_protect_set_di
4008               : gen_stack_protect_set_si) (operands[0], operands[1]));
4009   DONE;
4012 (define_insn "stack_protect_set_<mode>"
4013   [(set (match_operand:PTR 0 "memory_operand" "=m")
4014         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
4015          UNSPEC_SP_SET))
4016    (set (match_scratch:PTR 2 "=&r") (const_int 0))]
4017   ""
4018   "ldr\\t%<w>2, %1\;str\\t%<w>2, %0\;mov\t%<w>2,0"
4019   [(set_attr "length" "12")
4020    (set_attr "type" "multiple")])
4022 (define_expand "stack_protect_test"
4023   [(match_operand 0 "memory_operand")
4024    (match_operand 1 "memory_operand")
4025    (match_operand 2)]
4026   ""
4028   rtx result;
4029   machine_mode mode = GET_MODE (operands[0]);
4031   result = gen_reg_rtx(mode);
4033   emit_insn ((mode == DImode
4034               ? gen_stack_protect_test_di
4035               : gen_stack_protect_test_si) (result,
4036                                             operands[0],
4037                                             operands[1]));
4039   if (mode == DImode)
4040     emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4041                                     result, const0_rtx, operands[2]));
4042   else
4043     emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4044                                     result, const0_rtx, operands[2]));
4045   DONE;
4048 (define_insn "stack_protect_test_<mode>"
4049   [(set (match_operand:PTR 0 "register_operand" "=r")
4050         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
4051                      (match_operand:PTR 2 "memory_operand" "m")]
4052          UNSPEC_SP_TEST))
4053    (clobber (match_scratch:PTR 3 "=&r"))]
4054   ""
4055   "ldr\t%<w>3, %x1\;ldr\t%<w>0, %x2\;eor\t%<w>0, %<w>3, %<w>0"
4056   [(set_attr "length" "12")
4057    (set_attr "type" "multiple")])
4059 ;; Write Floating-point Control Register.
4060 (define_insn "set_fpcr"
4061   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
4062   ""
4063   "msr\\tfpcr, %0"
4064   [(set_attr "type" "mrs")])
4066 ;; Read Floating-point Control Register.
4067 (define_insn "get_fpcr"
4068   [(set (match_operand:SI 0 "register_operand" "=r")
4069         (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
4070   ""
4071   "mrs\\t%0, fpcr"
4072   [(set_attr "type" "mrs")])
4074 ;; Write Floating-point Status Register.
4075 (define_insn "set_fpsr"
4076   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
4077   ""
4078   "msr\\tfpsr, %0"
4079   [(set_attr "type" "mrs")])
4081 ;; Read Floating-point Status Register.
4082 (define_insn "get_fpsr"
4083   [(set (match_operand:SI 0 "register_operand" "=r")
4084         (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
4085   ""
4086   "mrs\\t%0, fpsr"
4087   [(set_attr "type" "mrs")])
4090 ;; AdvSIMD Stuff
4091 (include "aarch64-simd.md")
4093 ;; Atomic Operations
4094 (include "atomics.md")