[AArch64] Implement CRC32 ACLE intrinsics.
[official-gcc.git] / gcc / config / aarch64 / aarch64.md
bloba4d88878d9b86bfd5a3c1199dc21be81dea738e2
1 ;; Machine description for AArch64 architecture.
2 ;; Copyright (C) 2009-2014 Free Software Foundation, Inc.
3 ;; Contributed by ARM Ltd.
4 ;;
5 ;; This file is part of GCC.
6 ;;
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
12 ;; GCC is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 ;; General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;; Register numbers
22 (define_constants
23   [
24     (R0_REGNUM          0)
25     (R1_REGNUM          1)
26     (R2_REGNUM          2)
27     (R3_REGNUM          3)
28     (R4_REGNUM          4)
29     (R5_REGNUM          5)
30     (R6_REGNUM          6)
31     (R7_REGNUM          7)
32     (R8_REGNUM          8)
33     (R9_REGNUM          9)
34     (R10_REGNUM         10)
35     (R11_REGNUM         11)
36     (R12_REGNUM         12)
37     (R13_REGNUM         13)
38     (R14_REGNUM         14)
39     (R15_REGNUM         15)
40     (R16_REGNUM         16)
41     (IP0_REGNUM         16)
42     (R17_REGNUM         17)
43     (IP1_REGNUM         17)
44     (R18_REGNUM         18)
45     (R19_REGNUM         19)
46     (R20_REGNUM         20)
47     (R21_REGNUM         21)
48     (R22_REGNUM         22)
49     (R23_REGNUM         23)
50     (R24_REGNUM         24)
51     (R25_REGNUM         25)
52     (R26_REGNUM         26)
53     (R27_REGNUM         27)
54     (R28_REGNUM         28)
55     (R29_REGNUM         29)
56     (R30_REGNUM         30)
57     (LR_REGNUM          30)
58     (SP_REGNUM          31)
59     (V0_REGNUM          32)
60     (V15_REGNUM         47)
61     (V31_REGNUM         63)
62     (SFP_REGNUM         64)
63     (AP_REGNUM          65)
64     (CC_REGNUM          66)
65   ]
68 (define_c_enum "unspec" [
69     UNSPEC_CASESI
70     UNSPEC_CLS
71     UNSPEC_CRC32B
72     UNSPEC_CRC32CB
73     UNSPEC_CRC32CH
74     UNSPEC_CRC32CW
75     UNSPEC_CRC32CX
76     UNSPEC_CRC32H
77     UNSPEC_CRC32W
78     UNSPEC_CRC32X
79     UNSPEC_FRECPE
80     UNSPEC_FRECPS
81     UNSPEC_FRECPX
82     UNSPEC_FRINTA
83     UNSPEC_FRINTI
84     UNSPEC_FRINTM
85     UNSPEC_FRINTN
86     UNSPEC_FRINTP
87     UNSPEC_FRINTX
88     UNSPEC_FRINTZ
89     UNSPEC_GOTSMALLPIC
90     UNSPEC_GOTSMALLTLS
91     UNSPEC_GOTTINYPIC
92     UNSPEC_LD1
93     UNSPEC_LD2
94     UNSPEC_LD3
95     UNSPEC_LD4
96     UNSPEC_MB
97     UNSPEC_NOP
98     UNSPEC_PRLG_STK
99     UNSPEC_RBIT
100     UNSPEC_SISD_NEG
101     UNSPEC_SISD_SSHL
102     UNSPEC_SISD_USHL
103     UNSPEC_SSHL_2S
104     UNSPEC_SSHR64
105     UNSPEC_ST1
106     UNSPEC_ST2
107     UNSPEC_ST3
108     UNSPEC_ST4
109     UNSPEC_ST2_LANE
110     UNSPEC_ST3_LANE
111     UNSPEC_ST4_LANE
112     UNSPEC_TLS
113     UNSPEC_TLSDESC
114     UNSPEC_USHL_2S
115     UNSPEC_USHR64
116     UNSPEC_VSTRUCTDUMMY
117     UNSPEC_SP_SET
118     UNSPEC_SP_TEST
121 (define_c_enum "unspecv" [
122     UNSPECV_EH_RETURN           ; Represent EH_RETURN
123     UNSPECV_GET_FPCR            ; Represent fetch of FPCR content.
124     UNSPECV_SET_FPCR            ; Represent assign of FPCR content.
125     UNSPECV_GET_FPSR            ; Represent fetch of FPSR content.
126     UNSPECV_SET_FPSR            ; Represent assign of FPSR content.
127   ]
130 ;; If further include files are added the defintion of MD_INCLUDES
131 ;; must be updated.
133 (include "constraints.md")
134 (include "predicates.md")
135 (include "iterators.md")
137 ;; -------------------------------------------------------------------
138 ;; Instruction types and attributes
139 ;; -------------------------------------------------------------------
141 ; The "type" attribute is is included here from AArch32 backend to be able
142 ; to share pipeline descriptions.
143 (include "../arm/types.md")
145 ;; Attribute that specifies whether or not the instruction touches fp
146 ;; registers.
147 (define_attr "fp" "no,yes" (const_string "no"))
149 ;; Attribute that specifies whether or not the instruction touches simd
150 ;; registers.
151 (define_attr "simd" "no,yes" (const_string "no"))
153 (define_attr "length" ""
154   (const_int 4))
156 ;; Attribute that controls whether an alternative is enabled or not.
157 ;; Currently it is only used to disable alternatives which touch fp or simd
158 ;; registers when -mgeneral-regs-only is specified.
159 (define_attr "enabled" "no,yes"
160   (cond [(ior
161         (and (eq_attr "fp" "yes")
162              (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
163         (and (eq_attr "simd" "yes")
164              (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
165              (const_string "no")
166         ] (const_string "yes")))
168 ;; -------------------------------------------------------------------
169 ;; Pipeline descriptions and scheduling
170 ;; -------------------------------------------------------------------
172 ;; Processor types.
173 (include "aarch64-tune.md")
175 ;; True if the generic scheduling description should be used.
177 (define_attr "generic_sched" "yes,no"
178   (const (if_then_else
179           (eq_attr "tune" "cortexa53,cortexa15")
180           (const_string "no")
181           (const_string "yes"))))
183 ;; Scheduling
184 (include "../arm/cortex-a53.md")
185 (include "../arm/cortex-a15.md")
187 ;; -------------------------------------------------------------------
188 ;; Jumps and other miscellaneous insns
189 ;; -------------------------------------------------------------------
191 (define_insn "indirect_jump"
192   [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
193   ""
194   "br\\t%0"
195   [(set_attr "type" "branch")]
198 (define_insn "jump"
199   [(set (pc) (label_ref (match_operand 0 "" "")))]
200   ""
201   "b\\t%l0"
202   [(set_attr "type" "branch")]
205 (define_expand "cbranch<mode>4"
206   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
207                             [(match_operand:GPI 1 "register_operand" "")
208                              (match_operand:GPI 2 "aarch64_plus_operand" "")])
209                            (label_ref (match_operand 3 "" ""))
210                            (pc)))]
211   ""
212   "
213   operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
214                                          operands[2]);
215   operands[2] = const0_rtx;
216   "
219 (define_expand "cbranch<mode>4"
220   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
221                             [(match_operand:GPF 1 "register_operand" "")
222                              (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
223                            (label_ref (match_operand 3 "" ""))
224                            (pc)))]
225   ""
226   "
227   operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
228                                          operands[2]);
229   operands[2] = const0_rtx;
230   "
233 (define_insn "*condjump"
234   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
235                             [(match_operand 1 "cc_register" "") (const_int 0)])
236                            (label_ref (match_operand 2 "" ""))
237                            (pc)))]
238   ""
239   "b%m0\\t%l2"
240   [(set_attr "type" "branch")]
243 (define_expand "casesi"
244   [(match_operand:SI 0 "register_operand" "")   ; Index
245    (match_operand:SI 1 "const_int_operand" "")  ; Lower bound
246    (match_operand:SI 2 "const_int_operand" "")  ; Total range
247    (match_operand:DI 3 "" "")                   ; Table label
248    (match_operand:DI 4 "" "")]                  ; Out of range label
249   ""
250   {
251     if (operands[1] != const0_rtx)
252       {
253         rtx reg = gen_reg_rtx (SImode);
255         /* Canonical RTL says that if you have:
257            (minus (X) (CONST))
259            then this should be emitted as:
261            (plus (X) (-CONST))
263            The use of trunc_int_for_mode ensures that the resulting
264            constant can be represented in SImode, this is important
265            for the corner case where operand[1] is INT_MIN.  */
267         operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
269         if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
270               (operands[1], SImode))
271           operands[1] = force_reg (SImode, operands[1]);
272         emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
273         operands[0] = reg;
274       }
276     if (!aarch64_plus_operand (operands[2], SImode))
277       operands[2] = force_reg (SImode, operands[2]);
278     emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
279                                                  const0_rtx),
280                                     operands[0], operands[2], operands[4]));
282     operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
283     emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
284                                          operands[3]));
285     DONE;
286   }
289 (define_insn "casesi_dispatch"
290   [(parallel
291     [(set (pc)
292           (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
293                            (match_operand:SI 1 "register_operand" "r")]
294                         UNSPEC_CASESI)))
295      (clobber (reg:CC CC_REGNUM))
296      (clobber (match_scratch:DI 3 "=r"))
297      (clobber (match_scratch:DI 4 "=r"))
298      (use (label_ref (match_operand 2 "" "")))])]
299   ""
300   "*
301   return aarch64_output_casesi (operands);
302   "
303   [(set_attr "length" "16")
304    (set_attr "type" "branch")]
307 (define_insn "nop"
308   [(unspec[(const_int 0)] UNSPEC_NOP)]
309   ""
310   "nop"
311   [(set_attr "type" "no_insn")]
314 (define_insn "trap"
315   [(trap_if (const_int 1) (const_int 8))]
316   ""
317   "brk #1000"
318   [(set_attr "type" "trap")])
320 (define_expand "prologue"
321   [(clobber (const_int 0))]
322   ""
323   "
324   aarch64_expand_prologue ();
325   DONE;
326   "
329 (define_expand "epilogue"
330   [(clobber (const_int 0))]
331   ""
332   "
333   aarch64_expand_epilogue (false);
334   DONE;
335   "
338 (define_expand "sibcall_epilogue"
339   [(clobber (const_int 0))]
340   ""
341   "
342   aarch64_expand_epilogue (true);
343   DONE;
344   "
347 (define_insn "*do_return"
348   [(return)]
349   ""
350   "ret"
351   [(set_attr "type" "branch")]
354 (define_insn "eh_return"
355   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
356     UNSPECV_EH_RETURN)]
357   ""
358   "#"
359   [(set_attr "type" "branch")]
363 (define_split
364   [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
365     UNSPECV_EH_RETURN)]
366   "reload_completed"
367   [(set (match_dup 1) (match_dup 0))]
368   {
369     operands[1] = aarch64_final_eh_return_addr ();
370   }
373 (define_insn "*cb<optab><mode>1"
374   [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
375                                 (const_int 0))
376                            (label_ref (match_operand 1 "" ""))
377                            (pc)))]
378   ""
379   "<cbz>\\t%<w>0, %l1"
380   [(set_attr "type" "branch")]
384 (define_insn "*tb<optab><mode>1"
385   [(set (pc) (if_then_else
386               (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
387                                     (const_int 1)
388                                     (match_operand 1 "const_int_operand" "n"))
389                    (const_int 0))
390              (label_ref (match_operand 2 "" ""))
391              (pc)))
392    (clobber (match_scratch:DI 3 "=r"))]
393   ""
394   "*
395   if (get_attr_length (insn) == 8)
396     return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
397   return \"<tbz>\\t%<w>0, %1, %l2\";
398   "
399   [(set_attr "type" "branch")
400    (set (attr "length")
401         (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
402                            (lt (minus (match_dup 2) (pc)) (const_int 32764)))
403                       (const_int 4)
404                       (const_int 8)))]
407 (define_insn "*cb<optab><mode>1"
408   [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
409                                  (const_int 0))
410                            (label_ref (match_operand 1 "" ""))
411                            (pc)))
412    (clobber (match_scratch:DI 2 "=r"))]
413   ""
414   "*
415   if (get_attr_length (insn) == 8)
416     return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
417   return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
418   "
419   [(set_attr "type" "branch")
420    (set (attr "length")
421         (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
422                            (lt (minus (match_dup 1) (pc)) (const_int 32764)))
423                       (const_int 4)
424                       (const_int 8)))]
427 ;; -------------------------------------------------------------------
428 ;; Subroutine calls and sibcalls
429 ;; -------------------------------------------------------------------
431 (define_expand "call"
432   [(parallel [(call (match_operand 0 "memory_operand" "")
433                     (match_operand 1 "general_operand" ""))
434               (use (match_operand 2 "" ""))
435               (clobber (reg:DI LR_REGNUM))])]
436   ""
437   "
438   {
439     rtx callee;
441     /* In an untyped call, we can get NULL for operand 2.  */
442     if (operands[2] == NULL)
443       operands[2] = const0_rtx;
445     /* Decide if we should generate indirect calls by loading the
446        64-bit address of the callee into a register before performing
447        the branch-and-link.  */
448     callee = XEXP (operands[0], 0);
449     if (GET_CODE (callee) == SYMBOL_REF
450         ? aarch64_is_long_call_p (callee)
451         : !REG_P (callee))
452       XEXP (operands[0], 0) = force_reg (Pmode, callee);
453   }"
456 (define_insn "*call_reg"
457   [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
458          (match_operand 1 "" ""))
459    (use (match_operand 2 "" ""))
460    (clobber (reg:DI LR_REGNUM))]
461   ""
462   "blr\\t%0"
463   [(set_attr "type" "call")]
466 (define_insn "*call_symbol"
467   [(call (mem:DI (match_operand:DI 0 "" ""))
468          (match_operand 1 "" ""))
469    (use (match_operand 2 "" ""))
470    (clobber (reg:DI LR_REGNUM))]
471   "GET_CODE (operands[0]) == SYMBOL_REF
472    && !aarch64_is_long_call_p (operands[0])"
473   "bl\\t%a0"
474   [(set_attr "type" "call")]
477 (define_expand "call_value"
478   [(parallel [(set (match_operand 0 "" "")
479                    (call (match_operand 1 "memory_operand" "")
480                          (match_operand 2 "general_operand" "")))
481               (use (match_operand 3 "" ""))
482               (clobber (reg:DI LR_REGNUM))])]
483   ""
484   "
485   {
486     rtx callee;
488     /* In an untyped call, we can get NULL for operand 3.  */
489     if (operands[3] == NULL)
490       operands[3] = const0_rtx;
492     /* Decide if we should generate indirect calls by loading the
493        64-bit address of the callee into a register before performing
494        the branch-and-link.  */
495     callee = XEXP (operands[1], 0);
496     if (GET_CODE (callee) == SYMBOL_REF
497         ? aarch64_is_long_call_p (callee)
498         : !REG_P (callee))
499       XEXP (operands[1], 0) = force_reg (Pmode, callee);
500   }"
503 (define_insn "*call_value_reg"
504   [(set (match_operand 0 "" "")
505         (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
506                       (match_operand 2 "" "")))
507    (use (match_operand 3 "" ""))
508    (clobber (reg:DI LR_REGNUM))]
509   ""
510   "blr\\t%1"
511   [(set_attr "type" "call")]
515 (define_insn "*call_value_symbol"
516   [(set (match_operand 0 "" "")
517         (call (mem:DI (match_operand:DI 1 "" ""))
518               (match_operand 2 "" "")))
519    (use (match_operand 3 "" ""))
520    (clobber (reg:DI LR_REGNUM))]
521   "GET_CODE (operands[1]) == SYMBOL_REF
522    && !aarch64_is_long_call_p (operands[1])"
523   "bl\\t%a1"
524   [(set_attr "type" "call")]
527 (define_expand "sibcall"
528   [(parallel [(call (match_operand 0 "memory_operand" "")
529                     (match_operand 1 "general_operand" ""))
530               (return)
531               (use (match_operand 2 "" ""))])]
532   ""
533   {
534     if (!REG_P (XEXP (operands[0], 0))
535        && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
536      XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
538     if (operands[2] == NULL_RTX)
539       operands[2] = const0_rtx;
540   }
543 (define_expand "sibcall_value"
544   [(parallel [(set (match_operand 0 "" "")
545                    (call (match_operand 1 "memory_operand" "")
546                          (match_operand 2 "general_operand" "")))
547               (return)
548               (use (match_operand 3 "" ""))])]
549   ""
550   {
551     if (!REG_P (XEXP (operands[1], 0))
552        && (GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF))
553      XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
555     if (operands[3] == NULL_RTX)
556       operands[3] = const0_rtx;
557   }
560 (define_insn "*sibcall_insn"
561   [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucs, Usf"))
562          (match_operand 1 "" ""))
563    (return)
564    (use (match_operand 2 "" ""))]
565   "SIBLING_CALL_P (insn)"
566   "@
567    br\\t%0
568    b\\t%a0"
569   [(set_attr "type" "branch, branch")]
572 (define_insn "*sibcall_value_insn"
573   [(set (match_operand 0 "" "")
574         (call (mem:DI (match_operand 1 "aarch64_call_insn_operand" "Ucs, Usf"))
575               (match_operand 2 "" "")))
576    (return)
577    (use (match_operand 3 "" ""))]
578   "SIBLING_CALL_P (insn)"
579   "@
580    br\\t%1
581    b\\t%a1"
582   [(set_attr "type" "branch, branch")]
585 ;; Call subroutine returning any type.
587 (define_expand "untyped_call"
588   [(parallel [(call (match_operand 0 "")
589                     (const_int 0))
590               (match_operand 1 "")
591               (match_operand 2 "")])]
592   ""
594   int i;
596   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
598   for (i = 0; i < XVECLEN (operands[2], 0); i++)
599     {
600       rtx set = XVECEXP (operands[2], 0, i);
601       emit_move_insn (SET_DEST (set), SET_SRC (set));
602     }
604   /* The optimizer does not know that the call sets the function value
605      registers we stored in the result block.  We avoid problems by
606      claiming that all hard registers are used and clobbered at this
607      point.  */
608   emit_insn (gen_blockage ());
609   DONE;
612 ;; -------------------------------------------------------------------
613 ;; Moves
614 ;; -------------------------------------------------------------------
616 (define_expand "mov<mode>"
617   [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
618         (match_operand:SHORT 1 "general_operand" ""))]
619   ""
620   "
621     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
622       operands[1] = force_reg (<MODE>mode, operands[1]);
623   "
626 (define_insn "*mov<mode>_aarch64"
627   [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r,   *w,r,*w, m, m, r,*w,*w")
628         (match_operand:SHORT 1 "general_operand"      " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
629   "(register_operand (operands[0], <MODE>mode)
630     || aarch64_reg_or_zero (operands[1], <MODE>mode))"
632    switch (which_alternative)
633      {
634      case 0:
635        return "mov\t%w0, %w1";
636      case 1:
637        return "mov\t%w0, %1";
638      case 2:
639        return aarch64_output_scalar_simd_mov_immediate (operands[1],
640                                                         <MODE>mode);
641      case 3:
642        return "ldr<size>\t%w0, %1";
643      case 4:
644        return "ldr\t%<size>0, %1";
645      case 5:
646        return "str<size>\t%w1, %0";
647      case 6:
648        return "str\t%<size>1, %0";
649      case 7:
650        return "umov\t%w0, %1.<v>[0]";
651      case 8:
652        return "dup\t%0.<Vallxd>, %w1";
653      case 9:
654        return "dup\t%<Vetype>0, %1.<v>[0]";
655      default:
656        gcc_unreachable ();
657      }
659   [(set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
660                      neon_from_gp<q>,neon_from_gp<q>, neon_dup")
661    (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")]
664 (define_expand "mov<mode>"
665   [(set (match_operand:GPI 0 "nonimmediate_operand" "")
666         (match_operand:GPI 1 "general_operand" ""))]
667   ""
668   "
669     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
670       operands[1] = force_reg (<MODE>mode, operands[1]);
672     if (CONSTANT_P (operands[1]))
673       {
674         aarch64_expand_mov_immediate (operands[0], operands[1]);
675         DONE;
676       }
677   "
680 (define_insn "*movsi_aarch64"
681   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m,  m,r,r  ,*w, r,*w")
682         (match_operand:SI 1 "aarch64_mov_operand"  " r,r,k,M,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
683   "(register_operand (operands[0], SImode)
684     || aarch64_reg_or_zero (operands[1], SImode))"
685   "@
686    mov\\t%w0, %w1
687    mov\\t%w0, %w1
688    mov\\t%w0, %w1
689    mov\\t%w0, %1
690    ldr\\t%w0, %1
691    ldr\\t%s0, %1
692    str\\t%w1, %0
693    str\\t%s1, %0
694    adr\\t%x0, %a1
695    adrp\\t%x0, %A1
696    fmov\\t%s0, %w1
697    fmov\\t%w0, %s1
698    fmov\\t%s0, %s1"
699   [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
700                      adr,adr,f_mcr,f_mrc,fmov")
701    (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
704 (define_insn "*movdi_aarch64"
705   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m,  m,r,r,  *w, r,*w,w")
706         (match_operand:DI 1 "aarch64_mov_operand"  " r,r,k,N,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))]
707   "(register_operand (operands[0], DImode)
708     || aarch64_reg_or_zero (operands[1], DImode))"
709   "@
710    mov\\t%x0, %x1
711    mov\\t%0, %x1
712    mov\\t%x0, %1
713    mov\\t%x0, %1
714    ldr\\t%x0, %1
715    ldr\\t%d0, %1
716    str\\t%x1, %0
717    str\\t%d1, %0
718    adr\\t%x0, %a1
719    adrp\\t%x0, %A1
720    fmov\\t%d0, %x1
721    fmov\\t%x0, %d1
722    fmov\\t%d0, %d1
723    movi\\t%d0, %1"
724   [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
725                      adr,adr,f_mcr,f_mrc,fmov,fmov")
726    (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
727    (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
730 (define_insn "insv_imm<mode>"
731   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
732                           (const_int 16)
733                           (match_operand:GPI 1 "const_int_operand" "n"))
734         (match_operand:GPI 2 "const_int_operand" "n"))]
735   "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
736    && UINTVAL (operands[1]) % 16 == 0"
737   "movk\\t%<w>0, %X2, lsl %1"
738   [(set_attr "type" "mov_imm")]
741 (define_expand "movti"
742   [(set (match_operand:TI 0 "nonimmediate_operand" "")
743         (match_operand:TI 1 "general_operand" ""))]
744   ""
745   "
746     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
747       operands[1] = force_reg (TImode, operands[1]);
748   "
751 (define_insn "*movti_aarch64"
752   [(set (match_operand:TI 0
753          "nonimmediate_operand"  "=r, *w,r ,*w,r  ,Ump,Ump,*w,m")
754         (match_operand:TI 1
755          "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r  ,Z  , m,*w"))]
756   "(register_operand (operands[0], TImode)
757     || aarch64_reg_or_zero (operands[1], TImode))"
758   "@
759    #
760    #
761    #
762    orr\\t%0.16b, %1.16b, %1.16b
763    ldp\\t%0, %H0, %1
764    stp\\t%1, %H1, %0
765    stp\\txzr, xzr, %0
766    ldr\\t%q0, %1
767    str\\t%q1, %0"
768   [(set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \
769                              load2,store2,store2,f_loadd,f_stored")
770    (set_attr "length" "8,8,8,4,4,4,4,4,4")
771    (set_attr "simd" "*,*,*,yes,*,*,*,*,*")
772    (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
775 ;; Split a TImode register-register or register-immediate move into
776 ;; its component DImode pieces, taking care to handle overlapping
777 ;; source and dest registers.
778 (define_split
779    [(set (match_operand:TI 0 "register_operand" "")
780          (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
781   "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
782   [(const_int 0)]
784   aarch64_split_128bit_move (operands[0], operands[1]);
785   DONE;
788 (define_expand "mov<mode>"
789   [(set (match_operand:GPF 0 "nonimmediate_operand" "")
790         (match_operand:GPF 1 "general_operand" ""))]
791   ""
792   "
793     if (!TARGET_FLOAT)
794      {
795         sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
796         FAIL;
797      }
799     if (GET_CODE (operands[0]) == MEM)
800       operands[1] = force_reg (<MODE>mode, operands[1]);
801   "
804 (define_insn "*movsf_aarch64"
805   [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w  ,w,m,r,m ,r")
806         (match_operand:SF 1 "general_operand"      "?rY, w,w,Ufc,m,w,m,rY,r"))]
807   "TARGET_FLOAT && (register_operand (operands[0], SFmode)
808     || register_operand (operands[1], SFmode))"
809   "@
810    fmov\\t%s0, %w1
811    fmov\\t%w0, %s1
812    fmov\\t%s0, %s1
813    fmov\\t%s0, %1
814    ldr\\t%s0, %1
815    str\\t%s1, %0
816    ldr\\t%w0, %1
817    str\\t%w1, %0
818    mov\\t%w0, %w1"
819   [(set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
820                      f_loads,f_stores,f_loads,f_stores,mov_reg")]
823 (define_insn "*movdf_aarch64"
824   [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w  ,w,m,r,m ,r")
825         (match_operand:DF 1 "general_operand"      "?rY, w,w,Ufc,m,w,m,rY,r"))]
826   "TARGET_FLOAT && (register_operand (operands[0], DFmode)
827     || register_operand (operands[1], DFmode))"
828   "@
829    fmov\\t%d0, %x1
830    fmov\\t%x0, %d1
831    fmov\\t%d0, %d1
832    fmov\\t%d0, %1
833    ldr\\t%d0, %1
834    str\\t%d1, %0
835    ldr\\t%x0, %1
836    str\\t%x1, %0
837    mov\\t%x0, %x1"
838   [(set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
839                      f_loadd,f_stored,f_loadd,f_stored,mov_reg")]
842 (define_expand "movtf"
843   [(set (match_operand:TF 0 "nonimmediate_operand" "")
844         (match_operand:TF 1 "general_operand" ""))]
845   ""
846   "
847     if (!TARGET_FLOAT)
848      {
849         sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
850         FAIL;
851      }
853     if (GET_CODE (operands[0]) == MEM)
854       operands[1] = force_reg (TFmode, operands[1]);
855   "
858 (define_insn "*movtf_aarch64"
859   [(set (match_operand:TF 0
860          "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
861         (match_operand:TF 1
862          "general_operand"      " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
863   "TARGET_FLOAT && (register_operand (operands[0], TFmode)
864     || register_operand (operands[1], TFmode))"
865   "@
866    orr\\t%0.16b, %1.16b, %1.16b
867    #
868    #
869    #
870    movi\\t%0.2d, #0
871    fmov\\t%s0, wzr
872    ldr\\t%q0, %1
873    str\\t%q1, %0
874    ldp\\t%0, %H0, %1
875    stp\\t%1, %H1, %0"
876   [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,fconstd,fconstd,\
877                      f_loadd,f_stored,neon_load1_2reg,neon_store1_2reg")
878    (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
879    (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
880    (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
883 (define_split
884    [(set (match_operand:TF 0 "register_operand" "")
885          (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
886   "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
887   [(const_int 0)]
888   {
889     aarch64_split_128bit_move (operands[0], operands[1]);
890     DONE;
891   }
894 ;; 0 is dst
895 ;; 1 is src
896 ;; 2 is size of move in bytes
897 ;; 3 is alignment
899 (define_expand "movmemdi"
900   [(match_operand:BLK 0 "memory_operand")
901    (match_operand:BLK 1 "memory_operand")
902    (match_operand:DI 2 "immediate_operand")
903    (match_operand:DI 3 "immediate_operand")]
904    "!STRICT_ALIGNMENT"
906   if (aarch64_expand_movmem (operands))
907     DONE;
908   FAIL;
912 ;; Operands 1 and 3 are tied together by the final condition; so we allow
913 ;; fairly lax checking on the second memory operation.
914 (define_insn "load_pair<mode>"
915   [(set (match_operand:GPI 0 "register_operand" "=r")
916         (match_operand:GPI 1 "aarch64_mem_pair_operand" "Ump"))
917    (set (match_operand:GPI 2 "register_operand" "=r")
918         (match_operand:GPI 3 "memory_operand" "m"))]
919   "rtx_equal_p (XEXP (operands[3], 0),
920                 plus_constant (Pmode,
921                                XEXP (operands[1], 0),
922                                GET_MODE_SIZE (<MODE>mode)))"
923   "ldp\\t%<w>0, %<w>2, %1"
924   [(set_attr "type" "load2")]
927 ;; Operands 0 and 2 are tied together by the final condition; so we allow
928 ;; fairly lax checking on the second memory operation.
929 (define_insn "store_pair<mode>"
930   [(set (match_operand:GPI 0 "aarch64_mem_pair_operand" "=Ump")
931         (match_operand:GPI 1 "register_operand" "r"))
932    (set (match_operand:GPI 2 "memory_operand" "=m")
933         (match_operand:GPI 3 "register_operand" "r"))]
934   "rtx_equal_p (XEXP (operands[2], 0),
935                 plus_constant (Pmode,
936                                XEXP (operands[0], 0),
937                                GET_MODE_SIZE (<MODE>mode)))"
938   "stp\\t%<w>1, %<w>3, %0"
939   [(set_attr "type" "store2")]
942 ;; Operands 1 and 3 are tied together by the final condition; so we allow
943 ;; fairly lax checking on the second memory operation.
944 (define_insn "load_pair<mode>"
945   [(set (match_operand:GPF 0 "register_operand" "=w")
946         (match_operand:GPF 1 "aarch64_mem_pair_operand" "Ump"))
947    (set (match_operand:GPF 2 "register_operand" "=w")
948         (match_operand:GPF 3 "memory_operand" "m"))]
949   "rtx_equal_p (XEXP (operands[3], 0),
950                 plus_constant (Pmode,
951                                XEXP (operands[1], 0),
952                                GET_MODE_SIZE (<MODE>mode)))"
953   "ldp\\t%<w>0, %<w>2, %1"
954   [(set_attr "type" "neon_load1_2reg<q>")]
957 ;; Operands 0 and 2 are tied together by the final condition; so we allow
958 ;; fairly lax checking on the second memory operation.
959 (define_insn "store_pair<mode>"
960   [(set (match_operand:GPF 0 "aarch64_mem_pair_operand" "=Ump")
961         (match_operand:GPF 1 "register_operand" "w"))
962    (set (match_operand:GPF 2 "memory_operand" "=m")
963         (match_operand:GPF 3 "register_operand" "w"))]
964   "rtx_equal_p (XEXP (operands[2], 0),
965                 plus_constant (Pmode,
966                                XEXP (operands[0], 0),
967                                GET_MODE_SIZE (<MODE>mode)))"
968   "stp\\t%<w>1, %<w>3, %0"
969   [(set_attr "type" "neon_store1_2reg<q>")]
972 ;; Load pair with writeback.  This is primarily used in function epilogues
973 ;; when restoring [fp,lr]
974 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
975   [(parallel
976     [(set (match_operand:P 0 "register_operand" "=k")
977           (plus:P (match_operand:P 1 "register_operand" "0")
978                   (match_operand:P 4 "const_int_operand" "n")))
979      (set (match_operand:GPI 2 "register_operand" "=r")
980           (mem:GPI (plus:P (match_dup 1)
981                    (match_dup 4))))
982      (set (match_operand:GPI 3 "register_operand" "=r")
983           (mem:GPI (plus:P (match_dup 1)
984                    (match_operand:P 5 "const_int_operand" "n"))))])]
985   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
986   "ldp\\t%<w>2, %<w>3, [%1], %4"
987   [(set_attr "type" "load2")]
990 ;; Store pair with writeback.  This is primarily used in function prologues
991 ;; when saving [fp,lr]
992 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
993   [(parallel
994     [(set (match_operand:P 0 "register_operand" "=&k")
995           (plus:P (match_operand:P 1 "register_operand" "0")
996                   (match_operand:P 4 "const_int_operand" "n")))
997      (set (mem:GPI (plus:P (match_dup 0)
998                    (match_dup 4)))
999           (match_operand:GPI 2 "register_operand" "r"))
1000      (set (mem:GPI (plus:P (match_dup 0)
1001                    (match_operand:P 5 "const_int_operand" "n")))
1002           (match_operand:GPI 3 "register_operand" "r"))])]
1003   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1004   "stp\\t%<w>2, %<w>3, [%0, %4]!"
1005   [(set_attr "type" "store2")]
1008 ;; -------------------------------------------------------------------
1009 ;; Sign/Zero extension
1010 ;; -------------------------------------------------------------------
1012 (define_expand "<optab>sidi2"
1013   [(set (match_operand:DI 0 "register_operand")
1014         (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1015   ""
1018 (define_insn "*extendsidi2_aarch64"
1019   [(set (match_operand:DI 0 "register_operand" "=r,r")
1020         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1021   ""
1022   "@
1023    sxtw\t%0, %w1
1024    ldrsw\t%0, %1"
1025   [(set_attr "type" "extend,load1")]
1028 (define_insn "*zero_extendsidi2_aarch64"
1029   [(set (match_operand:DI 0 "register_operand" "=r,r")
1030         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1031   ""
1032   "@
1033    uxtw\t%0, %w1
1034    ldr\t%w0, %1"
1035   [(set_attr "type" "extend,load1")]
1038 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1039   [(set (match_operand:GPI 0 "register_operand")
1040         (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1041   ""
1044 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1045   [(set (match_operand:GPI 0 "register_operand" "=r,r")
1046         (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1047   ""
1048   "@
1049    sxt<SHORT:size>\t%<GPI:w>0, %w1
1050    ldrs<SHORT:size>\t%<GPI:w>0, %1"
1051   [(set_attr "type" "extend,load1")]
1054 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1055   [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1056         (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1057   ""
1058   "@
1059    uxt<SHORT:size>\t%<GPI:w>0, %w1
1060    ldr<SHORT:size>\t%w0, %1
1061    ldr\t%<SHORT:size>0, %1"
1062   [(set_attr "type" "extend,load1,load1")]
1065 (define_expand "<optab>qihi2"
1066   [(set (match_operand:HI 0 "register_operand")
1067         (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1068   ""
1071 (define_insn "*<optab>qihi2_aarch64"
1072   [(set (match_operand:HI 0 "register_operand" "=r,r")
1073         (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1074   ""
1075   "@
1076    <su>xtb\t%w0, %w1
1077    <ldrxt>b\t%w0, %1"
1078   [(set_attr "type" "extend,load1")]
1081 ;; -------------------------------------------------------------------
1082 ;; Simple arithmetic
1083 ;; -------------------------------------------------------------------
1085 (define_expand "add<mode>3"
1086   [(set
1087     (match_operand:GPI 0 "register_operand" "")
1088     (plus:GPI (match_operand:GPI 1 "register_operand" "")
1089               (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1090   ""
1091   "
1092   if (! aarch64_plus_operand (operands[2], VOIDmode))
1093     {
1094       rtx subtarget = ((optimize && can_create_pseudo_p ())
1095                        ? gen_reg_rtx (<MODE>mode) : operands[0]);
1096       HOST_WIDE_INT imm = INTVAL (operands[2]);
1098       if (imm < 0)
1099         imm = -(-imm & ~0xfff);
1100       else
1101         imm &= ~0xfff;
1103       emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1104       operands[1] = subtarget;
1105       operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1106     }
1107   "
1110 (define_insn "*addsi3_aarch64"
1111   [(set
1112     (match_operand:SI 0 "register_operand" "=rk,rk,rk")
1113     (plus:SI
1114      (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1115      (match_operand:SI 2 "aarch64_plus_operand" "I,r,J")))]
1116   ""
1117   "@
1118   add\\t%w0, %w1, %2
1119   add\\t%w0, %w1, %w2
1120   sub\\t%w0, %w1, #%n2"
1121   [(set_attr "type" "alu_imm,alu_reg,alu_imm")]
1124 ;; zero_extend version of above
1125 (define_insn "*addsi3_aarch64_uxtw"
1126   [(set
1127     (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1128     (zero_extend:DI
1129      (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1130               (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1131   ""
1132   "@
1133   add\\t%w0, %w1, %2
1134   add\\t%w0, %w1, %w2
1135   sub\\t%w0, %w1, #%n2"
1136   [(set_attr "type" "alu_imm,alu_reg,alu_imm")]
1139 (define_insn "*adddi3_aarch64"
1140   [(set
1141     (match_operand:DI 0 "register_operand" "=rk,rk,rk,!w")
1142     (plus:DI
1143      (match_operand:DI 1 "register_operand" "%rk,rk,rk,!w")
1144      (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,!w")))]
1145   ""
1146   "@
1147   add\\t%x0, %x1, %2
1148   add\\t%x0, %x1, %x2
1149   sub\\t%x0, %x1, #%n2
1150   add\\t%d0, %d1, %d2"
1151   [(set_attr "type" "alu_imm,alu_reg,alu_imm,alu_reg")
1152    (set_attr "simd" "*,*,*,yes")]
1155 (define_expand "addti3"
1156   [(set (match_operand:TI 0 "register_operand" "")
1157         (plus:TI (match_operand:TI 1 "register_operand" "")
1158                  (match_operand:TI 2 "register_operand" "")))]
1159   ""
1161   rtx low = gen_reg_rtx (DImode);
1162   emit_insn (gen_adddi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1163                                   gen_lowpart (DImode, operands[2])));
1165   rtx high = gen_reg_rtx (DImode);
1166   emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]),
1167                                  gen_highpart (DImode, operands[2])));
1169   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1170   emit_move_insn (gen_highpart (DImode, operands[0]), high);
1171   DONE;
1174 (define_insn "add<mode>3_compare0"
1175   [(set (reg:CC_NZ CC_REGNUM)
1176         (compare:CC_NZ
1177          (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1178                    (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1179          (const_int 0)))
1180    (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1181         (plus:GPI (match_dup 1) (match_dup 2)))]
1182   ""
1183   "@
1184   adds\\t%<w>0, %<w>1, %<w>2
1185   adds\\t%<w>0, %<w>1, %<w>2
1186   subs\\t%<w>0, %<w>1, #%n2"
1187   [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1190 ;; zero_extend version of above
1191 (define_insn "*addsi3_compare0_uxtw"
1192   [(set (reg:CC_NZ CC_REGNUM)
1193         (compare:CC_NZ
1194          (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1195                   (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1196          (const_int 0)))
1197    (set (match_operand:DI 0 "register_operand" "=r,r,r")
1198         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1199   ""
1200   "@
1201   adds\\t%w0, %w1, %w2
1202   adds\\t%w0, %w1, %w2
1203   subs\\t%w0, %w1, #%n2"
1204   [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1207 (define_insn "*adds_mul_imm_<mode>"
1208   [(set (reg:CC_NZ CC_REGNUM)
1209         (compare:CC_NZ
1210          (plus:GPI (mult:GPI
1211                     (match_operand:GPI 1 "register_operand" "r")
1212                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1213                    (match_operand:GPI 3 "register_operand" "r"))
1214          (const_int 0)))
1215    (set (match_operand:GPI 0 "register_operand" "=r")
1216         (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1217                   (match_dup 3)))]
1218   ""
1219   "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1220   [(set_attr "type" "alus_shift_imm")]
1223 (define_insn "*subs_mul_imm_<mode>"
1224   [(set (reg:CC_NZ CC_REGNUM)
1225         (compare:CC_NZ
1226          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1227                     (mult:GPI
1228                      (match_operand:GPI 2 "register_operand" "r")
1229                      (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1230          (const_int 0)))
1231    (set (match_operand:GPI 0 "register_operand" "=r")
1232         (minus:GPI (match_dup 1)
1233                    (mult:GPI (match_dup 2) (match_dup 3))))]
1234   ""
1235   "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1236   [(set_attr "type" "alus_shift_imm")]
1239 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1240   [(set (reg:CC_NZ CC_REGNUM)
1241         (compare:CC_NZ
1242          (plus:GPI
1243           (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1244           (match_operand:GPI 2 "register_operand" "r"))
1245         (const_int 0)))
1246    (set (match_operand:GPI 0 "register_operand" "=r")
1247         (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1248   ""
1249   "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1250   [(set_attr "type" "alus_ext")]
1253 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1254   [(set (reg:CC_NZ CC_REGNUM)
1255         (compare:CC_NZ
1256          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1257                     (ANY_EXTEND:GPI
1258                      (match_operand:ALLX 2 "register_operand" "r")))
1259         (const_int 0)))
1260    (set (match_operand:GPI 0 "register_operand" "=r")
1261         (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1262   ""
1263   "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1264   [(set_attr "type" "alus_ext")]
1267 (define_insn "*adds_<optab><mode>_multp2"
1268   [(set (reg:CC_NZ CC_REGNUM)
1269         (compare:CC_NZ
1270          (plus:GPI (ANY_EXTRACT:GPI
1271                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1272                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1273                     (match_operand 3 "const_int_operand" "n")
1274                     (const_int 0))
1275                    (match_operand:GPI 4 "register_operand" "r"))
1276         (const_int 0)))
1277    (set (match_operand:GPI 0 "register_operand" "=r")
1278         (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1279                                    (match_dup 3)
1280                                    (const_int 0))
1281                   (match_dup 4)))]
1282   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1283   "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1284   [(set_attr "type" "alus_ext")]
1287 (define_insn "*subs_<optab><mode>_multp2"
1288   [(set (reg:CC_NZ CC_REGNUM)
1289         (compare:CC_NZ
1290          (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1291                     (ANY_EXTRACT:GPI
1292                      (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1293                                (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1294                      (match_operand 3 "const_int_operand" "n")
1295                      (const_int 0)))
1296         (const_int 0)))
1297    (set (match_operand:GPI 0 "register_operand" "=r")
1298         (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1299                                   (mult:GPI (match_dup 1) (match_dup 2))
1300                                   (match_dup 3)
1301                                   (const_int 0))))]
1302   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1303   "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1304   [(set_attr "type" "alus_ext")]
1307 (define_insn "*add<mode>3nr_compare0"
1308   [(set (reg:CC_NZ CC_REGNUM)
1309         (compare:CC_NZ
1310          (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1311                    (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1312          (const_int 0)))]
1313   ""
1314   "@
1315   cmn\\t%<w>0, %<w>1
1316   cmn\\t%<w>0, %<w>1
1317   cmp\\t%<w>0, #%n1"
1318   [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1321 (define_insn "*compare_neg<mode>"
1322   [(set (reg:CC_Z CC_REGNUM)
1323         (compare:CC_Z
1324          (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1325          (match_operand:GPI 1 "register_operand" "r")))]
1326   ""
1327   "cmn\\t%<w>1, %<w>0"
1328   [(set_attr "type" "alus_reg")]
1331 (define_insn "*add_<shift>_<mode>"
1332   [(set (match_operand:GPI 0 "register_operand" "=r")
1333         (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1334                               (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1335                   (match_operand:GPI 3 "register_operand" "r")))]
1336   ""
1337   "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1338   [(set_attr "type" "alu_shift_imm")]
1341 ;; zero_extend version of above
1342 (define_insn "*add_<shift>_si_uxtw"
1343   [(set (match_operand:DI 0 "register_operand" "=r")
1344         (zero_extend:DI
1345          (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1346                              (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1347                   (match_operand:SI 3 "register_operand" "r"))))]
1348   ""
1349   "add\\t%w0, %w3, %w1, <shift> %2"
1350   [(set_attr "type" "alu_shift_imm")]
1353 (define_insn "*add_mul_imm_<mode>"
1354   [(set (match_operand:GPI 0 "register_operand" "=r")
1355         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1356                             (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1357                   (match_operand:GPI 3 "register_operand" "r")))]
1358   ""
1359   "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1360   [(set_attr "type" "alu_shift_imm")]
1363 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1364   [(set (match_operand:GPI 0 "register_operand" "=rk")
1365         (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1366                   (match_operand:GPI 2 "register_operand" "r")))]
1367   ""
1368   "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1369   [(set_attr "type" "alu_ext")]
1372 ;; zero_extend version of above
1373 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1374   [(set (match_operand:DI 0 "register_operand" "=rk")
1375         (zero_extend:DI
1376          (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1377                   (match_operand:GPI 2 "register_operand" "r"))))]
1378   ""
1379   "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1380   [(set_attr "type" "alu_ext")]
1383 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1384   [(set (match_operand:GPI 0 "register_operand" "=rk")
1385         (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1386                                (match_operand:ALLX 1 "register_operand" "r"))
1387                               (match_operand 2 "aarch64_imm3" "Ui3"))
1388                   (match_operand:GPI 3 "register_operand" "r")))]
1389   ""
1390   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1391   [(set_attr "type" "alu_ext")]
1394 ;; zero_extend version of above
1395 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1396   [(set (match_operand:DI 0 "register_operand" "=rk")
1397         (zero_extend:DI
1398          (plus:SI (ashift:SI (ANY_EXTEND:SI
1399                               (match_operand:SHORT 1 "register_operand" "r"))
1400                              (match_operand 2 "aarch64_imm3" "Ui3"))
1401                   (match_operand:SI 3 "register_operand" "r"))))]
1402   ""
1403   "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1404   [(set_attr "type" "alu_ext")]
1407 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1408   [(set (match_operand:GPI 0 "register_operand" "=rk")
1409         (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1410                              (match_operand:ALLX 1 "register_operand" "r"))
1411                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1412                   (match_operand:GPI 3 "register_operand" "r")))]
1413   ""
1414   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1415   [(set_attr "type" "alu_ext")]
1418 ;; zero_extend version of above
1419 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1420   [(set (match_operand:DI 0 "register_operand" "=rk")
1421         (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1422                              (match_operand:SHORT 1 "register_operand" "r"))
1423                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1424                   (match_operand:SI 3 "register_operand" "r"))))]
1425   ""
1426   "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1427   [(set_attr "type" "alu_ext")]
1430 (define_insn "*add_<optab><mode>_multp2"
1431   [(set (match_operand:GPI 0 "register_operand" "=rk")
1432         (plus:GPI (ANY_EXTRACT:GPI
1433                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1434                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1435                    (match_operand 3 "const_int_operand" "n")
1436                    (const_int 0))
1437                   (match_operand:GPI 4 "register_operand" "r")))]
1438   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1439   "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1440   [(set_attr "type" "alu_ext")]
1443 ;; zero_extend version of above
1444 (define_insn "*add_<optab>si_multp2_uxtw"
1445   [(set (match_operand:DI 0 "register_operand" "=rk")
1446         (zero_extend:DI
1447          (plus:SI (ANY_EXTRACT:SI
1448                    (mult:SI (match_operand:SI 1 "register_operand" "r")
1449                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1450                    (match_operand 3 "const_int_operand" "n")
1451                    (const_int 0))
1452                   (match_operand:SI 4 "register_operand" "r"))))]
1453   "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1454   "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1455   [(set_attr "type" "alu_ext")]
1458 (define_insn "add<mode>3_carryin"
1459   [(set
1460     (match_operand:GPI 0 "register_operand" "=r")
1461     (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1462               (plus:GPI
1463                 (match_operand:GPI 1 "register_operand" "r")
1464                 (match_operand:GPI 2 "register_operand" "r"))))]
1465    ""
1466    "adc\\t%<w>0, %<w>1, %<w>2"
1467   [(set_attr "type" "adc_reg")]
1470 ;; zero_extend version of above
1471 (define_insn "*addsi3_carryin_uxtw"
1472   [(set
1473     (match_operand:DI 0 "register_operand" "=r")
1474     (zero_extend:DI
1475      (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1476               (plus:SI
1477                (match_operand:SI 1 "register_operand" "r")
1478                (match_operand:SI 2 "register_operand" "r")))))]
1479    ""
1480    "adc\\t%w0, %w1, %w2"
1481   [(set_attr "type" "adc_reg")]
1484 (define_insn "*add<mode>3_carryin_alt1"
1485   [(set
1486     (match_operand:GPI 0 "register_operand" "=r")
1487     (plus:GPI (plus:GPI
1488                 (match_operand:GPI 1 "register_operand" "r")
1489                 (match_operand:GPI 2 "register_operand" "r"))
1490               (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1491    ""
1492    "adc\\t%<w>0, %<w>1, %<w>2"
1493   [(set_attr "type" "adc_reg")]
1496 ;; zero_extend version of above
1497 (define_insn "*addsi3_carryin_alt1_uxtw"
1498   [(set
1499     (match_operand:DI 0 "register_operand" "=r")
1500     (zero_extend:DI
1501      (plus:SI (plus:SI
1502                (match_operand:SI 1 "register_operand" "r")
1503                (match_operand:SI 2 "register_operand" "r"))
1504               (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1505    ""
1506    "adc\\t%w0, %w1, %w2"
1507   [(set_attr "type" "adc_reg")]
1510 (define_insn "*add<mode>3_carryin_alt2"
1511   [(set
1512     (match_operand:GPI 0 "register_operand" "=r")
1513     (plus:GPI (plus:GPI
1514                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1515                 (match_operand:GPI 1 "register_operand" "r"))
1516               (match_operand:GPI 2 "register_operand" "r")))]
1517    ""
1518    "adc\\t%<w>0, %<w>1, %<w>2"
1519   [(set_attr "type" "adc_reg")]
1522 ;; zero_extend version of above
1523 (define_insn "*addsi3_carryin_alt2_uxtw"
1524   [(set
1525     (match_operand:DI 0 "register_operand" "=r")
1526     (zero_extend:DI
1527      (plus:SI (plus:SI
1528                (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1529                (match_operand:SI 1 "register_operand" "r"))
1530               (match_operand:SI 2 "register_operand" "r"))))]
1531    ""
1532    "adc\\t%w0, %w1, %w2"
1533   [(set_attr "type" "adc_reg")]
1536 (define_insn "*add<mode>3_carryin_alt3"
1537   [(set
1538     (match_operand:GPI 0 "register_operand" "=r")
1539     (plus:GPI (plus:GPI
1540                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1541                 (match_operand:GPI 2 "register_operand" "r"))
1542               (match_operand:GPI 1 "register_operand" "r")))]
1543    ""
1544    "adc\\t%<w>0, %<w>1, %<w>2"
1545   [(set_attr "type" "adc_reg")]
1548 ;; zero_extend version of above
1549 (define_insn "*addsi3_carryin_alt3_uxtw"
1550   [(set
1551     (match_operand:DI 0 "register_operand" "=r")
1552     (zero_extend:DI
1553      (plus:SI (plus:SI
1554                (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1555                (match_operand:SI 2 "register_operand" "r"))
1556               (match_operand:SI 1 "register_operand" "r"))))]
1557    ""
1558    "adc\\t%w0, %w1, %w2"
1559   [(set_attr "type" "adc_reg")]
1562 (define_insn "*add_uxt<mode>_multp2"
1563   [(set (match_operand:GPI 0 "register_operand" "=rk")
1564         (plus:GPI (and:GPI
1565                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1566                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1567                    (match_operand 3 "const_int_operand" "n"))
1568                   (match_operand:GPI 4 "register_operand" "r")))]
1569   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1570   "*
1571   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1572                                            INTVAL (operands[3])));
1573   return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1574   [(set_attr "type" "alu_ext")]
1577 ;; zero_extend version of above
1578 (define_insn "*add_uxtsi_multp2_uxtw"
1579   [(set (match_operand:DI 0 "register_operand" "=rk")
1580         (zero_extend:DI
1581          (plus:SI (and:SI
1582                    (mult:SI (match_operand:SI 1 "register_operand" "r")
1583                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1584                    (match_operand 3 "const_int_operand" "n"))
1585                   (match_operand:SI 4 "register_operand" "r"))))]
1586   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1587   "*
1588   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1589                                            INTVAL (operands[3])));
1590   return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1591   [(set_attr "type" "alu_ext")]
1594 (define_insn "subsi3"
1595   [(set (match_operand:SI 0 "register_operand" "=rk")
1596         (minus:SI (match_operand:SI 1 "register_operand" "r")
1597                    (match_operand:SI 2 "register_operand" "r")))]
1598   ""
1599   "sub\\t%w0, %w1, %w2"
1600   [(set_attr "type" "alu_reg")]
1603 ;; zero_extend version of above
1604 (define_insn "*subsi3_uxtw"
1605   [(set (match_operand:DI 0 "register_operand" "=rk")
1606         (zero_extend:DI
1607          (minus:SI (match_operand:SI 1 "register_operand" "r")
1608                    (match_operand:SI 2 "register_operand" "r"))))]
1609   ""
1610   "sub\\t%w0, %w1, %w2"
1611   [(set_attr "type" "alu_reg")]
1614 (define_insn "subdi3"
1615   [(set (match_operand:DI 0 "register_operand" "=rk,!w")
1616         (minus:DI (match_operand:DI 1 "register_operand" "r,!w")
1617                    (match_operand:DI 2 "register_operand" "r,!w")))]
1618   ""
1619   "@
1620    sub\\t%x0, %x1, %x2
1621    sub\\t%d0, %d1, %d2"
1622   [(set_attr "type" "alu_reg, neon_sub")
1623    (set_attr "simd" "*,yes")]
1626 (define_expand "subti3"
1627   [(set (match_operand:TI 0 "register_operand" "")
1628         (minus:TI (match_operand:TI 1 "register_operand" "")
1629                   (match_operand:TI 2 "register_operand" "")))]
1630   ""
1632   rtx low = gen_reg_rtx (DImode);
1633   emit_insn (gen_subdi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1634                                   gen_lowpart (DImode, operands[2])));
1636   rtx high = gen_reg_rtx (DImode);
1637   emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]),
1638                                  gen_highpart (DImode, operands[2])));
1640   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1641   emit_move_insn (gen_highpart (DImode, operands[0]), high);
1642   DONE;
1645 (define_insn "sub<mode>3_compare0"
1646   [(set (reg:CC_NZ CC_REGNUM)
1647         (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1648                                   (match_operand:GPI 2 "register_operand" "r"))
1649                        (const_int 0)))
1650    (set (match_operand:GPI 0 "register_operand" "=r")
1651         (minus:GPI (match_dup 1) (match_dup 2)))]
1652   ""
1653   "subs\\t%<w>0, %<w>1, %<w>2"
1654   [(set_attr "type" "alus_reg")]
1657 ;; zero_extend version of above
1658 (define_insn "*subsi3_compare0_uxtw"
1659   [(set (reg:CC_NZ CC_REGNUM)
1660         (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1661                                  (match_operand:SI 2 "register_operand" "r"))
1662                        (const_int 0)))
1663    (set (match_operand:DI 0 "register_operand" "=r")
1664         (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1665   ""
1666   "subs\\t%w0, %w1, %w2"
1667   [(set_attr "type" "alus_reg")]
1670 (define_insn "*sub_<shift>_<mode>"
1671   [(set (match_operand:GPI 0 "register_operand" "=r")
1672         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1673                    (ASHIFT:GPI
1674                     (match_operand:GPI 1 "register_operand" "r")
1675                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1676   ""
1677   "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1678   [(set_attr "type" "alu_shift_imm")]
1681 ;; zero_extend version of above
1682 (define_insn "*sub_<shift>_si_uxtw"
1683   [(set (match_operand:DI 0 "register_operand" "=r")
1684         (zero_extend:DI
1685          (minus:SI (match_operand:SI 3 "register_operand" "r")
1686                    (ASHIFT:SI
1687                     (match_operand:SI 1 "register_operand" "r")
1688                     (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1689   ""
1690   "sub\\t%w0, %w3, %w1, <shift> %2"
1691   [(set_attr "type" "alu_shift_imm")]
1694 (define_insn "*sub_mul_imm_<mode>"
1695   [(set (match_operand:GPI 0 "register_operand" "=r")
1696         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1697                    (mult:GPI
1698                     (match_operand:GPI 1 "register_operand" "r")
1699                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1700   ""
1701   "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1702   [(set_attr "type" "alu_shift_imm")]
1705 ;; zero_extend version of above
1706 (define_insn "*sub_mul_imm_si_uxtw"
1707   [(set (match_operand:DI 0 "register_operand" "=r")
1708         (zero_extend:DI
1709          (minus:SI (match_operand:SI 3 "register_operand" "r")
1710                    (mult:SI
1711                     (match_operand:SI 1 "register_operand" "r")
1712                     (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
1713   ""
1714   "sub\\t%w0, %w3, %w1, lsl %p2"
1715   [(set_attr "type" "alu_shift_imm")]
1718 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
1719   [(set (match_operand:GPI 0 "register_operand" "=rk")
1720         (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1721                    (ANY_EXTEND:GPI
1722                     (match_operand:ALLX 2 "register_operand" "r"))))]
1723   ""
1724   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1725   [(set_attr "type" "alu_ext")]
1728 ;; zero_extend version of above
1729 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
1730   [(set (match_operand:DI 0 "register_operand" "=rk")
1731         (zero_extend:DI
1732          (minus:SI (match_operand:SI 1 "register_operand" "r")
1733                    (ANY_EXTEND:SI
1734                     (match_operand:SHORT 2 "register_operand" "r")))))]
1735   ""
1736   "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
1737   [(set_attr "type" "alu_ext")]
1740 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
1741   [(set (match_operand:GPI 0 "register_operand" "=rk")
1742         (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1743                    (ashift:GPI (ANY_EXTEND:GPI
1744                                 (match_operand:ALLX 2 "register_operand" "r"))
1745                                (match_operand 3 "aarch64_imm3" "Ui3"))))]
1746   ""
1747   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1748   [(set_attr "type" "alu_ext")]
1751 ;; zero_extend version of above
1752 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
1753   [(set (match_operand:DI 0 "register_operand" "=rk")
1754         (zero_extend:DI
1755          (minus:SI (match_operand:SI 1 "register_operand" "r")
1756                    (ashift:SI (ANY_EXTEND:SI
1757                                (match_operand:SHORT 2 "register_operand" "r"))
1758                               (match_operand 3 "aarch64_imm3" "Ui3")))))]
1759   ""
1760   "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
1761   [(set_attr "type" "alu_ext")]
1764 (define_insn "*sub_<optab><mode>_multp2"
1765   [(set (match_operand:GPI 0 "register_operand" "=rk")
1766         (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1767                    (ANY_EXTRACT:GPI
1768                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1769                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1770                     (match_operand 3 "const_int_operand" "n")
1771                     (const_int 0))))]
1772   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1773   "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1774   [(set_attr "type" "alu_ext")]
1777 ;; zero_extend version of above
1778 (define_insn "*sub_<optab>si_multp2_uxtw"
1779   [(set (match_operand:DI 0 "register_operand" "=rk")
1780         (zero_extend:DI
1781          (minus:SI (match_operand:SI 4 "register_operand" "r")
1782                    (ANY_EXTRACT:SI
1783                     (mult:SI (match_operand:SI 1 "register_operand" "r")
1784                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1785                     (match_operand 3 "const_int_operand" "n")
1786                     (const_int 0)))))]
1787   "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1788   "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1789   [(set_attr "type" "alu_ext")]
1792 (define_insn "sub<mode>3_carryin"
1793   [(set
1794     (match_operand:GPI 0 "register_operand" "=r")
1795     (minus:GPI (minus:GPI
1796                 (match_operand:GPI 1 "register_operand" "r")
1797                 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
1798                (match_operand:GPI 2 "register_operand" "r")))]
1799    ""
1800    "sbc\\t%<w>0, %<w>1, %<w>2"
1801   [(set_attr "type" "adc_reg")]
1804 ;; zero_extend version of the above
1805 (define_insn "*subsi3_carryin_uxtw"
1806   [(set
1807     (match_operand:DI 0 "register_operand" "=r")
1808     (zero_extend:DI
1809      (minus:SI (minus:SI
1810                 (match_operand:SI 1 "register_operand" "r")
1811                 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
1812                (match_operand:SI 2 "register_operand" "r"))))]
1813    ""
1814    "sbc\\t%w0, %w1, %w2"
1815   [(set_attr "type" "adc_reg")]
1818 (define_insn "*sub_uxt<mode>_multp2"
1819   [(set (match_operand:GPI 0 "register_operand" "=rk")
1820         (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1821                    (and:GPI
1822                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1823                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1824                     (match_operand 3 "const_int_operand" "n"))))]
1825   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1826   "*
1827   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1828                                            INTVAL (operands[3])));
1829   return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1830   [(set_attr "type" "alu_ext")]
1833 ;; zero_extend version of above
1834 (define_insn "*sub_uxtsi_multp2_uxtw"
1835   [(set (match_operand:DI 0 "register_operand" "=rk")
1836         (zero_extend:DI
1837          (minus:SI (match_operand:SI 4 "register_operand" "r")
1838                    (and:SI
1839                     (mult:SI (match_operand:SI 1 "register_operand" "r")
1840                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1841                     (match_operand 3 "const_int_operand" "n")))))]
1842   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1843   "*
1844   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1845                                            INTVAL (operands[3])));
1846   return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
1847   [(set_attr "type" "alu_ext")]
1850 (define_insn_and_split "absdi2"
1851   [(set (match_operand:DI 0 "register_operand" "=r,w")
1852         (abs:DI (match_operand:DI 1 "register_operand" "r,w")))
1853    (clobber (match_scratch:DI 2 "=&r,X"))]
1854   ""
1855   "@
1856    #
1857    abs\\t%d0, %d1"
1858   "reload_completed
1859    && GP_REGNUM_P (REGNO (operands[0]))
1860    && GP_REGNUM_P (REGNO (operands[1]))"
1861   [(const_int 0)]
1862   {
1863     emit_insn (gen_rtx_SET (VOIDmode, operands[2],
1864                             gen_rtx_XOR (DImode,
1865                                          gen_rtx_ASHIFTRT (DImode,
1866                                                            operands[1],
1867                                                            GEN_INT (63)),
1868                                          operands[1])));
1869     emit_insn (gen_rtx_SET (VOIDmode,
1870                             operands[0],
1871                             gen_rtx_MINUS (DImode,
1872                                            operands[2],
1873                                            gen_rtx_ASHIFTRT (DImode,
1874                                                              operands[1],
1875                                                              GEN_INT (63)))));
1876     DONE;
1877   }
1878   [(set_attr "type" "alu_reg")]
1881 (define_insn "neg<mode>2"
1882   [(set (match_operand:GPI 0 "register_operand" "=r,w")
1883         (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
1884   ""
1885   "@
1886    neg\\t%<w>0, %<w>1
1887    neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
1888   [(set_attr "type" "alu_reg, neon_neg<q>")
1889    (set_attr "simd" "*,yes")]
1892 ;; zero_extend version of above
1893 (define_insn "*negsi2_uxtw"
1894   [(set (match_operand:DI 0 "register_operand" "=r")
1895         (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
1896   ""
1897   "neg\\t%w0, %w1"
1898   [(set_attr "type" "alu_reg")]
1901 (define_insn "*ngc<mode>"
1902   [(set (match_operand:GPI 0 "register_operand" "=r")
1903         (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
1904                    (match_operand:GPI 1 "register_operand" "r")))]
1905   ""
1906   "ngc\\t%<w>0, %<w>1"
1907   [(set_attr "type" "adc_reg")]
1910 (define_insn "*ngcsi_uxtw"
1911   [(set (match_operand:DI 0 "register_operand" "=r")
1912         (zero_extend:DI
1913          (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
1914                    (match_operand:SI 1 "register_operand" "r"))))]
1915   ""
1916   "ngc\\t%w0, %w1"
1917   [(set_attr "type" "adc_reg")]
1920 (define_insn "*neg<mode>2_compare0"
1921   [(set (reg:CC_NZ CC_REGNUM)
1922         (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
1923                        (const_int 0)))
1924    (set (match_operand:GPI 0 "register_operand" "=r")
1925         (neg:GPI (match_dup 1)))]
1926   ""
1927   "negs\\t%<w>0, %<w>1"
1928   [(set_attr "type" "alus_reg")]
1931 ;; zero_extend version of above
1932 (define_insn "*negsi2_compare0_uxtw"
1933   [(set (reg:CC_NZ CC_REGNUM)
1934         (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
1935                        (const_int 0)))
1936    (set (match_operand:DI 0 "register_operand" "=r")
1937         (zero_extend:DI (neg:SI (match_dup 1))))]
1938   ""
1939   "negs\\t%w0, %w1"
1940   [(set_attr "type" "alus_reg")]
1943 (define_insn "*neg_<shift><mode>3_compare0"
1944   [(set (reg:CC_NZ CC_REGNUM)
1945         (compare:CC_NZ
1946          (neg:GPI (ASHIFT:GPI
1947                    (match_operand:GPI 1 "register_operand" "r")
1948                    (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
1949          (const_int 0)))
1950    (set (match_operand:GPI 0 "register_operand" "=r")
1951         (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
1952   ""
1953   "negs\\t%<w>0, %<w>1, <shift> %2"
1954   [(set_attr "type" "alus_shift_imm")]
1957 (define_insn "*neg_<shift>_<mode>2"
1958   [(set (match_operand:GPI 0 "register_operand" "=r")
1959         (neg:GPI (ASHIFT:GPI
1960                   (match_operand:GPI 1 "register_operand" "r")
1961                   (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1962   ""
1963   "neg\\t%<w>0, %<w>1, <shift> %2"
1964   [(set_attr "type" "alu_shift_imm")]
1967 ;; zero_extend version of above
1968 (define_insn "*neg_<shift>_si2_uxtw"
1969   [(set (match_operand:DI 0 "register_operand" "=r")
1970         (zero_extend:DI
1971          (neg:SI (ASHIFT:SI
1972                   (match_operand:SI 1 "register_operand" "r")
1973                   (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1974   ""
1975   "neg\\t%w0, %w1, <shift> %2"
1976   [(set_attr "type" "alu_shift_imm")]
1979 (define_insn "*neg_mul_imm_<mode>2"
1980   [(set (match_operand:GPI 0 "register_operand" "=r")
1981         (neg:GPI (mult:GPI
1982                   (match_operand:GPI 1 "register_operand" "r")
1983                   (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1984   ""
1985   "neg\\t%<w>0, %<w>1, lsl %p2"
1986   [(set_attr "type" "alu_shift_imm")]
1989 ;; zero_extend version of above
1990 (define_insn "*neg_mul_imm_si2_uxtw"
1991   [(set (match_operand:DI 0 "register_operand" "=r")
1992         (zero_extend:DI
1993          (neg:SI (mult:SI
1994                   (match_operand:SI 1 "register_operand" "r")
1995                   (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
1996   ""
1997   "neg\\t%w0, %w1, lsl %p2"
1998   [(set_attr "type" "alu_shift_imm")]
2001 (define_insn "mul<mode>3"
2002   [(set (match_operand:GPI 0 "register_operand" "=r")
2003         (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2004                   (match_operand:GPI 2 "register_operand" "r")))]
2005   ""
2006   "mul\\t%<w>0, %<w>1, %<w>2"
2007   [(set_attr "type" "mul")]
2010 ;; zero_extend version of above
2011 (define_insn "*mulsi3_uxtw"
2012   [(set (match_operand:DI 0 "register_operand" "=r")
2013         (zero_extend:DI
2014          (mult:SI (match_operand:SI 1 "register_operand" "r")
2015                   (match_operand:SI 2 "register_operand" "r"))))]
2016   ""
2017   "mul\\t%w0, %w1, %w2"
2018   [(set_attr "type" "mul")]
2021 (define_insn "madd<mode>"
2022   [(set (match_operand:GPI 0 "register_operand" "=r")
2023         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2024                             (match_operand:GPI 2 "register_operand" "r"))
2025                   (match_operand:GPI 3 "register_operand" "r")))]
2026   ""
2027   "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2028   [(set_attr "type" "mla")]
2031 ;; zero_extend version of above
2032 (define_insn "*maddsi_uxtw"
2033   [(set (match_operand:DI 0 "register_operand" "=r")
2034         (zero_extend:DI
2035          (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2036                            (match_operand:SI 2 "register_operand" "r"))
2037                   (match_operand:SI 3 "register_operand" "r"))))]
2038   ""
2039   "madd\\t%w0, %w1, %w2, %w3"
2040   [(set_attr "type" "mla")]
2043 (define_insn "*msub<mode>"
2044   [(set (match_operand:GPI 0 "register_operand" "=r")
2045         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2046                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2047                              (match_operand:GPI 2 "register_operand" "r"))))]
2049   ""
2050   "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2051   [(set_attr "type" "mla")]
2054 ;; zero_extend version of above
2055 (define_insn "*msubsi_uxtw"
2056   [(set (match_operand:DI 0 "register_operand" "=r")
2057         (zero_extend:DI
2058          (minus:SI (match_operand:SI 3 "register_operand" "r")
2059                    (mult:SI (match_operand:SI 1 "register_operand" "r")
2060                             (match_operand:SI 2 "register_operand" "r")))))]
2062   ""
2063   "msub\\t%w0, %w1, %w2, %w3"
2064   [(set_attr "type" "mla")]
2067 (define_insn "*mul<mode>_neg"
2068   [(set (match_operand:GPI 0 "register_operand" "=r")
2069         (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2070                   (match_operand:GPI 2 "register_operand" "r")))]
2072   ""
2073   "mneg\\t%<w>0, %<w>1, %<w>2"
2074   [(set_attr "type" "mul")]
2077 ;; zero_extend version of above
2078 (define_insn "*mulsi_neg_uxtw"
2079   [(set (match_operand:DI 0 "register_operand" "=r")
2080         (zero_extend:DI
2081          (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2082                   (match_operand:SI 2 "register_operand" "r"))))]
2084   ""
2085   "mneg\\t%w0, %w1, %w2"
2086   [(set_attr "type" "mul")]
2089 (define_insn "<su_optab>mulsidi3"
2090   [(set (match_operand:DI 0 "register_operand" "=r")
2091         (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2092                  (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2093   ""
2094   "<su>mull\\t%0, %w1, %w2"
2095   [(set_attr "type" "<su>mull")]
2098 (define_insn "<su_optab>maddsidi4"
2099   [(set (match_operand:DI 0 "register_operand" "=r")
2100         (plus:DI (mult:DI
2101                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2102                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2103                  (match_operand:DI 3 "register_operand" "r")))]
2104   ""
2105   "<su>maddl\\t%0, %w1, %w2, %3"
2106   [(set_attr "type" "<su>mlal")]
2109 (define_insn "<su_optab>msubsidi4"
2110   [(set (match_operand:DI 0 "register_operand" "=r")
2111         (minus:DI
2112          (match_operand:DI 3 "register_operand" "r")
2113          (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2114                   (ANY_EXTEND:DI
2115                    (match_operand:SI 2 "register_operand" "r")))))]
2116   ""
2117   "<su>msubl\\t%0, %w1, %w2, %3"
2118   [(set_attr "type" "<su>mlal")]
2121 (define_insn "*<su_optab>mulsidi_neg"
2122   [(set (match_operand:DI 0 "register_operand" "=r")
2123         (mult:DI (neg:DI
2124                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2125                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2126   ""
2127   "<su>mnegl\\t%0, %w1, %w2"
2128   [(set_attr "type" "<su>mull")]
2131 (define_expand "<su_optab>mulditi3"
2132   [(set (match_operand:TI 0 "register_operand")
2133         (mult:TI (ANY_EXTEND:TI (match_operand:DI 1 "register_operand"))
2134                  (ANY_EXTEND:TI (match_operand:DI 2 "register_operand"))))]
2135   ""
2137   rtx low = gen_reg_rtx (DImode);
2138   emit_insn (gen_muldi3 (low, operands[1], operands[2]));
2140   rtx high = gen_reg_rtx (DImode);
2141   emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2]));
2143   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2144   emit_move_insn (gen_highpart (DImode, operands[0]), high);
2145   DONE;
2148 ;; The default expansion of multi3 using umuldi3_highpart will perform
2149 ;; the additions in an order that fails to combine into two madd insns.
2150 (define_expand "multi3"
2151   [(set (match_operand:TI 0 "register_operand")
2152         (mult:TI (match_operand:TI 1 "register_operand")
2153                  (match_operand:TI 2 "register_operand")))]
2154   ""
2156   rtx l0 = gen_reg_rtx (DImode);
2157   rtx l1 = gen_lowpart (DImode, operands[1]);
2158   rtx l2 = gen_lowpart (DImode, operands[2]);
2159   rtx h0 = gen_reg_rtx (DImode);
2160   rtx h1 = gen_highpart (DImode, operands[1]);
2161   rtx h2 = gen_highpart (DImode, operands[2]);
2163   emit_insn (gen_muldi3 (l0, l1, l2));
2164   emit_insn (gen_umuldi3_highpart (h0, l1, l2));
2165   emit_insn (gen_madddi (h0, h1, l2, h0));
2166   emit_insn (gen_madddi (h0, l1, h2, h0));
2168   emit_move_insn (gen_lowpart (DImode, operands[0]), l0);
2169   emit_move_insn (gen_highpart (DImode, operands[0]), h0);
2170   DONE;
2173 (define_insn "<su>muldi3_highpart"
2174   [(set (match_operand:DI 0 "register_operand" "=r")
2175         (truncate:DI
2176          (lshiftrt:TI
2177           (mult:TI
2178            (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2179            (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2180           (const_int 64))))]
2181   ""
2182   "<su>mulh\\t%0, %1, %2"
2183   [(set_attr "type" "<su>mull")]
2186 (define_insn "<su_optab>div<mode>3"
2187   [(set (match_operand:GPI 0 "register_operand" "=r")
2188         (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2189                      (match_operand:GPI 2 "register_operand" "r")))]
2190   ""
2191   "<su>div\\t%<w>0, %<w>1, %<w>2"
2192   [(set_attr "type" "<su>div")]
2195 ;; zero_extend version of above
2196 (define_insn "*<su_optab>divsi3_uxtw"
2197   [(set (match_operand:DI 0 "register_operand" "=r")
2198         (zero_extend:DI
2199          (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2200                      (match_operand:SI 2 "register_operand" "r"))))]
2201   ""
2202   "<su>div\\t%w0, %w1, %w2"
2203   [(set_attr "type" "<su>div")]
2206 ;; -------------------------------------------------------------------
2207 ;; Comparison insns
2208 ;; -------------------------------------------------------------------
2210 (define_insn "*cmp<mode>"
2211   [(set (reg:CC CC_REGNUM)
2212         (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2213                     (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2214   ""
2215   "@
2216    cmp\\t%<w>0, %<w>1
2217    cmp\\t%<w>0, %<w>1
2218    cmn\\t%<w>0, #%n1"
2219   [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
2222 (define_insn "*cmp<mode>"
2223   [(set (reg:CCFP CC_REGNUM)
2224         (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2225                       (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2226    "TARGET_FLOAT"
2227    "@
2228     fcmp\\t%<s>0, #0.0
2229     fcmp\\t%<s>0, %<s>1"
2230   [(set_attr "type" "fcmp<s>")]
2233 (define_insn "*cmpe<mode>"
2234   [(set (reg:CCFPE CC_REGNUM)
2235         (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2236                        (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2237    "TARGET_FLOAT"
2238    "@
2239     fcmpe\\t%<s>0, #0.0
2240     fcmpe\\t%<s>0, %<s>1"
2241   [(set_attr "type" "fcmp<s>")]
2244 (define_insn "*cmp_swp_<shift>_reg<mode>"
2245   [(set (reg:CC_SWP CC_REGNUM)
2246         (compare:CC_SWP (ASHIFT:GPI
2247                          (match_operand:GPI 0 "register_operand" "r")
2248                          (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2249                         (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2250   ""
2251   "cmp\\t%<w>2, %<w>0, <shift> %1"
2252   [(set_attr "type" "alus_shift_imm")]
2255 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2256   [(set (reg:CC_SWP CC_REGNUM)
2257         (compare:CC_SWP (ANY_EXTEND:GPI
2258                          (match_operand:ALLX 0 "register_operand" "r"))
2259                         (match_operand:GPI 1 "register_operand" "r")))]
2260   ""
2261   "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2262   [(set_attr "type" "alus_ext")]
2265 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2266   [(set (reg:CC_SWP CC_REGNUM)
2267         (compare:CC_SWP (ashift:GPI
2268                          (ANY_EXTEND:GPI
2269                           (match_operand:ALLX 0 "register_operand" "r"))
2270                          (match_operand 1 "aarch64_imm3" "Ui3"))
2271         (match_operand:GPI 2 "register_operand" "r")))]
2272   ""
2273   "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2274   [(set_attr "type" "alus_ext")]
2277 ;; -------------------------------------------------------------------
2278 ;; Store-flag and conditional select insns
2279 ;; -------------------------------------------------------------------
2281 (define_expand "cstore<mode>4"
2282   [(set (match_operand:SI 0 "register_operand" "")
2283         (match_operator:SI 1 "aarch64_comparison_operator"
2284          [(match_operand:GPI 2 "register_operand" "")
2285           (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2286   ""
2287   "
2288   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2289                                       operands[3]);
2290   operands[3] = const0_rtx;
2291   "
2294 (define_expand "cstore<mode>4"
2295   [(set (match_operand:SI 0 "register_operand" "")
2296         (match_operator:SI 1 "aarch64_comparison_operator"
2297          [(match_operand:GPF 2 "register_operand" "")
2298           (match_operand:GPF 3 "register_operand" "")]))]
2299   ""
2300   "
2301   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2302                                       operands[3]);
2303   operands[3] = const0_rtx;
2304   "
2307 (define_insn "*cstore<mode>_insn"
2308   [(set (match_operand:ALLI 0 "register_operand" "=r")
2309         (match_operator:ALLI 1 "aarch64_comparison_operator"
2310          [(match_operand 2 "cc_register" "") (const_int 0)]))]
2311   ""
2312   "cset\\t%<w>0, %m1"
2313   [(set_attr "type" "csel")]
2316 ;; zero_extend version of the above
2317 (define_insn "*cstoresi_insn_uxtw"
2318   [(set (match_operand:DI 0 "register_operand" "=r")
2319         (zero_extend:DI
2320          (match_operator:SI 1 "aarch64_comparison_operator"
2321           [(match_operand 2 "cc_register" "") (const_int 0)])))]
2322   ""
2323   "cset\\t%w0, %m1"
2324   [(set_attr "type" "csel")]
2327 (define_insn "cstore<mode>_neg"
2328   [(set (match_operand:ALLI 0 "register_operand" "=r")
2329         (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2330                   [(match_operand 2 "cc_register" "") (const_int 0)])))]
2331   ""
2332   "csetm\\t%<w>0, %m1"
2333   [(set_attr "type" "csel")]
2336 ;; zero_extend version of the above
2337 (define_insn "*cstoresi_neg_uxtw"
2338   [(set (match_operand:DI 0 "register_operand" "=r")
2339         (zero_extend:DI
2340          (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2341                   [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2342   ""
2343   "csetm\\t%w0, %m1"
2344   [(set_attr "type" "csel")]
2347 (define_expand "cmov<mode>6"
2348   [(set (match_operand:GPI 0 "register_operand" "")
2349         (if_then_else:GPI
2350          (match_operator 1 "aarch64_comparison_operator"
2351           [(match_operand:GPI 2 "register_operand" "")
2352            (match_operand:GPI 3 "aarch64_plus_operand" "")])
2353          (match_operand:GPI 4 "register_operand" "")
2354          (match_operand:GPI 5 "register_operand" "")))]
2355   ""
2356   "
2357   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2358                                       operands[3]);
2359   operands[3] = const0_rtx;
2360   "
2363 (define_expand "cmov<mode>6"
2364   [(set (match_operand:GPF 0 "register_operand" "")
2365         (if_then_else:GPF
2366          (match_operator 1 "aarch64_comparison_operator"
2367           [(match_operand:GPF 2 "register_operand" "")
2368            (match_operand:GPF 3 "register_operand" "")])
2369          (match_operand:GPF 4 "register_operand" "")
2370          (match_operand:GPF 5 "register_operand" "")))]
2371   ""
2372   "
2373   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2374                                       operands[3]);
2375   operands[3] = const0_rtx;
2376   "
2379 (define_insn "*cmov<mode>_insn"
2380   [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2381         (if_then_else:ALLI
2382          (match_operator 1 "aarch64_comparison_operator"
2383           [(match_operand 2 "cc_register" "") (const_int 0)])
2384          (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2385          (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2386   "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2387      || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2388   ;; Final two alternatives should be unreachable, but included for completeness
2389   "@
2390    csel\\t%<w>0, %<w>3, %<w>4, %m1
2391    csinv\\t%<w>0, %<w>3, <w>zr, %m1
2392    csinv\\t%<w>0, %<w>4, <w>zr, %M1
2393    csinc\\t%<w>0, %<w>3, <w>zr, %m1
2394    csinc\\t%<w>0, %<w>4, <w>zr, %M1
2395    mov\\t%<w>0, -1
2396    mov\\t%<w>0, 1"
2397   [(set_attr "type" "csel")]
2400 ;; zero_extend version of above
2401 (define_insn "*cmovsi_insn_uxtw"
2402   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2403         (zero_extend:DI
2404          (if_then_else:SI
2405           (match_operator 1 "aarch64_comparison_operator"
2406            [(match_operand 2 "cc_register" "") (const_int 0)])
2407           (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2408           (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2409   "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2410      || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2411   ;; Final two alternatives should be unreachable, but included for completeness
2412   "@
2413    csel\\t%w0, %w3, %w4, %m1
2414    csinv\\t%w0, %w3, wzr, %m1
2415    csinv\\t%w0, %w4, wzr, %M1
2416    csinc\\t%w0, %w3, wzr, %m1
2417    csinc\\t%w0, %w4, wzr, %M1
2418    mov\\t%w0, -1
2419    mov\\t%w0, 1"
2420   [(set_attr "type" "csel")]
2423 (define_insn "*cmov<mode>_insn"
2424   [(set (match_operand:GPF 0 "register_operand" "=w")
2425         (if_then_else:GPF
2426          (match_operator 1 "aarch64_comparison_operator"
2427           [(match_operand 2 "cc_register" "") (const_int 0)])
2428          (match_operand:GPF 3 "register_operand" "w")
2429          (match_operand:GPF 4 "register_operand" "w")))]
2430   "TARGET_FLOAT"
2431   "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2432   [(set_attr "type" "fcsel")]
2435 (define_expand "mov<mode>cc"
2436   [(set (match_operand:ALLI 0 "register_operand" "")
2437         (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2438                            (match_operand:ALLI 2 "register_operand" "")
2439                            (match_operand:ALLI 3 "register_operand" "")))]
2440   ""
2441   {
2442     rtx ccreg;
2443     enum rtx_code code = GET_CODE (operands[1]);
2445     if (code == UNEQ || code == LTGT)
2446       FAIL;
2448     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2449                                   XEXP (operands[1], 1));
2450     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2451   }
2454 (define_expand "mov<GPF:mode><GPI:mode>cc"
2455   [(set (match_operand:GPI 0 "register_operand" "")
2456         (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2457                           (match_operand:GPF 2 "register_operand" "")
2458                           (match_operand:GPF 3 "register_operand" "")))]
2459   ""
2460   {
2461     rtx ccreg;
2462     enum rtx_code code = GET_CODE (operands[1]);
2464     if (code == UNEQ || code == LTGT)
2465       FAIL;
2467     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2468                                   XEXP (operands[1], 1));
2469     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2470   }
2473 (define_expand "mov<mode>cc"
2474   [(set (match_operand:GPF 0 "register_operand" "")
2475         (if_then_else:GPF (match_operand 1 "aarch64_comparison_operator" "")
2476                           (match_operand:GPF 2 "register_operand" "")
2477                           (match_operand:GPF 3 "register_operand" "")))]
2478   ""
2479   {
2480     rtx ccreg;
2481     enum rtx_code code = GET_CODE (operands[1]);
2483     if (code == UNEQ || code == LTGT)
2484       FAIL;
2486     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2487                                   XEXP (operands[1], 1));
2488     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2489   }
2493 ;; CRC32 instructions.
2494 (define_insn "aarch64_<crc_variant>"
2495   [(set (match_operand:SI 0 "register_operand" "=r")
2496         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2497                     (match_operand:<crc_mode> 2 "register_operand" "r")]
2498          CRC))]
2499   "TARGET_CRC32"
2500   {
2501     if (GET_MODE_BITSIZE (GET_MODE (operands[2])) >= 64)
2502       return "<crc_variant>\\t%w0, %w1, %x2";
2503     else
2504       return "<crc_variant>\\t%w0, %w1, %w2";
2505   }
2506   [(set_attr "type" "crc")]
2509 (define_insn "*csinc2<mode>_insn"
2510   [(set (match_operand:GPI 0 "register_operand" "=r")
2511         (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator"
2512                   [(match_operand:CC 3 "cc_register" "") (const_int 0)])
2513                  (match_operand:GPI 1 "register_operand" "r")))]
2514   ""
2515   "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2516   [(set_attr "type" "csel")]
2519 (define_insn "csinc3<mode>_insn"
2520   [(set (match_operand:GPI 0 "register_operand" "=r")
2521         (if_then_else:GPI
2522           (match_operator:GPI 1 "aarch64_comparison_operator"
2523            [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2524           (plus:GPI (match_operand:GPI 3 "register_operand" "r")
2525                     (const_int 1))
2526           (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2527   ""
2528   "csinc\\t%<w>0, %<w>4, %<w>3, %M1"
2529   [(set_attr "type" "csel")]
2532 (define_insn "*csinv3<mode>_insn"
2533   [(set (match_operand:GPI 0 "register_operand" "=r")
2534         (if_then_else:GPI
2535           (match_operator:GPI 1 "aarch64_comparison_operator"
2536            [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2537           (not:GPI (match_operand:GPI 3 "register_operand" "r"))
2538           (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2539   ""
2540   "csinv\\t%<w>0, %<w>4, %<w>3, %M1"
2541   [(set_attr "type" "csel")]
2544 (define_insn "*csneg3<mode>_insn"
2545   [(set (match_operand:GPI 0 "register_operand" "=r")
2546         (if_then_else:GPI
2547           (match_operator:GPI 1 "aarch64_comparison_operator"
2548            [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2549           (neg:GPI (match_operand:GPI 3 "register_operand" "r"))
2550           (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2551   ""
2552   "csneg\\t%<w>0, %<w>4, %<w>3, %M1"
2553   [(set_attr "type" "csel")]
2556 ;; -------------------------------------------------------------------
2557 ;; Logical operations
2558 ;; -------------------------------------------------------------------
2560 (define_insn "<optab><mode>3"
2561   [(set (match_operand:GPI 0 "register_operand" "=r,rk")
2562         (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2563                      (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
2564   ""
2565   "<logical>\\t%<w>0, %<w>1, %<w>2"
2566   [(set_attr "type" "logic_reg,logic_imm")]
2569 ;; zero_extend version of above
2570 (define_insn "*<optab>si3_uxtw"
2571   [(set (match_operand:DI 0 "register_operand" "=r,rk")
2572         (zero_extend:DI
2573          (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2574                      (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2575   ""
2576   "<logical>\\t%w0, %w1, %w2"
2577   [(set_attr "type" "logic_reg,logic_imm")]
2580 (define_insn "*and<mode>3_compare0"
2581   [(set (reg:CC_NZ CC_REGNUM)
2582         (compare:CC_NZ
2583          (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2584                   (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2585          (const_int 0)))
2586    (set (match_operand:GPI 0 "register_operand" "=r,r")
2587         (and:GPI (match_dup 1) (match_dup 2)))]
2588   ""
2589   "ands\\t%<w>0, %<w>1, %<w>2"
2590   [(set_attr "type" "logics_reg,logics_imm")]
2593 ;; zero_extend version of above
2594 (define_insn "*andsi3_compare0_uxtw"
2595   [(set (reg:CC_NZ CC_REGNUM)
2596         (compare:CC_NZ
2597          (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2598                  (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2599          (const_int 0)))
2600    (set (match_operand:DI 0 "register_operand" "=r,r")
2601         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2602   ""
2603   "ands\\t%w0, %w1, %w2"
2604   [(set_attr "type" "logics_reg,logics_imm")]
2607 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2608   [(set (reg:CC_NZ CC_REGNUM)
2609         (compare:CC_NZ
2610          (and:GPI (SHIFT:GPI
2611                    (match_operand:GPI 1 "register_operand" "r")
2612                    (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2613                   (match_operand:GPI 3 "register_operand" "r"))
2614          (const_int 0)))
2615    (set (match_operand:GPI 0 "register_operand" "=r")
2616         (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2617   ""
2618   "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2619   [(set_attr "type" "logics_shift_imm")]
2622 ;; zero_extend version of above
2623 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2624   [(set (reg:CC_NZ CC_REGNUM)
2625         (compare:CC_NZ
2626          (and:SI (SHIFT:SI
2627                   (match_operand:SI 1 "register_operand" "r")
2628                   (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2629                  (match_operand:SI 3 "register_operand" "r"))
2630          (const_int 0)))
2631    (set (match_operand:DI 0 "register_operand" "=r")
2632         (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2633                                 (match_dup 3))))]
2634   ""
2635   "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2636   [(set_attr "type" "logics_shift_imm")]
2639 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2640   [(set (match_operand:GPI 0 "register_operand" "=r")
2641         (LOGICAL: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   ""
2646   "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2647   [(set_attr "type" "logic_shift_imm")]
2650 (define_insn "*<optab>_rol<mode>3"
2651   [(set (match_operand:GPI 0 "register_operand" "=r")
2652         (LOGICAL:GPI (rotate:GPI
2653                       (match_operand:GPI 1 "register_operand" "r")
2654                       (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2655                      (match_operand:GPI 3 "register_operand" "r")))]
2656   ""
2657   "<logical>\\t%<w>0, %<w>3, %<w>1, ror (<sizen> - %2)"
2658   [(set_attr "type" "logic_shift_imm")]
2661 ;; zero_extend versions of above
2662 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
2663   [(set (match_operand:DI 0 "register_operand" "=r")
2664         (zero_extend:DI
2665          (LOGICAL:SI (SHIFT:SI
2666                       (match_operand:SI 1 "register_operand" "r")
2667                       (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2668                      (match_operand:SI 3 "register_operand" "r"))))]
2669   ""
2670   "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2671   [(set_attr "type" "logic_shift_imm")]
2674 (define_insn "*<optab>_rolsi3_uxtw"
2675   [(set (match_operand:DI 0 "register_operand" "=r")
2676         (zero_extend:DI
2677          (LOGICAL:SI (rotate:SI
2678                       (match_operand:SI 1 "register_operand" "r")
2679                       (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2680                      (match_operand:SI 3 "register_operand" "r"))))]
2681   ""
2682   "<logical>\\t%w0, %w3, %w1, ror (32 - %2)"
2683   [(set_attr "type" "logic_shift_imm")]
2686 (define_insn "one_cmpl<mode>2"
2687   [(set (match_operand:GPI 0 "register_operand" "=r")
2688         (not:GPI (match_operand:GPI 1 "register_operand" "r")))]
2689   ""
2690   "mvn\\t%<w>0, %<w>1"
2691   [(set_attr "type" "logic_reg")]
2694 (define_insn "*one_cmpl_<optab><mode>2"
2695   [(set (match_operand:GPI 0 "register_operand" "=r")
2696         (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
2697                             (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2698   ""
2699   "mvn\\t%<w>0, %<w>1, <shift> %2"
2700   [(set_attr "type" "logic_shift_imm")]
2703 (define_insn "*<LOGICAL:optab>_one_cmpl<mode>3"
2704   [(set (match_operand:GPI 0 "register_operand" "=r")
2705         (LOGICAL:GPI (not:GPI
2706                       (match_operand:GPI 1 "register_operand" "r"))
2707                      (match_operand:GPI 2 "register_operand" "r")))]
2708   ""
2709   "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1"
2710   [(set_attr "type" "logic_reg")]
2713 (define_insn "*and_one_cmpl<mode>3_compare0"
2714   [(set (reg:CC_NZ CC_REGNUM)
2715         (compare:CC_NZ
2716          (and:GPI (not:GPI
2717                    (match_operand:GPI 1 "register_operand" "r"))
2718                   (match_operand:GPI 2 "register_operand" "r"))
2719          (const_int 0)))
2720    (set (match_operand:GPI 0 "register_operand" "=r")
2721         (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
2722   ""
2723   "bics\\t%<w>0, %<w>2, %<w>1"
2724   [(set_attr "type" "logics_reg")]
2727 ;; zero_extend version of above
2728 (define_insn "*and_one_cmplsi3_compare0_uxtw"
2729   [(set (reg:CC_NZ CC_REGNUM)
2730         (compare:CC_NZ
2731          (and:SI (not:SI
2732                   (match_operand:SI 1 "register_operand" "r"))
2733                  (match_operand:SI 2 "register_operand" "r"))
2734          (const_int 0)))
2735    (set (match_operand:DI 0 "register_operand" "=r")
2736         (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
2737   ""
2738   "bics\\t%w0, %w2, %w1"
2739   [(set_attr "type" "logics_reg")]
2742 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
2743   [(set (match_operand:GPI 0 "register_operand" "=r")
2744         (LOGICAL:GPI (not:GPI
2745                       (SHIFT:GPI
2746                        (match_operand:GPI 1 "register_operand" "r")
2747                        (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2748                      (match_operand:GPI 3 "register_operand" "r")))]
2749   ""
2750   "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2751   [(set_attr "type" "logics_shift_imm")]
2754 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
2755   [(set (reg:CC_NZ CC_REGNUM)
2756         (compare:CC_NZ
2757          (and:GPI (not:GPI
2758                    (SHIFT:GPI
2759                     (match_operand:GPI 1 "register_operand" "r")
2760                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2761                   (match_operand:GPI 3 "register_operand" "r"))
2762          (const_int 0)))
2763    (set (match_operand:GPI 0 "register_operand" "=r")
2764         (and:GPI (not:GPI
2765                   (SHIFT:GPI
2766                    (match_dup 1) (match_dup 2))) (match_dup 3)))]
2767   ""
2768   "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2769   [(set_attr "type" "logics_shift_imm")]
2772 ;; zero_extend version of above
2773 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
2774   [(set (reg:CC_NZ CC_REGNUM)
2775         (compare:CC_NZ
2776          (and:SI (not:SI
2777                   (SHIFT:SI
2778                    (match_operand:SI 1 "register_operand" "r")
2779                    (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
2780                  (match_operand:SI 3 "register_operand" "r"))
2781          (const_int 0)))
2782    (set (match_operand:DI 0 "register_operand" "=r")
2783         (zero_extend:DI (and:SI
2784                          (not:SI
2785                           (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
2786   ""
2787   "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2788   [(set_attr "type" "logics_shift_imm")]
2791 (define_insn "clz<mode>2"
2792   [(set (match_operand:GPI 0 "register_operand" "=r")
2793         (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
2794   ""
2795   "clz\\t%<w>0, %<w>1"
2796   [(set_attr "type" "clz")]
2799 (define_expand "ffs<mode>2"
2800   [(match_operand:GPI 0 "register_operand")
2801    (match_operand:GPI 1 "register_operand")]
2802   ""
2803   {
2804     rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
2805     rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
2807     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2808     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2809     emit_insn (gen_csinc3<mode>_insn (operands[0], x, ccreg, operands[0], const0_rtx));
2810     DONE;
2811   }
2814 (define_insn "clrsb<mode>2"
2815   [(set (match_operand:GPI 0 "register_operand" "=r")
2816         (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_CLS))]
2817   ""
2818   "cls\\t%<w>0, %<w>1"
2819   [(set_attr "type" "clz")]
2822 (define_insn "rbit<mode>2"
2823   [(set (match_operand:GPI 0 "register_operand" "=r")
2824         (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
2825   ""
2826   "rbit\\t%<w>0, %<w>1"
2827   [(set_attr "type" "rbit")]
2830 (define_expand "ctz<mode>2"
2831   [(match_operand:GPI 0 "register_operand")
2832    (match_operand:GPI 1 "register_operand")]
2833   ""
2834   {
2835     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2836     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2837     DONE;
2838   }
2841 (define_insn "*and<mode>3nr_compare0"
2842   [(set (reg:CC_NZ CC_REGNUM)
2843         (compare:CC_NZ
2844          (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
2845                   (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
2846          (const_int 0)))]
2847   ""
2848   "tst\\t%<w>0, %<w>1"
2849   [(set_attr "type" "logics_reg")]
2852 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
2853   [(set (reg:CC_NZ CC_REGNUM)
2854         (compare:CC_NZ
2855          (and:GPI (SHIFT:GPI
2856                    (match_operand:GPI 0 "register_operand" "r")
2857                    (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2858                   (match_operand:GPI 2 "register_operand" "r"))
2859         (const_int 0)))]
2860   ""
2861   "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
2862   [(set_attr "type" "logics_shift_imm")]
2865 ;; -------------------------------------------------------------------
2866 ;; Shifts
2867 ;; -------------------------------------------------------------------
2869 (define_expand "<optab><mode>3"
2870   [(set (match_operand:GPI 0 "register_operand")
2871         (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
2872                     (match_operand:QI 2 "nonmemory_operand")))]
2873   ""
2874   {
2875     if (CONST_INT_P (operands[2]))
2876       {
2877         operands[2] = GEN_INT (INTVAL (operands[2])
2878                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2880         if (operands[2] == const0_rtx)
2881           {
2882             emit_insn (gen_mov<mode> (operands[0], operands[1]));
2883             DONE;
2884           }
2885       }
2886   }
2889 (define_expand "ashl<mode>3"
2890   [(set (match_operand:SHORT 0 "register_operand")
2891         (ashift:SHORT (match_operand:SHORT 1 "register_operand")
2892                       (match_operand:QI 2 "nonmemory_operand")))]
2893   ""
2894   {
2895     if (CONST_INT_P (operands[2]))
2896       {
2897         operands[2] = GEN_INT (INTVAL (operands[2])
2898                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2900         if (operands[2] == const0_rtx)
2901           {
2902             emit_insn (gen_mov<mode> (operands[0], operands[1]));
2903             DONE;
2904           }
2905       }
2906   }
2909 (define_expand "rotr<mode>3"
2910   [(set (match_operand:GPI 0 "register_operand")
2911         (rotatert:GPI (match_operand:GPI 1 "register_operand")
2912                       (match_operand:QI 2 "nonmemory_operand")))]
2913   ""
2914   {
2915     if (CONST_INT_P (operands[2]))
2916       {
2917         operands[2] = GEN_INT (INTVAL (operands[2])
2918                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2920         if (operands[2] == const0_rtx)
2921           {
2922             emit_insn (gen_mov<mode> (operands[0], operands[1]));
2923             DONE;
2924           }
2925       }
2926   }
2929 (define_expand "rotl<mode>3"
2930   [(set (match_operand:GPI 0 "register_operand")
2931         (rotatert:GPI (match_operand:GPI 1 "register_operand")
2932                       (match_operand:QI 2 "nonmemory_operand")))]
2933   ""
2934   {
2935     /* (SZ - cnt) % SZ == -cnt % SZ */
2936     if (CONST_INT_P (operands[2]))
2937       {
2938         operands[2] = GEN_INT ((-INTVAL (operands[2]))
2939                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2940         if (operands[2] == const0_rtx)
2941           {
2942             emit_insn (gen_mov<mode> (operands[0], operands[1]));
2943             DONE;
2944           }
2945       }
2946     else
2947       operands[2] = expand_simple_unop (QImode, NEG, operands[2],
2948                                         NULL_RTX, 1);
2949   }
2952 ;; Logical left shift using SISD or Integer instruction
2953 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
2954   [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
2955         (ashift:GPI
2956           (match_operand:GPI 1 "register_operand" "w,w,r")
2957           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
2958   ""
2959   "@
2960    shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
2961    ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
2962    lsl\t%<w>0, %<w>1, %<w>2"
2963   [(set_attr "simd" "yes,yes,no")
2964    (set_attr "type" "neon_shift_imm<q>, neon_shift_reg<q>,shift_reg")]
2967 ;; Logical right shift using SISD or Integer instruction
2968 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
2969   [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
2970         (lshiftrt:GPI
2971           (match_operand:GPI 1 "register_operand" "w,w,r")
2972           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
2973   ""
2974   "@
2975    ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
2976    #
2977    lsr\t%<w>0, %<w>1, %<w>2"
2978   [(set_attr "simd" "yes,yes,no")
2979    (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")]
2982 (define_split
2983   [(set (match_operand:DI 0 "aarch64_simd_register")
2984         (lshiftrt:DI
2985            (match_operand:DI 1 "aarch64_simd_register")
2986            (match_operand:QI 2 "aarch64_simd_register")))]
2987   "TARGET_SIMD && reload_completed"
2988   [(set (match_dup 2)
2989         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
2990    (set (match_dup 0)
2991         (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_USHL))]
2992   ""
2995 (define_split
2996   [(set (match_operand:SI 0 "aarch64_simd_register")
2997         (lshiftrt:SI
2998            (match_operand:SI 1 "aarch64_simd_register")
2999            (match_operand:QI 2 "aarch64_simd_register")))]
3000   "TARGET_SIMD && reload_completed"
3001   [(set (match_dup 2)
3002         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3003    (set (match_dup 0)
3004         (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_USHL_2S))]
3005   ""
3008 ;; Arithmetic right shift using SISD or Integer instruction
3009 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3010   [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3011         (ashiftrt:GPI
3012           (match_operand:GPI 1 "register_operand" "w,w,r")
3013           (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,rUs<cmode>")))]
3014   ""
3015   "@
3016    sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3017    #
3018    asr\t%<w>0, %<w>1, %<w>2"
3019   [(set_attr "simd" "yes,yes,no")
3020    (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")]
3023 (define_split
3024   [(set (match_operand:DI 0 "aarch64_simd_register")
3025         (ashiftrt:DI
3026            (match_operand:DI 1 "aarch64_simd_register")
3027            (match_operand:QI 2 "aarch64_simd_register")))]
3028   "TARGET_SIMD && reload_completed"
3029   [(set (match_dup 2)
3030         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3031    (set (match_dup 0)
3032         (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_SSHL))]
3033   ""
3036 (define_split
3037   [(set (match_operand:SI 0 "aarch64_simd_register")
3038         (ashiftrt:SI
3039            (match_operand:SI 1 "aarch64_simd_register")
3040            (match_operand:QI 2 "aarch64_simd_register")))]
3041   "TARGET_SIMD && reload_completed"
3042   [(set (match_dup 2)
3043         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3044    (set (match_dup 0)
3045         (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_SSHL_2S))]
3046   ""
3049 (define_insn "*aarch64_sisd_ushl"
3050   [(set (match_operand:DI 0 "register_operand" "=w")
3051         (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3052                     (match_operand:QI 2 "register_operand" "w")]
3053                    UNSPEC_SISD_USHL))]
3054   "TARGET_SIMD"
3055   "ushl\t%d0, %d1, %d2"
3056   [(set_attr "simd" "yes")
3057    (set_attr "type" "neon_shift_reg")]
3060 (define_insn "*aarch64_ushl_2s"
3061   [(set (match_operand:SI 0 "register_operand" "=w")
3062         (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3063                     (match_operand:QI 2 "register_operand" "w")]
3064                    UNSPEC_USHL_2S))]
3065   "TARGET_SIMD"
3066   "ushl\t%0.2s, %1.2s, %2.2s"
3067   [(set_attr "simd" "yes")
3068    (set_attr "type" "neon_shift_reg")]
3071 (define_insn "*aarch64_sisd_sshl"
3072   [(set (match_operand:DI 0 "register_operand" "=w")
3073         (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3074                     (match_operand:QI 2 "register_operand" "w")]
3075                    UNSPEC_SISD_SSHL))]
3076   "TARGET_SIMD"
3077   "sshl\t%d0, %d1, %d2"
3078   [(set_attr "simd" "yes")
3079    (set_attr "type" "neon_shift_reg")]
3082 (define_insn "*aarch64_sshl_2s"
3083   [(set (match_operand:SI 0 "register_operand" "=w")
3084         (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3085                     (match_operand:QI 2 "register_operand" "w")]
3086                    UNSPEC_SSHL_2S))]
3087   "TARGET_SIMD"
3088   "sshl\t%0.2s, %1.2s, %2.2s"
3089   [(set_attr "simd" "yes")
3090    (set_attr "type" "neon_shift_reg")]
3093 (define_insn "*aarch64_sisd_neg_qi"
3094   [(set (match_operand:QI 0 "register_operand" "=w")
3095         (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3096                    UNSPEC_SISD_NEG))]
3097   "TARGET_SIMD"
3098   "neg\t%d0, %d1"
3099   [(set_attr "simd" "yes")
3100    (set_attr "type" "neon_neg")]
3103 ;; Rotate right
3104 (define_insn "*ror<mode>3_insn"
3105   [(set (match_operand:GPI 0 "register_operand" "=r")
3106         (rotatert:GPI
3107           (match_operand:GPI 1 "register_operand" "r")
3108           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3109   ""
3110   "ror\\t%<w>0, %<w>1, %<w>2"
3111   [(set_attr "type" "shift_reg")]
3114 ;; zero_extend version of above
3115 (define_insn "*<optab>si3_insn_uxtw"
3116   [(set (match_operand:DI 0 "register_operand" "=r")
3117         (zero_extend:DI (SHIFT:SI
3118          (match_operand:SI 1 "register_operand" "r")
3119          (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3120   ""
3121   "<shift>\\t%w0, %w1, %w2"
3122   [(set_attr "type" "shift_reg")]
3125 (define_insn "*ashl<mode>3_insn"
3126   [(set (match_operand:SHORT 0 "register_operand" "=r")
3127         (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3128                       (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
3129   ""
3130   "lsl\\t%<w>0, %<w>1, %<w>2"
3131   [(set_attr "type" "shift_reg")]
3134 (define_insn "*<optab><mode>3_insn"
3135   [(set (match_operand:SHORT 0 "register_operand" "=r")
3136         (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3137                       (match_operand 2 "const_int_operand" "n")))]
3138   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3140   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3141   return "<bfshift>\t%w0, %w1, %2, %3";
3143   [(set_attr "type" "bfm")]
3146 (define_insn "*extr<mode>5_insn"
3147   [(set (match_operand:GPI 0 "register_operand" "=r")
3148         (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3149                              (match_operand 3 "const_int_operand" "n"))
3150                  (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3151                                (match_operand 4 "const_int_operand" "n"))))]
3152   "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3153    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3154   "extr\\t%<w>0, %<w>1, %<w>2, %4"
3155   [(set_attr "type" "shift_imm")]
3158 ;; zero_extend version of the above
3159 (define_insn "*extrsi5_insn_uxtw"
3160   [(set (match_operand:DI 0 "register_operand" "=r")
3161         (zero_extend:DI
3162          (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3163                             (match_operand 3 "const_int_operand" "n"))
3164                  (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3165                               (match_operand 4 "const_int_operand" "n")))))]
3166   "UINTVAL (operands[3]) < 32 &&
3167    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3168   "extr\\t%w0, %w1, %w2, %4"
3169   [(set_attr "type" "shift_imm")]
3172 (define_insn "*ror<mode>3_insn"
3173   [(set (match_operand:GPI 0 "register_operand" "=r")
3174         (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3175                     (match_operand 2 "const_int_operand" "n")))]
3176   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3178   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3179   return "ror\\t%<w>0, %<w>1, %3";
3181   [(set_attr "type" "shift_imm")]
3184 ;; zero_extend version of the above
3185 (define_insn "*rorsi3_insn_uxtw"
3186   [(set (match_operand:DI 0 "register_operand" "=r")
3187         (zero_extend:DI
3188          (rotate:SI (match_operand:SI 1 "register_operand" "r")
3189                     (match_operand 2 "const_int_operand" "n"))))]
3190   "UINTVAL (operands[2]) < 32"
3192   operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3193   return "ror\\t%w0, %w1, %3";
3195   [(set_attr "type" "shift_imm")]
3198 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3199   [(set (match_operand:GPI 0 "register_operand" "=r")
3200         (ANY_EXTEND:GPI
3201          (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3202                        (match_operand 2 "const_int_operand" "n"))))]
3203   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3205   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3206   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3208   [(set_attr "type" "bfm")]
3211 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3212   [(set (match_operand:GPI 0 "register_operand" "=r")
3213         (zero_extend:GPI
3214          (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3215                          (match_operand 2 "const_int_operand" "n"))))]
3216   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3218   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3219   return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3221   [(set_attr "type" "bfm")]
3224 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3225   [(set (match_operand:GPI 0 "register_operand" "=r")
3226         (sign_extend:GPI
3227          (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3228                          (match_operand 2 "const_int_operand" "n"))))]
3229   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3231   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3232   return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3234   [(set_attr "type" "bfm")]
3237 ;; -------------------------------------------------------------------
3238 ;; Bitfields
3239 ;; -------------------------------------------------------------------
3241 (define_expand "<optab>"
3242   [(set (match_operand:DI 0 "register_operand" "=r")
3243         (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3244                         (match_operand 2 "const_int_operand" "n")
3245                         (match_operand 3 "const_int_operand" "n")))]
3246   ""
3247   ""
3250 (define_insn "*<optab><mode>"
3251   [(set (match_operand:GPI 0 "register_operand" "=r")
3252         (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3253                          (match_operand 2 "const_int_operand" "n")
3254                          (match_operand 3 "const_int_operand" "n")))]
3255   ""
3256   "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3257   [(set_attr "type" "bfm")]
3260 ;; Bitfield Insert (insv)
3261 (define_expand "insv<mode>"
3262   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3263                           (match_operand 1 "const_int_operand")
3264                           (match_operand 2 "const_int_operand"))
3265         (match_operand:GPI 3 "general_operand"))]
3266   ""
3268   unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3269   unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3270   rtx value = operands[3];
3272   if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3273     FAIL;
3275   if (CONST_INT_P (value))
3276     {
3277       unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3279       /* Prefer AND/OR for inserting all zeros or all ones.  */
3280       if ((UINTVAL (value) & mask) == 0
3281            || (UINTVAL (value) & mask) == mask)
3282         FAIL;
3284       /* 16-bit aligned 16-bit wide insert is handled by insv_imm.  */
3285       if (width == 16 && (pos % 16) == 0)
3286         DONE;
3287     }
3288   operands[3] = force_reg (<MODE>mode, value);
3291 (define_insn "*insv_reg<mode>"
3292   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3293                           (match_operand 1 "const_int_operand" "n")
3294                           (match_operand 2 "const_int_operand" "n"))
3295         (match_operand:GPI 3 "register_operand" "r"))]
3296   "!(UINTVAL (operands[1]) == 0
3297      || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3298          > GET_MODE_BITSIZE (<MODE>mode)))"
3299   "bfi\\t%<w>0, %<w>3, %2, %1"
3300   [(set_attr "type" "bfm")]
3303 (define_insn "*extr_insv_lower_reg<mode>"
3304   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3305                           (match_operand 1 "const_int_operand" "n")
3306                           (const_int 0))
3307         (zero_extract:GPI (match_operand:GPI 2 "register_operand" "+r")
3308                           (match_dup 1)
3309                           (match_operand 3 "const_int_operand" "n")))]
3310   "!(UINTVAL (operands[1]) == 0
3311      || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3312          > GET_MODE_BITSIZE (<MODE>mode)))"
3313   "bfxil\\t%<w>0, %<w>2, %3, %1"
3314   [(set_attr "type" "bfm")]
3317 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3318   [(set (match_operand:GPI 0 "register_operand" "=r")
3319         (ashift:GPI (ANY_EXTEND:GPI
3320                      (match_operand:ALLX 1 "register_operand" "r"))
3321                     (match_operand 2 "const_int_operand" "n")))]
3322   "UINTVAL (operands[2]) < <GPI:sizen>"
3324   operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3325               ? GEN_INT (<ALLX:sizen>)
3326               : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3327   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3329   [(set_attr "type" "bfm")]
3332 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3334 (define_insn "*andim_ashift<mode>_bfiz"
3335   [(set (match_operand:GPI 0 "register_operand" "=r")
3336         (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3337                              (match_operand 2 "const_int_operand" "n"))
3338                  (match_operand 3 "const_int_operand" "n")))]
3339   "exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3340    && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3341   "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3342   [(set_attr "type" "bfm")]
3345 (define_insn "bswap<mode>2"
3346   [(set (match_operand:GPI 0 "register_operand" "=r")
3347         (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3348   ""
3349   "rev\\t%<w>0, %<w>1"
3350   [(set_attr "type" "rev")]
3353 (define_insn "bswaphi2"
3354   [(set (match_operand:HI 0 "register_operand" "=r")
3355         (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3356   ""
3357   "rev16\\t%w0, %w1"
3358   [(set_attr "type" "rev")]
3361 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
3362 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
3363 ;; each valid permutation.
3365 (define_insn "rev16<mode>2"
3366   [(set (match_operand:GPI 0 "register_operand" "=r")
3367         (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3368                                       (const_int 8))
3369                           (match_operand:GPI 3 "const_int_operand" "n"))
3370                  (and:GPI (lshiftrt:GPI (match_dup 1)
3371                                         (const_int 8))
3372                           (match_operand:GPI 2 "const_int_operand" "n"))))]
3373   "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3374    && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3375   "rev16\\t%<w>0, %<w>1"
3376   [(set_attr "type" "rev")]
3379 (define_insn "rev16<mode>2_alt"
3380   [(set (match_operand:GPI 0 "register_operand" "=r")
3381         (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r")
3382                                         (const_int 8))
3383                           (match_operand:GPI 2 "const_int_operand" "n"))
3384                  (and:GPI (ashift:GPI (match_dup 1)
3385                                       (const_int 8))
3386                           (match_operand:GPI 3 "const_int_operand" "n"))))]
3387   "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3388    && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3389   "rev16\\t%<w>0, %<w>1"
3390   [(set_attr "type" "rev")]
3393 ;; zero_extend version of above
3394 (define_insn "*bswapsi2_uxtw"
3395   [(set (match_operand:DI 0 "register_operand" "=r")
3396         (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3397   ""
3398   "rev\\t%w0, %w1"
3399   [(set_attr "type" "rev")]
3402 ;; -------------------------------------------------------------------
3403 ;; Floating-point intrinsics
3404 ;; -------------------------------------------------------------------
3406 ;; frint floating-point round to integral standard patterns.
3407 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round, frintn.
3409 (define_insn "<frint_pattern><mode>2"
3410   [(set (match_operand:GPF 0 "register_operand" "=w")
3411         (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3412          FRINT))]
3413   "TARGET_FLOAT"
3414   "frint<frint_suffix>\\t%<s>0, %<s>1"
3415   [(set_attr "type" "f_rint<s>")]
3418 ;; frcvt floating-point round to integer and convert standard patterns.
3419 ;; Expands to lbtrunc, lceil, lfloor, lround.
3420 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3421   [(set (match_operand:GPI 0 "register_operand" "=r")
3422         (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3423                       FCVT)))]
3424   "TARGET_FLOAT"
3425   "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3426   [(set_attr "type" "f_cvtf2i")]
3429 ;; fma - no throw
3431 (define_insn "fma<mode>4"
3432   [(set (match_operand:GPF 0 "register_operand" "=w")
3433         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3434                  (match_operand:GPF 2 "register_operand" "w")
3435                  (match_operand:GPF 3 "register_operand" "w")))]
3436   "TARGET_FLOAT"
3437   "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3438   [(set_attr "type" "fmac<s>")]
3441 (define_insn "fnma<mode>4"
3442   [(set (match_operand:GPF 0 "register_operand" "=w")
3443         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3444                  (match_operand:GPF 2 "register_operand" "w")
3445                  (match_operand:GPF 3 "register_operand" "w")))]
3446   "TARGET_FLOAT"
3447   "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3448   [(set_attr "type" "fmac<s>")]
3451 (define_insn "fms<mode>4"
3452   [(set (match_operand:GPF 0 "register_operand" "=w")
3453         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3454                  (match_operand:GPF 2 "register_operand" "w")
3455                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3456   "TARGET_FLOAT"
3457   "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3458   [(set_attr "type" "fmac<s>")]
3461 (define_insn "fnms<mode>4"
3462   [(set (match_operand:GPF 0 "register_operand" "=w")
3463         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3464                  (match_operand:GPF 2 "register_operand" "w")
3465                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3466   "TARGET_FLOAT"
3467   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3468   [(set_attr "type" "fmac<s>")]
3471 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3472 (define_insn "*fnmadd<mode>4"
3473   [(set (match_operand:GPF 0 "register_operand" "=w")
3474         (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3475                           (match_operand:GPF 2 "register_operand" "w")
3476                           (match_operand:GPF 3 "register_operand" "w"))))]
3477   "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3478   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3479   [(set_attr "type" "fmac<s>")]
3482 ;; -------------------------------------------------------------------
3483 ;; Floating-point conversions
3484 ;; -------------------------------------------------------------------
3486 (define_insn "extendsfdf2"
3487   [(set (match_operand:DF 0 "register_operand" "=w")
3488         (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3489   "TARGET_FLOAT"
3490   "fcvt\\t%d0, %s1"
3491   [(set_attr "type" "f_cvt")]
3494 (define_insn "truncdfsf2"
3495   [(set (match_operand:SF 0 "register_operand" "=w")
3496         (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3497   "TARGET_FLOAT"
3498   "fcvt\\t%s0, %d1"
3499   [(set_attr "type" "f_cvt")]
3502 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3503   [(set (match_operand:GPI 0 "register_operand" "=r")
3504         (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3505   "TARGET_FLOAT"
3506   "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3507   [(set_attr "type" "f_cvtf2i")]
3510 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3511   [(set (match_operand:GPI 0 "register_operand" "=r")
3512         (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3513   "TARGET_FLOAT"
3514   "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3515   [(set_attr "type" "f_cvtf2i")]
3518 (define_insn "<optab><fcvt_target><GPF:mode>2"
3519   [(set (match_operand:GPF 0 "register_operand" "=w,w")
3520         (FLOATUORS:GPF (match_operand:<FCVT_TARGET> 1 "register_operand" "w,r")))]
3521   ""
3522   "@
3523    <su_optab>cvtf\t%<GPF:s>0, %<s>1
3524    <su_optab>cvtf\t%<GPF:s>0, %<w1>1"
3525   [(set_attr "simd" "yes,no")
3526    (set_attr "fp" "no,yes")
3527    (set_attr "type" "neon_int_to_fp_<Vetype>,f_cvti2f")]
3530 (define_insn "<optab><fcvt_iesize><GPF:mode>2"
3531   [(set (match_operand:GPF 0 "register_operand" "=w")
3532         (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand" "r")))]
3533   "TARGET_FLOAT"
3534   "<su_optab>cvtf\t%<GPF:s>0, %<w2>1"
3535   [(set_attr "type" "f_cvti2f")]
3538 ;; -------------------------------------------------------------------
3539 ;; Floating-point arithmetic
3540 ;; -------------------------------------------------------------------
3542 (define_insn "add<mode>3"
3543   [(set (match_operand:GPF 0 "register_operand" "=w")
3544         (plus:GPF
3545          (match_operand:GPF 1 "register_operand" "w")
3546          (match_operand:GPF 2 "register_operand" "w")))]
3547   "TARGET_FLOAT"
3548   "fadd\\t%<s>0, %<s>1, %<s>2"
3549   [(set_attr "type" "fadd<s>")]
3552 (define_insn "sub<mode>3"
3553   [(set (match_operand:GPF 0 "register_operand" "=w")
3554         (minus:GPF
3555          (match_operand:GPF 1 "register_operand" "w")
3556          (match_operand:GPF 2 "register_operand" "w")))]
3557   "TARGET_FLOAT"
3558   "fsub\\t%<s>0, %<s>1, %<s>2"
3559   [(set_attr "type" "fadd<s>")]
3562 (define_insn "mul<mode>3"
3563   [(set (match_operand:GPF 0 "register_operand" "=w")
3564         (mult:GPF
3565          (match_operand:GPF 1 "register_operand" "w")
3566          (match_operand:GPF 2 "register_operand" "w")))]
3567   "TARGET_FLOAT"
3568   "fmul\\t%<s>0, %<s>1, %<s>2"
3569   [(set_attr "type" "fmul<s>")]
3572 (define_insn "*fnmul<mode>3"
3573   [(set (match_operand:GPF 0 "register_operand" "=w")
3574         (mult:GPF
3575                  (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3576                  (match_operand:GPF 2 "register_operand" "w")))]
3577   "TARGET_FLOAT"
3578   "fnmul\\t%<s>0, %<s>1, %<s>2"
3579   [(set_attr "type" "fmul<s>")]
3582 (define_insn "div<mode>3"
3583   [(set (match_operand:GPF 0 "register_operand" "=w")
3584         (div:GPF
3585          (match_operand:GPF 1 "register_operand" "w")
3586          (match_operand:GPF 2 "register_operand" "w")))]
3587   "TARGET_FLOAT"
3588   "fdiv\\t%<s>0, %<s>1, %<s>2"
3589   [(set_attr "type" "fdiv<s>")]
3592 (define_insn "neg<mode>2"
3593   [(set (match_operand:GPF 0 "register_operand" "=w")
3594         (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
3595   "TARGET_FLOAT"
3596   "fneg\\t%<s>0, %<s>1"
3597   [(set_attr "type" "ffarith<s>")]
3600 (define_insn "sqrt<mode>2"
3601   [(set (match_operand:GPF 0 "register_operand" "=w")
3602         (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
3603   "TARGET_FLOAT"
3604   "fsqrt\\t%<s>0, %<s>1"
3605   [(set_attr "type" "fsqrt<s>")]
3608 (define_insn "abs<mode>2"
3609   [(set (match_operand:GPF 0 "register_operand" "=w")
3610         (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
3611   "TARGET_FLOAT"
3612   "fabs\\t%<s>0, %<s>1"
3613   [(set_attr "type" "ffarith<s>")]
3616 ;; Given that smax/smin do not specify the result when either input is NaN,
3617 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
3618 ;; for smin.
3620 (define_insn "smax<mode>3"
3621   [(set (match_operand:GPF 0 "register_operand" "=w")
3622         (smax:GPF (match_operand:GPF 1 "register_operand" "w")
3623                   (match_operand:GPF 2 "register_operand" "w")))]
3624   "TARGET_FLOAT"
3625   "fmaxnm\\t%<s>0, %<s>1, %<s>2"
3626   [(set_attr "type" "f_minmax<s>")]
3629 (define_insn "smin<mode>3"
3630   [(set (match_operand:GPF 0 "register_operand" "=w")
3631         (smin:GPF (match_operand:GPF 1 "register_operand" "w")
3632                   (match_operand:GPF 2 "register_operand" "w")))]
3633   "TARGET_FLOAT"
3634   "fminnm\\t%<s>0, %<s>1, %<s>2"
3635   [(set_attr "type" "f_minmax<s>")]
3638 ;; -------------------------------------------------------------------
3639 ;; Reload support
3640 ;; -------------------------------------------------------------------
3642 (define_expand "aarch64_reload_mov<mode>"
3643   [(set (match_operand:TX 0 "register_operand" "=w")
3644         (match_operand:TX 1 "register_operand" "w"))
3645    (clobber (match_operand:DI 2 "register_operand" "=&r"))
3646   ]
3647   ""
3648   {
3649     rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
3650     rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
3651     gen_aarch64_movtilow_tilow (op0, op1);
3652     gen_aarch64_movdi_tihigh (operands[2], op1);
3653     gen_aarch64_movtihigh_di (op0, operands[2]);
3654     DONE;
3655   }
3658 ;; The following secondary reload helpers patterns are invoked
3659 ;; after or during reload as we don't want these patterns to start
3660 ;; kicking in during the combiner.
3662 (define_insn "aarch64_movdi_<mode>low"
3663   [(set (match_operand:DI 0 "register_operand" "=r")
3664         (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
3665   "reload_completed || reload_in_progress"
3666   "fmov\\t%x0, %d1"
3667   [(set_attr "type" "f_mrc")
3668    (set_attr "length" "4")
3669   ])
3671 (define_insn "aarch64_movdi_<mode>high"
3672   [(set (match_operand:DI 0 "register_operand" "=r")
3673         (truncate:DI
3674           (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
3675                        (const_int 64))))]
3676   "reload_completed || reload_in_progress"
3677   "fmov\\t%x0, %1.d[1]"
3678   [(set_attr "type" "f_mrc")
3679    (set_attr "length" "4")
3680   ])
3682 (define_insn "aarch64_mov<mode>high_di"
3683   [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
3684                          (const_int 64) (const_int 64))
3685         (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
3686   "reload_completed || reload_in_progress"
3687   "fmov\\t%0.d[1], %x1"
3688   [(set_attr "type" "f_mcr")
3689    (set_attr "length" "4")
3690   ])
3692 (define_insn "aarch64_mov<mode>low_di"
3693   [(set (match_operand:TX 0 "register_operand" "=w")
3694         (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
3695   "reload_completed || reload_in_progress"
3696   "fmov\\t%d0, %x1"
3697   [(set_attr "type" "f_mcr")
3698    (set_attr "length" "4")
3699   ])
3701 (define_insn "aarch64_movtilow_tilow"
3702   [(set (match_operand:TI 0 "register_operand" "=w")
3703         (zero_extend:TI 
3704           (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
3705   "reload_completed || reload_in_progress"
3706   "fmov\\t%d0, %d1"
3707   [(set_attr "type" "fmov")
3708    (set_attr "length" "4")
3709   ])
3711 ;; There is a deliberate reason why the parameters of high and lo_sum's
3712 ;; don't have modes for ADRP and ADD instructions.  This is to allow high
3713 ;; and lo_sum's to be used with the labels defining the jump tables in
3714 ;; rodata section.
3716 (define_expand "add_losym"
3717   [(set (match_operand 0 "register_operand" "=r")
3718         (lo_sum (match_operand 1 "register_operand" "r")
3719                 (match_operand 2 "aarch64_valid_symref" "S")))]
3720   ""
3722   enum machine_mode mode = GET_MODE (operands[0]);
3724   emit_insn ((mode == DImode
3725               ? gen_add_losym_di
3726               : gen_add_losym_si) (operands[0],
3727                                    operands[1],
3728                                    operands[2]));
3729   DONE;
3732 (define_insn "add_losym_<mode>"
3733   [(set (match_operand:P 0 "register_operand" "=r")
3734         (lo_sum:P (match_operand:P 1 "register_operand" "r")
3735                   (match_operand 2 "aarch64_valid_symref" "S")))]
3736   ""
3737   "add\\t%<w>0, %<w>1, :lo12:%a2"
3738   [(set_attr "type" "alu_reg")]
3741 (define_insn "ldr_got_small_<mode>"
3742   [(set (match_operand:PTR 0 "register_operand" "=r")
3743         (unspec:PTR [(mem:PTR (lo_sum:PTR
3744                               (match_operand:PTR 1 "register_operand" "r")
3745                               (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
3746                     UNSPEC_GOTSMALLPIC))]
3747   ""
3748   "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
3749   [(set_attr "type" "load1")]
3752 (define_insn "ldr_got_small_sidi"
3753   [(set (match_operand:DI 0 "register_operand" "=r")
3754         (zero_extend:DI
3755          (unspec:SI [(mem:SI (lo_sum:DI
3756                              (match_operand:DI 1 "register_operand" "r")
3757                              (match_operand:DI 2 "aarch64_valid_symref" "S")))]
3758                     UNSPEC_GOTSMALLPIC)))]
3759   "TARGET_ILP32"
3760   "ldr\\t%w0, [%1, #:got_lo12:%a2]"
3761   [(set_attr "type" "load1")]
3764 (define_insn "ldr_got_tiny"
3765   [(set (match_operand:DI 0 "register_operand" "=r")
3766         (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
3767                    UNSPEC_GOTTINYPIC))]
3768   ""
3769   "ldr\\t%0, %L1"
3770   [(set_attr "type" "load1")]
3773 (define_insn "aarch64_load_tp_hard"
3774   [(set (match_operand:DI 0 "register_operand" "=r")
3775         (unspec:DI [(const_int 0)] UNSPEC_TLS))]
3776   ""
3777   "mrs\\t%0, tpidr_el0"
3778   [(set_attr "type" "mrs")]
3781 ;; The TLS ABI specifically requires that the compiler does not schedule
3782 ;; instructions in the TLS stubs, in order to enable linker relaxation.
3783 ;; Therefore we treat the stubs as an atomic sequence.
3784 (define_expand "tlsgd_small"
3785  [(parallel [(set (match_operand 0 "register_operand" "")
3786                   (call (mem:DI (match_dup 2)) (const_int 1)))
3787              (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
3788              (clobber (reg:DI LR_REGNUM))])]
3789  ""
3791   operands[2] = aarch64_tls_get_addr ();
3794 (define_insn "*tlsgd_small"
3795   [(set (match_operand 0 "register_operand" "")
3796         (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
3797    (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
3798    (clobber (reg:DI LR_REGNUM))
3799   ]
3800   ""
3801   "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
3802   [(set_attr "type" "call")
3803    (set_attr "length" "16")])
3805 (define_insn "tlsie_small_<mode>"
3806   [(set (match_operand:PTR 0 "register_operand" "=r")
3807         (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
3808                    UNSPEC_GOTSMALLTLS))]
3809   ""
3810   "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
3811   [(set_attr "type" "load1")
3812    (set_attr "length" "8")]
3815 (define_insn "tlsie_small_sidi"
3816   [(set (match_operand:DI 0 "register_operand" "=r")
3817         (zero_extend:DI
3818           (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")]
3819                       UNSPEC_GOTSMALLTLS)))]
3820   ""
3821   "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
3822   [(set_attr "type" "load1")
3823    (set_attr "length" "8")]
3826 (define_expand "tlsle_small"
3827   [(set (match_operand 0 "register_operand" "=r")
3828         (unspec [(match_operand 1 "register_operand" "r")
3829                    (match_operand 2 "aarch64_tls_le_symref" "S")]
3830                    UNSPEC_GOTSMALLTLS))]
3831   ""
3833   enum machine_mode mode = GET_MODE (operands[0]);
3834   emit_insn ((mode == DImode
3835               ? gen_tlsle_small_di
3836               : gen_tlsle_small_si) (operands[0],
3837                                      operands[1],
3838                                      operands[2]));
3839   DONE;
3842 (define_insn "tlsle_small_<mode>"
3843   [(set (match_operand:P 0 "register_operand" "=r")
3844         (unspec:P [(match_operand:P 1 "register_operand" "r")
3845                    (match_operand 2 "aarch64_tls_le_symref" "S")]
3846                    UNSPEC_GOTSMALLTLS))]
3847   ""
3848   "add\\t%<w>0, %<w>1, #%G2\;add\\t%<w>0, %<w>0, #%L2"
3849   [(set_attr "type" "alu_reg")
3850    (set_attr "length" "8")]
3853 (define_insn "tlsdesc_small_<mode>"
3854   [(set (reg:PTR R0_REGNUM)
3855         (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
3856                    UNSPEC_TLSDESC))
3857    (clobber (reg:DI LR_REGNUM))
3858    (clobber (match_scratch:DI 1 "=r"))]
3859   "TARGET_TLS_DESC"
3860   "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
3861   [(set_attr "type" "call")
3862    (set_attr "length" "16")])
3864 (define_insn "stack_tie"
3865   [(set (mem:BLK (scratch))
3866         (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
3867                      (match_operand:DI 1 "register_operand" "rk")]
3868                     UNSPEC_PRLG_STK))]
3869   ""
3870   ""
3871   [(set_attr "length" "0")]
3874 ;; Named pattern for expanding thread pointer reference.
3875 (define_expand "get_thread_pointerdi"
3876   [(match_operand:DI 0 "register_operand" "=r")]
3877   ""
3879   rtx tmp = aarch64_load_tp (operands[0]);
3880   if (tmp != operands[0])
3881     emit_move_insn (operands[0], tmp);
3882   DONE;
3885 ;; Named patterns for stack smashing protection.
3886 (define_expand "stack_protect_set"
3887   [(match_operand 0 "memory_operand")
3888    (match_operand 1 "memory_operand")]
3889   ""
3891   enum machine_mode mode = GET_MODE (operands[0]);
3893   emit_insn ((mode == DImode
3894               ? gen_stack_protect_set_di
3895               : gen_stack_protect_set_si) (operands[0], operands[1]));
3896   DONE;
3899 (define_insn "stack_protect_set_<mode>"
3900   [(set (match_operand:PTR 0 "memory_operand" "=m")
3901         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
3902          UNSPEC_SP_SET))
3903    (set (match_scratch:PTR 2 "=&r") (const_int 0))]
3904   ""
3905   "ldr\\t%<w>2, %1\;str\\t%<w>2, %0\;mov\t%<w>2,0"
3906   [(set_attr "length" "12")
3907    (set_attr "type" "multiple")])
3909 (define_expand "stack_protect_test"
3910   [(match_operand 0 "memory_operand")
3911    (match_operand 1 "memory_operand")
3912    (match_operand 2)]
3913   ""
3915   rtx result;
3916   enum machine_mode mode = GET_MODE (operands[0]);
3918   result = gen_reg_rtx(mode);
3920   emit_insn ((mode == DImode
3921               ? gen_stack_protect_test_di
3922               : gen_stack_protect_test_si) (result,
3923                                             operands[0],
3924                                             operands[1]));
3926   if (mode == DImode)
3927     emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
3928                                     result, const0_rtx, operands[2]));
3929   else
3930     emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
3931                                     result, const0_rtx, operands[2]));
3932   DONE;
3935 (define_insn "stack_protect_test_<mode>"
3936   [(set (match_operand:PTR 0 "register_operand")
3937         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
3938                      (match_operand:PTR 2 "memory_operand" "m")]
3939          UNSPEC_SP_TEST))
3940    (clobber (match_scratch:PTR 3 "=&r"))]
3941   ""
3942   "ldr\t%<w>3, %x1\;ldr\t%<w>0, %x2\;eor\t%<w>0, %<w>3, %<w>0"
3943   [(set_attr "length" "12")
3944    (set_attr "type" "multiple")])
3946 ;; Write Floating-point Control Register.
3947 (define_insn "set_fpcr"
3948   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
3949   ""
3950   "msr\\tfpcr, %0"
3951   [(set_attr "type" "mrs")])
3953 ;; Read Floating-point Control Register.
3954 (define_insn "get_fpcr"
3955   [(set (match_operand:SI 0 "register_operand" "=r")
3956         (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
3957   ""
3958   "mrs\\t%0, fpcr"
3959   [(set_attr "type" "mrs")])
3961 ;; Write Floating-point Status Register.
3962 (define_insn "set_fpsr"
3963   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
3964   ""
3965   "msr\\tfpsr, %0"
3966   [(set_attr "type" "mrs")])
3968 ;; Read Floating-point Status Register.
3969 (define_insn "get_fpsr"
3970   [(set (match_operand:SI 0 "register_operand" "=r")
3971         (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
3972   ""
3973   "mrs\\t%0, fpsr"
3974   [(set_attr "type" "mrs")])
3977 ;; AdvSIMD Stuff
3978 (include "aarch64-simd.md")
3980 ;; Atomic Operations
3981 (include "atomics.md")