Re: [AArch64] Implement ADD in vector registers for 32-bit scalar values.
[official-gcc.git] / gcc / config / aarch64 / aarch64.md
blob8705ee9d1892882af70b2a528d0007d3013a135b
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_CLS
71     UNSPEC_CRC32B
72     UNSPEC_CRC32CB
73     UNSPEC_CRC32CH
74     UNSPEC_CRC32CW
75     UNSPEC_CRC32CX
76     UNSPEC_CRC32H
77     UNSPEC_CRC32W
78     UNSPEC_CRC32X
79     UNSPEC_FRECPE
80     UNSPEC_FRECPS
81     UNSPEC_FRECPX
82     UNSPEC_FRINTA
83     UNSPEC_FRINTI
84     UNSPEC_FRINTM
85     UNSPEC_FRINTN
86     UNSPEC_FRINTP
87     UNSPEC_FRINTX
88     UNSPEC_FRINTZ
89     UNSPEC_GOTSMALLPIC
90     UNSPEC_GOTSMALLTLS
91     UNSPEC_GOTTINYPIC
92     UNSPEC_LD1
93     UNSPEC_LD2
94     UNSPEC_LD3
95     UNSPEC_LD4
96     UNSPEC_MB
97     UNSPEC_NOP
98     UNSPEC_PRLG_STK
99     UNSPEC_RBIT
100     UNSPEC_SISD_NEG
101     UNSPEC_SISD_SSHL
102     UNSPEC_SISD_USHL
103     UNSPEC_SSHL_2S
104     UNSPEC_SSHR64
105     UNSPEC_ST1
106     UNSPEC_ST2
107     UNSPEC_ST3
108     UNSPEC_ST4
109     UNSPEC_ST2_LANE
110     UNSPEC_ST3_LANE
111     UNSPEC_ST4_LANE
112     UNSPEC_TLS
113     UNSPEC_TLSDESC
114     UNSPEC_USHL_2S
115     UNSPEC_USHR64
116     UNSPEC_VSTRUCTDUMMY
117     UNSPEC_SP_SET
118     UNSPEC_SP_TEST
121 (define_c_enum "unspecv" [
122     UNSPECV_EH_RETURN           ; Represent EH_RETURN
123     UNSPECV_GET_FPCR            ; Represent fetch of FPCR content.
124     UNSPECV_SET_FPCR            ; Represent assign of FPCR content.
125     UNSPECV_GET_FPSR            ; Represent fetch of FPSR content.
126     UNSPECV_SET_FPSR            ; Represent assign of FPSR content.
127   ]
130 ;; If further include files are added the defintion of MD_INCLUDES
131 ;; must be updated.
133 (include "constraints.md")
134 (include "predicates.md")
135 (include "iterators.md")
137 ;; -------------------------------------------------------------------
138 ;; Instruction types and attributes
139 ;; -------------------------------------------------------------------
141 ; The "type" attribute is is included here from AArch32 backend to be able
142 ; to share pipeline descriptions.
143 (include "../arm/types.md")
145 ;; Attribute that specifies whether or not the instruction touches fp
146 ;; registers.
147 (define_attr "fp" "no,yes" (const_string "no"))
149 ;; Attribute that specifies whether or not the instruction touches simd
150 ;; registers.
151 (define_attr "simd" "no,yes" (const_string "no"))
153 (define_attr "length" ""
154   (const_int 4))
156 ;; Attribute that controls whether an alternative is enabled or not.
157 ;; Currently it is only used to disable alternatives which touch fp or simd
158 ;; registers when -mgeneral-regs-only is specified.
159 (define_attr "enabled" "no,yes"
160   (cond [(ior
161         (and (eq_attr "fp" "yes")
162              (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
163         (and (eq_attr "simd" "yes")
164              (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
165              (const_string "no")
166         ] (const_string "yes")))
168 ;; -------------------------------------------------------------------
169 ;; Pipeline descriptions and scheduling
170 ;; -------------------------------------------------------------------
172 ;; Processor types.
173 (include "aarch64-tune.md")
175 ;; True if the generic scheduling description should be used.
177 (define_attr "generic_sched" "yes,no"
178   (const (if_then_else
179           (eq_attr "tune" "cortexa53,cortexa15")
180           (const_string "no")
181           (const_string "yes"))))
183 ;; Scheduling
184 (include "../arm/cortex-a53.md")
185 (include "../arm/cortex-a15.md")
187 ;; -------------------------------------------------------------------
188 ;; Jumps and other miscellaneous insns
189 ;; -------------------------------------------------------------------
191 (define_insn "indirect_jump"
192   [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
193   ""
194   "br\\t%0"
195   [(set_attr "type" "branch")]
198 (define_insn "jump"
199   [(set (pc) (label_ref (match_operand 0 "" "")))]
200   ""
201   "b\\t%l0"
202   [(set_attr "type" "branch")]
205 (define_expand "cbranch<mode>4"
206   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
207                             [(match_operand:GPI 1 "register_operand" "")
208                              (match_operand:GPI 2 "aarch64_plus_operand" "")])
209                            (label_ref (match_operand 3 "" ""))
210                            (pc)))]
211   ""
212   "
213   operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
214                                          operands[2]);
215   operands[2] = const0_rtx;
216   "
219 (define_expand "cbranch<mode>4"
220   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
221                             [(match_operand:GPF 1 "register_operand" "")
222                              (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
223                            (label_ref (match_operand 3 "" ""))
224                            (pc)))]
225   ""
226   "
227   operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
228                                          operands[2]);
229   operands[2] = const0_rtx;
230   "
233 (define_insn "*condjump"
234   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
235                             [(match_operand 1 "cc_register" "") (const_int 0)])
236                            (label_ref (match_operand 2 "" ""))
237                            (pc)))]
238   ""
239   "b%m0\\t%l2"
240   [(set_attr "type" "branch")]
243 (define_expand "casesi"
244   [(match_operand:SI 0 "register_operand" "")   ; Index
245    (match_operand:SI 1 "const_int_operand" "")  ; Lower bound
246    (match_operand:SI 2 "const_int_operand" "")  ; Total range
247    (match_operand:DI 3 "" "")                   ; Table label
248    (match_operand:DI 4 "" "")]                  ; Out of range label
249   ""
250   {
251     if (operands[1] != const0_rtx)
252       {
253         rtx reg = gen_reg_rtx (SImode);
255         /* Canonical RTL says that if you have:
257            (minus (X) (CONST))
259            then this should be emitted as:
261            (plus (X) (-CONST))
263            The use of trunc_int_for_mode ensures that the resulting
264            constant can be represented in SImode, this is important
265            for the corner case where operand[1] is INT_MIN.  */
267         operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
269         if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
270               (operands[1], SImode))
271           operands[1] = force_reg (SImode, operands[1]);
272         emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
273         operands[0] = reg;
274       }
276     if (!aarch64_plus_operand (operands[2], SImode))
277       operands[2] = force_reg (SImode, operands[2]);
278     emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
279                                                  const0_rtx),
280                                     operands[0], operands[2], operands[4]));
282     operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
283     emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
284                                          operands[3]));
285     DONE;
286   }
289 (define_insn "casesi_dispatch"
290   [(parallel
291     [(set (pc)
292           (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
293                            (match_operand:SI 1 "register_operand" "r")]
294                         UNSPEC_CASESI)))
295      (clobber (reg:CC CC_REGNUM))
296      (clobber (match_scratch:DI 3 "=r"))
297      (clobber (match_scratch:DI 4 "=r"))
298      (use (label_ref (match_operand 2 "" "")))])]
299   ""
300   "*
301   return aarch64_output_casesi (operands);
302   "
303   [(set_attr "length" "16")
304    (set_attr "type" "branch")]
307 (define_insn "nop"
308   [(unspec[(const_int 0)] UNSPEC_NOP)]
309   ""
310   "nop"
311   [(set_attr "type" "no_insn")]
314 (define_insn "trap"
315   [(trap_if (const_int 1) (const_int 8))]
316   ""
317   "brk #1000"
318   [(set_attr "type" "trap")])
320 (define_expand "prologue"
321   [(clobber (const_int 0))]
322   ""
323   "
324   aarch64_expand_prologue ();
325   DONE;
326   "
329 (define_expand "epilogue"
330   [(clobber (const_int 0))]
331   ""
332   "
333   aarch64_expand_epilogue (false);
334   DONE;
335   "
338 (define_expand "sibcall_epilogue"
339   [(clobber (const_int 0))]
340   ""
341   "
342   aarch64_expand_epilogue (true);
343   DONE;
344   "
347 (define_insn "*do_return"
348   [(return)]
349   ""
350   "ret"
351   [(set_attr "type" "branch")]
354 (define_insn "eh_return"
355   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
356     UNSPECV_EH_RETURN)]
357   ""
358   "#"
359   [(set_attr "type" "branch")]
363 (define_split
364   [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
365     UNSPECV_EH_RETURN)]
366   "reload_completed"
367   [(set (match_dup 1) (match_dup 0))]
368   {
369     operands[1] = aarch64_final_eh_return_addr ();
370   }
373 (define_insn "*cb<optab><mode>1"
374   [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
375                                 (const_int 0))
376                            (label_ref (match_operand 1 "" ""))
377                            (pc)))]
378   ""
379   "<cbz>\\t%<w>0, %l1"
380   [(set_attr "type" "branch")]
384 (define_insn "*tb<optab><mode>1"
385   [(set (pc) (if_then_else
386               (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
387                                     (const_int 1)
388                                     (match_operand 1 "const_int_operand" "n"))
389                    (const_int 0))
390              (label_ref (match_operand 2 "" ""))
391              (pc)))
392    (clobber (match_scratch:DI 3 "=r"))]
393   ""
394   "*
395   if (get_attr_length (insn) == 8)
396     return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
397   return \"<tbz>\\t%<w>0, %1, %l2\";
398   "
399   [(set_attr "type" "branch")
400    (set (attr "length")
401         (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
402                            (lt (minus (match_dup 2) (pc)) (const_int 32764)))
403                       (const_int 4)
404                       (const_int 8)))]
407 (define_insn "*cb<optab><mode>1"
408   [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
409                                  (const_int 0))
410                            (label_ref (match_operand 1 "" ""))
411                            (pc)))
412    (clobber (match_scratch:DI 2 "=r"))]
413   ""
414   "*
415   if (get_attr_length (insn) == 8)
416     return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
417   return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
418   "
419   [(set_attr "type" "branch")
420    (set (attr "length")
421         (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
422                            (lt (minus (match_dup 1) (pc)) (const_int 32764)))
423                       (const_int 4)
424                       (const_int 8)))]
427 ;; -------------------------------------------------------------------
428 ;; Subroutine calls and sibcalls
429 ;; -------------------------------------------------------------------
431 (define_expand "call_internal"
432   [(parallel [(call (match_operand 0 "memory_operand" "")
433                     (match_operand 1 "general_operand" ""))
434               (use (match_operand 2 "" ""))
435               (clobber (reg:DI LR_REGNUM))])])
437 (define_expand "call"
438   [(parallel [(call (match_operand 0 "memory_operand" "")
439                     (match_operand 1 "general_operand" ""))
440               (use (match_operand 2 "" ""))
441               (clobber (reg:DI LR_REGNUM))])]
442   ""
443   "
444   {
445     rtx callee, pat;
447     /* In an untyped call, we can get NULL for operand 2.  */
448     if (operands[2] == NULL)
449       operands[2] = const0_rtx;
451     /* Decide if we should generate indirect calls by loading the
452        64-bit address of the callee into a register before performing
453        the branch-and-link.  */
454     callee = XEXP (operands[0], 0);
455     if (GET_CODE (callee) == SYMBOL_REF
456         ? aarch64_is_long_call_p (callee)
457         : !REG_P (callee))
458       XEXP (operands[0], 0) = force_reg (Pmode, callee);
460     pat = gen_call_internal (operands[0], operands[1], operands[2]);
461     aarch64_emit_call_insn (pat);
462     DONE;
463   }"
466 (define_insn "*call_reg"
467   [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
468          (match_operand 1 "" ""))
469    (use (match_operand 2 "" ""))
470    (clobber (reg:DI LR_REGNUM))]
471   ""
472   "blr\\t%0"
473   [(set_attr "type" "call")]
476 (define_insn "*call_symbol"
477   [(call (mem:DI (match_operand:DI 0 "" ""))
478          (match_operand 1 "" ""))
479    (use (match_operand 2 "" ""))
480    (clobber (reg:DI LR_REGNUM))]
481   "GET_CODE (operands[0]) == SYMBOL_REF
482    && !aarch64_is_long_call_p (operands[0])"
483   "bl\\t%a0"
484   [(set_attr "type" "call")]
487 (define_expand "call_value_internal"
488   [(parallel [(set (match_operand 0 "" "")
489                    (call (match_operand 1 "memory_operand" "")
490                          (match_operand 2 "general_operand" "")))
491               (use (match_operand 3 "" ""))
492               (clobber (reg:DI LR_REGNUM))])])
494 (define_expand "call_value"
495   [(parallel [(set (match_operand 0 "" "")
496                    (call (match_operand 1 "memory_operand" "")
497                          (match_operand 2 "general_operand" "")))
498               (use (match_operand 3 "" ""))
499               (clobber (reg:DI LR_REGNUM))])]
500   ""
501   "
502   {
503     rtx callee, pat;
505     /* In an untyped call, we can get NULL for operand 3.  */
506     if (operands[3] == NULL)
507       operands[3] = const0_rtx;
509     /* Decide if we should generate indirect calls by loading the
510        64-bit address of the callee into a register before performing
511        the branch-and-link.  */
512     callee = XEXP (operands[1], 0);
513     if (GET_CODE (callee) == SYMBOL_REF
514         ? aarch64_is_long_call_p (callee)
515         : !REG_P (callee))
516       XEXP (operands[1], 0) = force_reg (Pmode, callee);
518     pat = gen_call_value_internal (operands[0], operands[1], operands[2],
519                                    operands[3]);
520     aarch64_emit_call_insn (pat);
521     DONE;
522   }"
525 (define_insn "*call_value_reg"
526   [(set (match_operand 0 "" "")
527         (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
528                       (match_operand 2 "" "")))
529    (use (match_operand 3 "" ""))
530    (clobber (reg:DI LR_REGNUM))]
531   ""
532   "blr\\t%1"
533   [(set_attr "type" "call")]
537 (define_insn "*call_value_symbol"
538   [(set (match_operand 0 "" "")
539         (call (mem:DI (match_operand:DI 1 "" ""))
540               (match_operand 2 "" "")))
541    (use (match_operand 3 "" ""))
542    (clobber (reg:DI LR_REGNUM))]
543   "GET_CODE (operands[1]) == SYMBOL_REF
544    && !aarch64_is_long_call_p (operands[1])"
545   "bl\\t%a1"
546   [(set_attr "type" "call")]
549 (define_expand "sibcall_internal"
550   [(parallel [(call (match_operand 0 "memory_operand" "")
551                     (match_operand 1 "general_operand" ""))
552               (return)
553               (use (match_operand 2 "" ""))])])
555 (define_expand "sibcall"
556   [(parallel [(call (match_operand 0 "memory_operand" "")
557                     (match_operand 1 "general_operand" ""))
558               (return)
559               (use (match_operand 2 "" ""))])]
560   ""
561   {
562     rtx pat;
564     if (!REG_P (XEXP (operands[0], 0))
565        && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
566      XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
568     if (operands[2] == NULL_RTX)
569       operands[2] = const0_rtx;
571     pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
572     aarch64_emit_call_insn (pat);
573     DONE;
574   }
577 (define_expand "sibcall_value_internal"
578   [(parallel [(set (match_operand 0 "" "")
579                    (call (match_operand 1 "memory_operand" "")
580                          (match_operand 2 "general_operand" "")))
581               (return)
582               (use (match_operand 3 "" ""))])])
584 (define_expand "sibcall_value"
585   [(parallel [(set (match_operand 0 "" "")
586                    (call (match_operand 1 "memory_operand" "")
587                          (match_operand 2 "general_operand" "")))
588               (return)
589               (use (match_operand 3 "" ""))])]
590   ""
591   {
592     rtx pat;
594     if (!REG_P (XEXP (operands[1], 0))
595        && (GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF))
596      XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
598     if (operands[3] == NULL_RTX)
599       operands[3] = const0_rtx;
601     pat = gen_sibcall_value_internal (operands[0], operands[1], operands[2],
602                                       operands[3]);
603     aarch64_emit_call_insn (pat);
604     DONE;
605   }
608 (define_insn "*sibcall_insn"
609   [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucs, Usf"))
610          (match_operand 1 "" ""))
611    (return)
612    (use (match_operand 2 "" ""))]
613   "SIBLING_CALL_P (insn)"
614   "@
615    br\\t%0
616    b\\t%a0"
617   [(set_attr "type" "branch, branch")]
620 (define_insn "*sibcall_value_insn"
621   [(set (match_operand 0 "" "")
622         (call (mem:DI (match_operand 1 "aarch64_call_insn_operand" "Ucs, Usf"))
623               (match_operand 2 "" "")))
624    (return)
625    (use (match_operand 3 "" ""))]
626   "SIBLING_CALL_P (insn)"
627   "@
628    br\\t%1
629    b\\t%a1"
630   [(set_attr "type" "branch, branch")]
633 ;; Call subroutine returning any type.
635 (define_expand "untyped_call"
636   [(parallel [(call (match_operand 0 "")
637                     (const_int 0))
638               (match_operand 1 "")
639               (match_operand 2 "")])]
640   ""
642   int i;
644   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
646   for (i = 0; i < XVECLEN (operands[2], 0); i++)
647     {
648       rtx set = XVECEXP (operands[2], 0, i);
649       emit_move_insn (SET_DEST (set), SET_SRC (set));
650     }
652   /* The optimizer does not know that the call sets the function value
653      registers we stored in the result block.  We avoid problems by
654      claiming that all hard registers are used and clobbered at this
655      point.  */
656   emit_insn (gen_blockage ());
657   DONE;
660 ;; -------------------------------------------------------------------
661 ;; Moves
662 ;; -------------------------------------------------------------------
664 (define_expand "mov<mode>"
665   [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
666         (match_operand:SHORT 1 "general_operand" ""))]
667   ""
668   "
669     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
670       operands[1] = force_reg (<MODE>mode, operands[1]);
671   "
674 (define_insn "*mov<mode>_aarch64"
675   [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r,   *w,r,*w, m, m, r,*w,*w")
676         (match_operand:SHORT 1 "general_operand"      " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
677   "(register_operand (operands[0], <MODE>mode)
678     || aarch64_reg_or_zero (operands[1], <MODE>mode))"
680    switch (which_alternative)
681      {
682      case 0:
683        return "mov\t%w0, %w1";
684      case 1:
685        return "mov\t%w0, %1";
686      case 2:
687        return aarch64_output_scalar_simd_mov_immediate (operands[1],
688                                                         <MODE>mode);
689      case 3:
690        return "ldr<size>\t%w0, %1";
691      case 4:
692        return "ldr\t%<size>0, %1";
693      case 5:
694        return "str<size>\t%w1, %0";
695      case 6:
696        return "str\t%<size>1, %0";
697      case 7:
698        return "umov\t%w0, %1.<v>[0]";
699      case 8:
700        return "dup\t%0.<Vallxd>, %w1";
701      case 9:
702        return "dup\t%<Vetype>0, %1.<v>[0]";
703      default:
704        gcc_unreachable ();
705      }
707   [(set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
708                      neon_from_gp<q>,neon_from_gp<q>, neon_dup")
709    (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")]
712 (define_expand "mov<mode>"
713   [(set (match_operand:GPI 0 "nonimmediate_operand" "")
714         (match_operand:GPI 1 "general_operand" ""))]
715   ""
716   "
717     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
718       operands[1] = force_reg (<MODE>mode, operands[1]);
720     if (CONSTANT_P (operands[1]))
721       {
722         aarch64_expand_mov_immediate (operands[0], operands[1]);
723         DONE;
724       }
725   "
728 (define_insn "*movsi_aarch64"
729   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m,  m,r,r  ,*w, r,*w")
730         (match_operand:SI 1 "aarch64_mov_operand"  " r,r,k,M,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
731   "(register_operand (operands[0], SImode)
732     || aarch64_reg_or_zero (operands[1], SImode))"
733   "@
734    mov\\t%w0, %w1
735    mov\\t%w0, %w1
736    mov\\t%w0, %w1
737    mov\\t%w0, %1
738    ldr\\t%w0, %1
739    ldr\\t%s0, %1
740    str\\t%w1, %0
741    str\\t%s1, %0
742    adr\\t%x0, %a1
743    adrp\\t%x0, %A1
744    fmov\\t%s0, %w1
745    fmov\\t%w0, %s1
746    fmov\\t%s0, %s1"
747   [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
748                      adr,adr,f_mcr,f_mrc,fmov")
749    (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
752 (define_insn "*movdi_aarch64"
753   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m,  m,r,r,  *w, r,*w,w")
754         (match_operand:DI 1 "aarch64_mov_operand"  " r,r,k,N,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))]
755   "(register_operand (operands[0], DImode)
756     || aarch64_reg_or_zero (operands[1], DImode))"
757   "@
758    mov\\t%x0, %x1
759    mov\\t%0, %x1
760    mov\\t%x0, %1
761    mov\\t%x0, %1
762    ldr\\t%x0, %1
763    ldr\\t%d0, %1
764    str\\t%x1, %0
765    str\\t%d1, %0
766    adr\\t%x0, %a1
767    adrp\\t%x0, %A1
768    fmov\\t%d0, %x1
769    fmov\\t%x0, %d1
770    fmov\\t%d0, %d1
771    movi\\t%d0, %1"
772   [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
773                      adr,adr,f_mcr,f_mrc,fmov,fmov")
774    (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
775    (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
778 (define_insn "insv_imm<mode>"
779   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
780                           (const_int 16)
781                           (match_operand:GPI 1 "const_int_operand" "n"))
782         (match_operand:GPI 2 "const_int_operand" "n"))]
783   "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
784    && UINTVAL (operands[1]) % 16 == 0"
785   "movk\\t%<w>0, %X2, lsl %1"
786   [(set_attr "type" "mov_imm")]
789 (define_expand "movti"
790   [(set (match_operand:TI 0 "nonimmediate_operand" "")
791         (match_operand:TI 1 "general_operand" ""))]
792   ""
793   "
794     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
795       operands[1] = force_reg (TImode, operands[1]);
796   "
799 (define_insn "*movti_aarch64"
800   [(set (match_operand:TI 0
801          "nonimmediate_operand"  "=r, *w,r ,*w,r  ,Ump,Ump,*w,m")
802         (match_operand:TI 1
803          "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r  ,Z  , m,*w"))]
804   "(register_operand (operands[0], TImode)
805     || aarch64_reg_or_zero (operands[1], TImode))"
806   "@
807    #
808    #
809    #
810    orr\\t%0.16b, %1.16b, %1.16b
811    ldp\\t%0, %H0, %1
812    stp\\t%1, %H1, %0
813    stp\\txzr, xzr, %0
814    ldr\\t%q0, %1
815    str\\t%q1, %0"
816   [(set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \
817                              load2,store2,store2,f_loadd,f_stored")
818    (set_attr "length" "8,8,8,4,4,4,4,4,4")
819    (set_attr "simd" "*,*,*,yes,*,*,*,*,*")
820    (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
823 ;; Split a TImode register-register or register-immediate move into
824 ;; its component DImode pieces, taking care to handle overlapping
825 ;; source and dest registers.
826 (define_split
827    [(set (match_operand:TI 0 "register_operand" "")
828          (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
829   "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
830   [(const_int 0)]
832   aarch64_split_128bit_move (operands[0], operands[1]);
833   DONE;
836 (define_expand "mov<mode>"
837   [(set (match_operand:GPF 0 "nonimmediate_operand" "")
838         (match_operand:GPF 1 "general_operand" ""))]
839   ""
840   "
841     if (!TARGET_FLOAT)
842      {
843         sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
844         FAIL;
845      }
847     if (GET_CODE (operands[0]) == MEM)
848       operands[1] = force_reg (<MODE>mode, operands[1]);
849   "
852 (define_insn "*movsf_aarch64"
853   [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w  ,w,m,r,m ,r")
854         (match_operand:SF 1 "general_operand"      "?rY, w,w,Ufc,m,w,m,rY,r"))]
855   "TARGET_FLOAT && (register_operand (operands[0], SFmode)
856     || register_operand (operands[1], SFmode))"
857   "@
858    fmov\\t%s0, %w1
859    fmov\\t%w0, %s1
860    fmov\\t%s0, %s1
861    fmov\\t%s0, %1
862    ldr\\t%s0, %1
863    str\\t%s1, %0
864    ldr\\t%w0, %1
865    str\\t%w1, %0
866    mov\\t%w0, %w1"
867   [(set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
868                      f_loads,f_stores,f_loads,f_stores,mov_reg")]
871 (define_insn "*movdf_aarch64"
872   [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w  ,w,m,r,m ,r")
873         (match_operand:DF 1 "general_operand"      "?rY, w,w,Ufc,m,w,m,rY,r"))]
874   "TARGET_FLOAT && (register_operand (operands[0], DFmode)
875     || register_operand (operands[1], DFmode))"
876   "@
877    fmov\\t%d0, %x1
878    fmov\\t%x0, %d1
879    fmov\\t%d0, %d1
880    fmov\\t%d0, %1
881    ldr\\t%d0, %1
882    str\\t%d1, %0
883    ldr\\t%x0, %1
884    str\\t%x1, %0
885    mov\\t%x0, %x1"
886   [(set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
887                      f_loadd,f_stored,f_loadd,f_stored,mov_reg")]
890 (define_expand "movtf"
891   [(set (match_operand:TF 0 "nonimmediate_operand" "")
892         (match_operand:TF 1 "general_operand" ""))]
893   ""
894   "
895     if (!TARGET_FLOAT)
896      {
897         sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
898         FAIL;
899      }
901     if (GET_CODE (operands[0]) == MEM)
902       operands[1] = force_reg (TFmode, operands[1]);
903   "
906 (define_insn "*movtf_aarch64"
907   [(set (match_operand:TF 0
908          "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
909         (match_operand:TF 1
910          "general_operand"      " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
911   "TARGET_FLOAT && (register_operand (operands[0], TFmode)
912     || register_operand (operands[1], TFmode))"
913   "@
914    orr\\t%0.16b, %1.16b, %1.16b
915    #
916    #
917    #
918    movi\\t%0.2d, #0
919    fmov\\t%s0, wzr
920    ldr\\t%q0, %1
921    str\\t%q1, %0
922    ldp\\t%0, %H0, %1
923    stp\\t%1, %H1, %0"
924   [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,fconstd,fconstd,\
925                      f_loadd,f_stored,neon_load1_2reg,neon_store1_2reg")
926    (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
927    (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
928    (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
931 (define_split
932    [(set (match_operand:TF 0 "register_operand" "")
933          (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
934   "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
935   [(const_int 0)]
936   {
937     aarch64_split_128bit_move (operands[0], operands[1]);
938     DONE;
939   }
942 ;; 0 is dst
943 ;; 1 is src
944 ;; 2 is size of move in bytes
945 ;; 3 is alignment
947 (define_expand "movmemdi"
948   [(match_operand:BLK 0 "memory_operand")
949    (match_operand:BLK 1 "memory_operand")
950    (match_operand:DI 2 "immediate_operand")
951    (match_operand:DI 3 "immediate_operand")]
952    "!STRICT_ALIGNMENT"
954   if (aarch64_expand_movmem (operands))
955     DONE;
956   FAIL;
960 ;; Operands 1 and 3 are tied together by the final condition; so we allow
961 ;; fairly lax checking on the second memory operation.
962 (define_insn "load_pair<mode>"
963   [(set (match_operand:GPI 0 "register_operand" "=r")
964         (match_operand:GPI 1 "aarch64_mem_pair_operand" "Ump"))
965    (set (match_operand:GPI 2 "register_operand" "=r")
966         (match_operand:GPI 3 "memory_operand" "m"))]
967   "rtx_equal_p (XEXP (operands[3], 0),
968                 plus_constant (Pmode,
969                                XEXP (operands[1], 0),
970                                GET_MODE_SIZE (<MODE>mode)))"
971   "ldp\\t%<w>0, %<w>2, %1"
972   [(set_attr "type" "load2")]
975 ;; Operands 0 and 2 are tied together by the final condition; so we allow
976 ;; fairly lax checking on the second memory operation.
977 (define_insn "store_pair<mode>"
978   [(set (match_operand:GPI 0 "aarch64_mem_pair_operand" "=Ump")
979         (match_operand:GPI 1 "register_operand" "r"))
980    (set (match_operand:GPI 2 "memory_operand" "=m")
981         (match_operand:GPI 3 "register_operand" "r"))]
982   "rtx_equal_p (XEXP (operands[2], 0),
983                 plus_constant (Pmode,
984                                XEXP (operands[0], 0),
985                                GET_MODE_SIZE (<MODE>mode)))"
986   "stp\\t%<w>1, %<w>3, %0"
987   [(set_attr "type" "store2")]
990 ;; Operands 1 and 3 are tied together by the final condition; so we allow
991 ;; fairly lax checking on the second memory operation.
992 (define_insn "load_pair<mode>"
993   [(set (match_operand:GPF 0 "register_operand" "=w")
994         (match_operand:GPF 1 "aarch64_mem_pair_operand" "Ump"))
995    (set (match_operand:GPF 2 "register_operand" "=w")
996         (match_operand:GPF 3 "memory_operand" "m"))]
997   "rtx_equal_p (XEXP (operands[3], 0),
998                 plus_constant (Pmode,
999                                XEXP (operands[1], 0),
1000                                GET_MODE_SIZE (<MODE>mode)))"
1001   "ldp\\t%<w>0, %<w>2, %1"
1002   [(set_attr "type" "neon_load1_2reg<q>")]
1005 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1006 ;; fairly lax checking on the second memory operation.
1007 (define_insn "store_pair<mode>"
1008   [(set (match_operand:GPF 0 "aarch64_mem_pair_operand" "=Ump")
1009         (match_operand:GPF 1 "register_operand" "w"))
1010    (set (match_operand:GPF 2 "memory_operand" "=m")
1011         (match_operand:GPF 3 "register_operand" "w"))]
1012   "rtx_equal_p (XEXP (operands[2], 0),
1013                 plus_constant (Pmode,
1014                                XEXP (operands[0], 0),
1015                                GET_MODE_SIZE (<MODE>mode)))"
1016   "stp\\t%<w>1, %<w>3, %0"
1017   [(set_attr "type" "neon_store1_2reg<q>")]
1020 ;; Load pair with writeback.  This is primarily used in function epilogues
1021 ;; when restoring [fp,lr]
1022 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
1023   [(parallel
1024     [(set (match_operand:P 0 "register_operand" "=k")
1025           (plus:P (match_operand:P 1 "register_operand" "0")
1026                   (match_operand:P 4 "const_int_operand" "n")))
1027      (set (match_operand:GPI 2 "register_operand" "=r")
1028           (mem:GPI (plus:P (match_dup 1)
1029                    (match_dup 4))))
1030      (set (match_operand:GPI 3 "register_operand" "=r")
1031           (mem:GPI (plus:P (match_dup 1)
1032                    (match_operand:P 5 "const_int_operand" "n"))))])]
1033   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1034   "ldp\\t%<w>2, %<w>3, [%1], %4"
1035   [(set_attr "type" "load2")]
1038 ;; Store pair with writeback.  This is primarily used in function prologues
1039 ;; when saving [fp,lr]
1040 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
1041   [(parallel
1042     [(set (match_operand:P 0 "register_operand" "=&k")
1043           (plus:P (match_operand:P 1 "register_operand" "0")
1044                   (match_operand:P 4 "const_int_operand" "n")))
1045      (set (mem:GPI (plus:P (match_dup 0)
1046                    (match_dup 4)))
1047           (match_operand:GPI 2 "register_operand" "r"))
1048      (set (mem:GPI (plus:P (match_dup 0)
1049                    (match_operand:P 5 "const_int_operand" "n")))
1050           (match_operand:GPI 3 "register_operand" "r"))])]
1051   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1052   "stp\\t%<w>2, %<w>3, [%0, %4]!"
1053   [(set_attr "type" "store2")]
1056 ;; -------------------------------------------------------------------
1057 ;; Sign/Zero extension
1058 ;; -------------------------------------------------------------------
1060 (define_expand "<optab>sidi2"
1061   [(set (match_operand:DI 0 "register_operand")
1062         (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1063   ""
1066 (define_insn "*extendsidi2_aarch64"
1067   [(set (match_operand:DI 0 "register_operand" "=r,r")
1068         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1069   ""
1070   "@
1071    sxtw\t%0, %w1
1072    ldrsw\t%0, %1"
1073   [(set_attr "type" "extend,load1")]
1076 (define_insn "*zero_extendsidi2_aarch64"
1077   [(set (match_operand:DI 0 "register_operand" "=r,r")
1078         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1079   ""
1080   "@
1081    uxtw\t%0, %w1
1082    ldr\t%w0, %1"
1083   [(set_attr "type" "extend,load1")]
1086 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1087   [(set (match_operand:GPI 0 "register_operand")
1088         (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1089   ""
1092 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1093   [(set (match_operand:GPI 0 "register_operand" "=r,r")
1094         (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1095   ""
1096   "@
1097    sxt<SHORT:size>\t%<GPI:w>0, %w1
1098    ldrs<SHORT:size>\t%<GPI:w>0, %1"
1099   [(set_attr "type" "extend,load1")]
1102 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1103   [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1104         (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1105   ""
1106   "@
1107    uxt<SHORT:size>\t%<GPI:w>0, %w1
1108    ldr<SHORT:size>\t%w0, %1
1109    ldr\t%<SHORT:size>0, %1"
1110   [(set_attr "type" "extend,load1,load1")]
1113 (define_expand "<optab>qihi2"
1114   [(set (match_operand:HI 0 "register_operand")
1115         (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1116   ""
1119 (define_insn "*<optab>qihi2_aarch64"
1120   [(set (match_operand:HI 0 "register_operand" "=r,r")
1121         (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1122   ""
1123   "@
1124    <su>xtb\t%w0, %w1
1125    <ldrxt>b\t%w0, %1"
1126   [(set_attr "type" "extend,load1")]
1129 ;; -------------------------------------------------------------------
1130 ;; Simple arithmetic
1131 ;; -------------------------------------------------------------------
1133 (define_expand "add<mode>3"
1134   [(set
1135     (match_operand:GPI 0 "register_operand" "")
1136     (plus:GPI (match_operand:GPI 1 "register_operand" "")
1137               (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1138   ""
1139   "
1140   if (! aarch64_plus_operand (operands[2], VOIDmode))
1141     {
1142       rtx subtarget = ((optimize && can_create_pseudo_p ())
1143                        ? gen_reg_rtx (<MODE>mode) : operands[0]);
1144       HOST_WIDE_INT imm = INTVAL (operands[2]);
1146       if (imm < 0)
1147         imm = -(-imm & ~0xfff);
1148       else
1149         imm &= ~0xfff;
1151       emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1152       operands[1] = subtarget;
1153       operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1154     }
1155   "
1158 (define_insn "*addsi3_aarch64"
1159   [(set
1160     (match_operand:SI 0 "register_operand" "=rk,rk,w,rk")
1161     (plus:SI
1162      (match_operand:SI 1 "register_operand" "%rk,rk,w,rk")
1163      (match_operand:SI 2 "aarch64_plus_operand" "I,r,w,J")))]
1164   ""
1165   "@
1166   add\\t%w0, %w1, %2
1167   add\\t%w0, %w1, %w2
1168   add\\t%0.2s, %1.2s, %2.2s
1169   sub\\t%w0, %w1, #%n2"
1170   [(set_attr "type" "alu_imm,alu_reg,neon_add,alu_imm")
1171    (set_attr "simd" "*,*,yes,*")]
1174 ;; zero_extend version of above
1175 (define_insn "*addsi3_aarch64_uxtw"
1176   [(set
1177     (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1178     (zero_extend:DI
1179      (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1180               (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1181   ""
1182   "@
1183   add\\t%w0, %w1, %2
1184   add\\t%w0, %w1, %w2
1185   sub\\t%w0, %w1, #%n2"
1186   [(set_attr "type" "alu_imm,alu_reg,alu_imm")]
1189 (define_insn "*adddi3_aarch64"
1190   [(set
1191     (match_operand:DI 0 "register_operand" "=rk,rk,rk,!w")
1192     (plus:DI
1193      (match_operand:DI 1 "register_operand" "%rk,rk,rk,!w")
1194      (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,!w")))]
1195   ""
1196   "@
1197   add\\t%x0, %x1, %2
1198   add\\t%x0, %x1, %x2
1199   sub\\t%x0, %x1, #%n2
1200   add\\t%d0, %d1, %d2"
1201   [(set_attr "type" "alu_imm,alu_reg,alu_imm,alu_reg")
1202    (set_attr "simd" "*,*,*,yes")]
1205 (define_expand "addti3"
1206   [(set (match_operand:TI 0 "register_operand" "")
1207         (plus:TI (match_operand:TI 1 "register_operand" "")
1208                  (match_operand:TI 2 "register_operand" "")))]
1209   ""
1211   rtx low = gen_reg_rtx (DImode);
1212   emit_insn (gen_adddi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1213                                   gen_lowpart (DImode, operands[2])));
1215   rtx high = gen_reg_rtx (DImode);
1216   emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]),
1217                                  gen_highpart (DImode, operands[2])));
1219   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1220   emit_move_insn (gen_highpart (DImode, operands[0]), high);
1221   DONE;
1224 (define_insn "add<mode>3_compare0"
1225   [(set (reg:CC_NZ CC_REGNUM)
1226         (compare:CC_NZ
1227          (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1228                    (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1229          (const_int 0)))
1230    (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1231         (plus:GPI (match_dup 1) (match_dup 2)))]
1232   ""
1233   "@
1234   adds\\t%<w>0, %<w>1, %<w>2
1235   adds\\t%<w>0, %<w>1, %<w>2
1236   subs\\t%<w>0, %<w>1, #%n2"
1237   [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1240 ;; zero_extend version of above
1241 (define_insn "*addsi3_compare0_uxtw"
1242   [(set (reg:CC_NZ CC_REGNUM)
1243         (compare:CC_NZ
1244          (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1245                   (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1246          (const_int 0)))
1247    (set (match_operand:DI 0 "register_operand" "=r,r,r")
1248         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1249   ""
1250   "@
1251   adds\\t%w0, %w1, %w2
1252   adds\\t%w0, %w1, %w2
1253   subs\\t%w0, %w1, #%n2"
1254   [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1257 (define_insn "*adds_mul_imm_<mode>"
1258   [(set (reg:CC_NZ CC_REGNUM)
1259         (compare:CC_NZ
1260          (plus:GPI (mult:GPI
1261                     (match_operand:GPI 1 "register_operand" "r")
1262                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1263                    (match_operand:GPI 3 "register_operand" "r"))
1264          (const_int 0)))
1265    (set (match_operand:GPI 0 "register_operand" "=r")
1266         (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1267                   (match_dup 3)))]
1268   ""
1269   "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1270   [(set_attr "type" "alus_shift_imm")]
1273 (define_insn "*subs_mul_imm_<mode>"
1274   [(set (reg:CC_NZ CC_REGNUM)
1275         (compare:CC_NZ
1276          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1277                     (mult:GPI
1278                      (match_operand:GPI 2 "register_operand" "r")
1279                      (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1280          (const_int 0)))
1281    (set (match_operand:GPI 0 "register_operand" "=r")
1282         (minus:GPI (match_dup 1)
1283                    (mult:GPI (match_dup 2) (match_dup 3))))]
1284   ""
1285   "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1286   [(set_attr "type" "alus_shift_imm")]
1289 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1290   [(set (reg:CC_NZ CC_REGNUM)
1291         (compare:CC_NZ
1292          (plus:GPI
1293           (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1294           (match_operand:GPI 2 "register_operand" "r"))
1295         (const_int 0)))
1296    (set (match_operand:GPI 0 "register_operand" "=r")
1297         (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1298   ""
1299   "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1300   [(set_attr "type" "alus_ext")]
1303 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1304   [(set (reg:CC_NZ CC_REGNUM)
1305         (compare:CC_NZ
1306          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1307                     (ANY_EXTEND:GPI
1308                      (match_operand:ALLX 2 "register_operand" "r")))
1309         (const_int 0)))
1310    (set (match_operand:GPI 0 "register_operand" "=r")
1311         (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1312   ""
1313   "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1314   [(set_attr "type" "alus_ext")]
1317 (define_insn "*adds_<optab><mode>_multp2"
1318   [(set (reg:CC_NZ CC_REGNUM)
1319         (compare:CC_NZ
1320          (plus:GPI (ANY_EXTRACT:GPI
1321                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1322                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1323                     (match_operand 3 "const_int_operand" "n")
1324                     (const_int 0))
1325                    (match_operand:GPI 4 "register_operand" "r"))
1326         (const_int 0)))
1327    (set (match_operand:GPI 0 "register_operand" "=r")
1328         (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1329                                    (match_dup 3)
1330                                    (const_int 0))
1331                   (match_dup 4)))]
1332   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1333   "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1334   [(set_attr "type" "alus_ext")]
1337 (define_insn "*subs_<optab><mode>_multp2"
1338   [(set (reg:CC_NZ CC_REGNUM)
1339         (compare:CC_NZ
1340          (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1341                     (ANY_EXTRACT:GPI
1342                      (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1343                                (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1344                      (match_operand 3 "const_int_operand" "n")
1345                      (const_int 0)))
1346         (const_int 0)))
1347    (set (match_operand:GPI 0 "register_operand" "=r")
1348         (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1349                                   (mult:GPI (match_dup 1) (match_dup 2))
1350                                   (match_dup 3)
1351                                   (const_int 0))))]
1352   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1353   "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1354   [(set_attr "type" "alus_ext")]
1357 (define_insn "*add<mode>3nr_compare0"
1358   [(set (reg:CC_NZ CC_REGNUM)
1359         (compare:CC_NZ
1360          (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1361                    (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1362          (const_int 0)))]
1363   ""
1364   "@
1365   cmn\\t%<w>0, %<w>1
1366   cmn\\t%<w>0, %<w>1
1367   cmp\\t%<w>0, #%n1"
1368   [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1371 (define_insn "*compare_neg<mode>"
1372   [(set (reg:CC_Z CC_REGNUM)
1373         (compare:CC_Z
1374          (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1375          (match_operand:GPI 1 "register_operand" "r")))]
1376   ""
1377   "cmn\\t%<w>1, %<w>0"
1378   [(set_attr "type" "alus_reg")]
1381 (define_insn "*add_<shift>_<mode>"
1382   [(set (match_operand:GPI 0 "register_operand" "=r")
1383         (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1384                               (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1385                   (match_operand:GPI 3 "register_operand" "r")))]
1386   ""
1387   "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1388   [(set_attr "type" "alu_shift_imm")]
1391 ;; zero_extend version of above
1392 (define_insn "*add_<shift>_si_uxtw"
1393   [(set (match_operand:DI 0 "register_operand" "=r")
1394         (zero_extend:DI
1395          (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1396                              (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1397                   (match_operand:SI 3 "register_operand" "r"))))]
1398   ""
1399   "add\\t%w0, %w3, %w1, <shift> %2"
1400   [(set_attr "type" "alu_shift_imm")]
1403 (define_insn "*add_mul_imm_<mode>"
1404   [(set (match_operand:GPI 0 "register_operand" "=r")
1405         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1406                             (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1407                   (match_operand:GPI 3 "register_operand" "r")))]
1408   ""
1409   "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1410   [(set_attr "type" "alu_shift_imm")]
1413 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1414   [(set (match_operand:GPI 0 "register_operand" "=rk")
1415         (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1416                   (match_operand:GPI 2 "register_operand" "r")))]
1417   ""
1418   "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1419   [(set_attr "type" "alu_ext")]
1422 ;; zero_extend version of above
1423 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1424   [(set (match_operand:DI 0 "register_operand" "=rk")
1425         (zero_extend:DI
1426          (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1427                   (match_operand:GPI 2 "register_operand" "r"))))]
1428   ""
1429   "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1430   [(set_attr "type" "alu_ext")]
1433 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1434   [(set (match_operand:GPI 0 "register_operand" "=rk")
1435         (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1436                                (match_operand:ALLX 1 "register_operand" "r"))
1437                               (match_operand 2 "aarch64_imm3" "Ui3"))
1438                   (match_operand:GPI 3 "register_operand" "r")))]
1439   ""
1440   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1441   [(set_attr "type" "alu_ext")]
1444 ;; zero_extend version of above
1445 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1446   [(set (match_operand:DI 0 "register_operand" "=rk")
1447         (zero_extend:DI
1448          (plus:SI (ashift:SI (ANY_EXTEND:SI
1449                               (match_operand:SHORT 1 "register_operand" "r"))
1450                              (match_operand 2 "aarch64_imm3" "Ui3"))
1451                   (match_operand:SI 3 "register_operand" "r"))))]
1452   ""
1453   "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1454   [(set_attr "type" "alu_ext")]
1457 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1458   [(set (match_operand:GPI 0 "register_operand" "=rk")
1459         (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1460                              (match_operand:ALLX 1 "register_operand" "r"))
1461                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1462                   (match_operand:GPI 3 "register_operand" "r")))]
1463   ""
1464   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1465   [(set_attr "type" "alu_ext")]
1468 ;; zero_extend version of above
1469 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1470   [(set (match_operand:DI 0 "register_operand" "=rk")
1471         (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1472                              (match_operand:SHORT 1 "register_operand" "r"))
1473                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1474                   (match_operand:SI 3 "register_operand" "r"))))]
1475   ""
1476   "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1477   [(set_attr "type" "alu_ext")]
1480 (define_insn "*add_<optab><mode>_multp2"
1481   [(set (match_operand:GPI 0 "register_operand" "=rk")
1482         (plus:GPI (ANY_EXTRACT:GPI
1483                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1484                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1485                    (match_operand 3 "const_int_operand" "n")
1486                    (const_int 0))
1487                   (match_operand:GPI 4 "register_operand" "r")))]
1488   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1489   "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1490   [(set_attr "type" "alu_ext")]
1493 ;; zero_extend version of above
1494 (define_insn "*add_<optab>si_multp2_uxtw"
1495   [(set (match_operand:DI 0 "register_operand" "=rk")
1496         (zero_extend:DI
1497          (plus:SI (ANY_EXTRACT:SI
1498                    (mult:SI (match_operand:SI 1 "register_operand" "r")
1499                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1500                    (match_operand 3 "const_int_operand" "n")
1501                    (const_int 0))
1502                   (match_operand:SI 4 "register_operand" "r"))))]
1503   "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1504   "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1505   [(set_attr "type" "alu_ext")]
1508 (define_insn "add<mode>3_carryin"
1509   [(set
1510     (match_operand:GPI 0 "register_operand" "=r")
1511     (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1512               (plus:GPI
1513                 (match_operand:GPI 1 "register_operand" "r")
1514                 (match_operand:GPI 2 "register_operand" "r"))))]
1515    ""
1516    "adc\\t%<w>0, %<w>1, %<w>2"
1517   [(set_attr "type" "adc_reg")]
1520 ;; zero_extend version of above
1521 (define_insn "*addsi3_carryin_uxtw"
1522   [(set
1523     (match_operand:DI 0 "register_operand" "=r")
1524     (zero_extend:DI
1525      (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1526               (plus:SI
1527                (match_operand:SI 1 "register_operand" "r")
1528                (match_operand:SI 2 "register_operand" "r")))))]
1529    ""
1530    "adc\\t%w0, %w1, %w2"
1531   [(set_attr "type" "adc_reg")]
1534 (define_insn "*add<mode>3_carryin_alt1"
1535   [(set
1536     (match_operand:GPI 0 "register_operand" "=r")
1537     (plus:GPI (plus:GPI
1538                 (match_operand:GPI 1 "register_operand" "r")
1539                 (match_operand:GPI 2 "register_operand" "r"))
1540               (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1541    ""
1542    "adc\\t%<w>0, %<w>1, %<w>2"
1543   [(set_attr "type" "adc_reg")]
1546 ;; zero_extend version of above
1547 (define_insn "*addsi3_carryin_alt1_uxtw"
1548   [(set
1549     (match_operand:DI 0 "register_operand" "=r")
1550     (zero_extend:DI
1551      (plus:SI (plus:SI
1552                (match_operand:SI 1 "register_operand" "r")
1553                (match_operand:SI 2 "register_operand" "r"))
1554               (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1555    ""
1556    "adc\\t%w0, %w1, %w2"
1557   [(set_attr "type" "adc_reg")]
1560 (define_insn "*add<mode>3_carryin_alt2"
1561   [(set
1562     (match_operand:GPI 0 "register_operand" "=r")
1563     (plus:GPI (plus:GPI
1564                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1565                 (match_operand:GPI 1 "register_operand" "r"))
1566               (match_operand:GPI 2 "register_operand" "r")))]
1567    ""
1568    "adc\\t%<w>0, %<w>1, %<w>2"
1569   [(set_attr "type" "adc_reg")]
1572 ;; zero_extend version of above
1573 (define_insn "*addsi3_carryin_alt2_uxtw"
1574   [(set
1575     (match_operand:DI 0 "register_operand" "=r")
1576     (zero_extend:DI
1577      (plus:SI (plus:SI
1578                (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1579                (match_operand:SI 1 "register_operand" "r"))
1580               (match_operand:SI 2 "register_operand" "r"))))]
1581    ""
1582    "adc\\t%w0, %w1, %w2"
1583   [(set_attr "type" "adc_reg")]
1586 (define_insn "*add<mode>3_carryin_alt3"
1587   [(set
1588     (match_operand:GPI 0 "register_operand" "=r")
1589     (plus:GPI (plus:GPI
1590                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1591                 (match_operand:GPI 2 "register_operand" "r"))
1592               (match_operand:GPI 1 "register_operand" "r")))]
1593    ""
1594    "adc\\t%<w>0, %<w>1, %<w>2"
1595   [(set_attr "type" "adc_reg")]
1598 ;; zero_extend version of above
1599 (define_insn "*addsi3_carryin_alt3_uxtw"
1600   [(set
1601     (match_operand:DI 0 "register_operand" "=r")
1602     (zero_extend:DI
1603      (plus:SI (plus:SI
1604                (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1605                (match_operand:SI 2 "register_operand" "r"))
1606               (match_operand:SI 1 "register_operand" "r"))))]
1607    ""
1608    "adc\\t%w0, %w1, %w2"
1609   [(set_attr "type" "adc_reg")]
1612 (define_insn "*add_uxt<mode>_multp2"
1613   [(set (match_operand:GPI 0 "register_operand" "=rk")
1614         (plus:GPI (and:GPI
1615                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1616                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1617                    (match_operand 3 "const_int_operand" "n"))
1618                   (match_operand:GPI 4 "register_operand" "r")))]
1619   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1620   "*
1621   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1622                                            INTVAL (operands[3])));
1623   return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1624   [(set_attr "type" "alu_ext")]
1627 ;; zero_extend version of above
1628 (define_insn "*add_uxtsi_multp2_uxtw"
1629   [(set (match_operand:DI 0 "register_operand" "=rk")
1630         (zero_extend:DI
1631          (plus:SI (and:SI
1632                    (mult:SI (match_operand:SI 1 "register_operand" "r")
1633                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1634                    (match_operand 3 "const_int_operand" "n"))
1635                   (match_operand:SI 4 "register_operand" "r"))))]
1636   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1637   "*
1638   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1639                                            INTVAL (operands[3])));
1640   return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1641   [(set_attr "type" "alu_ext")]
1644 (define_insn "subsi3"
1645   [(set (match_operand:SI 0 "register_operand" "=rk")
1646         (minus:SI (match_operand:SI 1 "register_operand" "r")
1647                    (match_operand:SI 2 "register_operand" "r")))]
1648   ""
1649   "sub\\t%w0, %w1, %w2"
1650   [(set_attr "type" "alu_reg")]
1653 ;; zero_extend version of above
1654 (define_insn "*subsi3_uxtw"
1655   [(set (match_operand:DI 0 "register_operand" "=rk")
1656         (zero_extend:DI
1657          (minus:SI (match_operand:SI 1 "register_operand" "r")
1658                    (match_operand:SI 2 "register_operand" "r"))))]
1659   ""
1660   "sub\\t%w0, %w1, %w2"
1661   [(set_attr "type" "alu_reg")]
1664 (define_insn "subdi3"
1665   [(set (match_operand:DI 0 "register_operand" "=rk,!w")
1666         (minus:DI (match_operand:DI 1 "register_operand" "r,!w")
1667                    (match_operand:DI 2 "register_operand" "r,!w")))]
1668   ""
1669   "@
1670    sub\\t%x0, %x1, %x2
1671    sub\\t%d0, %d1, %d2"
1672   [(set_attr "type" "alu_reg, neon_sub")
1673    (set_attr "simd" "*,yes")]
1676 (define_expand "subti3"
1677   [(set (match_operand:TI 0 "register_operand" "")
1678         (minus:TI (match_operand:TI 1 "register_operand" "")
1679                   (match_operand:TI 2 "register_operand" "")))]
1680   ""
1682   rtx low = gen_reg_rtx (DImode);
1683   emit_insn (gen_subdi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1684                                   gen_lowpart (DImode, operands[2])));
1686   rtx high = gen_reg_rtx (DImode);
1687   emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]),
1688                                  gen_highpart (DImode, operands[2])));
1690   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1691   emit_move_insn (gen_highpart (DImode, operands[0]), high);
1692   DONE;
1695 (define_insn "sub<mode>3_compare0"
1696   [(set (reg:CC_NZ CC_REGNUM)
1697         (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1698                                   (match_operand:GPI 2 "register_operand" "r"))
1699                        (const_int 0)))
1700    (set (match_operand:GPI 0 "register_operand" "=r")
1701         (minus:GPI (match_dup 1) (match_dup 2)))]
1702   ""
1703   "subs\\t%<w>0, %<w>1, %<w>2"
1704   [(set_attr "type" "alus_reg")]
1707 ;; zero_extend version of above
1708 (define_insn "*subsi3_compare0_uxtw"
1709   [(set (reg:CC_NZ CC_REGNUM)
1710         (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1711                                  (match_operand:SI 2 "register_operand" "r"))
1712                        (const_int 0)))
1713    (set (match_operand:DI 0 "register_operand" "=r")
1714         (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1715   ""
1716   "subs\\t%w0, %w1, %w2"
1717   [(set_attr "type" "alus_reg")]
1720 (define_insn "*sub_<shift>_<mode>"
1721   [(set (match_operand:GPI 0 "register_operand" "=r")
1722         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1723                    (ASHIFT:GPI
1724                     (match_operand:GPI 1 "register_operand" "r")
1725                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1726   ""
1727   "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1728   [(set_attr "type" "alu_shift_imm")]
1731 ;; zero_extend version of above
1732 (define_insn "*sub_<shift>_si_uxtw"
1733   [(set (match_operand:DI 0 "register_operand" "=r")
1734         (zero_extend:DI
1735          (minus:SI (match_operand:SI 3 "register_operand" "r")
1736                    (ASHIFT:SI
1737                     (match_operand:SI 1 "register_operand" "r")
1738                     (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1739   ""
1740   "sub\\t%w0, %w3, %w1, <shift> %2"
1741   [(set_attr "type" "alu_shift_imm")]
1744 (define_insn "*sub_mul_imm_<mode>"
1745   [(set (match_operand:GPI 0 "register_operand" "=r")
1746         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1747                    (mult:GPI
1748                     (match_operand:GPI 1 "register_operand" "r")
1749                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1750   ""
1751   "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1752   [(set_attr "type" "alu_shift_imm")]
1755 ;; zero_extend version of above
1756 (define_insn "*sub_mul_imm_si_uxtw"
1757   [(set (match_operand:DI 0 "register_operand" "=r")
1758         (zero_extend:DI
1759          (minus:SI (match_operand:SI 3 "register_operand" "r")
1760                    (mult:SI
1761                     (match_operand:SI 1 "register_operand" "r")
1762                     (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
1763   ""
1764   "sub\\t%w0, %w3, %w1, lsl %p2"
1765   [(set_attr "type" "alu_shift_imm")]
1768 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
1769   [(set (match_operand:GPI 0 "register_operand" "=rk")
1770         (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1771                    (ANY_EXTEND:GPI
1772                     (match_operand:ALLX 2 "register_operand" "r"))))]
1773   ""
1774   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1775   [(set_attr "type" "alu_ext")]
1778 ;; zero_extend version of above
1779 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
1780   [(set (match_operand:DI 0 "register_operand" "=rk")
1781         (zero_extend:DI
1782          (minus:SI (match_operand:SI 1 "register_operand" "r")
1783                    (ANY_EXTEND:SI
1784                     (match_operand:SHORT 2 "register_operand" "r")))))]
1785   ""
1786   "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
1787   [(set_attr "type" "alu_ext")]
1790 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
1791   [(set (match_operand:GPI 0 "register_operand" "=rk")
1792         (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1793                    (ashift:GPI (ANY_EXTEND:GPI
1794                                 (match_operand:ALLX 2 "register_operand" "r"))
1795                                (match_operand 3 "aarch64_imm3" "Ui3"))))]
1796   ""
1797   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1798   [(set_attr "type" "alu_ext")]
1801 ;; zero_extend version of above
1802 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
1803   [(set (match_operand:DI 0 "register_operand" "=rk")
1804         (zero_extend:DI
1805          (minus:SI (match_operand:SI 1 "register_operand" "r")
1806                    (ashift:SI (ANY_EXTEND:SI
1807                                (match_operand:SHORT 2 "register_operand" "r"))
1808                               (match_operand 3 "aarch64_imm3" "Ui3")))))]
1809   ""
1810   "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
1811   [(set_attr "type" "alu_ext")]
1814 (define_insn "*sub_<optab><mode>_multp2"
1815   [(set (match_operand:GPI 0 "register_operand" "=rk")
1816         (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1817                    (ANY_EXTRACT:GPI
1818                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1819                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1820                     (match_operand 3 "const_int_operand" "n")
1821                     (const_int 0))))]
1822   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1823   "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1824   [(set_attr "type" "alu_ext")]
1827 ;; zero_extend version of above
1828 (define_insn "*sub_<optab>si_multp2_uxtw"
1829   [(set (match_operand:DI 0 "register_operand" "=rk")
1830         (zero_extend:DI
1831          (minus:SI (match_operand:SI 4 "register_operand" "r")
1832                    (ANY_EXTRACT:SI
1833                     (mult:SI (match_operand:SI 1 "register_operand" "r")
1834                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1835                     (match_operand 3 "const_int_operand" "n")
1836                     (const_int 0)))))]
1837   "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1838   "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1839   [(set_attr "type" "alu_ext")]
1842 (define_insn "sub<mode>3_carryin"
1843   [(set
1844     (match_operand:GPI 0 "register_operand" "=r")
1845     (minus:GPI (minus:GPI
1846                 (match_operand:GPI 1 "register_operand" "r")
1847                 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
1848                (match_operand:GPI 2 "register_operand" "r")))]
1849    ""
1850    "sbc\\t%<w>0, %<w>1, %<w>2"
1851   [(set_attr "type" "adc_reg")]
1854 ;; zero_extend version of the above
1855 (define_insn "*subsi3_carryin_uxtw"
1856   [(set
1857     (match_operand:DI 0 "register_operand" "=r")
1858     (zero_extend:DI
1859      (minus:SI (minus:SI
1860                 (match_operand:SI 1 "register_operand" "r")
1861                 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
1862                (match_operand:SI 2 "register_operand" "r"))))]
1863    ""
1864    "sbc\\t%w0, %w1, %w2"
1865   [(set_attr "type" "adc_reg")]
1868 (define_insn "*sub_uxt<mode>_multp2"
1869   [(set (match_operand:GPI 0 "register_operand" "=rk")
1870         (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1871                    (and:GPI
1872                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1873                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1874                     (match_operand 3 "const_int_operand" "n"))))]
1875   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1876   "*
1877   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1878                                            INTVAL (operands[3])));
1879   return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1880   [(set_attr "type" "alu_ext")]
1883 ;; zero_extend version of above
1884 (define_insn "*sub_uxtsi_multp2_uxtw"
1885   [(set (match_operand:DI 0 "register_operand" "=rk")
1886         (zero_extend:DI
1887          (minus:SI (match_operand:SI 4 "register_operand" "r")
1888                    (and:SI
1889                     (mult:SI (match_operand:SI 1 "register_operand" "r")
1890                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1891                     (match_operand 3 "const_int_operand" "n")))))]
1892   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1893   "*
1894   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1895                                            INTVAL (operands[3])));
1896   return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
1897   [(set_attr "type" "alu_ext")]
1900 (define_insn_and_split "absdi2"
1901   [(set (match_operand:DI 0 "register_operand" "=r,w")
1902         (abs:DI (match_operand:DI 1 "register_operand" "r,w")))
1903    (clobber (match_scratch:DI 2 "=&r,X"))]
1904   ""
1905   "@
1906    #
1907    abs\\t%d0, %d1"
1908   "reload_completed
1909    && GP_REGNUM_P (REGNO (operands[0]))
1910    && GP_REGNUM_P (REGNO (operands[1]))"
1911   [(const_int 0)]
1912   {
1913     emit_insn (gen_rtx_SET (VOIDmode, operands[2],
1914                             gen_rtx_XOR (DImode,
1915                                          gen_rtx_ASHIFTRT (DImode,
1916                                                            operands[1],
1917                                                            GEN_INT (63)),
1918                                          operands[1])));
1919     emit_insn (gen_rtx_SET (VOIDmode,
1920                             operands[0],
1921                             gen_rtx_MINUS (DImode,
1922                                            operands[2],
1923                                            gen_rtx_ASHIFTRT (DImode,
1924                                                              operands[1],
1925                                                              GEN_INT (63)))));
1926     DONE;
1927   }
1928   [(set_attr "type" "alu_reg")]
1931 (define_insn "neg<mode>2"
1932   [(set (match_operand:GPI 0 "register_operand" "=r,w")
1933         (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
1934   ""
1935   "@
1936    neg\\t%<w>0, %<w>1
1937    neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
1938   [(set_attr "type" "alu_reg, neon_neg<q>")
1939    (set_attr "simd" "*,yes")]
1942 ;; zero_extend version of above
1943 (define_insn "*negsi2_uxtw"
1944   [(set (match_operand:DI 0 "register_operand" "=r")
1945         (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
1946   ""
1947   "neg\\t%w0, %w1"
1948   [(set_attr "type" "alu_reg")]
1951 (define_insn "*ngc<mode>"
1952   [(set (match_operand:GPI 0 "register_operand" "=r")
1953         (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
1954                    (match_operand:GPI 1 "register_operand" "r")))]
1955   ""
1956   "ngc\\t%<w>0, %<w>1"
1957   [(set_attr "type" "adc_reg")]
1960 (define_insn "*ngcsi_uxtw"
1961   [(set (match_operand:DI 0 "register_operand" "=r")
1962         (zero_extend:DI
1963          (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
1964                    (match_operand:SI 1 "register_operand" "r"))))]
1965   ""
1966   "ngc\\t%w0, %w1"
1967   [(set_attr "type" "adc_reg")]
1970 (define_insn "*neg<mode>2_compare0"
1971   [(set (reg:CC_NZ CC_REGNUM)
1972         (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
1973                        (const_int 0)))
1974    (set (match_operand:GPI 0 "register_operand" "=r")
1975         (neg:GPI (match_dup 1)))]
1976   ""
1977   "negs\\t%<w>0, %<w>1"
1978   [(set_attr "type" "alus_reg")]
1981 ;; zero_extend version of above
1982 (define_insn "*negsi2_compare0_uxtw"
1983   [(set (reg:CC_NZ CC_REGNUM)
1984         (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
1985                        (const_int 0)))
1986    (set (match_operand:DI 0 "register_operand" "=r")
1987         (zero_extend:DI (neg:SI (match_dup 1))))]
1988   ""
1989   "negs\\t%w0, %w1"
1990   [(set_attr "type" "alus_reg")]
1993 (define_insn "*neg_<shift><mode>3_compare0"
1994   [(set (reg:CC_NZ CC_REGNUM)
1995         (compare:CC_NZ
1996          (neg:GPI (ASHIFT:GPI
1997                    (match_operand:GPI 1 "register_operand" "r")
1998                    (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
1999          (const_int 0)))
2000    (set (match_operand:GPI 0 "register_operand" "=r")
2001         (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2002   ""
2003   "negs\\t%<w>0, %<w>1, <shift> %2"
2004   [(set_attr "type" "alus_shift_imm")]
2007 (define_insn "*neg_<shift>_<mode>2"
2008   [(set (match_operand:GPI 0 "register_operand" "=r")
2009         (neg:GPI (ASHIFT:GPI
2010                   (match_operand:GPI 1 "register_operand" "r")
2011                   (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2012   ""
2013   "neg\\t%<w>0, %<w>1, <shift> %2"
2014   [(set_attr "type" "alu_shift_imm")]
2017 ;; zero_extend version of above
2018 (define_insn "*neg_<shift>_si2_uxtw"
2019   [(set (match_operand:DI 0 "register_operand" "=r")
2020         (zero_extend:DI
2021          (neg:SI (ASHIFT:SI
2022                   (match_operand:SI 1 "register_operand" "r")
2023                   (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2024   ""
2025   "neg\\t%w0, %w1, <shift> %2"
2026   [(set_attr "type" "alu_shift_imm")]
2029 (define_insn "*neg_mul_imm_<mode>2"
2030   [(set (match_operand:GPI 0 "register_operand" "=r")
2031         (neg:GPI (mult:GPI
2032                   (match_operand:GPI 1 "register_operand" "r")
2033                   (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2034   ""
2035   "neg\\t%<w>0, %<w>1, lsl %p2"
2036   [(set_attr "type" "alu_shift_imm")]
2039 ;; zero_extend version of above
2040 (define_insn "*neg_mul_imm_si2_uxtw"
2041   [(set (match_operand:DI 0 "register_operand" "=r")
2042         (zero_extend:DI
2043          (neg:SI (mult:SI
2044                   (match_operand:SI 1 "register_operand" "r")
2045                   (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2046   ""
2047   "neg\\t%w0, %w1, lsl %p2"
2048   [(set_attr "type" "alu_shift_imm")]
2051 (define_insn "mul<mode>3"
2052   [(set (match_operand:GPI 0 "register_operand" "=r")
2053         (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2054                   (match_operand:GPI 2 "register_operand" "r")))]
2055   ""
2056   "mul\\t%<w>0, %<w>1, %<w>2"
2057   [(set_attr "type" "mul")]
2060 ;; zero_extend version of above
2061 (define_insn "*mulsi3_uxtw"
2062   [(set (match_operand:DI 0 "register_operand" "=r")
2063         (zero_extend:DI
2064          (mult:SI (match_operand:SI 1 "register_operand" "r")
2065                   (match_operand:SI 2 "register_operand" "r"))))]
2066   ""
2067   "mul\\t%w0, %w1, %w2"
2068   [(set_attr "type" "mul")]
2071 (define_insn "madd<mode>"
2072   [(set (match_operand:GPI 0 "register_operand" "=r")
2073         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2074                             (match_operand:GPI 2 "register_operand" "r"))
2075                   (match_operand:GPI 3 "register_operand" "r")))]
2076   ""
2077   "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2078   [(set_attr "type" "mla")]
2081 ;; zero_extend version of above
2082 (define_insn "*maddsi_uxtw"
2083   [(set (match_operand:DI 0 "register_operand" "=r")
2084         (zero_extend:DI
2085          (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2086                            (match_operand:SI 2 "register_operand" "r"))
2087                   (match_operand:SI 3 "register_operand" "r"))))]
2088   ""
2089   "madd\\t%w0, %w1, %w2, %w3"
2090   [(set_attr "type" "mla")]
2093 (define_insn "*msub<mode>"
2094   [(set (match_operand:GPI 0 "register_operand" "=r")
2095         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2096                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2097                              (match_operand:GPI 2 "register_operand" "r"))))]
2099   ""
2100   "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2101   [(set_attr "type" "mla")]
2104 ;; zero_extend version of above
2105 (define_insn "*msubsi_uxtw"
2106   [(set (match_operand:DI 0 "register_operand" "=r")
2107         (zero_extend:DI
2108          (minus:SI (match_operand:SI 3 "register_operand" "r")
2109                    (mult:SI (match_operand:SI 1 "register_operand" "r")
2110                             (match_operand:SI 2 "register_operand" "r")))))]
2112   ""
2113   "msub\\t%w0, %w1, %w2, %w3"
2114   [(set_attr "type" "mla")]
2117 (define_insn "*mul<mode>_neg"
2118   [(set (match_operand:GPI 0 "register_operand" "=r")
2119         (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2120                   (match_operand:GPI 2 "register_operand" "r")))]
2122   ""
2123   "mneg\\t%<w>0, %<w>1, %<w>2"
2124   [(set_attr "type" "mul")]
2127 ;; zero_extend version of above
2128 (define_insn "*mulsi_neg_uxtw"
2129   [(set (match_operand:DI 0 "register_operand" "=r")
2130         (zero_extend:DI
2131          (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2132                   (match_operand:SI 2 "register_operand" "r"))))]
2134   ""
2135   "mneg\\t%w0, %w1, %w2"
2136   [(set_attr "type" "mul")]
2139 (define_insn "<su_optab>mulsidi3"
2140   [(set (match_operand:DI 0 "register_operand" "=r")
2141         (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2142                  (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2143   ""
2144   "<su>mull\\t%0, %w1, %w2"
2145   [(set_attr "type" "<su>mull")]
2148 (define_insn "<su_optab>maddsidi4"
2149   [(set (match_operand:DI 0 "register_operand" "=r")
2150         (plus:DI (mult:DI
2151                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2152                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2153                  (match_operand:DI 3 "register_operand" "r")))]
2154   ""
2155   "<su>maddl\\t%0, %w1, %w2, %3"
2156   [(set_attr "type" "<su>mlal")]
2159 (define_insn "<su_optab>msubsidi4"
2160   [(set (match_operand:DI 0 "register_operand" "=r")
2161         (minus:DI
2162          (match_operand:DI 3 "register_operand" "r")
2163          (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2164                   (ANY_EXTEND:DI
2165                    (match_operand:SI 2 "register_operand" "r")))))]
2166   ""
2167   "<su>msubl\\t%0, %w1, %w2, %3"
2168   [(set_attr "type" "<su>mlal")]
2171 (define_insn "*<su_optab>mulsidi_neg"
2172   [(set (match_operand:DI 0 "register_operand" "=r")
2173         (mult:DI (neg:DI
2174                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2175                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2176   ""
2177   "<su>mnegl\\t%0, %w1, %w2"
2178   [(set_attr "type" "<su>mull")]
2181 (define_expand "<su_optab>mulditi3"
2182   [(set (match_operand:TI 0 "register_operand")
2183         (mult:TI (ANY_EXTEND:TI (match_operand:DI 1 "register_operand"))
2184                  (ANY_EXTEND:TI (match_operand:DI 2 "register_operand"))))]
2185   ""
2187   rtx low = gen_reg_rtx (DImode);
2188   emit_insn (gen_muldi3 (low, operands[1], operands[2]));
2190   rtx high = gen_reg_rtx (DImode);
2191   emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2]));
2193   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2194   emit_move_insn (gen_highpart (DImode, operands[0]), high);
2195   DONE;
2198 ;; The default expansion of multi3 using umuldi3_highpart will perform
2199 ;; the additions in an order that fails to combine into two madd insns.
2200 (define_expand "multi3"
2201   [(set (match_operand:TI 0 "register_operand")
2202         (mult:TI (match_operand:TI 1 "register_operand")
2203                  (match_operand:TI 2 "register_operand")))]
2204   ""
2206   rtx l0 = gen_reg_rtx (DImode);
2207   rtx l1 = gen_lowpart (DImode, operands[1]);
2208   rtx l2 = gen_lowpart (DImode, operands[2]);
2209   rtx h0 = gen_reg_rtx (DImode);
2210   rtx h1 = gen_highpart (DImode, operands[1]);
2211   rtx h2 = gen_highpart (DImode, operands[2]);
2213   emit_insn (gen_muldi3 (l0, l1, l2));
2214   emit_insn (gen_umuldi3_highpart (h0, l1, l2));
2215   emit_insn (gen_madddi (h0, h1, l2, h0));
2216   emit_insn (gen_madddi (h0, l1, h2, h0));
2218   emit_move_insn (gen_lowpart (DImode, operands[0]), l0);
2219   emit_move_insn (gen_highpart (DImode, operands[0]), h0);
2220   DONE;
2223 (define_insn "<su>muldi3_highpart"
2224   [(set (match_operand:DI 0 "register_operand" "=r")
2225         (truncate:DI
2226          (lshiftrt:TI
2227           (mult:TI
2228            (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2229            (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2230           (const_int 64))))]
2231   ""
2232   "<su>mulh\\t%0, %1, %2"
2233   [(set_attr "type" "<su>mull")]
2236 (define_insn "<su_optab>div<mode>3"
2237   [(set (match_operand:GPI 0 "register_operand" "=r")
2238         (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2239                      (match_operand:GPI 2 "register_operand" "r")))]
2240   ""
2241   "<su>div\\t%<w>0, %<w>1, %<w>2"
2242   [(set_attr "type" "<su>div")]
2245 ;; zero_extend version of above
2246 (define_insn "*<su_optab>divsi3_uxtw"
2247   [(set (match_operand:DI 0 "register_operand" "=r")
2248         (zero_extend:DI
2249          (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2250                      (match_operand:SI 2 "register_operand" "r"))))]
2251   ""
2252   "<su>div\\t%w0, %w1, %w2"
2253   [(set_attr "type" "<su>div")]
2256 ;; -------------------------------------------------------------------
2257 ;; Comparison insns
2258 ;; -------------------------------------------------------------------
2260 (define_insn "*cmp<mode>"
2261   [(set (reg:CC CC_REGNUM)
2262         (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2263                     (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2264   ""
2265   "@
2266    cmp\\t%<w>0, %<w>1
2267    cmp\\t%<w>0, %<w>1
2268    cmn\\t%<w>0, #%n1"
2269   [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
2272 (define_insn "*cmp<mode>"
2273   [(set (reg:CCFP CC_REGNUM)
2274         (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2275                       (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2276    "TARGET_FLOAT"
2277    "@
2278     fcmp\\t%<s>0, #0.0
2279     fcmp\\t%<s>0, %<s>1"
2280   [(set_attr "type" "fcmp<s>")]
2283 (define_insn "*cmpe<mode>"
2284   [(set (reg:CCFPE CC_REGNUM)
2285         (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2286                        (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2287    "TARGET_FLOAT"
2288    "@
2289     fcmpe\\t%<s>0, #0.0
2290     fcmpe\\t%<s>0, %<s>1"
2291   [(set_attr "type" "fcmp<s>")]
2294 (define_insn "*cmp_swp_<shift>_reg<mode>"
2295   [(set (reg:CC_SWP CC_REGNUM)
2296         (compare:CC_SWP (ASHIFT:GPI
2297                          (match_operand:GPI 0 "register_operand" "r")
2298                          (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2299                         (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2300   ""
2301   "cmp\\t%<w>2, %<w>0, <shift> %1"
2302   [(set_attr "type" "alus_shift_imm")]
2305 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2306   [(set (reg:CC_SWP CC_REGNUM)
2307         (compare:CC_SWP (ANY_EXTEND:GPI
2308                          (match_operand:ALLX 0 "register_operand" "r"))
2309                         (match_operand:GPI 1 "register_operand" "r")))]
2310   ""
2311   "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2312   [(set_attr "type" "alus_ext")]
2315 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2316   [(set (reg:CC_SWP CC_REGNUM)
2317         (compare:CC_SWP (ashift:GPI
2318                          (ANY_EXTEND:GPI
2319                           (match_operand:ALLX 0 "register_operand" "r"))
2320                          (match_operand 1 "aarch64_imm3" "Ui3"))
2321         (match_operand:GPI 2 "register_operand" "r")))]
2322   ""
2323   "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2324   [(set_attr "type" "alus_ext")]
2327 ;; -------------------------------------------------------------------
2328 ;; Store-flag and conditional select insns
2329 ;; -------------------------------------------------------------------
2331 (define_expand "cstore<mode>4"
2332   [(set (match_operand:SI 0 "register_operand" "")
2333         (match_operator:SI 1 "aarch64_comparison_operator"
2334          [(match_operand:GPI 2 "register_operand" "")
2335           (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2336   ""
2337   "
2338   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2339                                       operands[3]);
2340   operands[3] = const0_rtx;
2341   "
2344 (define_expand "cstore<mode>4"
2345   [(set (match_operand:SI 0 "register_operand" "")
2346         (match_operator:SI 1 "aarch64_comparison_operator"
2347          [(match_operand:GPF 2 "register_operand" "")
2348           (match_operand:GPF 3 "register_operand" "")]))]
2349   ""
2350   "
2351   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2352                                       operands[3]);
2353   operands[3] = const0_rtx;
2354   "
2357 (define_insn "*cstore<mode>_insn"
2358   [(set (match_operand:ALLI 0 "register_operand" "=r")
2359         (match_operator:ALLI 1 "aarch64_comparison_operator"
2360          [(match_operand 2 "cc_register" "") (const_int 0)]))]
2361   ""
2362   "cset\\t%<w>0, %m1"
2363   [(set_attr "type" "csel")]
2366 ;; zero_extend version of the above
2367 (define_insn "*cstoresi_insn_uxtw"
2368   [(set (match_operand:DI 0 "register_operand" "=r")
2369         (zero_extend:DI
2370          (match_operator:SI 1 "aarch64_comparison_operator"
2371           [(match_operand 2 "cc_register" "") (const_int 0)])))]
2372   ""
2373   "cset\\t%w0, %m1"
2374   [(set_attr "type" "csel")]
2377 (define_insn "cstore<mode>_neg"
2378   [(set (match_operand:ALLI 0 "register_operand" "=r")
2379         (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2380                   [(match_operand 2 "cc_register" "") (const_int 0)])))]
2381   ""
2382   "csetm\\t%<w>0, %m1"
2383   [(set_attr "type" "csel")]
2386 ;; zero_extend version of the above
2387 (define_insn "*cstoresi_neg_uxtw"
2388   [(set (match_operand:DI 0 "register_operand" "=r")
2389         (zero_extend:DI
2390          (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2391                   [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2392   ""
2393   "csetm\\t%w0, %m1"
2394   [(set_attr "type" "csel")]
2397 (define_expand "cmov<mode>6"
2398   [(set (match_operand:GPI 0 "register_operand" "")
2399         (if_then_else:GPI
2400          (match_operator 1 "aarch64_comparison_operator"
2401           [(match_operand:GPI 2 "register_operand" "")
2402            (match_operand:GPI 3 "aarch64_plus_operand" "")])
2403          (match_operand:GPI 4 "register_operand" "")
2404          (match_operand:GPI 5 "register_operand" "")))]
2405   ""
2406   "
2407   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2408                                       operands[3]);
2409   operands[3] = const0_rtx;
2410   "
2413 (define_expand "cmov<mode>6"
2414   [(set (match_operand:GPF 0 "register_operand" "")
2415         (if_then_else:GPF
2416          (match_operator 1 "aarch64_comparison_operator"
2417           [(match_operand:GPF 2 "register_operand" "")
2418            (match_operand:GPF 3 "register_operand" "")])
2419          (match_operand:GPF 4 "register_operand" "")
2420          (match_operand:GPF 5 "register_operand" "")))]
2421   ""
2422   "
2423   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2424                                       operands[3]);
2425   operands[3] = const0_rtx;
2426   "
2429 (define_insn "*cmov<mode>_insn"
2430   [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2431         (if_then_else:ALLI
2432          (match_operator 1 "aarch64_comparison_operator"
2433           [(match_operand 2 "cc_register" "") (const_int 0)])
2434          (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2435          (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2436   "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2437      || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2438   ;; Final two alternatives should be unreachable, but included for completeness
2439   "@
2440    csel\\t%<w>0, %<w>3, %<w>4, %m1
2441    csinv\\t%<w>0, %<w>3, <w>zr, %m1
2442    csinv\\t%<w>0, %<w>4, <w>zr, %M1
2443    csinc\\t%<w>0, %<w>3, <w>zr, %m1
2444    csinc\\t%<w>0, %<w>4, <w>zr, %M1
2445    mov\\t%<w>0, -1
2446    mov\\t%<w>0, 1"
2447   [(set_attr "type" "csel")]
2450 ;; zero_extend version of above
2451 (define_insn "*cmovsi_insn_uxtw"
2452   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2453         (zero_extend:DI
2454          (if_then_else:SI
2455           (match_operator 1 "aarch64_comparison_operator"
2456            [(match_operand 2 "cc_register" "") (const_int 0)])
2457           (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2458           (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2459   "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2460      || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2461   ;; Final two alternatives should be unreachable, but included for completeness
2462   "@
2463    csel\\t%w0, %w3, %w4, %m1
2464    csinv\\t%w0, %w3, wzr, %m1
2465    csinv\\t%w0, %w4, wzr, %M1
2466    csinc\\t%w0, %w3, wzr, %m1
2467    csinc\\t%w0, %w4, wzr, %M1
2468    mov\\t%w0, -1
2469    mov\\t%w0, 1"
2470   [(set_attr "type" "csel")]
2473 (define_insn "*cmov<mode>_insn"
2474   [(set (match_operand:GPF 0 "register_operand" "=w")
2475         (if_then_else:GPF
2476          (match_operator 1 "aarch64_comparison_operator"
2477           [(match_operand 2 "cc_register" "") (const_int 0)])
2478          (match_operand:GPF 3 "register_operand" "w")
2479          (match_operand:GPF 4 "register_operand" "w")))]
2480   "TARGET_FLOAT"
2481   "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2482   [(set_attr "type" "fcsel")]
2485 (define_expand "mov<mode>cc"
2486   [(set (match_operand:ALLI 0 "register_operand" "")
2487         (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2488                            (match_operand:ALLI 2 "register_operand" "")
2489                            (match_operand:ALLI 3 "register_operand" "")))]
2490   ""
2491   {
2492     rtx ccreg;
2493     enum rtx_code code = GET_CODE (operands[1]);
2495     if (code == UNEQ || code == LTGT)
2496       FAIL;
2498     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2499                                   XEXP (operands[1], 1));
2500     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2501   }
2504 (define_expand "mov<GPF:mode><GPI:mode>cc"
2505   [(set (match_operand:GPI 0 "register_operand" "")
2506         (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2507                           (match_operand:GPF 2 "register_operand" "")
2508                           (match_operand:GPF 3 "register_operand" "")))]
2509   ""
2510   {
2511     rtx ccreg;
2512     enum rtx_code code = GET_CODE (operands[1]);
2514     if (code == UNEQ || code == LTGT)
2515       FAIL;
2517     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2518                                   XEXP (operands[1], 1));
2519     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2520   }
2523 (define_expand "mov<mode>cc"
2524   [(set (match_operand:GPF 0 "register_operand" "")
2525         (if_then_else:GPF (match_operand 1 "aarch64_comparison_operator" "")
2526                           (match_operand:GPF 2 "register_operand" "")
2527                           (match_operand:GPF 3 "register_operand" "")))]
2528   ""
2529   {
2530     rtx ccreg;
2531     enum rtx_code code = GET_CODE (operands[1]);
2533     if (code == UNEQ || code == LTGT)
2534       FAIL;
2536     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2537                                   XEXP (operands[1], 1));
2538     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2539   }
2543 ;; CRC32 instructions.
2544 (define_insn "aarch64_<crc_variant>"
2545   [(set (match_operand:SI 0 "register_operand" "=r")
2546         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2547                     (match_operand:<crc_mode> 2 "register_operand" "r")]
2548          CRC))]
2549   "TARGET_CRC32"
2550   {
2551     if (GET_MODE_BITSIZE (GET_MODE (operands[2])) >= 64)
2552       return "<crc_variant>\\t%w0, %w1, %x2";
2553     else
2554       return "<crc_variant>\\t%w0, %w1, %w2";
2555   }
2556   [(set_attr "type" "crc")]
2559 (define_insn "*csinc2<mode>_insn"
2560   [(set (match_operand:GPI 0 "register_operand" "=r")
2561         (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator"
2562                   [(match_operand:CC 3 "cc_register" "") (const_int 0)])
2563                  (match_operand:GPI 1 "register_operand" "r")))]
2564   ""
2565   "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2566   [(set_attr "type" "csel")]
2569 (define_insn "csinc3<mode>_insn"
2570   [(set (match_operand:GPI 0 "register_operand" "=r")
2571         (if_then_else:GPI
2572           (match_operator:GPI 1 "aarch64_comparison_operator"
2573            [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2574           (plus:GPI (match_operand:GPI 3 "register_operand" "r")
2575                     (const_int 1))
2576           (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2577   ""
2578   "csinc\\t%<w>0, %<w>4, %<w>3, %M1"
2579   [(set_attr "type" "csel")]
2582 (define_insn "*csinv3<mode>_insn"
2583   [(set (match_operand:GPI 0 "register_operand" "=r")
2584         (if_then_else:GPI
2585           (match_operator:GPI 1 "aarch64_comparison_operator"
2586            [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2587           (not:GPI (match_operand:GPI 3 "register_operand" "r"))
2588           (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2589   ""
2590   "csinv\\t%<w>0, %<w>4, %<w>3, %M1"
2591   [(set_attr "type" "csel")]
2594 (define_insn "*csneg3<mode>_insn"
2595   [(set (match_operand:GPI 0 "register_operand" "=r")
2596         (if_then_else:GPI
2597           (match_operator:GPI 1 "aarch64_comparison_operator"
2598            [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2599           (neg:GPI (match_operand:GPI 3 "register_operand" "r"))
2600           (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2601   ""
2602   "csneg\\t%<w>0, %<w>4, %<w>3, %M1"
2603   [(set_attr "type" "csel")]
2606 ;; -------------------------------------------------------------------
2607 ;; Logical operations
2608 ;; -------------------------------------------------------------------
2610 (define_insn "<optab><mode>3"
2611   [(set (match_operand:GPI 0 "register_operand" "=r,rk")
2612         (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2613                      (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
2614   ""
2615   "<logical>\\t%<w>0, %<w>1, %<w>2"
2616   [(set_attr "type" "logic_reg,logic_imm")]
2619 ;; zero_extend version of above
2620 (define_insn "*<optab>si3_uxtw"
2621   [(set (match_operand:DI 0 "register_operand" "=r,rk")
2622         (zero_extend:DI
2623          (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2624                      (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2625   ""
2626   "<logical>\\t%w0, %w1, %w2"
2627   [(set_attr "type" "logic_reg,logic_imm")]
2630 (define_insn "*and<mode>3_compare0"
2631   [(set (reg:CC_NZ CC_REGNUM)
2632         (compare:CC_NZ
2633          (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2634                   (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2635          (const_int 0)))
2636    (set (match_operand:GPI 0 "register_operand" "=r,r")
2637         (and:GPI (match_dup 1) (match_dup 2)))]
2638   ""
2639   "ands\\t%<w>0, %<w>1, %<w>2"
2640   [(set_attr "type" "logics_reg,logics_imm")]
2643 ;; zero_extend version of above
2644 (define_insn "*andsi3_compare0_uxtw"
2645   [(set (reg:CC_NZ CC_REGNUM)
2646         (compare:CC_NZ
2647          (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2648                  (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2649          (const_int 0)))
2650    (set (match_operand:DI 0 "register_operand" "=r,r")
2651         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2652   ""
2653   "ands\\t%w0, %w1, %w2"
2654   [(set_attr "type" "logics_reg,logics_imm")]
2657 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2658   [(set (reg:CC_NZ CC_REGNUM)
2659         (compare:CC_NZ
2660          (and:GPI (SHIFT:GPI
2661                    (match_operand:GPI 1 "register_operand" "r")
2662                    (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2663                   (match_operand:GPI 3 "register_operand" "r"))
2664          (const_int 0)))
2665    (set (match_operand:GPI 0 "register_operand" "=r")
2666         (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2667   ""
2668   "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2669   [(set_attr "type" "logics_shift_imm")]
2672 ;; zero_extend version of above
2673 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2674   [(set (reg:CC_NZ CC_REGNUM)
2675         (compare:CC_NZ
2676          (and:SI (SHIFT:SI
2677                   (match_operand:SI 1 "register_operand" "r")
2678                   (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2679                  (match_operand:SI 3 "register_operand" "r"))
2680          (const_int 0)))
2681    (set (match_operand:DI 0 "register_operand" "=r")
2682         (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2683                                 (match_dup 3))))]
2684   ""
2685   "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2686   [(set_attr "type" "logics_shift_imm")]
2689 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2690   [(set (match_operand:GPI 0 "register_operand" "=r")
2691         (LOGICAL:GPI (SHIFT:GPI
2692                       (match_operand:GPI 1 "register_operand" "r")
2693                       (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2694                      (match_operand:GPI 3 "register_operand" "r")))]
2695   ""
2696   "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2697   [(set_attr "type" "logic_shift_imm")]
2700 (define_insn "*<optab>_rol<mode>3"
2701   [(set (match_operand:GPI 0 "register_operand" "=r")
2702         (LOGICAL:GPI (rotate:GPI
2703                       (match_operand:GPI 1 "register_operand" "r")
2704                       (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2705                      (match_operand:GPI 3 "register_operand" "r")))]
2706   ""
2707   "<logical>\\t%<w>0, %<w>3, %<w>1, ror (<sizen> - %2)"
2708   [(set_attr "type" "logic_shift_imm")]
2711 ;; zero_extend versions of above
2712 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
2713   [(set (match_operand:DI 0 "register_operand" "=r")
2714         (zero_extend:DI
2715          (LOGICAL:SI (SHIFT:SI
2716                       (match_operand:SI 1 "register_operand" "r")
2717                       (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2718                      (match_operand:SI 3 "register_operand" "r"))))]
2719   ""
2720   "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2721   [(set_attr "type" "logic_shift_imm")]
2724 (define_insn "*<optab>_rolsi3_uxtw"
2725   [(set (match_operand:DI 0 "register_operand" "=r")
2726         (zero_extend:DI
2727          (LOGICAL:SI (rotate:SI
2728                       (match_operand:SI 1 "register_operand" "r")
2729                       (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2730                      (match_operand:SI 3 "register_operand" "r"))))]
2731   ""
2732   "<logical>\\t%w0, %w3, %w1, ror (32 - %2)"
2733   [(set_attr "type" "logic_shift_imm")]
2736 (define_insn "one_cmpl<mode>2"
2737   [(set (match_operand:GPI 0 "register_operand" "=r")
2738         (not:GPI (match_operand:GPI 1 "register_operand" "r")))]
2739   ""
2740   "mvn\\t%<w>0, %<w>1"
2741   [(set_attr "type" "logic_reg")]
2744 (define_insn "*one_cmpl_<optab><mode>2"
2745   [(set (match_operand:GPI 0 "register_operand" "=r")
2746         (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
2747                             (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2748   ""
2749   "mvn\\t%<w>0, %<w>1, <shift> %2"
2750   [(set_attr "type" "logic_shift_imm")]
2753 (define_insn "*<LOGICAL:optab>_one_cmpl<mode>3"
2754   [(set (match_operand:GPI 0 "register_operand" "=r")
2755         (LOGICAL:GPI (not:GPI
2756                       (match_operand:GPI 1 "register_operand" "r"))
2757                      (match_operand:GPI 2 "register_operand" "r")))]
2758   ""
2759   "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1"
2760   [(set_attr "type" "logic_reg")]
2763 (define_insn "*and_one_cmpl<mode>3_compare0"
2764   [(set (reg:CC_NZ CC_REGNUM)
2765         (compare:CC_NZ
2766          (and:GPI (not:GPI
2767                    (match_operand:GPI 1 "register_operand" "r"))
2768                   (match_operand:GPI 2 "register_operand" "r"))
2769          (const_int 0)))
2770    (set (match_operand:GPI 0 "register_operand" "=r")
2771         (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
2772   ""
2773   "bics\\t%<w>0, %<w>2, %<w>1"
2774   [(set_attr "type" "logics_reg")]
2777 ;; zero_extend version of above
2778 (define_insn "*and_one_cmplsi3_compare0_uxtw"
2779   [(set (reg:CC_NZ CC_REGNUM)
2780         (compare:CC_NZ
2781          (and:SI (not:SI
2782                   (match_operand:SI 1 "register_operand" "r"))
2783                  (match_operand:SI 2 "register_operand" "r"))
2784          (const_int 0)))
2785    (set (match_operand:DI 0 "register_operand" "=r")
2786         (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
2787   ""
2788   "bics\\t%w0, %w2, %w1"
2789   [(set_attr "type" "logics_reg")]
2792 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
2793   [(set (match_operand:GPI 0 "register_operand" "=r")
2794         (LOGICAL:GPI (not:GPI
2795                       (SHIFT:GPI
2796                        (match_operand:GPI 1 "register_operand" "r")
2797                        (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2798                      (match_operand:GPI 3 "register_operand" "r")))]
2799   ""
2800   "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2801   [(set_attr "type" "logics_shift_imm")]
2804 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
2805   [(set (reg:CC_NZ CC_REGNUM)
2806         (compare:CC_NZ
2807          (and:GPI (not:GPI
2808                    (SHIFT:GPI
2809                     (match_operand:GPI 1 "register_operand" "r")
2810                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2811                   (match_operand:GPI 3 "register_operand" "r"))
2812          (const_int 0)))
2813    (set (match_operand:GPI 0 "register_operand" "=r")
2814         (and:GPI (not:GPI
2815                   (SHIFT:GPI
2816                    (match_dup 1) (match_dup 2))) (match_dup 3)))]
2817   ""
2818   "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2819   [(set_attr "type" "logics_shift_imm")]
2822 ;; zero_extend version of above
2823 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
2824   [(set (reg:CC_NZ CC_REGNUM)
2825         (compare:CC_NZ
2826          (and:SI (not:SI
2827                   (SHIFT:SI
2828                    (match_operand:SI 1 "register_operand" "r")
2829                    (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
2830                  (match_operand:SI 3 "register_operand" "r"))
2831          (const_int 0)))
2832    (set (match_operand:DI 0 "register_operand" "=r")
2833         (zero_extend:DI (and:SI
2834                          (not:SI
2835                           (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
2836   ""
2837   "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2838   [(set_attr "type" "logics_shift_imm")]
2841 (define_insn "clz<mode>2"
2842   [(set (match_operand:GPI 0 "register_operand" "=r")
2843         (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
2844   ""
2845   "clz\\t%<w>0, %<w>1"
2846   [(set_attr "type" "clz")]
2849 (define_expand "ffs<mode>2"
2850   [(match_operand:GPI 0 "register_operand")
2851    (match_operand:GPI 1 "register_operand")]
2852   ""
2853   {
2854     rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
2855     rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
2857     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2858     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2859     emit_insn (gen_csinc3<mode>_insn (operands[0], x, ccreg, operands[0], const0_rtx));
2860     DONE;
2861   }
2864 (define_insn "clrsb<mode>2"
2865   [(set (match_operand:GPI 0 "register_operand" "=r")
2866         (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_CLS))]
2867   ""
2868   "cls\\t%<w>0, %<w>1"
2869   [(set_attr "type" "clz")]
2872 (define_insn "rbit<mode>2"
2873   [(set (match_operand:GPI 0 "register_operand" "=r")
2874         (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
2875   ""
2876   "rbit\\t%<w>0, %<w>1"
2877   [(set_attr "type" "rbit")]
2880 (define_expand "ctz<mode>2"
2881   [(match_operand:GPI 0 "register_operand")
2882    (match_operand:GPI 1 "register_operand")]
2883   ""
2884   {
2885     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2886     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2887     DONE;
2888   }
2891 (define_insn "*and<mode>3nr_compare0"
2892   [(set (reg:CC_NZ CC_REGNUM)
2893         (compare:CC_NZ
2894          (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
2895                   (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
2896          (const_int 0)))]
2897   ""
2898   "tst\\t%<w>0, %<w>1"
2899   [(set_attr "type" "logics_reg")]
2902 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
2903   [(set (reg:CC_NZ CC_REGNUM)
2904         (compare:CC_NZ
2905          (and:GPI (SHIFT:GPI
2906                    (match_operand:GPI 0 "register_operand" "r")
2907                    (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2908                   (match_operand:GPI 2 "register_operand" "r"))
2909         (const_int 0)))]
2910   ""
2911   "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
2912   [(set_attr "type" "logics_shift_imm")]
2915 ;; -------------------------------------------------------------------
2916 ;; Shifts
2917 ;; -------------------------------------------------------------------
2919 (define_expand "<optab><mode>3"
2920   [(set (match_operand:GPI 0 "register_operand")
2921         (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
2922                     (match_operand:QI 2 "nonmemory_operand")))]
2923   ""
2924   {
2925     if (CONST_INT_P (operands[2]))
2926       {
2927         operands[2] = GEN_INT (INTVAL (operands[2])
2928                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2930         if (operands[2] == const0_rtx)
2931           {
2932             emit_insn (gen_mov<mode> (operands[0], operands[1]));
2933             DONE;
2934           }
2935       }
2936   }
2939 (define_expand "ashl<mode>3"
2940   [(set (match_operand:SHORT 0 "register_operand")
2941         (ashift:SHORT (match_operand:SHORT 1 "register_operand")
2942                       (match_operand:QI 2 "nonmemory_operand")))]
2943   ""
2944   {
2945     if (CONST_INT_P (operands[2]))
2946       {
2947         operands[2] = GEN_INT (INTVAL (operands[2])
2948                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2950         if (operands[2] == const0_rtx)
2951           {
2952             emit_insn (gen_mov<mode> (operands[0], operands[1]));
2953             DONE;
2954           }
2955       }
2956   }
2959 (define_expand "rotr<mode>3"
2960   [(set (match_operand:GPI 0 "register_operand")
2961         (rotatert:GPI (match_operand:GPI 1 "register_operand")
2962                       (match_operand:QI 2 "nonmemory_operand")))]
2963   ""
2964   {
2965     if (CONST_INT_P (operands[2]))
2966       {
2967         operands[2] = GEN_INT (INTVAL (operands[2])
2968                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2970         if (operands[2] == const0_rtx)
2971           {
2972             emit_insn (gen_mov<mode> (operands[0], operands[1]));
2973             DONE;
2974           }
2975       }
2976   }
2979 (define_expand "rotl<mode>3"
2980   [(set (match_operand:GPI 0 "register_operand")
2981         (rotatert:GPI (match_operand:GPI 1 "register_operand")
2982                       (match_operand:QI 2 "nonmemory_operand")))]
2983   ""
2984   {
2985     /* (SZ - cnt) % SZ == -cnt % SZ */
2986     if (CONST_INT_P (operands[2]))
2987       {
2988         operands[2] = GEN_INT ((-INTVAL (operands[2]))
2989                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2990         if (operands[2] == const0_rtx)
2991           {
2992             emit_insn (gen_mov<mode> (operands[0], operands[1]));
2993             DONE;
2994           }
2995       }
2996     else
2997       operands[2] = expand_simple_unop (QImode, NEG, operands[2],
2998                                         NULL_RTX, 1);
2999   }
3002 ;; Logical left shift using SISD or Integer instruction
3003 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
3004   [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3005         (ashift:GPI
3006           (match_operand:GPI 1 "register_operand" "w,w,r")
3007           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3008   ""
3009   "@
3010    shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3011    ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
3012    lsl\t%<w>0, %<w>1, %<w>2"
3013   [(set_attr "simd" "yes,yes,no")
3014    (set_attr "type" "neon_shift_imm<q>, neon_shift_reg<q>,shift_reg")]
3017 ;; Logical right shift using SISD or Integer instruction
3018 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3019   [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3020         (lshiftrt:GPI
3021           (match_operand:GPI 1 "register_operand" "w,w,r")
3022           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3023   ""
3024   "@
3025    ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3026    #
3027    lsr\t%<w>0, %<w>1, %<w>2"
3028   [(set_attr "simd" "yes,yes,no")
3029    (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")]
3032 (define_split
3033   [(set (match_operand:DI 0 "aarch64_simd_register")
3034         (lshiftrt:DI
3035            (match_operand:DI 1 "aarch64_simd_register")
3036            (match_operand:QI 2 "aarch64_simd_register")))]
3037   "TARGET_SIMD && reload_completed"
3038   [(set (match_dup 2)
3039         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3040    (set (match_dup 0)
3041         (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_USHL))]
3042   ""
3045 (define_split
3046   [(set (match_operand:SI 0 "aarch64_simd_register")
3047         (lshiftrt:SI
3048            (match_operand:SI 1 "aarch64_simd_register")
3049            (match_operand:QI 2 "aarch64_simd_register")))]
3050   "TARGET_SIMD && reload_completed"
3051   [(set (match_dup 2)
3052         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3053    (set (match_dup 0)
3054         (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_USHL_2S))]
3055   ""
3058 ;; Arithmetic right shift using SISD or Integer instruction
3059 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3060   [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3061         (ashiftrt:GPI
3062           (match_operand:GPI 1 "register_operand" "w,w,r")
3063           (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,rUs<cmode>")))]
3064   ""
3065   "@
3066    sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3067    #
3068    asr\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 (define_split
3074   [(set (match_operand:DI 0 "aarch64_simd_register")
3075         (ashiftrt:DI
3076            (match_operand:DI 1 "aarch64_simd_register")
3077            (match_operand:QI 2 "aarch64_simd_register")))]
3078   "TARGET_SIMD && reload_completed"
3079   [(set (match_dup 2)
3080         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3081    (set (match_dup 0)
3082         (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_SSHL))]
3083   ""
3086 (define_split
3087   [(set (match_operand:SI 0 "aarch64_simd_register")
3088         (ashiftrt:SI
3089            (match_operand:SI 1 "aarch64_simd_register")
3090            (match_operand:QI 2 "aarch64_simd_register")))]
3091   "TARGET_SIMD && reload_completed"
3092   [(set (match_dup 2)
3093         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3094    (set (match_dup 0)
3095         (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_SSHL_2S))]
3096   ""
3099 (define_insn "*aarch64_sisd_ushl"
3100   [(set (match_operand:DI 0 "register_operand" "=w")
3101         (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3102                     (match_operand:QI 2 "register_operand" "w")]
3103                    UNSPEC_SISD_USHL))]
3104   "TARGET_SIMD"
3105   "ushl\t%d0, %d1, %d2"
3106   [(set_attr "simd" "yes")
3107    (set_attr "type" "neon_shift_reg")]
3110 (define_insn "*aarch64_ushl_2s"
3111   [(set (match_operand:SI 0 "register_operand" "=w")
3112         (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3113                     (match_operand:QI 2 "register_operand" "w")]
3114                    UNSPEC_USHL_2S))]
3115   "TARGET_SIMD"
3116   "ushl\t%0.2s, %1.2s, %2.2s"
3117   [(set_attr "simd" "yes")
3118    (set_attr "type" "neon_shift_reg")]
3121 (define_insn "*aarch64_sisd_sshl"
3122   [(set (match_operand:DI 0 "register_operand" "=w")
3123         (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3124                     (match_operand:QI 2 "register_operand" "w")]
3125                    UNSPEC_SISD_SSHL))]
3126   "TARGET_SIMD"
3127   "sshl\t%d0, %d1, %d2"
3128   [(set_attr "simd" "yes")
3129    (set_attr "type" "neon_shift_reg")]
3132 (define_insn "*aarch64_sshl_2s"
3133   [(set (match_operand:SI 0 "register_operand" "=w")
3134         (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3135                     (match_operand:QI 2 "register_operand" "w")]
3136                    UNSPEC_SSHL_2S))]
3137   "TARGET_SIMD"
3138   "sshl\t%0.2s, %1.2s, %2.2s"
3139   [(set_attr "simd" "yes")
3140    (set_attr "type" "neon_shift_reg")]
3143 (define_insn "*aarch64_sisd_neg_qi"
3144   [(set (match_operand:QI 0 "register_operand" "=w")
3145         (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3146                    UNSPEC_SISD_NEG))]
3147   "TARGET_SIMD"
3148   "neg\t%d0, %d1"
3149   [(set_attr "simd" "yes")
3150    (set_attr "type" "neon_neg")]
3153 ;; Rotate right
3154 (define_insn "*ror<mode>3_insn"
3155   [(set (match_operand:GPI 0 "register_operand" "=r")
3156         (rotatert:GPI
3157           (match_operand:GPI 1 "register_operand" "r")
3158           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3159   ""
3160   "ror\\t%<w>0, %<w>1, %<w>2"
3161   [(set_attr "type" "shift_reg")]
3164 ;; zero_extend version of above
3165 (define_insn "*<optab>si3_insn_uxtw"
3166   [(set (match_operand:DI 0 "register_operand" "=r")
3167         (zero_extend:DI (SHIFT:SI
3168          (match_operand:SI 1 "register_operand" "r")
3169          (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3170   ""
3171   "<shift>\\t%w0, %w1, %w2"
3172   [(set_attr "type" "shift_reg")]
3175 (define_insn "*ashl<mode>3_insn"
3176   [(set (match_operand:SHORT 0 "register_operand" "=r")
3177         (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3178                       (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
3179   ""
3180   "lsl\\t%<w>0, %<w>1, %<w>2"
3181   [(set_attr "type" "shift_reg")]
3184 (define_insn "*<optab><mode>3_insn"
3185   [(set (match_operand:SHORT 0 "register_operand" "=r")
3186         (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3187                       (match_operand 2 "const_int_operand" "n")))]
3188   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3190   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3191   return "<bfshift>\t%w0, %w1, %2, %3";
3193   [(set_attr "type" "bfm")]
3196 (define_insn "*extr<mode>5_insn"
3197   [(set (match_operand:GPI 0 "register_operand" "=r")
3198         (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3199                              (match_operand 3 "const_int_operand" "n"))
3200                  (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3201                                (match_operand 4 "const_int_operand" "n"))))]
3202   "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3203    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3204   "extr\\t%<w>0, %<w>1, %<w>2, %4"
3205   [(set_attr "type" "shift_imm")]
3208 ;; zero_extend version of the above
3209 (define_insn "*extrsi5_insn_uxtw"
3210   [(set (match_operand:DI 0 "register_operand" "=r")
3211         (zero_extend:DI
3212          (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3213                             (match_operand 3 "const_int_operand" "n"))
3214                  (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3215                               (match_operand 4 "const_int_operand" "n")))))]
3216   "UINTVAL (operands[3]) < 32 &&
3217    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3218   "extr\\t%w0, %w1, %w2, %4"
3219   [(set_attr "type" "shift_imm")]
3222 (define_insn "*ror<mode>3_insn"
3223   [(set (match_operand:GPI 0 "register_operand" "=r")
3224         (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3225                     (match_operand 2 "const_int_operand" "n")))]
3226   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3228   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3229   return "ror\\t%<w>0, %<w>1, %3";
3231   [(set_attr "type" "shift_imm")]
3234 ;; zero_extend version of the above
3235 (define_insn "*rorsi3_insn_uxtw"
3236   [(set (match_operand:DI 0 "register_operand" "=r")
3237         (zero_extend:DI
3238          (rotate:SI (match_operand:SI 1 "register_operand" "r")
3239                     (match_operand 2 "const_int_operand" "n"))))]
3240   "UINTVAL (operands[2]) < 32"
3242   operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3243   return "ror\\t%w0, %w1, %3";
3245   [(set_attr "type" "shift_imm")]
3248 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3249   [(set (match_operand:GPI 0 "register_operand" "=r")
3250         (ANY_EXTEND:GPI
3251          (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3252                        (match_operand 2 "const_int_operand" "n"))))]
3253   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3255   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3256   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3258   [(set_attr "type" "bfm")]
3261 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3262   [(set (match_operand:GPI 0 "register_operand" "=r")
3263         (zero_extend:GPI
3264          (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3265                          (match_operand 2 "const_int_operand" "n"))))]
3266   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3268   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3269   return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3271   [(set_attr "type" "bfm")]
3274 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3275   [(set (match_operand:GPI 0 "register_operand" "=r")
3276         (sign_extend:GPI
3277          (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3278                          (match_operand 2 "const_int_operand" "n"))))]
3279   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3281   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3282   return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3284   [(set_attr "type" "bfm")]
3287 ;; -------------------------------------------------------------------
3288 ;; Bitfields
3289 ;; -------------------------------------------------------------------
3291 (define_expand "<optab>"
3292   [(set (match_operand:DI 0 "register_operand" "=r")
3293         (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3294                         (match_operand 2 "const_int_operand" "n")
3295                         (match_operand 3 "const_int_operand" "n")))]
3296   ""
3297   ""
3300 (define_insn "*<optab><mode>"
3301   [(set (match_operand:GPI 0 "register_operand" "=r")
3302         (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3303                          (match_operand 2 "const_int_operand" "n")
3304                          (match_operand 3 "const_int_operand" "n")))]
3305   ""
3306   "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3307   [(set_attr "type" "bfm")]
3310 ;; Bitfield Insert (insv)
3311 (define_expand "insv<mode>"
3312   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3313                           (match_operand 1 "const_int_operand")
3314                           (match_operand 2 "const_int_operand"))
3315         (match_operand:GPI 3 "general_operand"))]
3316   ""
3318   unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3319   unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3320   rtx value = operands[3];
3322   if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3323     FAIL;
3325   if (CONST_INT_P (value))
3326     {
3327       unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3329       /* Prefer AND/OR for inserting all zeros or all ones.  */
3330       if ((UINTVAL (value) & mask) == 0
3331            || (UINTVAL (value) & mask) == mask)
3332         FAIL;
3334       /* 16-bit aligned 16-bit wide insert is handled by insv_imm.  */
3335       if (width == 16 && (pos % 16) == 0)
3336         DONE;
3337     }
3338   operands[3] = force_reg (<MODE>mode, value);
3341 (define_insn "*insv_reg<mode>"
3342   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3343                           (match_operand 1 "const_int_operand" "n")
3344                           (match_operand 2 "const_int_operand" "n"))
3345         (match_operand:GPI 3 "register_operand" "r"))]
3346   "!(UINTVAL (operands[1]) == 0
3347      || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3348          > GET_MODE_BITSIZE (<MODE>mode)))"
3349   "bfi\\t%<w>0, %<w>3, %2, %1"
3350   [(set_attr "type" "bfm")]
3353 (define_insn "*extr_insv_lower_reg<mode>"
3354   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3355                           (match_operand 1 "const_int_operand" "n")
3356                           (const_int 0))
3357         (zero_extract:GPI (match_operand:GPI 2 "register_operand" "+r")
3358                           (match_dup 1)
3359                           (match_operand 3 "const_int_operand" "n")))]
3360   "!(UINTVAL (operands[1]) == 0
3361      || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3362          > GET_MODE_BITSIZE (<MODE>mode)))"
3363   "bfxil\\t%<w>0, %<w>2, %3, %1"
3364   [(set_attr "type" "bfm")]
3367 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3368   [(set (match_operand:GPI 0 "register_operand" "=r")
3369         (ashift:GPI (ANY_EXTEND:GPI
3370                      (match_operand:ALLX 1 "register_operand" "r"))
3371                     (match_operand 2 "const_int_operand" "n")))]
3372   "UINTVAL (operands[2]) < <GPI:sizen>"
3374   operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3375               ? GEN_INT (<ALLX:sizen>)
3376               : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3377   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3379   [(set_attr "type" "bfm")]
3382 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3384 (define_insn "*andim_ashift<mode>_bfiz"
3385   [(set (match_operand:GPI 0 "register_operand" "=r")
3386         (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3387                              (match_operand 2 "const_int_operand" "n"))
3388                  (match_operand 3 "const_int_operand" "n")))]
3389   "exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3390    && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3391   "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3392   [(set_attr "type" "bfm")]
3395 (define_insn "bswap<mode>2"
3396   [(set (match_operand:GPI 0 "register_operand" "=r")
3397         (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3398   ""
3399   "rev\\t%<w>0, %<w>1"
3400   [(set_attr "type" "rev")]
3403 (define_insn "bswaphi2"
3404   [(set (match_operand:HI 0 "register_operand" "=r")
3405         (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3406   ""
3407   "rev16\\t%w0, %w1"
3408   [(set_attr "type" "rev")]
3411 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
3412 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
3413 ;; each valid permutation.
3415 (define_insn "rev16<mode>2"
3416   [(set (match_operand:GPI 0 "register_operand" "=r")
3417         (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3418                                       (const_int 8))
3419                           (match_operand:GPI 3 "const_int_operand" "n"))
3420                  (and:GPI (lshiftrt:GPI (match_dup 1)
3421                                         (const_int 8))
3422                           (match_operand:GPI 2 "const_int_operand" "n"))))]
3423   "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3424    && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3425   "rev16\\t%<w>0, %<w>1"
3426   [(set_attr "type" "rev")]
3429 (define_insn "rev16<mode>2_alt"
3430   [(set (match_operand:GPI 0 "register_operand" "=r")
3431         (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r")
3432                                         (const_int 8))
3433                           (match_operand:GPI 2 "const_int_operand" "n"))
3434                  (and:GPI (ashift:GPI (match_dup 1)
3435                                       (const_int 8))
3436                           (match_operand:GPI 3 "const_int_operand" "n"))))]
3437   "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3438    && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3439   "rev16\\t%<w>0, %<w>1"
3440   [(set_attr "type" "rev")]
3443 ;; zero_extend version of above
3444 (define_insn "*bswapsi2_uxtw"
3445   [(set (match_operand:DI 0 "register_operand" "=r")
3446         (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3447   ""
3448   "rev\\t%w0, %w1"
3449   [(set_attr "type" "rev")]
3452 ;; -------------------------------------------------------------------
3453 ;; Floating-point intrinsics
3454 ;; -------------------------------------------------------------------
3456 ;; frint floating-point round to integral standard patterns.
3457 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round, frintn.
3459 (define_insn "<frint_pattern><mode>2"
3460   [(set (match_operand:GPF 0 "register_operand" "=w")
3461         (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3462          FRINT))]
3463   "TARGET_FLOAT"
3464   "frint<frint_suffix>\\t%<s>0, %<s>1"
3465   [(set_attr "type" "f_rint<s>")]
3468 ;; frcvt floating-point round to integer and convert standard patterns.
3469 ;; Expands to lbtrunc, lceil, lfloor, lround.
3470 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3471   [(set (match_operand:GPI 0 "register_operand" "=r")
3472         (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3473                       FCVT)))]
3474   "TARGET_FLOAT"
3475   "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3476   [(set_attr "type" "f_cvtf2i")]
3479 ;; fma - no throw
3481 (define_insn "fma<mode>4"
3482   [(set (match_operand:GPF 0 "register_operand" "=w")
3483         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3484                  (match_operand:GPF 2 "register_operand" "w")
3485                  (match_operand:GPF 3 "register_operand" "w")))]
3486   "TARGET_FLOAT"
3487   "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3488   [(set_attr "type" "fmac<s>")]
3491 (define_insn "fnma<mode>4"
3492   [(set (match_operand:GPF 0 "register_operand" "=w")
3493         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3494                  (match_operand:GPF 2 "register_operand" "w")
3495                  (match_operand:GPF 3 "register_operand" "w")))]
3496   "TARGET_FLOAT"
3497   "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3498   [(set_attr "type" "fmac<s>")]
3501 (define_insn "fms<mode>4"
3502   [(set (match_operand:GPF 0 "register_operand" "=w")
3503         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3504                  (match_operand:GPF 2 "register_operand" "w")
3505                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3506   "TARGET_FLOAT"
3507   "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3508   [(set_attr "type" "fmac<s>")]
3511 (define_insn "fnms<mode>4"
3512   [(set (match_operand:GPF 0 "register_operand" "=w")
3513         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3514                  (match_operand:GPF 2 "register_operand" "w")
3515                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3516   "TARGET_FLOAT"
3517   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3518   [(set_attr "type" "fmac<s>")]
3521 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3522 (define_insn "*fnmadd<mode>4"
3523   [(set (match_operand:GPF 0 "register_operand" "=w")
3524         (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3525                           (match_operand:GPF 2 "register_operand" "w")
3526                           (match_operand:GPF 3 "register_operand" "w"))))]
3527   "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3528   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3529   [(set_attr "type" "fmac<s>")]
3532 ;; -------------------------------------------------------------------
3533 ;; Floating-point conversions
3534 ;; -------------------------------------------------------------------
3536 (define_insn "extendsfdf2"
3537   [(set (match_operand:DF 0 "register_operand" "=w")
3538         (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3539   "TARGET_FLOAT"
3540   "fcvt\\t%d0, %s1"
3541   [(set_attr "type" "f_cvt")]
3544 (define_insn "truncdfsf2"
3545   [(set (match_operand:SF 0 "register_operand" "=w")
3546         (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3547   "TARGET_FLOAT"
3548   "fcvt\\t%s0, %d1"
3549   [(set_attr "type" "f_cvt")]
3552 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3553   [(set (match_operand:GPI 0 "register_operand" "=r")
3554         (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3555   "TARGET_FLOAT"
3556   "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3557   [(set_attr "type" "f_cvtf2i")]
3560 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3561   [(set (match_operand:GPI 0 "register_operand" "=r")
3562         (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3563   "TARGET_FLOAT"
3564   "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3565   [(set_attr "type" "f_cvtf2i")]
3568 (define_insn "<optab><fcvt_target><GPF:mode>2"
3569   [(set (match_operand:GPF 0 "register_operand" "=w,w")
3570         (FLOATUORS:GPF (match_operand:<FCVT_TARGET> 1 "register_operand" "w,r")))]
3571   ""
3572   "@
3573    <su_optab>cvtf\t%<GPF:s>0, %<s>1
3574    <su_optab>cvtf\t%<GPF:s>0, %<w1>1"
3575   [(set_attr "simd" "yes,no")
3576    (set_attr "fp" "no,yes")
3577    (set_attr "type" "neon_int_to_fp_<Vetype>,f_cvti2f")]
3580 (define_insn "<optab><fcvt_iesize><GPF:mode>2"
3581   [(set (match_operand:GPF 0 "register_operand" "=w")
3582         (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand" "r")))]
3583   "TARGET_FLOAT"
3584   "<su_optab>cvtf\t%<GPF:s>0, %<w2>1"
3585   [(set_attr "type" "f_cvti2f")]
3588 ;; -------------------------------------------------------------------
3589 ;; Floating-point arithmetic
3590 ;; -------------------------------------------------------------------
3592 (define_insn "add<mode>3"
3593   [(set (match_operand:GPF 0 "register_operand" "=w")
3594         (plus:GPF
3595          (match_operand:GPF 1 "register_operand" "w")
3596          (match_operand:GPF 2 "register_operand" "w")))]
3597   "TARGET_FLOAT"
3598   "fadd\\t%<s>0, %<s>1, %<s>2"
3599   [(set_attr "type" "fadd<s>")]
3602 (define_insn "sub<mode>3"
3603   [(set (match_operand:GPF 0 "register_operand" "=w")
3604         (minus:GPF
3605          (match_operand:GPF 1 "register_operand" "w")
3606          (match_operand:GPF 2 "register_operand" "w")))]
3607   "TARGET_FLOAT"
3608   "fsub\\t%<s>0, %<s>1, %<s>2"
3609   [(set_attr "type" "fadd<s>")]
3612 (define_insn "mul<mode>3"
3613   [(set (match_operand:GPF 0 "register_operand" "=w")
3614         (mult:GPF
3615          (match_operand:GPF 1 "register_operand" "w")
3616          (match_operand:GPF 2 "register_operand" "w")))]
3617   "TARGET_FLOAT"
3618   "fmul\\t%<s>0, %<s>1, %<s>2"
3619   [(set_attr "type" "fmul<s>")]
3622 (define_insn "*fnmul<mode>3"
3623   [(set (match_operand:GPF 0 "register_operand" "=w")
3624         (mult:GPF
3625                  (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3626                  (match_operand:GPF 2 "register_operand" "w")))]
3627   "TARGET_FLOAT"
3628   "fnmul\\t%<s>0, %<s>1, %<s>2"
3629   [(set_attr "type" "fmul<s>")]
3632 (define_insn "div<mode>3"
3633   [(set (match_operand:GPF 0 "register_operand" "=w")
3634         (div:GPF
3635          (match_operand:GPF 1 "register_operand" "w")
3636          (match_operand:GPF 2 "register_operand" "w")))]
3637   "TARGET_FLOAT"
3638   "fdiv\\t%<s>0, %<s>1, %<s>2"
3639   [(set_attr "type" "fdiv<s>")]
3642 (define_insn "neg<mode>2"
3643   [(set (match_operand:GPF 0 "register_operand" "=w")
3644         (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
3645   "TARGET_FLOAT"
3646   "fneg\\t%<s>0, %<s>1"
3647   [(set_attr "type" "ffarith<s>")]
3650 (define_insn "sqrt<mode>2"
3651   [(set (match_operand:GPF 0 "register_operand" "=w")
3652         (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
3653   "TARGET_FLOAT"
3654   "fsqrt\\t%<s>0, %<s>1"
3655   [(set_attr "type" "fsqrt<s>")]
3658 (define_insn "abs<mode>2"
3659   [(set (match_operand:GPF 0 "register_operand" "=w")
3660         (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
3661   "TARGET_FLOAT"
3662   "fabs\\t%<s>0, %<s>1"
3663   [(set_attr "type" "ffarith<s>")]
3666 ;; Given that smax/smin do not specify the result when either input is NaN,
3667 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
3668 ;; for smin.
3670 (define_insn "smax<mode>3"
3671   [(set (match_operand:GPF 0 "register_operand" "=w")
3672         (smax:GPF (match_operand:GPF 1 "register_operand" "w")
3673                   (match_operand:GPF 2 "register_operand" "w")))]
3674   "TARGET_FLOAT"
3675   "fmaxnm\\t%<s>0, %<s>1, %<s>2"
3676   [(set_attr "type" "f_minmax<s>")]
3679 (define_insn "smin<mode>3"
3680   [(set (match_operand:GPF 0 "register_operand" "=w")
3681         (smin:GPF (match_operand:GPF 1 "register_operand" "w")
3682                   (match_operand:GPF 2 "register_operand" "w")))]
3683   "TARGET_FLOAT"
3684   "fminnm\\t%<s>0, %<s>1, %<s>2"
3685   [(set_attr "type" "f_minmax<s>")]
3688 ;; -------------------------------------------------------------------
3689 ;; Reload support
3690 ;; -------------------------------------------------------------------
3692 (define_expand "aarch64_reload_mov<mode>"
3693   [(set (match_operand:TX 0 "register_operand" "=w")
3694         (match_operand:TX 1 "register_operand" "w"))
3695    (clobber (match_operand:DI 2 "register_operand" "=&r"))
3696   ]
3697   ""
3698   {
3699     rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
3700     rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
3701     gen_aarch64_movtilow_tilow (op0, op1);
3702     gen_aarch64_movdi_tihigh (operands[2], op1);
3703     gen_aarch64_movtihigh_di (op0, operands[2]);
3704     DONE;
3705   }
3708 ;; The following secondary reload helpers patterns are invoked
3709 ;; after or during reload as we don't want these patterns to start
3710 ;; kicking in during the combiner.
3712 (define_insn "aarch64_movdi_<mode>low"
3713   [(set (match_operand:DI 0 "register_operand" "=r")
3714         (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
3715   "reload_completed || reload_in_progress"
3716   "fmov\\t%x0, %d1"
3717   [(set_attr "type" "f_mrc")
3718    (set_attr "length" "4")
3719   ])
3721 (define_insn "aarch64_movdi_<mode>high"
3722   [(set (match_operand:DI 0 "register_operand" "=r")
3723         (truncate:DI
3724           (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
3725                        (const_int 64))))]
3726   "reload_completed || reload_in_progress"
3727   "fmov\\t%x0, %1.d[1]"
3728   [(set_attr "type" "f_mrc")
3729    (set_attr "length" "4")
3730   ])
3732 (define_insn "aarch64_mov<mode>high_di"
3733   [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
3734                          (const_int 64) (const_int 64))
3735         (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
3736   "reload_completed || reload_in_progress"
3737   "fmov\\t%0.d[1], %x1"
3738   [(set_attr "type" "f_mcr")
3739    (set_attr "length" "4")
3740   ])
3742 (define_insn "aarch64_mov<mode>low_di"
3743   [(set (match_operand:TX 0 "register_operand" "=w")
3744         (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
3745   "reload_completed || reload_in_progress"
3746   "fmov\\t%d0, %x1"
3747   [(set_attr "type" "f_mcr")
3748    (set_attr "length" "4")
3749   ])
3751 (define_insn "aarch64_movtilow_tilow"
3752   [(set (match_operand:TI 0 "register_operand" "=w")
3753         (zero_extend:TI 
3754           (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
3755   "reload_completed || reload_in_progress"
3756   "fmov\\t%d0, %d1"
3757   [(set_attr "type" "fmov")
3758    (set_attr "length" "4")
3759   ])
3761 ;; There is a deliberate reason why the parameters of high and lo_sum's
3762 ;; don't have modes for ADRP and ADD instructions.  This is to allow high
3763 ;; and lo_sum's to be used with the labels defining the jump tables in
3764 ;; rodata section.
3766 (define_expand "add_losym"
3767   [(set (match_operand 0 "register_operand" "=r")
3768         (lo_sum (match_operand 1 "register_operand" "r")
3769                 (match_operand 2 "aarch64_valid_symref" "S")))]
3770   ""
3772   enum machine_mode mode = GET_MODE (operands[0]);
3774   emit_insn ((mode == DImode
3775               ? gen_add_losym_di
3776               : gen_add_losym_si) (operands[0],
3777                                    operands[1],
3778                                    operands[2]));
3779   DONE;
3782 (define_insn "add_losym_<mode>"
3783   [(set (match_operand:P 0 "register_operand" "=r")
3784         (lo_sum:P (match_operand:P 1 "register_operand" "r")
3785                   (match_operand 2 "aarch64_valid_symref" "S")))]
3786   ""
3787   "add\\t%<w>0, %<w>1, :lo12:%a2"
3788   [(set_attr "type" "alu_reg")]
3791 (define_insn "ldr_got_small_<mode>"
3792   [(set (match_operand:PTR 0 "register_operand" "=r")
3793         (unspec:PTR [(mem:PTR (lo_sum:PTR
3794                               (match_operand:PTR 1 "register_operand" "r")
3795                               (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
3796                     UNSPEC_GOTSMALLPIC))]
3797   ""
3798   "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
3799   [(set_attr "type" "load1")]
3802 (define_insn "ldr_got_small_sidi"
3803   [(set (match_operand:DI 0 "register_operand" "=r")
3804         (zero_extend:DI
3805          (unspec:SI [(mem:SI (lo_sum:DI
3806                              (match_operand:DI 1 "register_operand" "r")
3807                              (match_operand:DI 2 "aarch64_valid_symref" "S")))]
3808                     UNSPEC_GOTSMALLPIC)))]
3809   "TARGET_ILP32"
3810   "ldr\\t%w0, [%1, #:got_lo12:%a2]"
3811   [(set_attr "type" "load1")]
3814 (define_insn "ldr_got_tiny"
3815   [(set (match_operand:DI 0 "register_operand" "=r")
3816         (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
3817                    UNSPEC_GOTTINYPIC))]
3818   ""
3819   "ldr\\t%0, %L1"
3820   [(set_attr "type" "load1")]
3823 (define_insn "aarch64_load_tp_hard"
3824   [(set (match_operand:DI 0 "register_operand" "=r")
3825         (unspec:DI [(const_int 0)] UNSPEC_TLS))]
3826   ""
3827   "mrs\\t%0, tpidr_el0"
3828   [(set_attr "type" "mrs")]
3831 ;; The TLS ABI specifically requires that the compiler does not schedule
3832 ;; instructions in the TLS stubs, in order to enable linker relaxation.
3833 ;; Therefore we treat the stubs as an atomic sequence.
3834 (define_expand "tlsgd_small"
3835  [(parallel [(set (match_operand 0 "register_operand" "")
3836                   (call (mem:DI (match_dup 2)) (const_int 1)))
3837              (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
3838              (clobber (reg:DI LR_REGNUM))])]
3839  ""
3841   operands[2] = aarch64_tls_get_addr ();
3844 (define_insn "*tlsgd_small"
3845   [(set (match_operand 0 "register_operand" "")
3846         (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
3847    (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
3848    (clobber (reg:DI LR_REGNUM))
3849   ]
3850   ""
3851   "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
3852   [(set_attr "type" "call")
3853    (set_attr "length" "16")])
3855 (define_insn "tlsie_small_<mode>"
3856   [(set (match_operand:PTR 0 "register_operand" "=r")
3857         (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
3858                    UNSPEC_GOTSMALLTLS))]
3859   ""
3860   "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
3861   [(set_attr "type" "load1")
3862    (set_attr "length" "8")]
3865 (define_insn "tlsie_small_sidi"
3866   [(set (match_operand:DI 0 "register_operand" "=r")
3867         (zero_extend:DI
3868           (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")]
3869                       UNSPEC_GOTSMALLTLS)))]
3870   ""
3871   "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
3872   [(set_attr "type" "load1")
3873    (set_attr "length" "8")]
3876 (define_expand "tlsle_small"
3877   [(set (match_operand 0 "register_operand" "=r")
3878         (unspec [(match_operand 1 "register_operand" "r")
3879                    (match_operand 2 "aarch64_tls_le_symref" "S")]
3880                    UNSPEC_GOTSMALLTLS))]
3881   ""
3883   enum machine_mode mode = GET_MODE (operands[0]);
3884   emit_insn ((mode == DImode
3885               ? gen_tlsle_small_di
3886               : gen_tlsle_small_si) (operands[0],
3887                                      operands[1],
3888                                      operands[2]));
3889   DONE;
3892 (define_insn "tlsle_small_<mode>"
3893   [(set (match_operand:P 0 "register_operand" "=r")
3894         (unspec:P [(match_operand:P 1 "register_operand" "r")
3895                    (match_operand 2 "aarch64_tls_le_symref" "S")]
3896                    UNSPEC_GOTSMALLTLS))]
3897   ""
3898   "add\\t%<w>0, %<w>1, #%G2\;add\\t%<w>0, %<w>0, #%L2"
3899   [(set_attr "type" "alu_reg")
3900    (set_attr "length" "8")]
3903 (define_insn "tlsdesc_small_<mode>"
3904   [(set (reg:PTR R0_REGNUM)
3905         (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
3906                    UNSPEC_TLSDESC))
3907    (clobber (reg:DI LR_REGNUM))
3908    (clobber (reg:CC CC_REGNUM))
3909    (clobber (match_scratch:DI 1 "=r"))]
3910   "TARGET_TLS_DESC"
3911   "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
3912   [(set_attr "type" "call")
3913    (set_attr "length" "16")])
3915 (define_insn "stack_tie"
3916   [(set (mem:BLK (scratch))
3917         (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
3918                      (match_operand:DI 1 "register_operand" "rk")]
3919                     UNSPEC_PRLG_STK))]
3920   ""
3921   ""
3922   [(set_attr "length" "0")]
3925 ;; Named pattern for expanding thread pointer reference.
3926 (define_expand "get_thread_pointerdi"
3927   [(match_operand:DI 0 "register_operand" "=r")]
3928   ""
3930   rtx tmp = aarch64_load_tp (operands[0]);
3931   if (tmp != operands[0])
3932     emit_move_insn (operands[0], tmp);
3933   DONE;
3936 ;; Named patterns for stack smashing protection.
3937 (define_expand "stack_protect_set"
3938   [(match_operand 0 "memory_operand")
3939    (match_operand 1 "memory_operand")]
3940   ""
3942   enum machine_mode mode = GET_MODE (operands[0]);
3944   emit_insn ((mode == DImode
3945               ? gen_stack_protect_set_di
3946               : gen_stack_protect_set_si) (operands[0], operands[1]));
3947   DONE;
3950 (define_insn "stack_protect_set_<mode>"
3951   [(set (match_operand:PTR 0 "memory_operand" "=m")
3952         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
3953          UNSPEC_SP_SET))
3954    (set (match_scratch:PTR 2 "=&r") (const_int 0))]
3955   ""
3956   "ldr\\t%<w>2, %1\;str\\t%<w>2, %0\;mov\t%<w>2,0"
3957   [(set_attr "length" "12")
3958    (set_attr "type" "multiple")])
3960 (define_expand "stack_protect_test"
3961   [(match_operand 0 "memory_operand")
3962    (match_operand 1 "memory_operand")
3963    (match_operand 2)]
3964   ""
3966   rtx result;
3967   enum machine_mode mode = GET_MODE (operands[0]);
3969   result = gen_reg_rtx(mode);
3971   emit_insn ((mode == DImode
3972               ? gen_stack_protect_test_di
3973               : gen_stack_protect_test_si) (result,
3974                                             operands[0],
3975                                             operands[1]));
3977   if (mode == DImode)
3978     emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
3979                                     result, const0_rtx, operands[2]));
3980   else
3981     emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
3982                                     result, const0_rtx, operands[2]));
3983   DONE;
3986 (define_insn "stack_protect_test_<mode>"
3987   [(set (match_operand:PTR 0 "register_operand")
3988         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
3989                      (match_operand:PTR 2 "memory_operand" "m")]
3990          UNSPEC_SP_TEST))
3991    (clobber (match_scratch:PTR 3 "=&r"))]
3992   ""
3993   "ldr\t%<w>3, %x1\;ldr\t%<w>0, %x2\;eor\t%<w>0, %<w>3, %<w>0"
3994   [(set_attr "length" "12")
3995    (set_attr "type" "multiple")])
3997 ;; Write Floating-point Control Register.
3998 (define_insn "set_fpcr"
3999   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
4000   ""
4001   "msr\\tfpcr, %0"
4002   [(set_attr "type" "mrs")])
4004 ;; Read Floating-point Control Register.
4005 (define_insn "get_fpcr"
4006   [(set (match_operand:SI 0 "register_operand" "=r")
4007         (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
4008   ""
4009   "mrs\\t%0, fpcr"
4010   [(set_attr "type" "mrs")])
4012 ;; Write Floating-point Status Register.
4013 (define_insn "set_fpsr"
4014   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
4015   ""
4016   "msr\\tfpsr, %0"
4017   [(set_attr "type" "mrs")])
4019 ;; Read Floating-point Status Register.
4020 (define_insn "get_fpsr"
4021   [(set (match_operand:SI 0 "register_operand" "=r")
4022         (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
4023   ""
4024   "mrs\\t%0, fpsr"
4025   [(set_attr "type" "mrs")])
4028 ;; AdvSIMD Stuff
4029 (include "aarch64-simd.md")
4031 ;; Atomic Operations
4032 (include "atomics.md")