2014-08-26 Yvan Roux <yvan.roux@linaro.org>
[official-gcc.git] / gcc-4_9-branch / gcc / config / aarch64 / aarch64.md
blobbe1206dccf7326421cd0297f6324b2ba557d20bf
1 ;; Machine description for AArch64 architecture.
2 ;; Copyright (C) 2009-2014 Free Software Foundation, Inc.
3 ;; Contributed by ARM Ltd.
4 ;;
5 ;; This file is part of GCC.
6 ;;
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
12 ;; GCC is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 ;; General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;; Register numbers
22 (define_constants
23   [
24     (R0_REGNUM          0)
25     (R1_REGNUM          1)
26     (R2_REGNUM          2)
27     (R3_REGNUM          3)
28     (R4_REGNUM          4)
29     (R5_REGNUM          5)
30     (R6_REGNUM          6)
31     (R7_REGNUM          7)
32     (R8_REGNUM          8)
33     (R9_REGNUM          9)
34     (R10_REGNUM         10)
35     (R11_REGNUM         11)
36     (R12_REGNUM         12)
37     (R13_REGNUM         13)
38     (R14_REGNUM         14)
39     (R15_REGNUM         15)
40     (R16_REGNUM         16)
41     (IP0_REGNUM         16)
42     (R17_REGNUM         17)
43     (IP1_REGNUM         17)
44     (R18_REGNUM         18)
45     (R19_REGNUM         19)
46     (R20_REGNUM         20)
47     (R21_REGNUM         21)
48     (R22_REGNUM         22)
49     (R23_REGNUM         23)
50     (R24_REGNUM         24)
51     (R25_REGNUM         25)
52     (R26_REGNUM         26)
53     (R27_REGNUM         27)
54     (R28_REGNUM         28)
55     (R29_REGNUM         29)
56     (R30_REGNUM         30)
57     (LR_REGNUM          30)
58     (SP_REGNUM          31)
59     (V0_REGNUM          32)
60     (V15_REGNUM         47)
61     (V31_REGNUM         63)
62     (SFP_REGNUM         64)
63     (AP_REGNUM          65)
64     (CC_REGNUM          66)
65   ]
68 (define_c_enum "unspec" [
69     UNSPEC_CASESI
70     UNSPEC_CRC32B
71     UNSPEC_CRC32CB
72     UNSPEC_CRC32CH
73     UNSPEC_CRC32CW
74     UNSPEC_CRC32CX
75     UNSPEC_CRC32H
76     UNSPEC_CRC32W
77     UNSPEC_CRC32X
78     UNSPEC_FRECPE
79     UNSPEC_FRECPS
80     UNSPEC_FRECPX
81     UNSPEC_FRINTA
82     UNSPEC_FRINTI
83     UNSPEC_FRINTM
84     UNSPEC_FRINTN
85     UNSPEC_FRINTP
86     UNSPEC_FRINTX
87     UNSPEC_FRINTZ
88     UNSPEC_GOTSMALLPIC
89     UNSPEC_GOTSMALLTLS
90     UNSPEC_GOTTINYPIC
91     UNSPEC_LD1
92     UNSPEC_LD2
93     UNSPEC_LD3
94     UNSPEC_LD4
95     UNSPEC_MB
96     UNSPEC_NOP
97     UNSPEC_PRLG_STK
98     UNSPEC_RBIT
99     UNSPEC_SISD_NEG
100     UNSPEC_SISD_SSHL
101     UNSPEC_SISD_USHL
102     UNSPEC_SSHL_2S
103     UNSPEC_SSHR64
104     UNSPEC_ST1
105     UNSPEC_ST2
106     UNSPEC_ST3
107     UNSPEC_ST4
108     UNSPEC_ST2_LANE
109     UNSPEC_ST3_LANE
110     UNSPEC_ST4_LANE
111     UNSPEC_TLS
112     UNSPEC_TLSDESC
113     UNSPEC_USHL_2S
114     UNSPEC_USHR64
115     UNSPEC_VSTRUCTDUMMY
116     UNSPEC_SP_SET
117     UNSPEC_SP_TEST
120 (define_c_enum "unspecv" [
121     UNSPECV_EH_RETURN           ; Represent EH_RETURN
122     UNSPECV_GET_FPCR            ; Represent fetch of FPCR content.
123     UNSPECV_SET_FPCR            ; Represent assign of FPCR content.
124     UNSPECV_GET_FPSR            ; Represent fetch of FPSR content.
125     UNSPECV_SET_FPSR            ; Represent assign of FPSR content.
126   ]
129 ;; If further include files are added the defintion of MD_INCLUDES
130 ;; must be updated.
132 (include "constraints.md")
133 (include "predicates.md")
134 (include "iterators.md")
136 ;; -------------------------------------------------------------------
137 ;; Instruction types and attributes
138 ;; -------------------------------------------------------------------
140 ; The "type" attribute is is included here from AArch32 backend to be able
141 ; to share pipeline descriptions.
142 (include "../arm/types.md")
144 ;; Attribute that specifies whether or not the instruction touches fp
145 ;; registers.
146 (define_attr "fp" "no,yes" (const_string "no"))
148 ;; Attribute that specifies whether or not the instruction touches simd
149 ;; registers.
150 (define_attr "simd" "no,yes" (const_string "no"))
152 (define_attr "length" ""
153   (const_int 4))
155 ;; Attribute that controls whether an alternative is enabled or not.
156 ;; Currently it is only used to disable alternatives which touch fp or simd
157 ;; registers when -mgeneral-regs-only is specified.
158 (define_attr "enabled" "no,yes"
159   (cond [(ior
160         (and (eq_attr "fp" "yes")
161              (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
162         (and (eq_attr "simd" "yes")
163              (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
164              (const_string "no")
165         ] (const_string "yes")))
167 ;; -------------------------------------------------------------------
168 ;; Pipeline descriptions and scheduling
169 ;; -------------------------------------------------------------------
171 ;; Processor types.
172 (include "aarch64-tune.md")
174 ;; True if the generic scheduling description should be used.
176 (define_attr "generic_sched" "yes,no"
177   (const (if_then_else
178           (eq_attr "tune" "cortexa53,cortexa15")
179           (const_string "no")
180           (const_string "yes"))))
182 ;; Scheduling
183 (include "../arm/cortex-a53.md")
184 (include "../arm/cortex-a15.md")
186 ;; -------------------------------------------------------------------
187 ;; Jumps and other miscellaneous insns
188 ;; -------------------------------------------------------------------
190 (define_insn "indirect_jump"
191   [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
192   ""
193   "br\\t%0"
194   [(set_attr "type" "branch")]
197 (define_insn "jump"
198   [(set (pc) (label_ref (match_operand 0 "" "")))]
199   ""
200   "b\\t%l0"
201   [(set_attr "type" "branch")]
204 (define_expand "cbranch<mode>4"
205   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
206                             [(match_operand:GPI 1 "register_operand" "")
207                              (match_operand:GPI 2 "aarch64_plus_operand" "")])
208                            (label_ref (match_operand 3 "" ""))
209                            (pc)))]
210   ""
211   "
212   operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
213                                          operands[2]);
214   operands[2] = const0_rtx;
215   "
218 (define_expand "cbranch<mode>4"
219   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
220                             [(match_operand:GPF 1 "register_operand" "")
221                              (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
222                            (label_ref (match_operand 3 "" ""))
223                            (pc)))]
224   ""
225   "
226   operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
227                                          operands[2]);
228   operands[2] = const0_rtx;
229   "
232 (define_insn "*condjump"
233   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
234                             [(match_operand 1 "cc_register" "") (const_int 0)])
235                            (label_ref (match_operand 2 "" ""))
236                            (pc)))]
237   ""
238   "b%m0\\t%l2"
239   [(set_attr "type" "branch")]
242 (define_expand "casesi"
243   [(match_operand:SI 0 "register_operand" "")   ; Index
244    (match_operand:SI 1 "const_int_operand" "")  ; Lower bound
245    (match_operand:SI 2 "const_int_operand" "")  ; Total range
246    (match_operand:DI 3 "" "")                   ; Table label
247    (match_operand:DI 4 "" "")]                  ; Out of range label
248   ""
249   {
250     if (operands[1] != const0_rtx)
251       {
252         rtx reg = gen_reg_rtx (SImode);
254         /* Canonical RTL says that if you have:
256            (minus (X) (CONST))
258            then this should be emitted as:
260            (plus (X) (-CONST))
262            The use of trunc_int_for_mode ensures that the resulting
263            constant can be represented in SImode, this is important
264            for the corner case where operand[1] is INT_MIN.  */
266         operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
268         if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
269               (operands[1], SImode))
270           operands[1] = force_reg (SImode, operands[1]);
271         emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
272         operands[0] = reg;
273       }
275     if (!aarch64_plus_operand (operands[2], SImode))
276       operands[2] = force_reg (SImode, operands[2]);
277     emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
278                                                  const0_rtx),
279                                     operands[0], operands[2], operands[4]));
281     operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
282     emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
283                                          operands[3]));
284     DONE;
285   }
288 (define_insn "casesi_dispatch"
289   [(parallel
290     [(set (pc)
291           (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
292                            (match_operand:SI 1 "register_operand" "r")]
293                         UNSPEC_CASESI)))
294      (clobber (reg:CC CC_REGNUM))
295      (clobber (match_scratch:DI 3 "=r"))
296      (clobber (match_scratch:DI 4 "=r"))
297      (use (label_ref (match_operand 2 "" "")))])]
298   ""
299   "*
300   return aarch64_output_casesi (operands);
301   "
302   [(set_attr "length" "16")
303    (set_attr "type" "branch")]
306 (define_insn "nop"
307   [(unspec[(const_int 0)] UNSPEC_NOP)]
308   ""
309   "nop"
310   [(set_attr "type" "no_insn")]
313 (define_insn "trap"
314   [(trap_if (const_int 1) (const_int 8))]
315   ""
316   "brk #1000"
317   [(set_attr "type" "trap")])
319 (define_expand "prologue"
320   [(clobber (const_int 0))]
321   ""
322   "
323   aarch64_expand_prologue ();
324   DONE;
325   "
328 (define_expand "epilogue"
329   [(clobber (const_int 0))]
330   ""
331   "
332   aarch64_expand_epilogue (false);
333   DONE;
334   "
337 (define_expand "sibcall_epilogue"
338   [(clobber (const_int 0))]
339   ""
340   "
341   aarch64_expand_epilogue (true);
342   DONE;
343   "
346 (define_insn "*do_return"
347   [(return)]
348   ""
349   "ret"
350   [(set_attr "type" "branch")]
353 (define_insn "eh_return"
354   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
355     UNSPECV_EH_RETURN)]
356   ""
357   "#"
358   [(set_attr "type" "branch")]
362 (define_split
363   [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
364     UNSPECV_EH_RETURN)]
365   "reload_completed"
366   [(set (match_dup 1) (match_dup 0))]
367   {
368     operands[1] = aarch64_final_eh_return_addr ();
369   }
372 (define_insn "*cb<optab><mode>1"
373   [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
374                                 (const_int 0))
375                            (label_ref (match_operand 1 "" ""))
376                            (pc)))]
377   ""
378   "<cbz>\\t%<w>0, %l1"
379   [(set_attr "type" "branch")]
383 (define_insn "*tb<optab><mode>1"
384   [(set (pc) (if_then_else
385               (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
386                                     (const_int 1)
387                                     (match_operand 1 "const_int_operand" "n"))
388                    (const_int 0))
389              (label_ref (match_operand 2 "" ""))
390              (pc)))
391    (clobber (match_scratch:DI 3 "=r"))]
392   ""
393   "*
394   if (get_attr_length (insn) == 8)
395     return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
396   return \"<tbz>\\t%<w>0, %1, %l2\";
397   "
398   [(set_attr "type" "branch")
399    (set (attr "length")
400         (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
401                            (lt (minus (match_dup 2) (pc)) (const_int 32764)))
402                       (const_int 4)
403                       (const_int 8)))]
406 (define_insn "*cb<optab><mode>1"
407   [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
408                                  (const_int 0))
409                            (label_ref (match_operand 1 "" ""))
410                            (pc)))
411    (clobber (match_scratch:DI 2 "=r"))]
412   ""
413   "*
414   if (get_attr_length (insn) == 8)
415     return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
416   return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
417   "
418   [(set_attr "type" "branch")
419    (set (attr "length")
420         (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
421                            (lt (minus (match_dup 1) (pc)) (const_int 32764)))
422                       (const_int 4)
423                       (const_int 8)))]
426 ;; -------------------------------------------------------------------
427 ;; Subroutine calls and sibcalls
428 ;; -------------------------------------------------------------------
430 (define_expand "call"
431   [(parallel [(call (match_operand 0 "memory_operand" "")
432                     (match_operand 1 "general_operand" ""))
433               (use (match_operand 2 "" ""))
434               (clobber (reg:DI LR_REGNUM))])]
435   ""
436   "
437   {
438     rtx callee;
440     /* In an untyped call, we can get NULL for operand 2.  */
441     if (operands[2] == NULL)
442       operands[2] = const0_rtx;
444     /* Decide if we should generate indirect calls by loading the
445        64-bit address of the callee into a register before performing
446        the branch-and-link.  */
447     callee = XEXP (operands[0], 0);
448     if (GET_CODE (callee) == SYMBOL_REF
449         ? aarch64_is_long_call_p (callee)
450         : !REG_P (callee))
451       XEXP (operands[0], 0) = force_reg (Pmode, callee);
452   }"
455 (define_insn "*call_reg"
456   [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
457          (match_operand 1 "" ""))
458    (use (match_operand 2 "" ""))
459    (clobber (reg:DI LR_REGNUM))]
460   ""
461   "blr\\t%0"
462   [(set_attr "type" "call")]
465 (define_insn "*call_symbol"
466   [(call (mem:DI (match_operand:DI 0 "" ""))
467          (match_operand 1 "" ""))
468    (use (match_operand 2 "" ""))
469    (clobber (reg:DI LR_REGNUM))]
470   "GET_CODE (operands[0]) == SYMBOL_REF
471    && !aarch64_is_long_call_p (operands[0])"
472   "bl\\t%a0"
473   [(set_attr "type" "call")]
476 (define_expand "call_value"
477   [(parallel [(set (match_operand 0 "" "")
478                    (call (match_operand 1 "memory_operand" "")
479                          (match_operand 2 "general_operand" "")))
480               (use (match_operand 3 "" ""))
481               (clobber (reg:DI LR_REGNUM))])]
482   ""
483   "
484   {
485     rtx callee;
487     /* In an untyped call, we can get NULL for operand 3.  */
488     if (operands[3] == NULL)
489       operands[3] = const0_rtx;
491     /* Decide if we should generate indirect calls by loading the
492        64-bit address of the callee into a register before performing
493        the branch-and-link.  */
494     callee = XEXP (operands[1], 0);
495     if (GET_CODE (callee) == SYMBOL_REF
496         ? aarch64_is_long_call_p (callee)
497         : !REG_P (callee))
498       XEXP (operands[1], 0) = force_reg (Pmode, callee);
499   }"
502 (define_insn "*call_value_reg"
503   [(set (match_operand 0 "" "")
504         (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
505                       (match_operand 2 "" "")))
506    (use (match_operand 3 "" ""))
507    (clobber (reg:DI LR_REGNUM))]
508   ""
509   "blr\\t%1"
510   [(set_attr "type" "call")]
514 (define_insn "*call_value_symbol"
515   [(set (match_operand 0 "" "")
516         (call (mem:DI (match_operand:DI 1 "" ""))
517               (match_operand 2 "" "")))
518    (use (match_operand 3 "" ""))
519    (clobber (reg:DI LR_REGNUM))]
520   "GET_CODE (operands[1]) == SYMBOL_REF
521    && !aarch64_is_long_call_p (operands[1])"
522   "bl\\t%a1"
523   [(set_attr "type" "call")]
526 (define_expand "sibcall"
527   [(parallel [(call (match_operand 0 "memory_operand" "")
528                     (match_operand 1 "general_operand" ""))
529               (return)
530               (use (match_operand 2 "" ""))])]
531   ""
532   {
533     if (!REG_P (XEXP (operands[0], 0))
534        && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
535      XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
537     if (operands[2] == NULL_RTX)
538       operands[2] = const0_rtx;
539   }
542 (define_expand "sibcall_value"
543   [(parallel [(set (match_operand 0 "" "")
544                    (call (match_operand 1 "memory_operand" "")
545                          (match_operand 2 "general_operand" "")))
546               (return)
547               (use (match_operand 3 "" ""))])]
548   ""
549   {
550     if (!REG_P (XEXP (operands[1], 0))
551        && (GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF))
552      XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
554     if (operands[3] == NULL_RTX)
555       operands[3] = const0_rtx;
556   }
559 (define_insn "*sibcall_insn"
560   [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucs, Usf"))
561          (match_operand 1 "" ""))
562    (return)
563    (use (match_operand 2 "" ""))]
564   "SIBLING_CALL_P (insn)"
565   "@
566    br\\t%0
567    b\\t%a0"
568   [(set_attr "type" "branch, branch")]
571 (define_insn "*sibcall_value_insn"
572   [(set (match_operand 0 "" "")
573         (call (mem:DI (match_operand 1 "aarch64_call_insn_operand" "Ucs, Usf"))
574               (match_operand 2 "" "")))
575    (return)
576    (use (match_operand 3 "" ""))]
577   "SIBLING_CALL_P (insn)"
578   "@
579    br\\t%1
580    b\\t%a1"
581   [(set_attr "type" "branch, branch")]
584 ;; Call subroutine returning any type.
586 (define_expand "untyped_call"
587   [(parallel [(call (match_operand 0 "")
588                     (const_int 0))
589               (match_operand 1 "")
590               (match_operand 2 "")])]
591   ""
593   int i;
595   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
597   for (i = 0; i < XVECLEN (operands[2], 0); i++)
598     {
599       rtx set = XVECEXP (operands[2], 0, i);
600       emit_move_insn (SET_DEST (set), SET_SRC (set));
601     }
603   /* The optimizer does not know that the call sets the function value
604      registers we stored in the result block.  We avoid problems by
605      claiming that all hard registers are used and clobbered at this
606      point.  */
607   emit_insn (gen_blockage ());
608   DONE;
611 ;; -------------------------------------------------------------------
612 ;; Moves
613 ;; -------------------------------------------------------------------
615 (define_expand "mov<mode>"
616   [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
617         (match_operand:SHORT 1 "general_operand" ""))]
618   ""
619   "
620     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
621       operands[1] = force_reg (<MODE>mode, operands[1]);
622   "
625 (define_insn "*mov<mode>_aarch64"
626   [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r,   *w,r,*w, m, m, r,*w,*w")
627         (match_operand:SHORT 1 "general_operand"      " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
628   "(register_operand (operands[0], <MODE>mode)
629     || aarch64_reg_or_zero (operands[1], <MODE>mode))"
631    switch (which_alternative)
632      {
633      case 0:
634        return "mov\t%w0, %w1";
635      case 1:
636        return "mov\t%w0, %1";
637      case 2:
638        return aarch64_output_scalar_simd_mov_immediate (operands[1],
639                                                         <MODE>mode);
640      case 3:
641        return "ldr<size>\t%w0, %1";
642      case 4:
643        return "ldr\t%<size>0, %1";
644      case 5:
645        return "str<size>\t%w1, %0";
646      case 6:
647        return "str\t%<size>1, %0";
648      case 7:
649        return "umov\t%w0, %1.<v>[0]";
650      case 8:
651        return "dup\t%0.<Vallxd>, %w1";
652      case 9:
653        return "dup\t%<Vetype>0, %1.<v>[0]";
654      default:
655        gcc_unreachable ();
656      }
658   [(set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
659                      neon_from_gp<q>,neon_from_gp<q>, neon_dup")
660    (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")]
663 (define_expand "mov<mode>"
664   [(set (match_operand:GPI 0 "nonimmediate_operand" "")
665         (match_operand:GPI 1 "general_operand" ""))]
666   ""
667   "
668     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
669       operands[1] = force_reg (<MODE>mode, operands[1]);
671     if (CONSTANT_P (operands[1]))
672       {
673         aarch64_expand_mov_immediate (operands[0], operands[1]);
674         DONE;
675       }
676   "
679 (define_insn "*movsi_aarch64"
680   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m,  m,r,r  ,*w, r,*w")
681         (match_operand:SI 1 "aarch64_mov_operand"  " r,r,k,M,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
682   "(register_operand (operands[0], SImode)
683     || aarch64_reg_or_zero (operands[1], SImode))"
684   "@
685    mov\\t%w0, %w1
686    mov\\t%w0, %w1
687    mov\\t%w0, %w1
688    mov\\t%w0, %1
689    ldr\\t%w0, %1
690    ldr\\t%s0, %1
691    str\\t%w1, %0
692    str\\t%s1, %0
693    adr\\t%x0, %a1
694    adrp\\t%x0, %A1
695    fmov\\t%s0, %w1
696    fmov\\t%w0, %s1
697    fmov\\t%s0, %s1"
698   [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
699                      adr,adr,f_mcr,f_mrc,fmov")
700    (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
703 (define_insn "*movdi_aarch64"
704   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m,  m,r,r,  *w, r,*w,w")
705         (match_operand:DI 1 "aarch64_mov_operand"  " r,r,k,N,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))]
706   "(register_operand (operands[0], DImode)
707     || aarch64_reg_or_zero (operands[1], DImode))"
708   "@
709    mov\\t%x0, %x1
710    mov\\t%0, %x1
711    mov\\t%x0, %1
712    mov\\t%x0, %1
713    ldr\\t%x0, %1
714    ldr\\t%d0, %1
715    str\\t%x1, %0
716    str\\t%d1, %0
717    adr\\t%x0, %a1
718    adrp\\t%x0, %A1
719    fmov\\t%d0, %x1
720    fmov\\t%x0, %d1
721    fmov\\t%d0, %d1
722    movi\\t%d0, %1"
723   [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
724                      adr,adr,f_mcr,f_mrc,fmov,fmov")
725    (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
726    (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
729 (define_insn "insv_imm<mode>"
730   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
731                           (const_int 16)
732                           (match_operand:GPI 1 "const_int_operand" "n"))
733         (match_operand:GPI 2 "const_int_operand" "n"))]
734   "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
735    && UINTVAL (operands[1]) % 16 == 0"
736   "movk\\t%<w>0, %X2, lsl %1"
737   [(set_attr "type" "mov_imm")]
740 (define_expand "movti"
741   [(set (match_operand:TI 0 "nonimmediate_operand" "")
742         (match_operand:TI 1 "general_operand" ""))]
743   ""
744   "
745     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
746       operands[1] = force_reg (TImode, operands[1]);
747   "
750 (define_insn "*movti_aarch64"
751   [(set (match_operand:TI 0
752          "nonimmediate_operand"  "=r, *w,r ,*w,r  ,Ump,Ump,*w,m")
753         (match_operand:TI 1
754          "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r  ,Z  , m,*w"))]
755   "(register_operand (operands[0], TImode)
756     || aarch64_reg_or_zero (operands[1], TImode))"
757   "@
758    #
759    #
760    #
761    orr\\t%0.16b, %1.16b, %1.16b
762    ldp\\t%0, %H0, %1
763    stp\\t%1, %H1, %0
764    stp\\txzr, xzr, %0
765    ldr\\t%q0, %1
766    str\\t%q1, %0"
767   [(set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \
768                              load2,store2,store2,f_loadd,f_stored")
769    (set_attr "length" "8,8,8,4,4,4,4,4,4")
770    (set_attr "simd" "*,*,*,yes,*,*,*,*,*")
771    (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
774 ;; Split a TImode register-register or register-immediate move into
775 ;; its component DImode pieces, taking care to handle overlapping
776 ;; source and dest registers.
777 (define_split
778    [(set (match_operand:TI 0 "register_operand" "")
779          (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
780   "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
781   [(const_int 0)]
783   aarch64_split_128bit_move (operands[0], operands[1]);
784   DONE;
787 (define_expand "mov<mode>"
788   [(set (match_operand:GPF 0 "nonimmediate_operand" "")
789         (match_operand:GPF 1 "general_operand" ""))]
790   ""
791   "
792     if (!TARGET_FLOAT)
793      {
794         sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
795         FAIL;
796      }
798     if (GET_CODE (operands[0]) == MEM)
799       operands[1] = force_reg (<MODE>mode, operands[1]);
800   "
803 (define_insn "*movsf_aarch64"
804   [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w  ,w,m,r,m ,r")
805         (match_operand:SF 1 "general_operand"      "?rY, w,w,Ufc,m,w,m,rY,r"))]
806   "TARGET_FLOAT && (register_operand (operands[0], SFmode)
807     || register_operand (operands[1], SFmode))"
808   "@
809    fmov\\t%s0, %w1
810    fmov\\t%w0, %s1
811    fmov\\t%s0, %s1
812    fmov\\t%s0, %1
813    ldr\\t%s0, %1
814    str\\t%s1, %0
815    ldr\\t%w0, %1
816    str\\t%w1, %0
817    mov\\t%w0, %w1"
818   [(set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
819                      f_loads,f_stores,f_loads,f_stores,mov_reg")]
822 (define_insn "*movdf_aarch64"
823   [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w  ,w,m,r,m ,r")
824         (match_operand:DF 1 "general_operand"      "?rY, w,w,Ufc,m,w,m,rY,r"))]
825   "TARGET_FLOAT && (register_operand (operands[0], DFmode)
826     || register_operand (operands[1], DFmode))"
827   "@
828    fmov\\t%d0, %x1
829    fmov\\t%x0, %d1
830    fmov\\t%d0, %d1
831    fmov\\t%d0, %1
832    ldr\\t%d0, %1
833    str\\t%d1, %0
834    ldr\\t%x0, %1
835    str\\t%x1, %0
836    mov\\t%x0, %x1"
837   [(set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
838                      f_loadd,f_stored,f_loadd,f_stored,mov_reg")]
841 (define_expand "movtf"
842   [(set (match_operand:TF 0 "nonimmediate_operand" "")
843         (match_operand:TF 1 "general_operand" ""))]
844   ""
845   "
846     if (!TARGET_FLOAT)
847      {
848         sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
849         FAIL;
850      }
852     if (GET_CODE (operands[0]) == MEM)
853       operands[1] = force_reg (TFmode, operands[1]);
854   "
857 (define_insn "*movtf_aarch64"
858   [(set (match_operand:TF 0
859          "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
860         (match_operand:TF 1
861          "general_operand"      " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
862   "TARGET_FLOAT && (register_operand (operands[0], TFmode)
863     || register_operand (operands[1], TFmode))"
864   "@
865    orr\\t%0.16b, %1.16b, %1.16b
866    #
867    #
868    #
869    movi\\t%0.2d, #0
870    fmov\\t%s0, wzr
871    ldr\\t%q0, %1
872    str\\t%q1, %0
873    ldp\\t%0, %H0, %1
874    stp\\t%1, %H1, %0"
875   [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,fconstd,fconstd,\
876                      f_loadd,f_stored,neon_load1_2reg,neon_store1_2reg")
877    (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
878    (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
879    (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
882 (define_split
883    [(set (match_operand:TF 0 "register_operand" "")
884          (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
885   "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
886   [(const_int 0)]
887   {
888     aarch64_split_128bit_move (operands[0], operands[1]);
889     DONE;
890   }
893 ;; 0 is dst
894 ;; 1 is src
895 ;; 2 is size of move in bytes
896 ;; 3 is alignment
898 (define_expand "movmemdi"
899   [(match_operand:BLK 0 "memory_operand")
900    (match_operand:BLK 1 "memory_operand")
901    (match_operand:DI 2 "immediate_operand")
902    (match_operand:DI 3 "immediate_operand")]
903    "!STRICT_ALIGNMENT"
905   if (aarch64_expand_movmem (operands))
906     DONE;
907   FAIL;
911 ;; Operands 1 and 3 are tied together by the final condition; so we allow
912 ;; fairly lax checking on the second memory operation.
913 (define_insn "load_pair<mode>"
914   [(set (match_operand:GPI 0 "register_operand" "=r")
915         (match_operand:GPI 1 "aarch64_mem_pair_operand" "Ump"))
916    (set (match_operand:GPI 2 "register_operand" "=r")
917         (match_operand:GPI 3 "memory_operand" "m"))]
918   "rtx_equal_p (XEXP (operands[3], 0),
919                 plus_constant (Pmode,
920                                XEXP (operands[1], 0),
921                                GET_MODE_SIZE (<MODE>mode)))"
922   "ldp\\t%<w>0, %<w>2, %1"
923   [(set_attr "type" "load2")]
926 ;; Operands 0 and 2 are tied together by the final condition; so we allow
927 ;; fairly lax checking on the second memory operation.
928 (define_insn "store_pair<mode>"
929   [(set (match_operand:GPI 0 "aarch64_mem_pair_operand" "=Ump")
930         (match_operand:GPI 1 "register_operand" "r"))
931    (set (match_operand:GPI 2 "memory_operand" "=m")
932         (match_operand:GPI 3 "register_operand" "r"))]
933   "rtx_equal_p (XEXP (operands[2], 0),
934                 plus_constant (Pmode,
935                                XEXP (operands[0], 0),
936                                GET_MODE_SIZE (<MODE>mode)))"
937   "stp\\t%<w>1, %<w>3, %0"
938   [(set_attr "type" "store2")]
941 ;; Operands 1 and 3 are tied together by the final condition; so we allow
942 ;; fairly lax checking on the second memory operation.
943 (define_insn "load_pair<mode>"
944   [(set (match_operand:GPF 0 "register_operand" "=w")
945         (match_operand:GPF 1 "aarch64_mem_pair_operand" "Ump"))
946    (set (match_operand:GPF 2 "register_operand" "=w")
947         (match_operand:GPF 3 "memory_operand" "m"))]
948   "rtx_equal_p (XEXP (operands[3], 0),
949                 plus_constant (Pmode,
950                                XEXP (operands[1], 0),
951                                GET_MODE_SIZE (<MODE>mode)))"
952   "ldp\\t%<w>0, %<w>2, %1"
953   [(set_attr "type" "neon_load1_2reg<q>")]
956 ;; Operands 0 and 2 are tied together by the final condition; so we allow
957 ;; fairly lax checking on the second memory operation.
958 (define_insn "store_pair<mode>"
959   [(set (match_operand:GPF 0 "aarch64_mem_pair_operand" "=Ump")
960         (match_operand:GPF 1 "register_operand" "w"))
961    (set (match_operand:GPF 2 "memory_operand" "=m")
962         (match_operand:GPF 3 "register_operand" "w"))]
963   "rtx_equal_p (XEXP (operands[2], 0),
964                 plus_constant (Pmode,
965                                XEXP (operands[0], 0),
966                                GET_MODE_SIZE (<MODE>mode)))"
967   "stp\\t%<w>1, %<w>3, %0"
968   [(set_attr "type" "neon_store1_2reg<q>")]
971 ;; Load pair with post-index writeback.  This is primarily used in function
972 ;; epilogues.
973 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
974   [(parallel
975     [(set (match_operand:P 0 "register_operand" "=k")
976           (plus:P (match_operand:P 1 "register_operand" "0")
977                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
978      (set (match_operand:GPI 2 "register_operand" "=r")
979           (mem:GPI (match_dup 1)))
980      (set (match_operand:GPI 3 "register_operand" "=r")
981           (mem:GPI (plus:P (match_dup 1)
982                    (match_operand:P 5 "const_int_operand" "n"))))])]
983   "INTVAL (operands[5]) == GET_MODE_SIZE (<GPI:MODE>mode)"
984   "ldp\\t%<w>2, %<w>3, [%1], %4"
985   [(set_attr "type" "load2")]
988 (define_insn "loadwb_pair<GPF:mode>_<P:mode>"
989   [(parallel
990     [(set (match_operand:P 0 "register_operand" "=k")
991           (plus:P (match_operand:P 1 "register_operand" "0")
992                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
993      (set (match_operand:GPF 2 "register_operand" "=w")
994           (mem:GPF (match_dup 1)))
995      (set (match_operand:GPF 3 "register_operand" "=w")
996           (mem:GPF (plus:P (match_dup 1)
997                    (match_operand:P 5 "const_int_operand" "n"))))])]
998   "INTVAL (operands[5]) == GET_MODE_SIZE (<GPF:MODE>mode)"
999   "ldp\\t%<w>2, %<w>3, [%1], %4"
1000   [(set_attr "type" "neon_load1_2reg")]
1003 ;; Store pair with pre-index writeback.  This is primarily used in function
1004 ;; prologues.
1005 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
1006   [(parallel
1007     [(set (match_operand:P 0 "register_operand" "=&k")
1008           (plus:P (match_operand:P 1 "register_operand" "0")
1009                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1010      (set (mem:GPI (plus:P (match_dup 0)
1011                    (match_dup 4)))
1012           (match_operand:GPI 2 "register_operand" "r"))
1013      (set (mem:GPI (plus:P (match_dup 0)
1014                    (match_operand:P 5 "const_int_operand" "n")))
1015           (match_operand:GPI 3 "register_operand" "r"))])]
1016   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1017   "stp\\t%<w>2, %<w>3, [%0, %4]!"
1018   [(set_attr "type" "store2")]
1021 (define_insn "storewb_pair<GPF:mode>_<P:mode>"
1022   [(parallel
1023     [(set (match_operand:P 0 "register_operand" "=&k")
1024           (plus:P (match_operand:P 1 "register_operand" "0")
1025                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1026      (set (mem:GPF (plus:P (match_dup 0)
1027                    (match_dup 4)))
1028           (match_operand:GPF 2 "register_operand" "w"))
1029      (set (mem:GPF (plus:P (match_dup 0)
1030                    (match_operand:P 5 "const_int_operand" "n")))
1031           (match_operand:GPF 3 "register_operand" "w"))])]
1032   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPF:MODE>mode)"
1033   "stp\\t%<w>2, %<w>3, [%0, %4]!"
1034   [(set_attr "type" "neon_store1_2reg<q>")]
1037 ;; -------------------------------------------------------------------
1038 ;; Sign/Zero extension
1039 ;; -------------------------------------------------------------------
1041 (define_expand "<optab>sidi2"
1042   [(set (match_operand:DI 0 "register_operand")
1043         (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1044   ""
1047 (define_insn "*extendsidi2_aarch64"
1048   [(set (match_operand:DI 0 "register_operand" "=r,r")
1049         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1050   ""
1051   "@
1052    sxtw\t%0, %w1
1053    ldrsw\t%0, %1"
1054   [(set_attr "type" "extend,load1")]
1057 (define_insn "*zero_extendsidi2_aarch64"
1058   [(set (match_operand:DI 0 "register_operand" "=r,r")
1059         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1060   ""
1061   "@
1062    uxtw\t%0, %w1
1063    ldr\t%w0, %1"
1064   [(set_attr "type" "extend,load1")]
1067 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1068   [(set (match_operand:GPI 0 "register_operand")
1069         (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1070   ""
1073 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1074   [(set (match_operand:GPI 0 "register_operand" "=r,r")
1075         (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1076   ""
1077   "@
1078    sxt<SHORT:size>\t%<GPI:w>0, %w1
1079    ldrs<SHORT:size>\t%<GPI:w>0, %1"
1080   [(set_attr "type" "extend,load1")]
1083 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1084   [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1085         (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1086   ""
1087   "@
1088    uxt<SHORT:size>\t%<GPI:w>0, %w1
1089    ldr<SHORT:size>\t%w0, %1
1090    ldr\t%<SHORT:size>0, %1"
1091   [(set_attr "type" "extend,load1,load1")]
1094 (define_expand "<optab>qihi2"
1095   [(set (match_operand:HI 0 "register_operand")
1096         (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1097   ""
1100 (define_insn "*<optab>qihi2_aarch64"
1101   [(set (match_operand:HI 0 "register_operand" "=r,r")
1102         (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1103   ""
1104   "@
1105    <su>xtb\t%w0, %w1
1106    <ldrxt>b\t%w0, %1"
1107   [(set_attr "type" "extend,load1")]
1110 ;; -------------------------------------------------------------------
1111 ;; Simple arithmetic
1112 ;; -------------------------------------------------------------------
1114 (define_expand "add<mode>3"
1115   [(set
1116     (match_operand:GPI 0 "register_operand" "")
1117     (plus:GPI (match_operand:GPI 1 "register_operand" "")
1118               (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1119   ""
1120   "
1121   if (! aarch64_plus_operand (operands[2], VOIDmode))
1122     {
1123       rtx subtarget = ((optimize && can_create_pseudo_p ())
1124                        ? gen_reg_rtx (<MODE>mode) : operands[0]);
1125       HOST_WIDE_INT imm = INTVAL (operands[2]);
1127       if (imm < 0)
1128         imm = -(-imm & ~0xfff);
1129       else
1130         imm &= ~0xfff;
1132       emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1133       operands[1] = subtarget;
1134       operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1135     }
1136   "
1139 (define_insn "*addsi3_aarch64"
1140   [(set
1141     (match_operand:SI 0 "register_operand" "=rk,rk,w,rk")
1142     (plus:SI
1143      (match_operand:SI 1 "register_operand" "%rk,rk,w,rk")
1144      (match_operand:SI 2 "aarch64_plus_operand" "I,r,w,J")))]
1145   ""
1146   "@
1147   add\\t%w0, %w1, %2
1148   add\\t%w0, %w1, %w2
1149   add\\t%0.2s, %1.2s, %2.2s
1150   sub\\t%w0, %w1, #%n2"
1151   [(set_attr "type" "alu_imm,alu_reg,neon_add,alu_imm")
1152    (set_attr "simd" "*,*,yes,*")]
1155 ;; zero_extend version of above
1156 (define_insn "*addsi3_aarch64_uxtw"
1157   [(set
1158     (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1159     (zero_extend:DI
1160      (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1161               (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1162   ""
1163   "@
1164   add\\t%w0, %w1, %2
1165   add\\t%w0, %w1, %w2
1166   sub\\t%w0, %w1, #%n2"
1167   [(set_attr "type" "alu_imm,alu_reg,alu_imm")]
1170 (define_insn "*adddi3_aarch64"
1171   [(set
1172     (match_operand:DI 0 "register_operand" "=rk,rk,rk,!w")
1173     (plus:DI
1174      (match_operand:DI 1 "register_operand" "%rk,rk,rk,!w")
1175      (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,!w")))]
1176   ""
1177   "@
1178   add\\t%x0, %x1, %2
1179   add\\t%x0, %x1, %x2
1180   sub\\t%x0, %x1, #%n2
1181   add\\t%d0, %d1, %d2"
1182   [(set_attr "type" "alu_imm,alu_reg,alu_imm,alu_reg")
1183    (set_attr "simd" "*,*,*,yes")]
1186 (define_expand "addti3"
1187   [(set (match_operand:TI 0 "register_operand" "")
1188         (plus:TI (match_operand:TI 1 "register_operand" "")
1189                  (match_operand:TI 2 "register_operand" "")))]
1190   ""
1192   rtx low = gen_reg_rtx (DImode);
1193   emit_insn (gen_adddi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1194                                   gen_lowpart (DImode, operands[2])));
1196   rtx high = gen_reg_rtx (DImode);
1197   emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]),
1198                                  gen_highpart (DImode, operands[2])));
1200   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1201   emit_move_insn (gen_highpart (DImode, operands[0]), high);
1202   DONE;
1205 (define_insn "add<mode>3_compare0"
1206   [(set (reg:CC_NZ CC_REGNUM)
1207         (compare:CC_NZ
1208          (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1209                    (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1210          (const_int 0)))
1211    (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1212         (plus:GPI (match_dup 1) (match_dup 2)))]
1213   ""
1214   "@
1215   adds\\t%<w>0, %<w>1, %<w>2
1216   adds\\t%<w>0, %<w>1, %<w>2
1217   subs\\t%<w>0, %<w>1, #%n2"
1218   [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1221 ;; zero_extend version of above
1222 (define_insn "*addsi3_compare0_uxtw"
1223   [(set (reg:CC_NZ CC_REGNUM)
1224         (compare:CC_NZ
1225          (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1226                   (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1227          (const_int 0)))
1228    (set (match_operand:DI 0 "register_operand" "=r,r,r")
1229         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1230   ""
1231   "@
1232   adds\\t%w0, %w1, %w2
1233   adds\\t%w0, %w1, %w2
1234   subs\\t%w0, %w1, #%n2"
1235   [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1238 (define_insn "*adds_mul_imm_<mode>"
1239   [(set (reg:CC_NZ CC_REGNUM)
1240         (compare:CC_NZ
1241          (plus:GPI (mult:GPI
1242                     (match_operand:GPI 1 "register_operand" "r")
1243                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1244                    (match_operand:GPI 3 "register_operand" "r"))
1245          (const_int 0)))
1246    (set (match_operand:GPI 0 "register_operand" "=r")
1247         (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1248                   (match_dup 3)))]
1249   ""
1250   "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1251   [(set_attr "type" "alus_shift_imm")]
1254 (define_insn "*subs_mul_imm_<mode>"
1255   [(set (reg:CC_NZ CC_REGNUM)
1256         (compare:CC_NZ
1257          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1258                     (mult:GPI
1259                      (match_operand:GPI 2 "register_operand" "r")
1260                      (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1261          (const_int 0)))
1262    (set (match_operand:GPI 0 "register_operand" "=r")
1263         (minus:GPI (match_dup 1)
1264                    (mult:GPI (match_dup 2) (match_dup 3))))]
1265   ""
1266   "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1267   [(set_attr "type" "alus_shift_imm")]
1270 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1271   [(set (reg:CC_NZ CC_REGNUM)
1272         (compare:CC_NZ
1273          (plus:GPI
1274           (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1275           (match_operand:GPI 2 "register_operand" "r"))
1276         (const_int 0)))
1277    (set (match_operand:GPI 0 "register_operand" "=r")
1278         (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1279   ""
1280   "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1281   [(set_attr "type" "alus_ext")]
1284 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1285   [(set (reg:CC_NZ CC_REGNUM)
1286         (compare:CC_NZ
1287          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1288                     (ANY_EXTEND:GPI
1289                      (match_operand:ALLX 2 "register_operand" "r")))
1290         (const_int 0)))
1291    (set (match_operand:GPI 0 "register_operand" "=r")
1292         (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1293   ""
1294   "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1295   [(set_attr "type" "alus_ext")]
1298 (define_insn "*adds_<optab><mode>_multp2"
1299   [(set (reg:CC_NZ CC_REGNUM)
1300         (compare:CC_NZ
1301          (plus:GPI (ANY_EXTRACT:GPI
1302                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1303                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1304                     (match_operand 3 "const_int_operand" "n")
1305                     (const_int 0))
1306                    (match_operand:GPI 4 "register_operand" "r"))
1307         (const_int 0)))
1308    (set (match_operand:GPI 0 "register_operand" "=r")
1309         (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1310                                    (match_dup 3)
1311                                    (const_int 0))
1312                   (match_dup 4)))]
1313   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1314   "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1315   [(set_attr "type" "alus_ext")]
1318 (define_insn "*subs_<optab><mode>_multp2"
1319   [(set (reg:CC_NZ CC_REGNUM)
1320         (compare:CC_NZ
1321          (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1322                     (ANY_EXTRACT:GPI
1323                      (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1324                                (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1325                      (match_operand 3 "const_int_operand" "n")
1326                      (const_int 0)))
1327         (const_int 0)))
1328    (set (match_operand:GPI 0 "register_operand" "=r")
1329         (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1330                                   (mult:GPI (match_dup 1) (match_dup 2))
1331                                   (match_dup 3)
1332                                   (const_int 0))))]
1333   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1334   "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1335   [(set_attr "type" "alus_ext")]
1338 (define_insn "*add<mode>3nr_compare0"
1339   [(set (reg:CC_NZ CC_REGNUM)
1340         (compare:CC_NZ
1341          (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1342                    (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1343          (const_int 0)))]
1344   ""
1345   "@
1346   cmn\\t%<w>0, %<w>1
1347   cmn\\t%<w>0, %<w>1
1348   cmp\\t%<w>0, #%n1"
1349   [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1352 (define_insn "*compare_neg<mode>"
1353   [(set (reg:CC_Z CC_REGNUM)
1354         (compare:CC_Z
1355          (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1356          (match_operand:GPI 1 "register_operand" "r")))]
1357   ""
1358   "cmn\\t%<w>1, %<w>0"
1359   [(set_attr "type" "alus_reg")]
1362 (define_insn "*add_<shift>_<mode>"
1363   [(set (match_operand:GPI 0 "register_operand" "=r")
1364         (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1365                               (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1366                   (match_operand:GPI 3 "register_operand" "r")))]
1367   ""
1368   "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1369   [(set_attr "type" "alu_shift_imm")]
1372 ;; zero_extend version of above
1373 (define_insn "*add_<shift>_si_uxtw"
1374   [(set (match_operand:DI 0 "register_operand" "=r")
1375         (zero_extend:DI
1376          (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1377                              (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1378                   (match_operand:SI 3 "register_operand" "r"))))]
1379   ""
1380   "add\\t%w0, %w3, %w1, <shift> %2"
1381   [(set_attr "type" "alu_shift_imm")]
1384 (define_insn "*add_mul_imm_<mode>"
1385   [(set (match_operand:GPI 0 "register_operand" "=r")
1386         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1387                             (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1388                   (match_operand:GPI 3 "register_operand" "r")))]
1389   ""
1390   "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1391   [(set_attr "type" "alu_shift_imm")]
1394 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1395   [(set (match_operand:GPI 0 "register_operand" "=rk")
1396         (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1397                   (match_operand:GPI 2 "register_operand" "r")))]
1398   ""
1399   "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1400   [(set_attr "type" "alu_ext")]
1403 ;; zero_extend version of above
1404 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1405   [(set (match_operand:DI 0 "register_operand" "=rk")
1406         (zero_extend:DI
1407          (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1408                   (match_operand:GPI 2 "register_operand" "r"))))]
1409   ""
1410   "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1411   [(set_attr "type" "alu_ext")]
1414 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1415   [(set (match_operand:GPI 0 "register_operand" "=rk")
1416         (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1417                                (match_operand:ALLX 1 "register_operand" "r"))
1418                               (match_operand 2 "aarch64_imm3" "Ui3"))
1419                   (match_operand:GPI 3 "register_operand" "r")))]
1420   ""
1421   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1422   [(set_attr "type" "alu_ext")]
1425 ;; zero_extend version of above
1426 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1427   [(set (match_operand:DI 0 "register_operand" "=rk")
1428         (zero_extend:DI
1429          (plus:SI (ashift:SI (ANY_EXTEND:SI
1430                               (match_operand:SHORT 1 "register_operand" "r"))
1431                              (match_operand 2 "aarch64_imm3" "Ui3"))
1432                   (match_operand:SI 3 "register_operand" "r"))))]
1433   ""
1434   "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1435   [(set_attr "type" "alu_ext")]
1438 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1439   [(set (match_operand:GPI 0 "register_operand" "=rk")
1440         (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1441                              (match_operand:ALLX 1 "register_operand" "r"))
1442                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1443                   (match_operand:GPI 3 "register_operand" "r")))]
1444   ""
1445   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1446   [(set_attr "type" "alu_ext")]
1449 ;; zero_extend version of above
1450 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1451   [(set (match_operand:DI 0 "register_operand" "=rk")
1452         (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1453                              (match_operand:SHORT 1 "register_operand" "r"))
1454                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1455                   (match_operand:SI 3 "register_operand" "r"))))]
1456   ""
1457   "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1458   [(set_attr "type" "alu_ext")]
1461 (define_insn "*add_<optab><mode>_multp2"
1462   [(set (match_operand:GPI 0 "register_operand" "=rk")
1463         (plus:GPI (ANY_EXTRACT:GPI
1464                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1465                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1466                    (match_operand 3 "const_int_operand" "n")
1467                    (const_int 0))
1468                   (match_operand:GPI 4 "register_operand" "r")))]
1469   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1470   "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1471   [(set_attr "type" "alu_ext")]
1474 ;; zero_extend version of above
1475 (define_insn "*add_<optab>si_multp2_uxtw"
1476   [(set (match_operand:DI 0 "register_operand" "=rk")
1477         (zero_extend:DI
1478          (plus:SI (ANY_EXTRACT:SI
1479                    (mult:SI (match_operand:SI 1 "register_operand" "r")
1480                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1481                    (match_operand 3 "const_int_operand" "n")
1482                    (const_int 0))
1483                   (match_operand:SI 4 "register_operand" "r"))))]
1484   "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1485   "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1486   [(set_attr "type" "alu_ext")]
1489 (define_insn "add<mode>3_carryin"
1490   [(set
1491     (match_operand:GPI 0 "register_operand" "=r")
1492     (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1493               (plus:GPI
1494                 (match_operand:GPI 1 "register_operand" "r")
1495                 (match_operand:GPI 2 "register_operand" "r"))))]
1496    ""
1497    "adc\\t%<w>0, %<w>1, %<w>2"
1498   [(set_attr "type" "adc_reg")]
1501 ;; zero_extend version of above
1502 (define_insn "*addsi3_carryin_uxtw"
1503   [(set
1504     (match_operand:DI 0 "register_operand" "=r")
1505     (zero_extend:DI
1506      (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1507               (plus:SI
1508                (match_operand:SI 1 "register_operand" "r")
1509                (match_operand:SI 2 "register_operand" "r")))))]
1510    ""
1511    "adc\\t%w0, %w1, %w2"
1512   [(set_attr "type" "adc_reg")]
1515 (define_insn "*add<mode>3_carryin_alt1"
1516   [(set
1517     (match_operand:GPI 0 "register_operand" "=r")
1518     (plus:GPI (plus:GPI
1519                 (match_operand:GPI 1 "register_operand" "r")
1520                 (match_operand:GPI 2 "register_operand" "r"))
1521               (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1522    ""
1523    "adc\\t%<w>0, %<w>1, %<w>2"
1524   [(set_attr "type" "adc_reg")]
1527 ;; zero_extend version of above
1528 (define_insn "*addsi3_carryin_alt1_uxtw"
1529   [(set
1530     (match_operand:DI 0 "register_operand" "=r")
1531     (zero_extend:DI
1532      (plus:SI (plus:SI
1533                (match_operand:SI 1 "register_operand" "r")
1534                (match_operand:SI 2 "register_operand" "r"))
1535               (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1536    ""
1537    "adc\\t%w0, %w1, %w2"
1538   [(set_attr "type" "adc_reg")]
1541 (define_insn "*add<mode>3_carryin_alt2"
1542   [(set
1543     (match_operand:GPI 0 "register_operand" "=r")
1544     (plus:GPI (plus:GPI
1545                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1546                 (match_operand:GPI 1 "register_operand" "r"))
1547               (match_operand:GPI 2 "register_operand" "r")))]
1548    ""
1549    "adc\\t%<w>0, %<w>1, %<w>2"
1550   [(set_attr "type" "adc_reg")]
1553 ;; zero_extend version of above
1554 (define_insn "*addsi3_carryin_alt2_uxtw"
1555   [(set
1556     (match_operand:DI 0 "register_operand" "=r")
1557     (zero_extend:DI
1558      (plus:SI (plus:SI
1559                (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1560                (match_operand:SI 1 "register_operand" "r"))
1561               (match_operand:SI 2 "register_operand" "r"))))]
1562    ""
1563    "adc\\t%w0, %w1, %w2"
1564   [(set_attr "type" "adc_reg")]
1567 (define_insn "*add<mode>3_carryin_alt3"
1568   [(set
1569     (match_operand:GPI 0 "register_operand" "=r")
1570     (plus:GPI (plus:GPI
1571                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1572                 (match_operand:GPI 2 "register_operand" "r"))
1573               (match_operand:GPI 1 "register_operand" "r")))]
1574    ""
1575    "adc\\t%<w>0, %<w>1, %<w>2"
1576   [(set_attr "type" "adc_reg")]
1579 ;; zero_extend version of above
1580 (define_insn "*addsi3_carryin_alt3_uxtw"
1581   [(set
1582     (match_operand:DI 0 "register_operand" "=r")
1583     (zero_extend:DI
1584      (plus:SI (plus:SI
1585                (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1586                (match_operand:SI 2 "register_operand" "r"))
1587               (match_operand:SI 1 "register_operand" "r"))))]
1588    ""
1589    "adc\\t%w0, %w1, %w2"
1590   [(set_attr "type" "adc_reg")]
1593 (define_insn "*add_uxt<mode>_multp2"
1594   [(set (match_operand:GPI 0 "register_operand" "=rk")
1595         (plus:GPI (and:GPI
1596                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1597                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1598                    (match_operand 3 "const_int_operand" "n"))
1599                   (match_operand:GPI 4 "register_operand" "r")))]
1600   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1601   "*
1602   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1603                                            INTVAL (operands[3])));
1604   return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1605   [(set_attr "type" "alu_ext")]
1608 ;; zero_extend version of above
1609 (define_insn "*add_uxtsi_multp2_uxtw"
1610   [(set (match_operand:DI 0 "register_operand" "=rk")
1611         (zero_extend:DI
1612          (plus:SI (and:SI
1613                    (mult:SI (match_operand:SI 1 "register_operand" "r")
1614                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1615                    (match_operand 3 "const_int_operand" "n"))
1616                   (match_operand:SI 4 "register_operand" "r"))))]
1617   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1618   "*
1619   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1620                                            INTVAL (operands[3])));
1621   return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1622   [(set_attr "type" "alu_ext")]
1625 (define_insn "subsi3"
1626   [(set (match_operand:SI 0 "register_operand" "=rk")
1627         (minus:SI (match_operand:SI 1 "register_operand" "r")
1628                    (match_operand:SI 2 "register_operand" "r")))]
1629   ""
1630   "sub\\t%w0, %w1, %w2"
1631   [(set_attr "type" "alu_reg")]
1634 ;; zero_extend version of above
1635 (define_insn "*subsi3_uxtw"
1636   [(set (match_operand:DI 0 "register_operand" "=rk")
1637         (zero_extend:DI
1638          (minus:SI (match_operand:SI 1 "register_operand" "r")
1639                    (match_operand:SI 2 "register_operand" "r"))))]
1640   ""
1641   "sub\\t%w0, %w1, %w2"
1642   [(set_attr "type" "alu_reg")]
1645 (define_insn "subdi3"
1646   [(set (match_operand:DI 0 "register_operand" "=rk,!w")
1647         (minus:DI (match_operand:DI 1 "register_operand" "r,!w")
1648                    (match_operand:DI 2 "register_operand" "r,!w")))]
1649   ""
1650   "@
1651    sub\\t%x0, %x1, %x2
1652    sub\\t%d0, %d1, %d2"
1653   [(set_attr "type" "alu_reg, neon_sub")
1654    (set_attr "simd" "*,yes")]
1657 (define_expand "subti3"
1658   [(set (match_operand:TI 0 "register_operand" "")
1659         (minus:TI (match_operand:TI 1 "register_operand" "")
1660                   (match_operand:TI 2 "register_operand" "")))]
1661   ""
1663   rtx low = gen_reg_rtx (DImode);
1664   emit_insn (gen_subdi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1665                                   gen_lowpart (DImode, operands[2])));
1667   rtx high = gen_reg_rtx (DImode);
1668   emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]),
1669                                  gen_highpart (DImode, operands[2])));
1671   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1672   emit_move_insn (gen_highpart (DImode, operands[0]), high);
1673   DONE;
1676 (define_insn "sub<mode>3_compare0"
1677   [(set (reg:CC_NZ CC_REGNUM)
1678         (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1679                                   (match_operand:GPI 2 "register_operand" "r"))
1680                        (const_int 0)))
1681    (set (match_operand:GPI 0 "register_operand" "=r")
1682         (minus:GPI (match_dup 1) (match_dup 2)))]
1683   ""
1684   "subs\\t%<w>0, %<w>1, %<w>2"
1685   [(set_attr "type" "alus_reg")]
1688 ;; zero_extend version of above
1689 (define_insn "*subsi3_compare0_uxtw"
1690   [(set (reg:CC_NZ CC_REGNUM)
1691         (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1692                                  (match_operand:SI 2 "register_operand" "r"))
1693                        (const_int 0)))
1694    (set (match_operand:DI 0 "register_operand" "=r")
1695         (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1696   ""
1697   "subs\\t%w0, %w1, %w2"
1698   [(set_attr "type" "alus_reg")]
1701 (define_insn "*sub_<shift>_<mode>"
1702   [(set (match_operand:GPI 0 "register_operand" "=r")
1703         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1704                    (ASHIFT:GPI
1705                     (match_operand:GPI 1 "register_operand" "r")
1706                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1707   ""
1708   "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1709   [(set_attr "type" "alu_shift_imm")]
1712 ;; zero_extend version of above
1713 (define_insn "*sub_<shift>_si_uxtw"
1714   [(set (match_operand:DI 0 "register_operand" "=r")
1715         (zero_extend:DI
1716          (minus:SI (match_operand:SI 3 "register_operand" "r")
1717                    (ASHIFT:SI
1718                     (match_operand:SI 1 "register_operand" "r")
1719                     (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1720   ""
1721   "sub\\t%w0, %w3, %w1, <shift> %2"
1722   [(set_attr "type" "alu_shift_imm")]
1725 (define_insn "*sub_mul_imm_<mode>"
1726   [(set (match_operand:GPI 0 "register_operand" "=r")
1727         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1728                    (mult:GPI
1729                     (match_operand:GPI 1 "register_operand" "r")
1730                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1731   ""
1732   "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1733   [(set_attr "type" "alu_shift_imm")]
1736 ;; zero_extend version of above
1737 (define_insn "*sub_mul_imm_si_uxtw"
1738   [(set (match_operand:DI 0 "register_operand" "=r")
1739         (zero_extend:DI
1740          (minus:SI (match_operand:SI 3 "register_operand" "r")
1741                    (mult:SI
1742                     (match_operand:SI 1 "register_operand" "r")
1743                     (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
1744   ""
1745   "sub\\t%w0, %w3, %w1, lsl %p2"
1746   [(set_attr "type" "alu_shift_imm")]
1749 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
1750   [(set (match_operand:GPI 0 "register_operand" "=rk")
1751         (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1752                    (ANY_EXTEND:GPI
1753                     (match_operand:ALLX 2 "register_operand" "r"))))]
1754   ""
1755   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1756   [(set_attr "type" "alu_ext")]
1759 ;; zero_extend version of above
1760 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
1761   [(set (match_operand:DI 0 "register_operand" "=rk")
1762         (zero_extend:DI
1763          (minus:SI (match_operand:SI 1 "register_operand" "r")
1764                    (ANY_EXTEND:SI
1765                     (match_operand:SHORT 2 "register_operand" "r")))))]
1766   ""
1767   "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
1768   [(set_attr "type" "alu_ext")]
1771 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
1772   [(set (match_operand:GPI 0 "register_operand" "=rk")
1773         (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1774                    (ashift:GPI (ANY_EXTEND:GPI
1775                                 (match_operand:ALLX 2 "register_operand" "r"))
1776                                (match_operand 3 "aarch64_imm3" "Ui3"))))]
1777   ""
1778   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1779   [(set_attr "type" "alu_ext")]
1782 ;; zero_extend version of above
1783 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
1784   [(set (match_operand:DI 0 "register_operand" "=rk")
1785         (zero_extend:DI
1786          (minus:SI (match_operand:SI 1 "register_operand" "r")
1787                    (ashift:SI (ANY_EXTEND:SI
1788                                (match_operand:SHORT 2 "register_operand" "r"))
1789                               (match_operand 3 "aarch64_imm3" "Ui3")))))]
1790   ""
1791   "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
1792   [(set_attr "type" "alu_ext")]
1795 (define_insn "*sub_<optab><mode>_multp2"
1796   [(set (match_operand:GPI 0 "register_operand" "=rk")
1797         (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1798                    (ANY_EXTRACT:GPI
1799                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1800                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1801                     (match_operand 3 "const_int_operand" "n")
1802                     (const_int 0))))]
1803   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1804   "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1805   [(set_attr "type" "alu_ext")]
1808 ;; zero_extend version of above
1809 (define_insn "*sub_<optab>si_multp2_uxtw"
1810   [(set (match_operand:DI 0 "register_operand" "=rk")
1811         (zero_extend:DI
1812          (minus:SI (match_operand:SI 4 "register_operand" "r")
1813                    (ANY_EXTRACT:SI
1814                     (mult:SI (match_operand:SI 1 "register_operand" "r")
1815                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1816                     (match_operand 3 "const_int_operand" "n")
1817                     (const_int 0)))))]
1818   "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1819   "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1820   [(set_attr "type" "alu_ext")]
1823 (define_insn "sub<mode>3_carryin"
1824   [(set
1825     (match_operand:GPI 0 "register_operand" "=r")
1826     (minus:GPI (minus:GPI
1827                 (match_operand:GPI 1 "register_operand" "r")
1828                 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
1829                (match_operand:GPI 2 "register_operand" "r")))]
1830    ""
1831    "sbc\\t%<w>0, %<w>1, %<w>2"
1832   [(set_attr "type" "adc_reg")]
1835 ;; zero_extend version of the above
1836 (define_insn "*subsi3_carryin_uxtw"
1837   [(set
1838     (match_operand:DI 0 "register_operand" "=r")
1839     (zero_extend:DI
1840      (minus:SI (minus:SI
1841                 (match_operand:SI 1 "register_operand" "r")
1842                 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
1843                (match_operand:SI 2 "register_operand" "r"))))]
1844    ""
1845    "sbc\\t%w0, %w1, %w2"
1846   [(set_attr "type" "adc_reg")]
1849 (define_insn "*sub_uxt<mode>_multp2"
1850   [(set (match_operand:GPI 0 "register_operand" "=rk")
1851         (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1852                    (and:GPI
1853                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1854                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1855                     (match_operand 3 "const_int_operand" "n"))))]
1856   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1857   "*
1858   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1859                                            INTVAL (operands[3])));
1860   return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1861   [(set_attr "type" "alu_ext")]
1864 ;; zero_extend version of above
1865 (define_insn "*sub_uxtsi_multp2_uxtw"
1866   [(set (match_operand:DI 0 "register_operand" "=rk")
1867         (zero_extend:DI
1868          (minus:SI (match_operand:SI 4 "register_operand" "r")
1869                    (and:SI
1870                     (mult:SI (match_operand:SI 1 "register_operand" "r")
1871                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1872                     (match_operand 3 "const_int_operand" "n")))))]
1873   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1874   "*
1875   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1876                                            INTVAL (operands[3])));
1877   return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
1878   [(set_attr "type" "alu_ext")]
1881 (define_insn_and_split "absdi2"
1882   [(set (match_operand:DI 0 "register_operand" "=r,w")
1883         (abs:DI (match_operand:DI 1 "register_operand" "r,w")))
1884    (clobber (match_scratch:DI 2 "=&r,X"))]
1885   ""
1886   "@
1887    #
1888    abs\\t%d0, %d1"
1889   "reload_completed
1890    && GP_REGNUM_P (REGNO (operands[0]))
1891    && GP_REGNUM_P (REGNO (operands[1]))"
1892   [(const_int 0)]
1893   {
1894     emit_insn (gen_rtx_SET (VOIDmode, operands[2],
1895                             gen_rtx_XOR (DImode,
1896                                          gen_rtx_ASHIFTRT (DImode,
1897                                                            operands[1],
1898                                                            GEN_INT (63)),
1899                                          operands[1])));
1900     emit_insn (gen_rtx_SET (VOIDmode,
1901                             operands[0],
1902                             gen_rtx_MINUS (DImode,
1903                                            operands[2],
1904                                            gen_rtx_ASHIFTRT (DImode,
1905                                                              operands[1],
1906                                                              GEN_INT (63)))));
1907     DONE;
1908   }
1909   [(set_attr "type" "alu_reg")]
1912 (define_insn "neg<mode>2"
1913   [(set (match_operand:GPI 0 "register_operand" "=r,w")
1914         (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
1915   ""
1916   "@
1917    neg\\t%<w>0, %<w>1
1918    neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
1919   [(set_attr "type" "alu_reg, neon_neg<q>")
1920    (set_attr "simd" "*,yes")]
1923 ;; zero_extend version of above
1924 (define_insn "*negsi2_uxtw"
1925   [(set (match_operand:DI 0 "register_operand" "=r")
1926         (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
1927   ""
1928   "neg\\t%w0, %w1"
1929   [(set_attr "type" "alu_reg")]
1932 (define_insn "*ngc<mode>"
1933   [(set (match_operand:GPI 0 "register_operand" "=r")
1934         (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
1935                    (match_operand:GPI 1 "register_operand" "r")))]
1936   ""
1937   "ngc\\t%<w>0, %<w>1"
1938   [(set_attr "type" "adc_reg")]
1941 (define_insn "*ngcsi_uxtw"
1942   [(set (match_operand:DI 0 "register_operand" "=r")
1943         (zero_extend:DI
1944          (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
1945                    (match_operand:SI 1 "register_operand" "r"))))]
1946   ""
1947   "ngc\\t%w0, %w1"
1948   [(set_attr "type" "adc_reg")]
1951 (define_insn "*neg<mode>2_compare0"
1952   [(set (reg:CC_NZ CC_REGNUM)
1953         (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
1954                        (const_int 0)))
1955    (set (match_operand:GPI 0 "register_operand" "=r")
1956         (neg:GPI (match_dup 1)))]
1957   ""
1958   "negs\\t%<w>0, %<w>1"
1959   [(set_attr "type" "alus_reg")]
1962 ;; zero_extend version of above
1963 (define_insn "*negsi2_compare0_uxtw"
1964   [(set (reg:CC_NZ CC_REGNUM)
1965         (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
1966                        (const_int 0)))
1967    (set (match_operand:DI 0 "register_operand" "=r")
1968         (zero_extend:DI (neg:SI (match_dup 1))))]
1969   ""
1970   "negs\\t%w0, %w1"
1971   [(set_attr "type" "alus_reg")]
1974 (define_insn "*neg_<shift><mode>3_compare0"
1975   [(set (reg:CC_NZ CC_REGNUM)
1976         (compare:CC_NZ
1977          (neg:GPI (ASHIFT:GPI
1978                    (match_operand:GPI 1 "register_operand" "r")
1979                    (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
1980          (const_int 0)))
1981    (set (match_operand:GPI 0 "register_operand" "=r")
1982         (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
1983   ""
1984   "negs\\t%<w>0, %<w>1, <shift> %2"
1985   [(set_attr "type" "alus_shift_imm")]
1988 (define_insn "*neg_<shift>_<mode>2"
1989   [(set (match_operand:GPI 0 "register_operand" "=r")
1990         (neg:GPI (ASHIFT:GPI
1991                   (match_operand:GPI 1 "register_operand" "r")
1992                   (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1993   ""
1994   "neg\\t%<w>0, %<w>1, <shift> %2"
1995   [(set_attr "type" "alu_shift_imm")]
1998 ;; zero_extend version of above
1999 (define_insn "*neg_<shift>_si2_uxtw"
2000   [(set (match_operand:DI 0 "register_operand" "=r")
2001         (zero_extend:DI
2002          (neg:SI (ASHIFT:SI
2003                   (match_operand:SI 1 "register_operand" "r")
2004                   (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2005   ""
2006   "neg\\t%w0, %w1, <shift> %2"
2007   [(set_attr "type" "alu_shift_imm")]
2010 (define_insn "*neg_mul_imm_<mode>2"
2011   [(set (match_operand:GPI 0 "register_operand" "=r")
2012         (neg:GPI (mult:GPI
2013                   (match_operand:GPI 1 "register_operand" "r")
2014                   (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2015   ""
2016   "neg\\t%<w>0, %<w>1, lsl %p2"
2017   [(set_attr "type" "alu_shift_imm")]
2020 ;; zero_extend version of above
2021 (define_insn "*neg_mul_imm_si2_uxtw"
2022   [(set (match_operand:DI 0 "register_operand" "=r")
2023         (zero_extend:DI
2024          (neg:SI (mult:SI
2025                   (match_operand:SI 1 "register_operand" "r")
2026                   (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2027   ""
2028   "neg\\t%w0, %w1, lsl %p2"
2029   [(set_attr "type" "alu_shift_imm")]
2032 (define_insn "mul<mode>3"
2033   [(set (match_operand:GPI 0 "register_operand" "=r")
2034         (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2035                   (match_operand:GPI 2 "register_operand" "r")))]
2036   ""
2037   "mul\\t%<w>0, %<w>1, %<w>2"
2038   [(set_attr "type" "mul")]
2041 ;; zero_extend version of above
2042 (define_insn "*mulsi3_uxtw"
2043   [(set (match_operand:DI 0 "register_operand" "=r")
2044         (zero_extend:DI
2045          (mult:SI (match_operand:SI 1 "register_operand" "r")
2046                   (match_operand:SI 2 "register_operand" "r"))))]
2047   ""
2048   "mul\\t%w0, %w1, %w2"
2049   [(set_attr "type" "mul")]
2052 (define_insn "madd<mode>"
2053   [(set (match_operand:GPI 0 "register_operand" "=r")
2054         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2055                             (match_operand:GPI 2 "register_operand" "r"))
2056                   (match_operand:GPI 3 "register_operand" "r")))]
2057   ""
2058   "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2059   [(set_attr "type" "mla")]
2062 ;; zero_extend version of above
2063 (define_insn "*maddsi_uxtw"
2064   [(set (match_operand:DI 0 "register_operand" "=r")
2065         (zero_extend:DI
2066          (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2067                            (match_operand:SI 2 "register_operand" "r"))
2068                   (match_operand:SI 3 "register_operand" "r"))))]
2069   ""
2070   "madd\\t%w0, %w1, %w2, %w3"
2071   [(set_attr "type" "mla")]
2074 (define_insn "*msub<mode>"
2075   [(set (match_operand:GPI 0 "register_operand" "=r")
2076         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2077                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2078                              (match_operand:GPI 2 "register_operand" "r"))))]
2080   ""
2081   "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2082   [(set_attr "type" "mla")]
2085 ;; zero_extend version of above
2086 (define_insn "*msubsi_uxtw"
2087   [(set (match_operand:DI 0 "register_operand" "=r")
2088         (zero_extend:DI
2089          (minus:SI (match_operand:SI 3 "register_operand" "r")
2090                    (mult:SI (match_operand:SI 1 "register_operand" "r")
2091                             (match_operand:SI 2 "register_operand" "r")))))]
2093   ""
2094   "msub\\t%w0, %w1, %w2, %w3"
2095   [(set_attr "type" "mla")]
2098 (define_insn "*mul<mode>_neg"
2099   [(set (match_operand:GPI 0 "register_operand" "=r")
2100         (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2101                   (match_operand:GPI 2 "register_operand" "r")))]
2103   ""
2104   "mneg\\t%<w>0, %<w>1, %<w>2"
2105   [(set_attr "type" "mul")]
2108 ;; zero_extend version of above
2109 (define_insn "*mulsi_neg_uxtw"
2110   [(set (match_operand:DI 0 "register_operand" "=r")
2111         (zero_extend:DI
2112          (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2113                   (match_operand:SI 2 "register_operand" "r"))))]
2115   ""
2116   "mneg\\t%w0, %w1, %w2"
2117   [(set_attr "type" "mul")]
2120 (define_insn "<su_optab>mulsidi3"
2121   [(set (match_operand:DI 0 "register_operand" "=r")
2122         (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2123                  (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2124   ""
2125   "<su>mull\\t%0, %w1, %w2"
2126   [(set_attr "type" "<su>mull")]
2129 (define_insn "<su_optab>maddsidi4"
2130   [(set (match_operand:DI 0 "register_operand" "=r")
2131         (plus:DI (mult:DI
2132                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2133                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2134                  (match_operand:DI 3 "register_operand" "r")))]
2135   ""
2136   "<su>maddl\\t%0, %w1, %w2, %3"
2137   [(set_attr "type" "<su>mlal")]
2140 (define_insn "<su_optab>msubsidi4"
2141   [(set (match_operand:DI 0 "register_operand" "=r")
2142         (minus:DI
2143          (match_operand:DI 3 "register_operand" "r")
2144          (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2145                   (ANY_EXTEND:DI
2146                    (match_operand:SI 2 "register_operand" "r")))))]
2147   ""
2148   "<su>msubl\\t%0, %w1, %w2, %3"
2149   [(set_attr "type" "<su>mlal")]
2152 (define_insn "*<su_optab>mulsidi_neg"
2153   [(set (match_operand:DI 0 "register_operand" "=r")
2154         (mult:DI (neg:DI
2155                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2156                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2157   ""
2158   "<su>mnegl\\t%0, %w1, %w2"
2159   [(set_attr "type" "<su>mull")]
2162 (define_expand "<su_optab>mulditi3"
2163   [(set (match_operand:TI 0 "register_operand")
2164         (mult:TI (ANY_EXTEND:TI (match_operand:DI 1 "register_operand"))
2165                  (ANY_EXTEND:TI (match_operand:DI 2 "register_operand"))))]
2166   ""
2168   rtx low = gen_reg_rtx (DImode);
2169   emit_insn (gen_muldi3 (low, operands[1], operands[2]));
2171   rtx high = gen_reg_rtx (DImode);
2172   emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2]));
2174   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2175   emit_move_insn (gen_highpart (DImode, operands[0]), high);
2176   DONE;
2179 ;; The default expansion of multi3 using umuldi3_highpart will perform
2180 ;; the additions in an order that fails to combine into two madd insns.
2181 (define_expand "multi3"
2182   [(set (match_operand:TI 0 "register_operand")
2183         (mult:TI (match_operand:TI 1 "register_operand")
2184                  (match_operand:TI 2 "register_operand")))]
2185   ""
2187   rtx l0 = gen_reg_rtx (DImode);
2188   rtx l1 = gen_lowpart (DImode, operands[1]);
2189   rtx l2 = gen_lowpart (DImode, operands[2]);
2190   rtx h0 = gen_reg_rtx (DImode);
2191   rtx h1 = gen_highpart (DImode, operands[1]);
2192   rtx h2 = gen_highpart (DImode, operands[2]);
2194   emit_insn (gen_muldi3 (l0, l1, l2));
2195   emit_insn (gen_umuldi3_highpart (h0, l1, l2));
2196   emit_insn (gen_madddi (h0, h1, l2, h0));
2197   emit_insn (gen_madddi (h0, l1, h2, h0));
2199   emit_move_insn (gen_lowpart (DImode, operands[0]), l0);
2200   emit_move_insn (gen_highpart (DImode, operands[0]), h0);
2201   DONE;
2204 (define_insn "<su>muldi3_highpart"
2205   [(set (match_operand:DI 0 "register_operand" "=r")
2206         (truncate:DI
2207          (lshiftrt:TI
2208           (mult:TI
2209            (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2210            (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2211           (const_int 64))))]
2212   ""
2213   "<su>mulh\\t%0, %1, %2"
2214   [(set_attr "type" "<su>mull")]
2217 (define_insn "<su_optab>div<mode>3"
2218   [(set (match_operand:GPI 0 "register_operand" "=r")
2219         (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2220                      (match_operand:GPI 2 "register_operand" "r")))]
2221   ""
2222   "<su>div\\t%<w>0, %<w>1, %<w>2"
2223   [(set_attr "type" "<su>div")]
2226 ;; zero_extend version of above
2227 (define_insn "*<su_optab>divsi3_uxtw"
2228   [(set (match_operand:DI 0 "register_operand" "=r")
2229         (zero_extend:DI
2230          (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2231                      (match_operand:SI 2 "register_operand" "r"))))]
2232   ""
2233   "<su>div\\t%w0, %w1, %w2"
2234   [(set_attr "type" "<su>div")]
2237 ;; -------------------------------------------------------------------
2238 ;; Comparison insns
2239 ;; -------------------------------------------------------------------
2241 (define_insn "*cmp<mode>"
2242   [(set (reg:CC CC_REGNUM)
2243         (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2244                     (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2245   ""
2246   "@
2247    cmp\\t%<w>0, %<w>1
2248    cmp\\t%<w>0, %<w>1
2249    cmn\\t%<w>0, #%n1"
2250   [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
2253 (define_insn "*cmp<mode>"
2254   [(set (reg:CCFP CC_REGNUM)
2255         (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2256                       (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2257    "TARGET_FLOAT"
2258    "@
2259     fcmp\\t%<s>0, #0.0
2260     fcmp\\t%<s>0, %<s>1"
2261   [(set_attr "type" "fcmp<s>")]
2264 (define_insn "*cmpe<mode>"
2265   [(set (reg:CCFPE CC_REGNUM)
2266         (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2267                        (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2268    "TARGET_FLOAT"
2269    "@
2270     fcmpe\\t%<s>0, #0.0
2271     fcmpe\\t%<s>0, %<s>1"
2272   [(set_attr "type" "fcmp<s>")]
2275 (define_insn "*cmp_swp_<shift>_reg<mode>"
2276   [(set (reg:CC_SWP CC_REGNUM)
2277         (compare:CC_SWP (ASHIFT:GPI
2278                          (match_operand:GPI 0 "register_operand" "r")
2279                          (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2280                         (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2281   ""
2282   "cmp\\t%<w>2, %<w>0, <shift> %1"
2283   [(set_attr "type" "alus_shift_imm")]
2286 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2287   [(set (reg:CC_SWP CC_REGNUM)
2288         (compare:CC_SWP (ANY_EXTEND:GPI
2289                          (match_operand:ALLX 0 "register_operand" "r"))
2290                         (match_operand:GPI 1 "register_operand" "r")))]
2291   ""
2292   "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2293   [(set_attr "type" "alus_ext")]
2296 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2297   [(set (reg:CC_SWP CC_REGNUM)
2298         (compare:CC_SWP (ashift:GPI
2299                          (ANY_EXTEND:GPI
2300                           (match_operand:ALLX 0 "register_operand" "r"))
2301                          (match_operand 1 "aarch64_imm3" "Ui3"))
2302         (match_operand:GPI 2 "register_operand" "r")))]
2303   ""
2304   "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2305   [(set_attr "type" "alus_ext")]
2308 ;; -------------------------------------------------------------------
2309 ;; Store-flag and conditional select insns
2310 ;; -------------------------------------------------------------------
2312 (define_expand "cstore<mode>4"
2313   [(set (match_operand:SI 0 "register_operand" "")
2314         (match_operator:SI 1 "aarch64_comparison_operator"
2315          [(match_operand:GPI 2 "register_operand" "")
2316           (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2317   ""
2318   "
2319   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2320                                       operands[3]);
2321   operands[3] = const0_rtx;
2322   "
2325 (define_expand "cstore<mode>4"
2326   [(set (match_operand:SI 0 "register_operand" "")
2327         (match_operator:SI 1 "aarch64_comparison_operator"
2328          [(match_operand:GPF 2 "register_operand" "")
2329           (match_operand:GPF 3 "register_operand" "")]))]
2330   ""
2331   "
2332   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2333                                       operands[3]);
2334   operands[3] = const0_rtx;
2335   "
2338 (define_insn "*cstore<mode>_insn"
2339   [(set (match_operand:ALLI 0 "register_operand" "=r")
2340         (match_operator:ALLI 1 "aarch64_comparison_operator"
2341          [(match_operand 2 "cc_register" "") (const_int 0)]))]
2342   ""
2343   "cset\\t%<w>0, %m1"
2344   [(set_attr "type" "csel")]
2347 ;; zero_extend version of the above
2348 (define_insn "*cstoresi_insn_uxtw"
2349   [(set (match_operand:DI 0 "register_operand" "=r")
2350         (zero_extend:DI
2351          (match_operator:SI 1 "aarch64_comparison_operator"
2352           [(match_operand 2 "cc_register" "") (const_int 0)])))]
2353   ""
2354   "cset\\t%w0, %m1"
2355   [(set_attr "type" "csel")]
2358 (define_insn "cstore<mode>_neg"
2359   [(set (match_operand:ALLI 0 "register_operand" "=r")
2360         (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2361                   [(match_operand 2 "cc_register" "") (const_int 0)])))]
2362   ""
2363   "csetm\\t%<w>0, %m1"
2364   [(set_attr "type" "csel")]
2367 ;; zero_extend version of the above
2368 (define_insn "*cstoresi_neg_uxtw"
2369   [(set (match_operand:DI 0 "register_operand" "=r")
2370         (zero_extend:DI
2371          (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2372                   [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2373   ""
2374   "csetm\\t%w0, %m1"
2375   [(set_attr "type" "csel")]
2378 (define_expand "cmov<mode>6"
2379   [(set (match_operand:GPI 0 "register_operand" "")
2380         (if_then_else:GPI
2381          (match_operator 1 "aarch64_comparison_operator"
2382           [(match_operand:GPI 2 "register_operand" "")
2383            (match_operand:GPI 3 "aarch64_plus_operand" "")])
2384          (match_operand:GPI 4 "register_operand" "")
2385          (match_operand:GPI 5 "register_operand" "")))]
2386   ""
2387   "
2388   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2389                                       operands[3]);
2390   operands[3] = const0_rtx;
2391   "
2394 (define_expand "cmov<mode>6"
2395   [(set (match_operand:GPF 0 "register_operand" "")
2396         (if_then_else:GPF
2397          (match_operator 1 "aarch64_comparison_operator"
2398           [(match_operand:GPF 2 "register_operand" "")
2399            (match_operand:GPF 3 "register_operand" "")])
2400          (match_operand:GPF 4 "register_operand" "")
2401          (match_operand:GPF 5 "register_operand" "")))]
2402   ""
2403   "
2404   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2405                                       operands[3]);
2406   operands[3] = const0_rtx;
2407   "
2410 (define_insn "*cmov<mode>_insn"
2411   [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2412         (if_then_else:ALLI
2413          (match_operator 1 "aarch64_comparison_operator"
2414           [(match_operand 2 "cc_register" "") (const_int 0)])
2415          (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2416          (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2417   "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2418      || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2419   ;; Final two alternatives should be unreachable, but included for completeness
2420   "@
2421    csel\\t%<w>0, %<w>3, %<w>4, %m1
2422    csinv\\t%<w>0, %<w>3, <w>zr, %m1
2423    csinv\\t%<w>0, %<w>4, <w>zr, %M1
2424    csinc\\t%<w>0, %<w>3, <w>zr, %m1
2425    csinc\\t%<w>0, %<w>4, <w>zr, %M1
2426    mov\\t%<w>0, -1
2427    mov\\t%<w>0, 1"
2428   [(set_attr "type" "csel")]
2431 ;; zero_extend version of above
2432 (define_insn "*cmovsi_insn_uxtw"
2433   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2434         (zero_extend:DI
2435          (if_then_else:SI
2436           (match_operator 1 "aarch64_comparison_operator"
2437            [(match_operand 2 "cc_register" "") (const_int 0)])
2438           (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2439           (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2440   "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2441      || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2442   ;; Final two alternatives should be unreachable, but included for completeness
2443   "@
2444    csel\\t%w0, %w3, %w4, %m1
2445    csinv\\t%w0, %w3, wzr, %m1
2446    csinv\\t%w0, %w4, wzr, %M1
2447    csinc\\t%w0, %w3, wzr, %m1
2448    csinc\\t%w0, %w4, wzr, %M1
2449    mov\\t%w0, -1
2450    mov\\t%w0, 1"
2451   [(set_attr "type" "csel")]
2454 (define_insn "*cmov<mode>_insn"
2455   [(set (match_operand:GPF 0 "register_operand" "=w")
2456         (if_then_else:GPF
2457          (match_operator 1 "aarch64_comparison_operator"
2458           [(match_operand 2 "cc_register" "") (const_int 0)])
2459          (match_operand:GPF 3 "register_operand" "w")
2460          (match_operand:GPF 4 "register_operand" "w")))]
2461   "TARGET_FLOAT"
2462   "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2463   [(set_attr "type" "fcsel")]
2466 (define_expand "mov<mode>cc"
2467   [(set (match_operand:ALLI 0 "register_operand" "")
2468         (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2469                            (match_operand:ALLI 2 "register_operand" "")
2470                            (match_operand:ALLI 3 "register_operand" "")))]
2471   ""
2472   {
2473     rtx ccreg;
2474     enum rtx_code code = GET_CODE (operands[1]);
2476     if (code == UNEQ || code == LTGT)
2477       FAIL;
2479     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2480                                   XEXP (operands[1], 1));
2481     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2482   }
2485 (define_expand "mov<GPF:mode><GPI:mode>cc"
2486   [(set (match_operand:GPI 0 "register_operand" "")
2487         (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2488                           (match_operand:GPF 2 "register_operand" "")
2489                           (match_operand:GPF 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<mode>cc"
2505   [(set (match_operand:GPF 0 "register_operand" "")
2506         (if_then_else:GPF (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   }
2524 ;; CRC32 instructions.
2525 (define_insn "aarch64_<crc_variant>"
2526   [(set (match_operand:SI 0 "register_operand" "=r")
2527         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2528                     (match_operand:<crc_mode> 2 "register_operand" "r")]
2529          CRC))]
2530   "TARGET_CRC32"
2531   {
2532     if (GET_MODE_BITSIZE (GET_MODE (operands[2])) >= 64)
2533       return "<crc_variant>\\t%w0, %w1, %x2";
2534     else
2535       return "<crc_variant>\\t%w0, %w1, %w2";
2536   }
2537   [(set_attr "type" "crc")]
2540 (define_insn "*csinc2<mode>_insn"
2541   [(set (match_operand:GPI 0 "register_operand" "=r")
2542         (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator"
2543                   [(match_operand:CC 3 "cc_register" "") (const_int 0)])
2544                  (match_operand:GPI 1 "register_operand" "r")))]
2545   ""
2546   "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2547   [(set_attr "type" "csel")]
2550 (define_insn "csinc3<mode>_insn"
2551   [(set (match_operand:GPI 0 "register_operand" "=r")
2552         (if_then_else:GPI
2553           (match_operator:GPI 1 "aarch64_comparison_operator"
2554            [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2555           (plus:GPI (match_operand:GPI 3 "register_operand" "r")
2556                     (const_int 1))
2557           (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2558   ""
2559   "csinc\\t%<w>0, %<w>4, %<w>3, %M1"
2560   [(set_attr "type" "csel")]
2563 (define_insn "*csinv3<mode>_insn"
2564   [(set (match_operand:GPI 0 "register_operand" "=r")
2565         (if_then_else:GPI
2566           (match_operator:GPI 1 "aarch64_comparison_operator"
2567            [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2568           (not:GPI (match_operand:GPI 3 "register_operand" "r"))
2569           (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2570   ""
2571   "csinv\\t%<w>0, %<w>4, %<w>3, %M1"
2572   [(set_attr "type" "csel")]
2575 (define_insn "*csneg3<mode>_insn"
2576   [(set (match_operand:GPI 0 "register_operand" "=r")
2577         (if_then_else:GPI
2578           (match_operator:GPI 1 "aarch64_comparison_operator"
2579            [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2580           (neg:GPI (match_operand:GPI 3 "register_operand" "r"))
2581           (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2582   ""
2583   "csneg\\t%<w>0, %<w>4, %<w>3, %M1"
2584   [(set_attr "type" "csel")]
2587 ;; -------------------------------------------------------------------
2588 ;; Logical operations
2589 ;; -------------------------------------------------------------------
2591 (define_insn "<optab><mode>3"
2592   [(set (match_operand:GPI 0 "register_operand" "=r,rk")
2593         (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2594                      (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
2595   ""
2596   "<logical>\\t%<w>0, %<w>1, %<w>2"
2597   [(set_attr "type" "logic_reg,logic_imm")]
2600 ;; zero_extend version of above
2601 (define_insn "*<optab>si3_uxtw"
2602   [(set (match_operand:DI 0 "register_operand" "=r,rk")
2603         (zero_extend:DI
2604          (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2605                      (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2606   ""
2607   "<logical>\\t%w0, %w1, %w2"
2608   [(set_attr "type" "logic_reg,logic_imm")]
2611 (define_insn "*and<mode>3_compare0"
2612   [(set (reg:CC_NZ CC_REGNUM)
2613         (compare:CC_NZ
2614          (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2615                   (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2616          (const_int 0)))
2617    (set (match_operand:GPI 0 "register_operand" "=r,r")
2618         (and:GPI (match_dup 1) (match_dup 2)))]
2619   ""
2620   "ands\\t%<w>0, %<w>1, %<w>2"
2621   [(set_attr "type" "logics_reg,logics_imm")]
2624 ;; zero_extend version of above
2625 (define_insn "*andsi3_compare0_uxtw"
2626   [(set (reg:CC_NZ CC_REGNUM)
2627         (compare:CC_NZ
2628          (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2629                  (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2630          (const_int 0)))
2631    (set (match_operand:DI 0 "register_operand" "=r,r")
2632         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2633   ""
2634   "ands\\t%w0, %w1, %w2"
2635   [(set_attr "type" "logics_reg,logics_imm")]
2638 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2639   [(set (reg:CC_NZ CC_REGNUM)
2640         (compare:CC_NZ
2641          (and:GPI (SHIFT:GPI
2642                    (match_operand:GPI 1 "register_operand" "r")
2643                    (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2644                   (match_operand:GPI 3 "register_operand" "r"))
2645          (const_int 0)))
2646    (set (match_operand:GPI 0 "register_operand" "=r")
2647         (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2648   ""
2649   "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2650   [(set_attr "type" "logics_shift_imm")]
2653 ;; zero_extend version of above
2654 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2655   [(set (reg:CC_NZ CC_REGNUM)
2656         (compare:CC_NZ
2657          (and:SI (SHIFT:SI
2658                   (match_operand:SI 1 "register_operand" "r")
2659                   (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2660                  (match_operand:SI 3 "register_operand" "r"))
2661          (const_int 0)))
2662    (set (match_operand:DI 0 "register_operand" "=r")
2663         (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2664                                 (match_dup 3))))]
2665   ""
2666   "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2667   [(set_attr "type" "logics_shift_imm")]
2670 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2671   [(set (match_operand:GPI 0 "register_operand" "=r")
2672         (LOGICAL:GPI (SHIFT:GPI
2673                       (match_operand:GPI 1 "register_operand" "r")
2674                       (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2675                      (match_operand:GPI 3 "register_operand" "r")))]
2676   ""
2677   "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2678   [(set_attr "type" "logic_shift_imm")]
2681 (define_insn "*<optab>_rol<mode>3"
2682   [(set (match_operand:GPI 0 "register_operand" "=r")
2683         (LOGICAL:GPI (rotate:GPI
2684                       (match_operand:GPI 1 "register_operand" "r")
2685                       (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2686                      (match_operand:GPI 3 "register_operand" "r")))]
2687   ""
2688   "<logical>\\t%<w>0, %<w>3, %<w>1, ror (<sizen> - %2)"
2689   [(set_attr "type" "logic_shift_imm")]
2692 ;; zero_extend versions of above
2693 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
2694   [(set (match_operand:DI 0 "register_operand" "=r")
2695         (zero_extend:DI
2696          (LOGICAL:SI (SHIFT:SI
2697                       (match_operand:SI 1 "register_operand" "r")
2698                       (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2699                      (match_operand:SI 3 "register_operand" "r"))))]
2700   ""
2701   "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2702   [(set_attr "type" "logic_shift_imm")]
2705 (define_insn "*<optab>_rolsi3_uxtw"
2706   [(set (match_operand:DI 0 "register_operand" "=r")
2707         (zero_extend:DI
2708          (LOGICAL:SI (rotate:SI
2709                       (match_operand:SI 1 "register_operand" "r")
2710                       (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2711                      (match_operand:SI 3 "register_operand" "r"))))]
2712   ""
2713   "<logical>\\t%w0, %w3, %w1, ror (32 - %2)"
2714   [(set_attr "type" "logic_shift_imm")]
2717 (define_insn "one_cmpl<mode>2"
2718   [(set (match_operand:GPI 0 "register_operand" "=r")
2719         (not:GPI (match_operand:GPI 1 "register_operand" "r")))]
2720   ""
2721   "mvn\\t%<w>0, %<w>1"
2722   [(set_attr "type" "logic_reg")]
2725 (define_insn "*one_cmpl_<optab><mode>2"
2726   [(set (match_operand:GPI 0 "register_operand" "=r")
2727         (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
2728                             (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2729   ""
2730   "mvn\\t%<w>0, %<w>1, <shift> %2"
2731   [(set_attr "type" "logic_shift_imm")]
2734 (define_insn "*<LOGICAL:optab>_one_cmpl<mode>3"
2735   [(set (match_operand:GPI 0 "register_operand" "=r")
2736         (LOGICAL:GPI (not:GPI
2737                       (match_operand:GPI 1 "register_operand" "r"))
2738                      (match_operand:GPI 2 "register_operand" "r")))]
2739   ""
2740   "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1"
2741   [(set_attr "type" "logic_reg")]
2744 (define_insn "*and_one_cmpl<mode>3_compare0"
2745   [(set (reg:CC_NZ CC_REGNUM)
2746         (compare:CC_NZ
2747          (and:GPI (not:GPI
2748                    (match_operand:GPI 1 "register_operand" "r"))
2749                   (match_operand:GPI 2 "register_operand" "r"))
2750          (const_int 0)))
2751    (set (match_operand:GPI 0 "register_operand" "=r")
2752         (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
2753   ""
2754   "bics\\t%<w>0, %<w>2, %<w>1"
2755   [(set_attr "type" "logics_reg")]
2758 ;; zero_extend version of above
2759 (define_insn "*and_one_cmplsi3_compare0_uxtw"
2760   [(set (reg:CC_NZ CC_REGNUM)
2761         (compare:CC_NZ
2762          (and:SI (not:SI
2763                   (match_operand:SI 1 "register_operand" "r"))
2764                  (match_operand:SI 2 "register_operand" "r"))
2765          (const_int 0)))
2766    (set (match_operand:DI 0 "register_operand" "=r")
2767         (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
2768   ""
2769   "bics\\t%w0, %w2, %w1"
2770   [(set_attr "type" "logics_reg")]
2773 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
2774   [(set (match_operand:GPI 0 "register_operand" "=r")
2775         (LOGICAL:GPI (not:GPI
2776                       (SHIFT:GPI
2777                        (match_operand:GPI 1 "register_operand" "r")
2778                        (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2779                      (match_operand:GPI 3 "register_operand" "r")))]
2780   ""
2781   "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2782   [(set_attr "type" "logics_shift_imm")]
2785 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
2786   [(set (reg:CC_NZ CC_REGNUM)
2787         (compare:CC_NZ
2788          (and:GPI (not:GPI
2789                    (SHIFT:GPI
2790                     (match_operand:GPI 1 "register_operand" "r")
2791                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2792                   (match_operand:GPI 3 "register_operand" "r"))
2793          (const_int 0)))
2794    (set (match_operand:GPI 0 "register_operand" "=r")
2795         (and:GPI (not:GPI
2796                   (SHIFT:GPI
2797                    (match_dup 1) (match_dup 2))) (match_dup 3)))]
2798   ""
2799   "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2800   [(set_attr "type" "logics_shift_imm")]
2803 ;; zero_extend version of above
2804 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
2805   [(set (reg:CC_NZ CC_REGNUM)
2806         (compare:CC_NZ
2807          (and:SI (not:SI
2808                   (SHIFT:SI
2809                    (match_operand:SI 1 "register_operand" "r")
2810                    (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
2811                  (match_operand:SI 3 "register_operand" "r"))
2812          (const_int 0)))
2813    (set (match_operand:DI 0 "register_operand" "=r")
2814         (zero_extend:DI (and:SI
2815                          (not:SI
2816                           (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
2817   ""
2818   "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2819   [(set_attr "type" "logics_shift_imm")]
2822 (define_insn "clz<mode>2"
2823   [(set (match_operand:GPI 0 "register_operand" "=r")
2824         (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
2825   ""
2826   "clz\\t%<w>0, %<w>1"
2827   [(set_attr "type" "clz")]
2830 (define_expand "ffs<mode>2"
2831   [(match_operand:GPI 0 "register_operand")
2832    (match_operand:GPI 1 "register_operand")]
2833   ""
2834   {
2835     rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
2836     rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
2838     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2839     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2840     emit_insn (gen_csinc3<mode>_insn (operands[0], x, ccreg, operands[0], const0_rtx));
2841     DONE;
2842   }
2845 (define_insn "clrsb<mode>2"
2846   [(set (match_operand:GPI 0 "register_operand" "=r")
2847         (clrsb:GPI (match_operand:GPI 1 "register_operand" "r")))]
2848   ""
2849   "cls\\t%<w>0, %<w>1"
2850   [(set_attr "type" "clz")]
2853 (define_insn "rbit<mode>2"
2854   [(set (match_operand:GPI 0 "register_operand" "=r")
2855         (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
2856   ""
2857   "rbit\\t%<w>0, %<w>1"
2858   [(set_attr "type" "rbit")]
2861 (define_expand "ctz<mode>2"
2862   [(match_operand:GPI 0 "register_operand")
2863    (match_operand:GPI 1 "register_operand")]
2864   ""
2865   {
2866     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2867     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2868     DONE;
2869   }
2872 (define_insn "*and<mode>3nr_compare0"
2873   [(set (reg:CC_NZ CC_REGNUM)
2874         (compare:CC_NZ
2875          (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
2876                   (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
2877          (const_int 0)))]
2878   ""
2879   "tst\\t%<w>0, %<w>1"
2880   [(set_attr "type" "logics_reg")]
2883 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
2884   [(set (reg:CC_NZ CC_REGNUM)
2885         (compare:CC_NZ
2886          (and:GPI (SHIFT:GPI
2887                    (match_operand:GPI 0 "register_operand" "r")
2888                    (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2889                   (match_operand:GPI 2 "register_operand" "r"))
2890         (const_int 0)))]
2891   ""
2892   "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
2893   [(set_attr "type" "logics_shift_imm")]
2896 ;; -------------------------------------------------------------------
2897 ;; Shifts
2898 ;; -------------------------------------------------------------------
2900 (define_expand "<optab><mode>3"
2901   [(set (match_operand:GPI 0 "register_operand")
2902         (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
2903                     (match_operand:QI 2 "nonmemory_operand")))]
2904   ""
2905   {
2906     if (CONST_INT_P (operands[2]))
2907       {
2908         operands[2] = GEN_INT (INTVAL (operands[2])
2909                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2911         if (operands[2] == const0_rtx)
2912           {
2913             emit_insn (gen_mov<mode> (operands[0], operands[1]));
2914             DONE;
2915           }
2916       }
2917   }
2920 (define_expand "ashl<mode>3"
2921   [(set (match_operand:SHORT 0 "register_operand")
2922         (ashift:SHORT (match_operand:SHORT 1 "register_operand")
2923                       (match_operand:QI 2 "nonmemory_operand")))]
2924   ""
2925   {
2926     if (CONST_INT_P (operands[2]))
2927       {
2928         operands[2] = GEN_INT (INTVAL (operands[2])
2929                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2931         if (operands[2] == const0_rtx)
2932           {
2933             emit_insn (gen_mov<mode> (operands[0], operands[1]));
2934             DONE;
2935           }
2936       }
2937   }
2940 (define_expand "rotr<mode>3"
2941   [(set (match_operand:GPI 0 "register_operand")
2942         (rotatert:GPI (match_operand:GPI 1 "register_operand")
2943                       (match_operand:QI 2 "nonmemory_operand")))]
2944   ""
2945   {
2946     if (CONST_INT_P (operands[2]))
2947       {
2948         operands[2] = GEN_INT (INTVAL (operands[2])
2949                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2951         if (operands[2] == const0_rtx)
2952           {
2953             emit_insn (gen_mov<mode> (operands[0], operands[1]));
2954             DONE;
2955           }
2956       }
2957   }
2960 (define_expand "rotl<mode>3"
2961   [(set (match_operand:GPI 0 "register_operand")
2962         (rotatert:GPI (match_operand:GPI 1 "register_operand")
2963                       (match_operand:QI 2 "nonmemory_operand")))]
2964   ""
2965   {
2966     /* (SZ - cnt) % SZ == -cnt % SZ */
2967     if (CONST_INT_P (operands[2]))
2968       {
2969         operands[2] = GEN_INT ((-INTVAL (operands[2]))
2970                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2971         if (operands[2] == const0_rtx)
2972           {
2973             emit_insn (gen_mov<mode> (operands[0], operands[1]));
2974             DONE;
2975           }
2976       }
2977     else
2978       operands[2] = expand_simple_unop (QImode, NEG, operands[2],
2979                                         NULL_RTX, 1);
2980   }
2983 ;; Logical left shift using SISD or Integer instruction
2984 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
2985   [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
2986         (ashift:GPI
2987           (match_operand:GPI 1 "register_operand" "w,w,r")
2988           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
2989   ""
2990   "@
2991    shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
2992    ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
2993    lsl\t%<w>0, %<w>1, %<w>2"
2994   [(set_attr "simd" "yes,yes,no")
2995    (set_attr "type" "neon_shift_imm<q>, neon_shift_reg<q>,shift_reg")]
2998 ;; Logical right shift using SISD or Integer instruction
2999 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3000   [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3001         (lshiftrt:GPI
3002           (match_operand:GPI 1 "register_operand" "w,w,r")
3003           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3004   ""
3005   "@
3006    ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3007    #
3008    lsr\t%<w>0, %<w>1, %<w>2"
3009   [(set_attr "simd" "yes,yes,no")
3010    (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")]
3013 (define_split
3014   [(set (match_operand:DI 0 "aarch64_simd_register")
3015         (lshiftrt:DI
3016            (match_operand:DI 1 "aarch64_simd_register")
3017            (match_operand:QI 2 "aarch64_simd_register")))]
3018   "TARGET_SIMD && reload_completed"
3019   [(set (match_dup 2)
3020         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3021    (set (match_dup 0)
3022         (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_USHL))]
3023   ""
3026 (define_split
3027   [(set (match_operand:SI 0 "aarch64_simd_register")
3028         (lshiftrt:SI
3029            (match_operand:SI 1 "aarch64_simd_register")
3030            (match_operand:QI 2 "aarch64_simd_register")))]
3031   "TARGET_SIMD && reload_completed"
3032   [(set (match_dup 2)
3033         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3034    (set (match_dup 0)
3035         (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_USHL_2S))]
3036   ""
3039 ;; Arithmetic right shift using SISD or Integer instruction
3040 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3041   [(set (match_operand:GPI 0 "register_operand" "=w,&w,&w,r")
3042         (ashiftrt:GPI
3043           (match_operand:GPI 1 "register_operand" "w,w,w,r")
3044           (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,0,rUs<cmode>")))]
3045   ""
3046   "@
3047    sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3048    #
3049    #
3050    asr\t%<w>0, %<w>1, %<w>2"
3051   [(set_attr "simd" "yes,yes,yes,no")
3052    (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>,shift_reg")]
3055 (define_split
3056   [(set (match_operand:DI 0 "aarch64_simd_register")
3057         (ashiftrt:DI
3058            (match_operand:DI 1 "aarch64_simd_register")
3059            (match_operand:QI 2 "aarch64_simd_register")))]
3060   "TARGET_SIMD && reload_completed"
3061   [(set (match_dup 3)
3062         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3063    (set (match_dup 0)
3064         (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_SSHL))]
3066   operands[3] = gen_lowpart (QImode, operands[0]);
3070 (define_split
3071   [(set (match_operand:SI 0 "aarch64_simd_register")
3072         (ashiftrt:SI
3073            (match_operand:SI 1 "aarch64_simd_register")
3074            (match_operand:QI 2 "aarch64_simd_register")))]
3075   "TARGET_SIMD && reload_completed"
3076   [(set (match_dup 3)
3077         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3078    (set (match_dup 0)
3079         (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_SSHL_2S))]
3081   operands[3] = gen_lowpart (QImode, operands[0]);
3085 (define_insn "*aarch64_sisd_ushl"
3086   [(set (match_operand:DI 0 "register_operand" "=w")
3087         (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3088                     (match_operand:QI 2 "register_operand" "w")]
3089                    UNSPEC_SISD_USHL))]
3090   "TARGET_SIMD"
3091   "ushl\t%d0, %d1, %d2"
3092   [(set_attr "simd" "yes")
3093    (set_attr "type" "neon_shift_reg")]
3096 (define_insn "*aarch64_ushl_2s"
3097   [(set (match_operand:SI 0 "register_operand" "=w")
3098         (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3099                     (match_operand:QI 2 "register_operand" "w")]
3100                    UNSPEC_USHL_2S))]
3101   "TARGET_SIMD"
3102   "ushl\t%0.2s, %1.2s, %2.2s"
3103   [(set_attr "simd" "yes")
3104    (set_attr "type" "neon_shift_reg")]
3107 (define_insn "*aarch64_sisd_sshl"
3108   [(set (match_operand:DI 0 "register_operand" "=w")
3109         (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3110                     (match_operand:QI 2 "register_operand" "w")]
3111                    UNSPEC_SISD_SSHL))]
3112   "TARGET_SIMD"
3113   "sshl\t%d0, %d1, %d2"
3114   [(set_attr "simd" "yes")
3115    (set_attr "type" "neon_shift_reg")]
3118 (define_insn "*aarch64_sshl_2s"
3119   [(set (match_operand:SI 0 "register_operand" "=w")
3120         (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3121                     (match_operand:QI 2 "register_operand" "w")]
3122                    UNSPEC_SSHL_2S))]
3123   "TARGET_SIMD"
3124   "sshl\t%0.2s, %1.2s, %2.2s"
3125   [(set_attr "simd" "yes")
3126    (set_attr "type" "neon_shift_reg")]
3129 (define_insn "*aarch64_sisd_neg_qi"
3130   [(set (match_operand:QI 0 "register_operand" "=w")
3131         (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3132                    UNSPEC_SISD_NEG))]
3133   "TARGET_SIMD"
3134   "neg\t%d0, %d1"
3135   [(set_attr "simd" "yes")
3136    (set_attr "type" "neon_neg")]
3139 ;; Rotate right
3140 (define_insn "*ror<mode>3_insn"
3141   [(set (match_operand:GPI 0 "register_operand" "=r")
3142         (rotatert:GPI
3143           (match_operand:GPI 1 "register_operand" "r")
3144           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3145   ""
3146   "ror\\t%<w>0, %<w>1, %<w>2"
3147   [(set_attr "type" "shift_reg")]
3150 ;; zero_extend version of above
3151 (define_insn "*<optab>si3_insn_uxtw"
3152   [(set (match_operand:DI 0 "register_operand" "=r")
3153         (zero_extend:DI (SHIFT:SI
3154          (match_operand:SI 1 "register_operand" "r")
3155          (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3156   ""
3157   "<shift>\\t%w0, %w1, %w2"
3158   [(set_attr "type" "shift_reg")]
3161 (define_insn "*ashl<mode>3_insn"
3162   [(set (match_operand:SHORT 0 "register_operand" "=r")
3163         (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3164                       (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
3165   ""
3166   "lsl\\t%<w>0, %<w>1, %<w>2"
3167   [(set_attr "type" "shift_reg")]
3170 (define_insn "*<optab><mode>3_insn"
3171   [(set (match_operand:SHORT 0 "register_operand" "=r")
3172         (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3173                       (match_operand 2 "const_int_operand" "n")))]
3174   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3176   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3177   return "<bfshift>\t%w0, %w1, %2, %3";
3179   [(set_attr "type" "bfm")]
3182 (define_insn "*extr<mode>5_insn"
3183   [(set (match_operand:GPI 0 "register_operand" "=r")
3184         (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3185                              (match_operand 3 "const_int_operand" "n"))
3186                  (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3187                                (match_operand 4 "const_int_operand" "n"))))]
3188   "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3189    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3190   "extr\\t%<w>0, %<w>1, %<w>2, %4"
3191   [(set_attr "type" "shift_imm")]
3194 ;; zero_extend version of the above
3195 (define_insn "*extrsi5_insn_uxtw"
3196   [(set (match_operand:DI 0 "register_operand" "=r")
3197         (zero_extend:DI
3198          (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3199                             (match_operand 3 "const_int_operand" "n"))
3200                  (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3201                               (match_operand 4 "const_int_operand" "n")))))]
3202   "UINTVAL (operands[3]) < 32 &&
3203    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3204   "extr\\t%w0, %w1, %w2, %4"
3205   [(set_attr "type" "shift_imm")]
3208 (define_insn "*ror<mode>3_insn"
3209   [(set (match_operand:GPI 0 "register_operand" "=r")
3210         (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3211                     (match_operand 2 "const_int_operand" "n")))]
3212   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3214   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3215   return "ror\\t%<w>0, %<w>1, %3";
3217   [(set_attr "type" "shift_imm")]
3220 ;; zero_extend version of the above
3221 (define_insn "*rorsi3_insn_uxtw"
3222   [(set (match_operand:DI 0 "register_operand" "=r")
3223         (zero_extend:DI
3224          (rotate:SI (match_operand:SI 1 "register_operand" "r")
3225                     (match_operand 2 "const_int_operand" "n"))))]
3226   "UINTVAL (operands[2]) < 32"
3228   operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3229   return "ror\\t%w0, %w1, %3";
3231   [(set_attr "type" "shift_imm")]
3234 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3235   [(set (match_operand:GPI 0 "register_operand" "=r")
3236         (ANY_EXTEND:GPI
3237          (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3238                        (match_operand 2 "const_int_operand" "n"))))]
3239   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3241   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3242   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3244   [(set_attr "type" "bfm")]
3247 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3248   [(set (match_operand:GPI 0 "register_operand" "=r")
3249         (zero_extend:GPI
3250          (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3251                          (match_operand 2 "const_int_operand" "n"))))]
3252   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3254   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3255   return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3257   [(set_attr "type" "bfm")]
3260 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3261   [(set (match_operand:GPI 0 "register_operand" "=r")
3262         (sign_extend:GPI
3263          (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3264                          (match_operand 2 "const_int_operand" "n"))))]
3265   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3267   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3268   return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3270   [(set_attr "type" "bfm")]
3273 ;; -------------------------------------------------------------------
3274 ;; Bitfields
3275 ;; -------------------------------------------------------------------
3277 (define_expand "<optab>"
3278   [(set (match_operand:DI 0 "register_operand" "=r")
3279         (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3280                         (match_operand 2 "const_int_operand" "n")
3281                         (match_operand 3 "const_int_operand" "n")))]
3282   ""
3283   ""
3286 (define_insn "*<optab><mode>"
3287   [(set (match_operand:GPI 0 "register_operand" "=r")
3288         (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3289                          (match_operand 2 "const_int_operand" "n")
3290                          (match_operand 3 "const_int_operand" "n")))]
3291   ""
3292   "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3293   [(set_attr "type" "bfm")]
3296 ;; Bitfield Insert (insv)
3297 (define_expand "insv<mode>"
3298   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3299                           (match_operand 1 "const_int_operand")
3300                           (match_operand 2 "const_int_operand"))
3301         (match_operand:GPI 3 "general_operand"))]
3302   ""
3304   unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3305   unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3306   rtx value = operands[3];
3308   if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3309     FAIL;
3311   if (CONST_INT_P (value))
3312     {
3313       unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3315       /* Prefer AND/OR for inserting all zeros or all ones.  */
3316       if ((UINTVAL (value) & mask) == 0
3317            || (UINTVAL (value) & mask) == mask)
3318         FAIL;
3320       /* 16-bit aligned 16-bit wide insert is handled by insv_imm.  */
3321       if (width == 16 && (pos % 16) == 0)
3322         DONE;
3323     }
3324   operands[3] = force_reg (<MODE>mode, value);
3327 (define_insn "*insv_reg<mode>"
3328   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3329                           (match_operand 1 "const_int_operand" "n")
3330                           (match_operand 2 "const_int_operand" "n"))
3331         (match_operand:GPI 3 "register_operand" "r"))]
3332   "!(UINTVAL (operands[1]) == 0
3333      || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3334          > GET_MODE_BITSIZE (<MODE>mode)))"
3335   "bfi\\t%<w>0, %<w>3, %2, %1"
3336   [(set_attr "type" "bfm")]
3339 (define_insn "*extr_insv_lower_reg<mode>"
3340   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3341                           (match_operand 1 "const_int_operand" "n")
3342                           (const_int 0))
3343         (zero_extract:GPI (match_operand:GPI 2 "register_operand" "+r")
3344                           (match_dup 1)
3345                           (match_operand 3 "const_int_operand" "n")))]
3346   "!(UINTVAL (operands[1]) == 0
3347      || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3348          > GET_MODE_BITSIZE (<MODE>mode)))"
3349   "bfxil\\t%<w>0, %<w>2, %3, %1"
3350   [(set_attr "type" "bfm")]
3353 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3354   [(set (match_operand:GPI 0 "register_operand" "=r")
3355         (ashift:GPI (ANY_EXTEND:GPI
3356                      (match_operand:ALLX 1 "register_operand" "r"))
3357                     (match_operand 2 "const_int_operand" "n")))]
3358   "UINTVAL (operands[2]) < <GPI:sizen>"
3360   operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3361               ? GEN_INT (<ALLX:sizen>)
3362               : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3363   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3365   [(set_attr "type" "bfm")]
3368 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3370 (define_insn "*andim_ashift<mode>_bfiz"
3371   [(set (match_operand:GPI 0 "register_operand" "=r")
3372         (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3373                              (match_operand 2 "const_int_operand" "n"))
3374                  (match_operand 3 "const_int_operand" "n")))]
3375   "exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3376    && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3377   "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3378   [(set_attr "type" "bfm")]
3381 (define_insn "bswap<mode>2"
3382   [(set (match_operand:GPI 0 "register_operand" "=r")
3383         (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3384   ""
3385   "rev\\t%<w>0, %<w>1"
3386   [(set_attr "type" "rev")]
3389 (define_insn "bswaphi2"
3390   [(set (match_operand:HI 0 "register_operand" "=r")
3391         (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3392   ""
3393   "rev16\\t%w0, %w1"
3394   [(set_attr "type" "rev")]
3397 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
3398 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
3399 ;; each valid permutation.
3401 (define_insn "rev16<mode>2"
3402   [(set (match_operand:GPI 0 "register_operand" "=r")
3403         (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3404                                       (const_int 8))
3405                           (match_operand:GPI 3 "const_int_operand" "n"))
3406                  (and:GPI (lshiftrt:GPI (match_dup 1)
3407                                         (const_int 8))
3408                           (match_operand:GPI 2 "const_int_operand" "n"))))]
3409   "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3410    && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3411   "rev16\\t%<w>0, %<w>1"
3412   [(set_attr "type" "rev")]
3415 (define_insn "rev16<mode>2_alt"
3416   [(set (match_operand:GPI 0 "register_operand" "=r")
3417         (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r")
3418                                         (const_int 8))
3419                           (match_operand:GPI 2 "const_int_operand" "n"))
3420                  (and:GPI (ashift:GPI (match_dup 1)
3421                                       (const_int 8))
3422                           (match_operand:GPI 3 "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 ;; zero_extend version of above
3430 (define_insn "*bswapsi2_uxtw"
3431   [(set (match_operand:DI 0 "register_operand" "=r")
3432         (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3433   ""
3434   "rev\\t%w0, %w1"
3435   [(set_attr "type" "rev")]
3438 ;; -------------------------------------------------------------------
3439 ;; Floating-point intrinsics
3440 ;; -------------------------------------------------------------------
3442 ;; frint floating-point round to integral standard patterns.
3443 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round, frintn.
3445 (define_insn "<frint_pattern><mode>2"
3446   [(set (match_operand:GPF 0 "register_operand" "=w")
3447         (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3448          FRINT))]
3449   "TARGET_FLOAT"
3450   "frint<frint_suffix>\\t%<s>0, %<s>1"
3451   [(set_attr "type" "f_rint<s>")]
3454 ;; frcvt floating-point round to integer and convert standard patterns.
3455 ;; Expands to lbtrunc, lceil, lfloor, lround.
3456 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3457   [(set (match_operand:GPI 0 "register_operand" "=r")
3458         (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3459                       FCVT)))]
3460   "TARGET_FLOAT"
3461   "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3462   [(set_attr "type" "f_cvtf2i")]
3465 ;; fma - no throw
3467 (define_insn "fma<mode>4"
3468   [(set (match_operand:GPF 0 "register_operand" "=w")
3469         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3470                  (match_operand:GPF 2 "register_operand" "w")
3471                  (match_operand:GPF 3 "register_operand" "w")))]
3472   "TARGET_FLOAT"
3473   "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3474   [(set_attr "type" "fmac<s>")]
3477 (define_insn "fnma<mode>4"
3478   [(set (match_operand:GPF 0 "register_operand" "=w")
3479         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3480                  (match_operand:GPF 2 "register_operand" "w")
3481                  (match_operand:GPF 3 "register_operand" "w")))]
3482   "TARGET_FLOAT"
3483   "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3484   [(set_attr "type" "fmac<s>")]
3487 (define_insn "fms<mode>4"
3488   [(set (match_operand:GPF 0 "register_operand" "=w")
3489         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3490                  (match_operand:GPF 2 "register_operand" "w")
3491                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3492   "TARGET_FLOAT"
3493   "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3494   [(set_attr "type" "fmac<s>")]
3497 (define_insn "fnms<mode>4"
3498   [(set (match_operand:GPF 0 "register_operand" "=w")
3499         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3500                  (match_operand:GPF 2 "register_operand" "w")
3501                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3502   "TARGET_FLOAT"
3503   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3504   [(set_attr "type" "fmac<s>")]
3507 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3508 (define_insn "*fnmadd<mode>4"
3509   [(set (match_operand:GPF 0 "register_operand" "=w")
3510         (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3511                           (match_operand:GPF 2 "register_operand" "w")
3512                           (match_operand:GPF 3 "register_operand" "w"))))]
3513   "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3514   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3515   [(set_attr "type" "fmac<s>")]
3518 ;; -------------------------------------------------------------------
3519 ;; Floating-point conversions
3520 ;; -------------------------------------------------------------------
3522 (define_insn "extendsfdf2"
3523   [(set (match_operand:DF 0 "register_operand" "=w")
3524         (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3525   "TARGET_FLOAT"
3526   "fcvt\\t%d0, %s1"
3527   [(set_attr "type" "f_cvt")]
3530 (define_insn "truncdfsf2"
3531   [(set (match_operand:SF 0 "register_operand" "=w")
3532         (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3533   "TARGET_FLOAT"
3534   "fcvt\\t%s0, %d1"
3535   [(set_attr "type" "f_cvt")]
3538 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3539   [(set (match_operand:GPI 0 "register_operand" "=r")
3540         (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3541   "TARGET_FLOAT"
3542   "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3543   [(set_attr "type" "f_cvtf2i")]
3546 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3547   [(set (match_operand:GPI 0 "register_operand" "=r")
3548         (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3549   "TARGET_FLOAT"
3550   "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3551   [(set_attr "type" "f_cvtf2i")]
3554 (define_insn "float<GPI:mode><GPF:mode>2"
3555   [(set (match_operand:GPF 0 "register_operand" "=w")
3556         (float:GPF (match_operand:GPI 1 "register_operand" "r")))]
3557   "TARGET_FLOAT"
3558   "scvtf\\t%<GPF:s>0, %<GPI:w>1"
3559   [(set_attr "type" "f_cvti2f")]
3562 (define_insn "floatuns<GPI:mode><GPF:mode>2"
3563   [(set (match_operand:GPF 0 "register_operand" "=w")
3564         (unsigned_float:GPF (match_operand:GPI 1 "register_operand" "r")))]
3565   "TARGET_FLOAT"
3566   "ucvtf\\t%<GPF:s>0, %<GPI:w>1"
3567   [(set_attr "type" "f_cvt")]
3570 ;; -------------------------------------------------------------------
3571 ;; Floating-point arithmetic
3572 ;; -------------------------------------------------------------------
3574 (define_insn "add<mode>3"
3575   [(set (match_operand:GPF 0 "register_operand" "=w")
3576         (plus:GPF
3577          (match_operand:GPF 1 "register_operand" "w")
3578          (match_operand:GPF 2 "register_operand" "w")))]
3579   "TARGET_FLOAT"
3580   "fadd\\t%<s>0, %<s>1, %<s>2"
3581   [(set_attr "type" "fadd<s>")]
3584 (define_insn "sub<mode>3"
3585   [(set (match_operand:GPF 0 "register_operand" "=w")
3586         (minus:GPF
3587          (match_operand:GPF 1 "register_operand" "w")
3588          (match_operand:GPF 2 "register_operand" "w")))]
3589   "TARGET_FLOAT"
3590   "fsub\\t%<s>0, %<s>1, %<s>2"
3591   [(set_attr "type" "fadd<s>")]
3594 (define_insn "mul<mode>3"
3595   [(set (match_operand:GPF 0 "register_operand" "=w")
3596         (mult:GPF
3597          (match_operand:GPF 1 "register_operand" "w")
3598          (match_operand:GPF 2 "register_operand" "w")))]
3599   "TARGET_FLOAT"
3600   "fmul\\t%<s>0, %<s>1, %<s>2"
3601   [(set_attr "type" "fmul<s>")]
3604 (define_insn "*fnmul<mode>3"
3605   [(set (match_operand:GPF 0 "register_operand" "=w")
3606         (mult:GPF
3607                  (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3608                  (match_operand:GPF 2 "register_operand" "w")))]
3609   "TARGET_FLOAT"
3610   "fnmul\\t%<s>0, %<s>1, %<s>2"
3611   [(set_attr "type" "fmul<s>")]
3614 (define_insn "div<mode>3"
3615   [(set (match_operand:GPF 0 "register_operand" "=w")
3616         (div:GPF
3617          (match_operand:GPF 1 "register_operand" "w")
3618          (match_operand:GPF 2 "register_operand" "w")))]
3619   "TARGET_FLOAT"
3620   "fdiv\\t%<s>0, %<s>1, %<s>2"
3621   [(set_attr "type" "fdiv<s>")]
3624 (define_insn "neg<mode>2"
3625   [(set (match_operand:GPF 0 "register_operand" "=w")
3626         (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
3627   "TARGET_FLOAT"
3628   "fneg\\t%<s>0, %<s>1"
3629   [(set_attr "type" "ffarith<s>")]
3632 (define_insn "sqrt<mode>2"
3633   [(set (match_operand:GPF 0 "register_operand" "=w")
3634         (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
3635   "TARGET_FLOAT"
3636   "fsqrt\\t%<s>0, %<s>1"
3637   [(set_attr "type" "fsqrt<s>")]
3640 (define_insn "abs<mode>2"
3641   [(set (match_operand:GPF 0 "register_operand" "=w")
3642         (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
3643   "TARGET_FLOAT"
3644   "fabs\\t%<s>0, %<s>1"
3645   [(set_attr "type" "ffarith<s>")]
3648 ;; Given that smax/smin do not specify the result when either input is NaN,
3649 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
3650 ;; for smin.
3652 (define_insn "smax<mode>3"
3653   [(set (match_operand:GPF 0 "register_operand" "=w")
3654         (smax:GPF (match_operand:GPF 1 "register_operand" "w")
3655                   (match_operand:GPF 2 "register_operand" "w")))]
3656   "TARGET_FLOAT"
3657   "fmaxnm\\t%<s>0, %<s>1, %<s>2"
3658   [(set_attr "type" "f_minmax<s>")]
3661 (define_insn "smin<mode>3"
3662   [(set (match_operand:GPF 0 "register_operand" "=w")
3663         (smin:GPF (match_operand:GPF 1 "register_operand" "w")
3664                   (match_operand:GPF 2 "register_operand" "w")))]
3665   "TARGET_FLOAT"
3666   "fminnm\\t%<s>0, %<s>1, %<s>2"
3667   [(set_attr "type" "f_minmax<s>")]
3670 ;; -------------------------------------------------------------------
3671 ;; Reload support
3672 ;; -------------------------------------------------------------------
3674 (define_expand "aarch64_reload_mov<mode>"
3675   [(set (match_operand:TX 0 "register_operand" "=w")
3676         (match_operand:TX 1 "register_operand" "w"))
3677    (clobber (match_operand:DI 2 "register_operand" "=&r"))
3678   ]
3679   ""
3680   {
3681     rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
3682     rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
3683     gen_aarch64_movtilow_tilow (op0, op1);
3684     gen_aarch64_movdi_tihigh (operands[2], op1);
3685     gen_aarch64_movtihigh_di (op0, operands[2]);
3686     DONE;
3687   }
3690 ;; The following secondary reload helpers patterns are invoked
3691 ;; after or during reload as we don't want these patterns to start
3692 ;; kicking in during the combiner.
3694 (define_insn "aarch64_movdi_<mode>low"
3695   [(set (match_operand:DI 0 "register_operand" "=r")
3696         (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
3697   "reload_completed || reload_in_progress"
3698   "fmov\\t%x0, %d1"
3699   [(set_attr "type" "f_mrc")
3700    (set_attr "length" "4")
3701   ])
3703 (define_insn "aarch64_movdi_<mode>high"
3704   [(set (match_operand:DI 0 "register_operand" "=r")
3705         (truncate:DI
3706           (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
3707                        (const_int 64))))]
3708   "reload_completed || reload_in_progress"
3709   "fmov\\t%x0, %1.d[1]"
3710   [(set_attr "type" "f_mrc")
3711    (set_attr "length" "4")
3712   ])
3714 (define_insn "aarch64_mov<mode>high_di"
3715   [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
3716                          (const_int 64) (const_int 64))
3717         (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
3718   "reload_completed || reload_in_progress"
3719   "fmov\\t%0.d[1], %x1"
3720   [(set_attr "type" "f_mcr")
3721    (set_attr "length" "4")
3722   ])
3724 (define_insn "aarch64_mov<mode>low_di"
3725   [(set (match_operand:TX 0 "register_operand" "=w")
3726         (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
3727   "reload_completed || reload_in_progress"
3728   "fmov\\t%d0, %x1"
3729   [(set_attr "type" "f_mcr")
3730    (set_attr "length" "4")
3731   ])
3733 (define_insn "aarch64_movtilow_tilow"
3734   [(set (match_operand:TI 0 "register_operand" "=w")
3735         (zero_extend:TI 
3736           (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
3737   "reload_completed || reload_in_progress"
3738   "fmov\\t%d0, %d1"
3739   [(set_attr "type" "fmov")
3740    (set_attr "length" "4")
3741   ])
3743 ;; There is a deliberate reason why the parameters of high and lo_sum's
3744 ;; don't have modes for ADRP and ADD instructions.  This is to allow high
3745 ;; and lo_sum's to be used with the labels defining the jump tables in
3746 ;; rodata section.
3748 (define_expand "add_losym"
3749   [(set (match_operand 0 "register_operand" "=r")
3750         (lo_sum (match_operand 1 "register_operand" "r")
3751                 (match_operand 2 "aarch64_valid_symref" "S")))]
3752   ""
3754   enum machine_mode mode = GET_MODE (operands[0]);
3756   emit_insn ((mode == DImode
3757               ? gen_add_losym_di
3758               : gen_add_losym_si) (operands[0],
3759                                    operands[1],
3760                                    operands[2]));
3761   DONE;
3764 (define_insn "add_losym_<mode>"
3765   [(set (match_operand:P 0 "register_operand" "=r")
3766         (lo_sum:P (match_operand:P 1 "register_operand" "r")
3767                   (match_operand 2 "aarch64_valid_symref" "S")))]
3768   ""
3769   "add\\t%<w>0, %<w>1, :lo12:%a2"
3770   [(set_attr "type" "alu_reg")]
3773 (define_insn "ldr_got_small_<mode>"
3774   [(set (match_operand:PTR 0 "register_operand" "=r")
3775         (unspec:PTR [(mem:PTR (lo_sum:PTR
3776                               (match_operand:PTR 1 "register_operand" "r")
3777                               (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
3778                     UNSPEC_GOTSMALLPIC))]
3779   ""
3780   "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
3781   [(set_attr "type" "load1")]
3784 (define_insn "ldr_got_small_sidi"
3785   [(set (match_operand:DI 0 "register_operand" "=r")
3786         (zero_extend:DI
3787          (unspec:SI [(mem:SI (lo_sum:DI
3788                              (match_operand:DI 1 "register_operand" "r")
3789                              (match_operand:DI 2 "aarch64_valid_symref" "S")))]
3790                     UNSPEC_GOTSMALLPIC)))]
3791   "TARGET_ILP32"
3792   "ldr\\t%w0, [%1, #:got_lo12:%a2]"
3793   [(set_attr "type" "load1")]
3796 (define_insn "ldr_got_tiny"
3797   [(set (match_operand:DI 0 "register_operand" "=r")
3798         (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
3799                    UNSPEC_GOTTINYPIC))]
3800   ""
3801   "ldr\\t%0, %L1"
3802   [(set_attr "type" "load1")]
3805 (define_insn "aarch64_load_tp_hard"
3806   [(set (match_operand:DI 0 "register_operand" "=r")
3807         (unspec:DI [(const_int 0)] UNSPEC_TLS))]
3808   ""
3809   "mrs\\t%0, tpidr_el0"
3810   [(set_attr "type" "mrs")]
3813 ;; The TLS ABI specifically requires that the compiler does not schedule
3814 ;; instructions in the TLS stubs, in order to enable linker relaxation.
3815 ;; Therefore we treat the stubs as an atomic sequence.
3816 (define_expand "tlsgd_small"
3817  [(parallel [(set (match_operand 0 "register_operand" "")
3818                   (call (mem:DI (match_dup 2)) (const_int 1)))
3819              (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
3820              (clobber (reg:DI LR_REGNUM))])]
3821  ""
3823   operands[2] = aarch64_tls_get_addr ();
3826 (define_insn "*tlsgd_small"
3827   [(set (match_operand 0 "register_operand" "")
3828         (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
3829    (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
3830    (clobber (reg:DI LR_REGNUM))
3831   ]
3832   ""
3833   "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
3834   [(set_attr "type" "call")
3835    (set_attr "length" "16")])
3837 (define_insn "tlsie_small_<mode>"
3838   [(set (match_operand:PTR 0 "register_operand" "=r")
3839         (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
3840                    UNSPEC_GOTSMALLTLS))]
3841   ""
3842   "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
3843   [(set_attr "type" "load1")
3844    (set_attr "length" "8")]
3847 (define_insn "tlsie_small_sidi"
3848   [(set (match_operand:DI 0 "register_operand" "=r")
3849         (zero_extend:DI
3850           (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")]
3851                       UNSPEC_GOTSMALLTLS)))]
3852   ""
3853   "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
3854   [(set_attr "type" "load1")
3855    (set_attr "length" "8")]
3858 (define_expand "tlsle_small"
3859   [(set (match_operand 0 "register_operand" "=r")
3860         (unspec [(match_operand 1 "register_operand" "r")
3861                    (match_operand 2 "aarch64_tls_le_symref" "S")]
3862                    UNSPEC_GOTSMALLTLS))]
3863   ""
3865   enum machine_mode mode = GET_MODE (operands[0]);
3866   emit_insn ((mode == DImode
3867               ? gen_tlsle_small_di
3868               : gen_tlsle_small_si) (operands[0],
3869                                      operands[1],
3870                                      operands[2]));
3871   DONE;
3874 (define_insn "tlsle_small_<mode>"
3875   [(set (match_operand:P 0 "register_operand" "=r")
3876         (unspec:P [(match_operand:P 1 "register_operand" "r")
3877                    (match_operand 2 "aarch64_tls_le_symref" "S")]
3878                    UNSPEC_GOTSMALLTLS))]
3879   ""
3880   "add\\t%<w>0, %<w>1, #%G2\;add\\t%<w>0, %<w>0, #%L2"
3881   [(set_attr "type" "alu_reg")
3882    (set_attr "length" "8")]
3885 (define_insn "tlsdesc_small_<mode>"
3886   [(set (reg:PTR R0_REGNUM)
3887         (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
3888                    UNSPEC_TLSDESC))
3889    (clobber (reg:DI LR_REGNUM))
3890    (clobber (reg:CC CC_REGNUM))
3891    (clobber (match_scratch:DI 1 "=r"))]
3892   "TARGET_TLS_DESC"
3893   "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
3894   [(set_attr "type" "call")
3895    (set_attr "length" "16")])
3897 (define_insn "stack_tie"
3898   [(set (mem:BLK (scratch))
3899         (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
3900                      (match_operand:DI 1 "register_operand" "rk")]
3901                     UNSPEC_PRLG_STK))]
3902   ""
3903   ""
3904   [(set_attr "length" "0")]
3907 ;; Named pattern for expanding thread pointer reference.
3908 (define_expand "get_thread_pointerdi"
3909   [(match_operand:DI 0 "register_operand" "=r")]
3910   ""
3912   rtx tmp = aarch64_load_tp (operands[0]);
3913   if (tmp != operands[0])
3914     emit_move_insn (operands[0], tmp);
3915   DONE;
3918 ;; Named patterns for stack smashing protection.
3919 (define_expand "stack_protect_set"
3920   [(match_operand 0 "memory_operand")
3921    (match_operand 1 "memory_operand")]
3922   ""
3924   enum machine_mode mode = GET_MODE (operands[0]);
3926   emit_insn ((mode == DImode
3927               ? gen_stack_protect_set_di
3928               : gen_stack_protect_set_si) (operands[0], operands[1]));
3929   DONE;
3932 (define_insn "stack_protect_set_<mode>"
3933   [(set (match_operand:PTR 0 "memory_operand" "=m")
3934         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
3935          UNSPEC_SP_SET))
3936    (set (match_scratch:PTR 2 "=&r") (const_int 0))]
3937   ""
3938   "ldr\\t%<w>2, %1\;str\\t%<w>2, %0\;mov\t%<w>2,0"
3939   [(set_attr "length" "12")
3940    (set_attr "type" "multiple")])
3942 (define_expand "stack_protect_test"
3943   [(match_operand 0 "memory_operand")
3944    (match_operand 1 "memory_operand")
3945    (match_operand 2)]
3946   ""
3948   rtx result;
3949   enum machine_mode mode = GET_MODE (operands[0]);
3951   result = gen_reg_rtx(mode);
3953   emit_insn ((mode == DImode
3954               ? gen_stack_protect_test_di
3955               : gen_stack_protect_test_si) (result,
3956                                             operands[0],
3957                                             operands[1]));
3959   if (mode == DImode)
3960     emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
3961                                     result, const0_rtx, operands[2]));
3962   else
3963     emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
3964                                     result, const0_rtx, operands[2]));
3965   DONE;
3968 (define_insn "stack_protect_test_<mode>"
3969   [(set (match_operand:PTR 0 "register_operand")
3970         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
3971                      (match_operand:PTR 2 "memory_operand" "m")]
3972          UNSPEC_SP_TEST))
3973    (clobber (match_scratch:PTR 3 "=&r"))]
3974   ""
3975   "ldr\t%<w>3, %x1\;ldr\t%<w>0, %x2\;eor\t%<w>0, %<w>3, %<w>0"
3976   [(set_attr "length" "12")
3977    (set_attr "type" "multiple")])
3979 ;; Write Floating-point Control Register.
3980 (define_insn "set_fpcr"
3981   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
3982   ""
3983   "msr\\tfpcr, %0"
3984   [(set_attr "type" "mrs")])
3986 ;; Read Floating-point Control Register.
3987 (define_insn "get_fpcr"
3988   [(set (match_operand:SI 0 "register_operand" "=r")
3989         (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
3990   ""
3991   "mrs\\t%0, fpcr"
3992   [(set_attr "type" "mrs")])
3994 ;; Write Floating-point Status Register.
3995 (define_insn "set_fpsr"
3996   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
3997   ""
3998   "msr\\tfpsr, %0"
3999   [(set_attr "type" "mrs")])
4001 ;; Read Floating-point Status Register.
4002 (define_insn "get_fpsr"
4003   [(set (match_operand:SI 0 "register_operand" "=r")
4004         (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
4005   ""
4006   "mrs\\t%0, fpsr"
4007   [(set_attr "type" "mrs")])
4010 ;; AdvSIMD Stuff
4011 (include "aarch64-simd.md")
4013 ;; Atomic Operations
4014 (include "atomics.md")