2014-09-03 Yvan Roux <yvan.roux@linaro.org>
[official-gcc.git] / gcc-4_9-branch / gcc / config / aarch64 / aarch64.md
blobcc957d7c83eeb2ddbc70e7e51d3543e08816499f
1 ;; Machine description for AArch64 architecture.
2 ;; Copyright (C) 2009-2014 Free Software Foundation, Inc.
3 ;; Contributed by ARM Ltd.
4 ;;
5 ;; This file is part of GCC.
6 ;;
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
12 ;; GCC is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 ;; General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;; Register numbers
22 (define_constants
23   [
24     (R0_REGNUM          0)
25     (R1_REGNUM          1)
26     (R2_REGNUM          2)
27     (R3_REGNUM          3)
28     (R4_REGNUM          4)
29     (R5_REGNUM          5)
30     (R6_REGNUM          6)
31     (R7_REGNUM          7)
32     (R8_REGNUM          8)
33     (R9_REGNUM          9)
34     (R10_REGNUM         10)
35     (R11_REGNUM         11)
36     (R12_REGNUM         12)
37     (R13_REGNUM         13)
38     (R14_REGNUM         14)
39     (R15_REGNUM         15)
40     (R16_REGNUM         16)
41     (IP0_REGNUM         16)
42     (R17_REGNUM         17)
43     (IP1_REGNUM         17)
44     (R18_REGNUM         18)
45     (R19_REGNUM         19)
46     (R20_REGNUM         20)
47     (R21_REGNUM         21)
48     (R22_REGNUM         22)
49     (R23_REGNUM         23)
50     (R24_REGNUM         24)
51     (R25_REGNUM         25)
52     (R26_REGNUM         26)
53     (R27_REGNUM         27)
54     (R28_REGNUM         28)
55     (R29_REGNUM         29)
56     (R30_REGNUM         30)
57     (LR_REGNUM          30)
58     (SP_REGNUM          31)
59     (V0_REGNUM          32)
60     (V15_REGNUM         47)
61     (V31_REGNUM         63)
62     (SFP_REGNUM         64)
63     (AP_REGNUM          65)
64     (CC_REGNUM          66)
65   ]
68 (define_c_enum "unspec" [
69     UNSPEC_CASESI
70     UNSPEC_CRC32B
71     UNSPEC_CRC32CB
72     UNSPEC_CRC32CH
73     UNSPEC_CRC32CW
74     UNSPEC_CRC32CX
75     UNSPEC_CRC32H
76     UNSPEC_CRC32W
77     UNSPEC_CRC32X
78     UNSPEC_FRECPE
79     UNSPEC_FRECPS
80     UNSPEC_FRECPX
81     UNSPEC_FRINTA
82     UNSPEC_FRINTI
83     UNSPEC_FRINTM
84     UNSPEC_FRINTN
85     UNSPEC_FRINTP
86     UNSPEC_FRINTX
87     UNSPEC_FRINTZ
88     UNSPEC_GOTSMALLPIC
89     UNSPEC_GOTSMALLTLS
90     UNSPEC_GOTTINYPIC
91     UNSPEC_LD1
92     UNSPEC_LD2
93     UNSPEC_LD3
94     UNSPEC_LD4
95     UNSPEC_MB
96     UNSPEC_NOP
97     UNSPEC_PRLG_STK
98     UNSPEC_RBIT
99     UNSPEC_SISD_NEG
100     UNSPEC_SISD_SSHL
101     UNSPEC_SISD_USHL
102     UNSPEC_SSHL_2S
103     UNSPEC_SSHR64
104     UNSPEC_ST1
105     UNSPEC_ST2
106     UNSPEC_ST3
107     UNSPEC_ST4
108     UNSPEC_ST2_LANE
109     UNSPEC_ST3_LANE
110     UNSPEC_ST4_LANE
111     UNSPEC_TLS
112     UNSPEC_TLSDESC
113     UNSPEC_USHL_2S
114     UNSPEC_USHR64
115     UNSPEC_VSTRUCTDUMMY
116     UNSPEC_SP_SET
117     UNSPEC_SP_TEST
120 (define_c_enum "unspecv" [
121     UNSPECV_EH_RETURN           ; Represent EH_RETURN
122     UNSPECV_GET_FPCR            ; Represent fetch of FPCR content.
123     UNSPECV_SET_FPCR            ; Represent assign of FPCR content.
124     UNSPECV_GET_FPSR            ; Represent fetch of FPSR content.
125     UNSPECV_SET_FPSR            ; Represent assign of FPSR content.
126   ]
129 ;; If further include files are added the defintion of MD_INCLUDES
130 ;; must be updated.
132 (include "constraints.md")
133 (include "predicates.md")
134 (include "iterators.md")
136 ;; -------------------------------------------------------------------
137 ;; Instruction types and attributes
138 ;; -------------------------------------------------------------------
140 ; The "type" attribute is is included here from AArch32 backend to be able
141 ; to share pipeline descriptions.
142 (include "../arm/types.md")
144 ;; It is important to set the fp or simd attributes to yes when a pattern
145 ;; alternative uses the FP or SIMD register files, usually signified by use of
146 ;; the 'w' constraint.  This will ensure that the alternative will be
147 ;; disabled when compiling with -mgeneral-regs-only or with the +nofp/+nosimd
148 ;; architecture extensions.  If all the alternatives in a pattern use the
149 ;; FP or SIMD registers then the pattern predicate should include TARGET_FLOAT
150 ;; or TARGET_SIMD.
152 ;; Attribute that specifies whether or not the instruction touches fp
153 ;; registers.  When this is set to yes for an alternative, that alternative
154 ;; will be disabled when !TARGET_FLOAT.
155 (define_attr "fp" "no,yes" (const_string "no"))
157 ;; Attribute that specifies whether or not the instruction touches simd
158 ;; registers.  When this is set to yes for an alternative, that alternative
159 ;; will be disabled when !TARGET_SIMD.
160 (define_attr "simd" "no,yes" (const_string "no"))
162 (define_attr "length" ""
163   (const_int 4))
165 ;; Attribute that controls whether an alternative is enabled or not.
166 ;; Currently it is only used to disable alternatives which touch fp or simd
167 ;; registers when -mgeneral-regs-only is specified.
168 (define_attr "enabled" "no,yes"
169   (cond [(ior
170         (and (eq_attr "fp" "yes")
171              (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
172         (and (eq_attr "simd" "yes")
173              (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
174              (const_string "no")
175         ] (const_string "yes")))
177 ;; -------------------------------------------------------------------
178 ;; Pipeline descriptions and scheduling
179 ;; -------------------------------------------------------------------
181 ;; Processor types.
182 (include "aarch64-tune.md")
184 ;; True if the generic scheduling description should be used.
186 (define_attr "generic_sched" "yes,no"
187   (const (if_then_else
188           (eq_attr "tune" "cortexa53,cortexa15")
189           (const_string "no")
190           (const_string "yes"))))
192 ;; Scheduling
193 (include "../arm/cortex-a53.md")
194 (include "../arm/cortex-a15.md")
196 ;; -------------------------------------------------------------------
197 ;; Jumps and other miscellaneous insns
198 ;; -------------------------------------------------------------------
200 (define_insn "indirect_jump"
201   [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
202   ""
203   "br\\t%0"
204   [(set_attr "type" "branch")]
207 (define_insn "jump"
208   [(set (pc) (label_ref (match_operand 0 "" "")))]
209   ""
210   "b\\t%l0"
211   [(set_attr "type" "branch")]
214 (define_expand "cbranch<mode>4"
215   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
216                             [(match_operand:GPI 1 "register_operand" "")
217                              (match_operand:GPI 2 "aarch64_plus_operand" "")])
218                            (label_ref (match_operand 3 "" ""))
219                            (pc)))]
220   ""
221   "
222   operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
223                                          operands[2]);
224   operands[2] = const0_rtx;
225   "
228 (define_expand "cbranch<mode>4"
229   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
230                             [(match_operand:GPF 1 "register_operand" "")
231                              (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
232                            (label_ref (match_operand 3 "" ""))
233                            (pc)))]
234   ""
235   "
236   operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
237                                          operands[2]);
238   operands[2] = const0_rtx;
239   "
242 (define_insn "*condjump"
243   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
244                             [(match_operand 1 "cc_register" "") (const_int 0)])
245                            (label_ref (match_operand 2 "" ""))
246                            (pc)))]
247   ""
248   "b%m0\\t%l2"
249   [(set_attr "type" "branch")]
252 (define_expand "casesi"
253   [(match_operand:SI 0 "register_operand" "")   ; Index
254    (match_operand:SI 1 "const_int_operand" "")  ; Lower bound
255    (match_operand:SI 2 "const_int_operand" "")  ; Total range
256    (match_operand:DI 3 "" "")                   ; Table label
257    (match_operand:DI 4 "" "")]                  ; Out of range label
258   ""
259   {
260     if (operands[1] != const0_rtx)
261       {
262         rtx reg = gen_reg_rtx (SImode);
264         /* Canonical RTL says that if you have:
266            (minus (X) (CONST))
268            then this should be emitted as:
270            (plus (X) (-CONST))
272            The use of trunc_int_for_mode ensures that the resulting
273            constant can be represented in SImode, this is important
274            for the corner case where operand[1] is INT_MIN.  */
276         operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
278         if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
279               (operands[1], SImode))
280           operands[1] = force_reg (SImode, operands[1]);
281         emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
282         operands[0] = reg;
283       }
285     if (!aarch64_plus_operand (operands[2], SImode))
286       operands[2] = force_reg (SImode, operands[2]);
287     emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
288                                                  const0_rtx),
289                                     operands[0], operands[2], operands[4]));
291     operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
292     emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
293                                          operands[3]));
294     DONE;
295   }
298 (define_insn "casesi_dispatch"
299   [(parallel
300     [(set (pc)
301           (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
302                            (match_operand:SI 1 "register_operand" "r")]
303                         UNSPEC_CASESI)))
304      (clobber (reg:CC CC_REGNUM))
305      (clobber (match_scratch:DI 3 "=r"))
306      (clobber (match_scratch:DI 4 "=r"))
307      (use (label_ref (match_operand 2 "" "")))])]
308   ""
309   "*
310   return aarch64_output_casesi (operands);
311   "
312   [(set_attr "length" "16")
313    (set_attr "type" "branch")]
316 (define_insn "nop"
317   [(unspec[(const_int 0)] UNSPEC_NOP)]
318   ""
319   "nop"
320   [(set_attr "type" "no_insn")]
323 (define_insn "trap"
324   [(trap_if (const_int 1) (const_int 8))]
325   ""
326   "brk #1000"
327   [(set_attr "type" "trap")])
329 (define_expand "prologue"
330   [(clobber (const_int 0))]
331   ""
332   "
333   aarch64_expand_prologue ();
334   DONE;
335   "
338 (define_expand "epilogue"
339   [(clobber (const_int 0))]
340   ""
341   "
342   aarch64_expand_epilogue (false);
343   DONE;
344   "
347 (define_expand "sibcall_epilogue"
348   [(clobber (const_int 0))]
349   ""
350   "
351   aarch64_expand_epilogue (true);
352   DONE;
353   "
356 (define_insn "*do_return"
357   [(return)]
358   ""
359   "ret"
360   [(set_attr "type" "branch")]
363 (define_insn "eh_return"
364   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
365     UNSPECV_EH_RETURN)]
366   ""
367   "#"
368   [(set_attr "type" "branch")]
372 (define_split
373   [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
374     UNSPECV_EH_RETURN)]
375   "reload_completed"
376   [(set (match_dup 1) (match_dup 0))]
377   {
378     operands[1] = aarch64_final_eh_return_addr ();
379   }
382 (define_insn "*cb<optab><mode>1"
383   [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
384                                 (const_int 0))
385                            (label_ref (match_operand 1 "" ""))
386                            (pc)))]
387   ""
388   "<cbz>\\t%<w>0, %l1"
389   [(set_attr "type" "branch")]
393 (define_insn "*tb<optab><mode>1"
394   [(set (pc) (if_then_else
395               (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
396                                     (const_int 1)
397                                     (match_operand 1 "const_int_operand" "n"))
398                    (const_int 0))
399              (label_ref (match_operand 2 "" ""))
400              (pc)))
401    (clobber (match_scratch:DI 3 "=r"))]
402   ""
403   "*
404   if (get_attr_length (insn) == 8)
405     return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
406   return \"<tbz>\\t%<w>0, %1, %l2\";
407   "
408   [(set_attr "type" "branch")
409    (set (attr "length")
410         (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
411                            (lt (minus (match_dup 2) (pc)) (const_int 32764)))
412                       (const_int 4)
413                       (const_int 8)))]
416 (define_insn "*cb<optab><mode>1"
417   [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
418                                  (const_int 0))
419                            (label_ref (match_operand 1 "" ""))
420                            (pc)))
421    (clobber (match_scratch:DI 2 "=r"))]
422   ""
423   "*
424   if (get_attr_length (insn) == 8)
425     return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
426   return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
427   "
428   [(set_attr "type" "branch")
429    (set (attr "length")
430         (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
431                            (lt (minus (match_dup 1) (pc)) (const_int 32764)))
432                       (const_int 4)
433                       (const_int 8)))]
436 ;; -------------------------------------------------------------------
437 ;; Subroutine calls and sibcalls
438 ;; -------------------------------------------------------------------
440 (define_expand "call"
441   [(parallel [(call (match_operand 0 "memory_operand" "")
442                     (match_operand 1 "general_operand" ""))
443               (use (match_operand 2 "" ""))
444               (clobber (reg:DI LR_REGNUM))])]
445   ""
446   "
447   {
448     rtx callee;
450     /* In an untyped call, we can get NULL for operand 2.  */
451     if (operands[2] == NULL)
452       operands[2] = const0_rtx;
454     /* Decide if we should generate indirect calls by loading the
455        64-bit address of the callee into a register before performing
456        the branch-and-link.  */
457     callee = XEXP (operands[0], 0);
458     if (GET_CODE (callee) == SYMBOL_REF
459         ? aarch64_is_long_call_p (callee)
460         : !REG_P (callee))
461       XEXP (operands[0], 0) = force_reg (Pmode, callee);
462   }"
465 (define_insn "*call_reg"
466   [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
467          (match_operand 1 "" ""))
468    (use (match_operand 2 "" ""))
469    (clobber (reg:DI LR_REGNUM))]
470   ""
471   "blr\\t%0"
472   [(set_attr "type" "call")]
475 (define_insn "*call_symbol"
476   [(call (mem:DI (match_operand:DI 0 "" ""))
477          (match_operand 1 "" ""))
478    (use (match_operand 2 "" ""))
479    (clobber (reg:DI LR_REGNUM))]
480   "GET_CODE (operands[0]) == SYMBOL_REF
481    && !aarch64_is_long_call_p (operands[0])"
482   "bl\\t%a0"
483   [(set_attr "type" "call")]
486 (define_expand "call_value"
487   [(parallel [(set (match_operand 0 "" "")
488                    (call (match_operand 1 "memory_operand" "")
489                          (match_operand 2 "general_operand" "")))
490               (use (match_operand 3 "" ""))
491               (clobber (reg:DI LR_REGNUM))])]
492   ""
493   "
494   {
495     rtx callee;
497     /* In an untyped call, we can get NULL for operand 3.  */
498     if (operands[3] == NULL)
499       operands[3] = const0_rtx;
501     /* Decide if we should generate indirect calls by loading the
502        64-bit address of the callee into a register before performing
503        the branch-and-link.  */
504     callee = XEXP (operands[1], 0);
505     if (GET_CODE (callee) == SYMBOL_REF
506         ? aarch64_is_long_call_p (callee)
507         : !REG_P (callee))
508       XEXP (operands[1], 0) = force_reg (Pmode, callee);
509   }"
512 (define_insn "*call_value_reg"
513   [(set (match_operand 0 "" "")
514         (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
515                       (match_operand 2 "" "")))
516    (use (match_operand 3 "" ""))
517    (clobber (reg:DI LR_REGNUM))]
518   ""
519   "blr\\t%1"
520   [(set_attr "type" "call")]
524 (define_insn "*call_value_symbol"
525   [(set (match_operand 0 "" "")
526         (call (mem:DI (match_operand:DI 1 "" ""))
527               (match_operand 2 "" "")))
528    (use (match_operand 3 "" ""))
529    (clobber (reg:DI LR_REGNUM))]
530   "GET_CODE (operands[1]) == SYMBOL_REF
531    && !aarch64_is_long_call_p (operands[1])"
532   "bl\\t%a1"
533   [(set_attr "type" "call")]
536 (define_expand "sibcall"
537   [(parallel [(call (match_operand 0 "memory_operand" "")
538                     (match_operand 1 "general_operand" ""))
539               (return)
540               (use (match_operand 2 "" ""))])]
541   ""
542   {
543     if (!REG_P (XEXP (operands[0], 0))
544        && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
545      XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
547     if (operands[2] == NULL_RTX)
548       operands[2] = const0_rtx;
549   }
552 (define_expand "sibcall_value"
553   [(parallel [(set (match_operand 0 "" "")
554                    (call (match_operand 1 "memory_operand" "")
555                          (match_operand 2 "general_operand" "")))
556               (return)
557               (use (match_operand 3 "" ""))])]
558   ""
559   {
560     if (!REG_P (XEXP (operands[1], 0))
561        && (GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF))
562      XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
564     if (operands[3] == NULL_RTX)
565       operands[3] = const0_rtx;
566   }
569 (define_insn "*sibcall_insn"
570   [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucs, Usf"))
571          (match_operand 1 "" ""))
572    (return)
573    (use (match_operand 2 "" ""))]
574   "SIBLING_CALL_P (insn)"
575   "@
576    br\\t%0
577    b\\t%a0"
578   [(set_attr "type" "branch, branch")]
581 (define_insn "*sibcall_value_insn"
582   [(set (match_operand 0 "" "")
583         (call (mem:DI (match_operand 1 "aarch64_call_insn_operand" "Ucs, Usf"))
584               (match_operand 2 "" "")))
585    (return)
586    (use (match_operand 3 "" ""))]
587   "SIBLING_CALL_P (insn)"
588   "@
589    br\\t%1
590    b\\t%a1"
591   [(set_attr "type" "branch, branch")]
594 ;; Call subroutine returning any type.
596 (define_expand "untyped_call"
597   [(parallel [(call (match_operand 0 "")
598                     (const_int 0))
599               (match_operand 1 "")
600               (match_operand 2 "")])]
601   ""
603   int i;
605   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
607   for (i = 0; i < XVECLEN (operands[2], 0); i++)
608     {
609       rtx set = XVECEXP (operands[2], 0, i);
610       emit_move_insn (SET_DEST (set), SET_SRC (set));
611     }
613   /* The optimizer does not know that the call sets the function value
614      registers we stored in the result block.  We avoid problems by
615      claiming that all hard registers are used and clobbered at this
616      point.  */
617   emit_insn (gen_blockage ());
618   DONE;
621 ;; -------------------------------------------------------------------
622 ;; Moves
623 ;; -------------------------------------------------------------------
625 (define_expand "mov<mode>"
626   [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
627         (match_operand:SHORT 1 "general_operand" ""))]
628   ""
629   "
630     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
631       operands[1] = force_reg (<MODE>mode, operands[1]);
632   "
635 (define_insn "*mov<mode>_aarch64"
636   [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r,   *w,r,*w, m, m, r,*w,*w")
637         (match_operand:SHORT 1 "general_operand"      " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
638   "(register_operand (operands[0], <MODE>mode)
639     || aarch64_reg_or_zero (operands[1], <MODE>mode))"
641    switch (which_alternative)
642      {
643      case 0:
644        return "mov\t%w0, %w1";
645      case 1:
646        return "mov\t%w0, %1";
647      case 2:
648        return aarch64_output_scalar_simd_mov_immediate (operands[1],
649                                                         <MODE>mode);
650      case 3:
651        return "ldr<size>\t%w0, %1";
652      case 4:
653        return "ldr\t%<size>0, %1";
654      case 5:
655        return "str<size>\t%w1, %0";
656      case 6:
657        return "str\t%<size>1, %0";
658      case 7:
659        return "umov\t%w0, %1.<v>[0]";
660      case 8:
661        return "dup\t%0.<Vallxd>, %w1";
662      case 9:
663        return "dup\t%<Vetype>0, %1.<v>[0]";
664      default:
665        gcc_unreachable ();
666      }
668   [(set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
669                      neon_from_gp<q>,neon_from_gp<q>, neon_dup")
670    (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")]
673 (define_expand "mov<mode>"
674   [(set (match_operand:GPI 0 "nonimmediate_operand" "")
675         (match_operand:GPI 1 "general_operand" ""))]
676   ""
677   "
678     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
679       operands[1] = force_reg (<MODE>mode, operands[1]);
681     if (CONSTANT_P (operands[1]))
682       {
683         aarch64_expand_mov_immediate (operands[0], operands[1]);
684         DONE;
685       }
686   "
689 (define_insn "*movsi_aarch64"
690   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m,  m,r,r  ,*w, r,*w")
691         (match_operand:SI 1 "aarch64_mov_operand"  " r,r,k,M,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
692   "(register_operand (operands[0], SImode)
693     || aarch64_reg_or_zero (operands[1], SImode))"
694   "@
695    mov\\t%w0, %w1
696    mov\\t%w0, %w1
697    mov\\t%w0, %w1
698    mov\\t%w0, %1
699    ldr\\t%w0, %1
700    ldr\\t%s0, %1
701    str\\t%w1, %0
702    str\\t%s1, %0
703    adr\\t%x0, %a1
704    adrp\\t%x0, %A1
705    fmov\\t%s0, %w1
706    fmov\\t%w0, %s1
707    fmov\\t%s0, %s1"
708   [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
709                      adr,adr,f_mcr,f_mrc,fmov")
710    (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
713 (define_insn "*movdi_aarch64"
714   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m,  m,r,r,  *w, r,*w,w")
715         (match_operand:DI 1 "aarch64_mov_operand"  " r,r,k,N,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))]
716   "(register_operand (operands[0], DImode)
717     || aarch64_reg_or_zero (operands[1], DImode))"
718   "@
719    mov\\t%x0, %x1
720    mov\\t%0, %x1
721    mov\\t%x0, %1
722    mov\\t%x0, %1
723    ldr\\t%x0, %1
724    ldr\\t%d0, %1
725    str\\t%x1, %0
726    str\\t%d1, %0
727    adr\\t%x0, %a1
728    adrp\\t%x0, %A1
729    fmov\\t%d0, %x1
730    fmov\\t%x0, %d1
731    fmov\\t%d0, %d1
732    movi\\t%d0, %1"
733   [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
734                      adr,adr,f_mcr,f_mrc,fmov,fmov")
735    (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
736    (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
739 (define_insn "insv_imm<mode>"
740   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
741                           (const_int 16)
742                           (match_operand:GPI 1 "const_int_operand" "n"))
743         (match_operand:GPI 2 "const_int_operand" "n"))]
744   "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
745    && UINTVAL (operands[1]) % 16 == 0"
746   "movk\\t%<w>0, %X2, lsl %1"
747   [(set_attr "type" "mov_imm")]
750 (define_expand "movti"
751   [(set (match_operand:TI 0 "nonimmediate_operand" "")
752         (match_operand:TI 1 "general_operand" ""))]
753   ""
754   "
755     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
756       operands[1] = force_reg (TImode, operands[1]);
757   "
760 (define_insn "*movti_aarch64"
761   [(set (match_operand:TI 0
762          "nonimmediate_operand"  "=r, *w,r ,*w,r  ,Ump,Ump,*w,m")
763         (match_operand:TI 1
764          "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r  ,Z  , m,*w"))]
765   "(register_operand (operands[0], TImode)
766     || aarch64_reg_or_zero (operands[1], TImode))"
767   "@
768    #
769    #
770    #
771    orr\\t%0.16b, %1.16b, %1.16b
772    ldp\\t%0, %H0, %1
773    stp\\t%1, %H1, %0
774    stp\\txzr, xzr, %0
775    ldr\\t%q0, %1
776    str\\t%q1, %0"
777   [(set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \
778                              load2,store2,store2,f_loadd,f_stored")
779    (set_attr "length" "8,8,8,4,4,4,4,4,4")
780    (set_attr "simd" "*,*,*,yes,*,*,*,*,*")
781    (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
784 ;; Split a TImode register-register or register-immediate move into
785 ;; its component DImode pieces, taking care to handle overlapping
786 ;; source and dest registers.
787 (define_split
788    [(set (match_operand:TI 0 "register_operand" "")
789          (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
790   "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
791   [(const_int 0)]
793   aarch64_split_128bit_move (operands[0], operands[1]);
794   DONE;
797 (define_expand "mov<mode>"
798   [(set (match_operand:GPF 0 "nonimmediate_operand" "")
799         (match_operand:GPF 1 "general_operand" ""))]
800   ""
801   "
802     if (!TARGET_FLOAT)
803      {
804         sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
805         FAIL;
806      }
808     if (GET_CODE (operands[0]) == MEM)
809       operands[1] = force_reg (<MODE>mode, operands[1]);
810   "
813 (define_insn "*movsf_aarch64"
814   [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w  ,w,m,r,m ,r")
815         (match_operand:SF 1 "general_operand"      "?rY, w,w,Ufc,m,w,m,rY,r"))]
816   "TARGET_FLOAT && (register_operand (operands[0], SFmode)
817     || register_operand (operands[1], SFmode))"
818   "@
819    fmov\\t%s0, %w1
820    fmov\\t%w0, %s1
821    fmov\\t%s0, %s1
822    fmov\\t%s0, %1
823    ldr\\t%s0, %1
824    str\\t%s1, %0
825    ldr\\t%w0, %1
826    str\\t%w1, %0
827    mov\\t%w0, %w1"
828   [(set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
829                      f_loads,f_stores,f_loads,f_stores,mov_reg")]
832 (define_insn "*movdf_aarch64"
833   [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w  ,w,m,r,m ,r")
834         (match_operand:DF 1 "general_operand"      "?rY, w,w,Ufc,m,w,m,rY,r"))]
835   "TARGET_FLOAT && (register_operand (operands[0], DFmode)
836     || register_operand (operands[1], DFmode))"
837   "@
838    fmov\\t%d0, %x1
839    fmov\\t%x0, %d1
840    fmov\\t%d0, %d1
841    fmov\\t%d0, %1
842    ldr\\t%d0, %1
843    str\\t%d1, %0
844    ldr\\t%x0, %1
845    str\\t%x1, %0
846    mov\\t%x0, %x1"
847   [(set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
848                      f_loadd,f_stored,f_loadd,f_stored,mov_reg")]
851 (define_expand "movtf"
852   [(set (match_operand:TF 0 "nonimmediate_operand" "")
853         (match_operand:TF 1 "general_operand" ""))]
854   ""
855   "
856     if (!TARGET_FLOAT)
857      {
858         sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
859         FAIL;
860      }
862     if (GET_CODE (operands[0]) == MEM)
863       operands[1] = force_reg (TFmode, operands[1]);
864   "
867 (define_insn "*movtf_aarch64"
868   [(set (match_operand:TF 0
869          "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
870         (match_operand:TF 1
871          "general_operand"      " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
872   "TARGET_FLOAT && (register_operand (operands[0], TFmode)
873     || register_operand (operands[1], TFmode))"
874   "@
875    orr\\t%0.16b, %1.16b, %1.16b
876    #
877    #
878    #
879    movi\\t%0.2d, #0
880    fmov\\t%s0, wzr
881    ldr\\t%q0, %1
882    str\\t%q1, %0
883    ldp\\t%0, %H0, %1
884    stp\\t%1, %H1, %0"
885   [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,fconstd,fconstd,\
886                      f_loadd,f_stored,neon_load1_2reg,neon_store1_2reg")
887    (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
888    (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
889    (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
892 (define_split
893    [(set (match_operand:TF 0 "register_operand" "")
894          (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
895   "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
896   [(const_int 0)]
897   {
898     aarch64_split_128bit_move (operands[0], operands[1]);
899     DONE;
900   }
903 ;; 0 is dst
904 ;; 1 is src
905 ;; 2 is size of move in bytes
906 ;; 3 is alignment
908 (define_expand "movmemdi"
909   [(match_operand:BLK 0 "memory_operand")
910    (match_operand:BLK 1 "memory_operand")
911    (match_operand:DI 2 "immediate_operand")
912    (match_operand:DI 3 "immediate_operand")]
913    "!STRICT_ALIGNMENT"
915   if (aarch64_expand_movmem (operands))
916     DONE;
917   FAIL;
921 ;; Operands 1 and 3 are tied together by the final condition; so we allow
922 ;; fairly lax checking on the second memory operation.
923 (define_insn "load_pair<mode>"
924   [(set (match_operand:GPI 0 "register_operand" "=r")
925         (match_operand:GPI 1 "aarch64_mem_pair_operand" "Ump"))
926    (set (match_operand:GPI 2 "register_operand" "=r")
927         (match_operand:GPI 3 "memory_operand" "m"))]
928   "rtx_equal_p (XEXP (operands[3], 0),
929                 plus_constant (Pmode,
930                                XEXP (operands[1], 0),
931                                GET_MODE_SIZE (<MODE>mode)))"
932   "ldp\\t%<w>0, %<w>2, %1"
933   [(set_attr "type" "load2")]
936 ;; Operands 0 and 2 are tied together by the final condition; so we allow
937 ;; fairly lax checking on the second memory operation.
938 (define_insn "store_pair<mode>"
939   [(set (match_operand:GPI 0 "aarch64_mem_pair_operand" "=Ump")
940         (match_operand:GPI 1 "register_operand" "r"))
941    (set (match_operand:GPI 2 "memory_operand" "=m")
942         (match_operand:GPI 3 "register_operand" "r"))]
943   "rtx_equal_p (XEXP (operands[2], 0),
944                 plus_constant (Pmode,
945                                XEXP (operands[0], 0),
946                                GET_MODE_SIZE (<MODE>mode)))"
947   "stp\\t%<w>1, %<w>3, %0"
948   [(set_attr "type" "store2")]
951 ;; Operands 1 and 3 are tied together by the final condition; so we allow
952 ;; fairly lax checking on the second memory operation.
953 (define_insn "load_pair<mode>"
954   [(set (match_operand:GPF 0 "register_operand" "=w")
955         (match_operand:GPF 1 "aarch64_mem_pair_operand" "Ump"))
956    (set (match_operand:GPF 2 "register_operand" "=w")
957         (match_operand:GPF 3 "memory_operand" "m"))]
958   "rtx_equal_p (XEXP (operands[3], 0),
959                 plus_constant (Pmode,
960                                XEXP (operands[1], 0),
961                                GET_MODE_SIZE (<MODE>mode)))"
962   "ldp\\t%<w>0, %<w>2, %1"
963   [(set_attr "type" "neon_load1_2reg<q>")]
966 ;; Operands 0 and 2 are tied together by the final condition; so we allow
967 ;; fairly lax checking on the second memory operation.
968 (define_insn "store_pair<mode>"
969   [(set (match_operand:GPF 0 "aarch64_mem_pair_operand" "=Ump")
970         (match_operand:GPF 1 "register_operand" "w"))
971    (set (match_operand:GPF 2 "memory_operand" "=m")
972         (match_operand:GPF 3 "register_operand" "w"))]
973   "rtx_equal_p (XEXP (operands[2], 0),
974                 plus_constant (Pmode,
975                                XEXP (operands[0], 0),
976                                GET_MODE_SIZE (<MODE>mode)))"
977   "stp\\t%<w>1, %<w>3, %0"
978   [(set_attr "type" "neon_store1_2reg<q>")]
981 ;; Load pair with post-index writeback.  This is primarily used in function
982 ;; epilogues.
983 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
984   [(parallel
985     [(set (match_operand:P 0 "register_operand" "=k")
986           (plus:P (match_operand:P 1 "register_operand" "0")
987                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
988      (set (match_operand:GPI 2 "register_operand" "=r")
989           (mem:GPI (match_dup 1)))
990      (set (match_operand:GPI 3 "register_operand" "=r")
991           (mem:GPI (plus:P (match_dup 1)
992                    (match_operand:P 5 "const_int_operand" "n"))))])]
993   "INTVAL (operands[5]) == GET_MODE_SIZE (<GPI:MODE>mode)"
994   "ldp\\t%<w>2, %<w>3, [%1], %4"
995   [(set_attr "type" "load2")]
998 (define_insn "loadwb_pair<GPF:mode>_<P:mode>"
999   [(parallel
1000     [(set (match_operand:P 0 "register_operand" "=k")
1001           (plus:P (match_operand:P 1 "register_operand" "0")
1002                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1003      (set (match_operand:GPF 2 "register_operand" "=w")
1004           (mem:GPF (match_dup 1)))
1005      (set (match_operand:GPF 3 "register_operand" "=w")
1006           (mem:GPF (plus:P (match_dup 1)
1007                    (match_operand:P 5 "const_int_operand" "n"))))])]
1008   "INTVAL (operands[5]) == GET_MODE_SIZE (<GPF:MODE>mode)"
1009   "ldp\\t%<w>2, %<w>3, [%1], %4"
1010   [(set_attr "type" "neon_load1_2reg")]
1013 ;; Store pair with pre-index writeback.  This is primarily used in function
1014 ;; prologues.
1015 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
1016   [(parallel
1017     [(set (match_operand:P 0 "register_operand" "=&k")
1018           (plus:P (match_operand:P 1 "register_operand" "0")
1019                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1020      (set (mem:GPI (plus:P (match_dup 0)
1021                    (match_dup 4)))
1022           (match_operand:GPI 2 "register_operand" "r"))
1023      (set (mem:GPI (plus:P (match_dup 0)
1024                    (match_operand:P 5 "const_int_operand" "n")))
1025           (match_operand:GPI 3 "register_operand" "r"))])]
1026   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1027   "stp\\t%<w>2, %<w>3, [%0, %4]!"
1028   [(set_attr "type" "store2")]
1031 (define_insn "storewb_pair<GPF:mode>_<P:mode>"
1032   [(parallel
1033     [(set (match_operand:P 0 "register_operand" "=&k")
1034           (plus:P (match_operand:P 1 "register_operand" "0")
1035                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1036      (set (mem:GPF (plus:P (match_dup 0)
1037                    (match_dup 4)))
1038           (match_operand:GPF 2 "register_operand" "w"))
1039      (set (mem:GPF (plus:P (match_dup 0)
1040                    (match_operand:P 5 "const_int_operand" "n")))
1041           (match_operand:GPF 3 "register_operand" "w"))])]
1042   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPF:MODE>mode)"
1043   "stp\\t%<w>2, %<w>3, [%0, %4]!"
1044   [(set_attr "type" "neon_store1_2reg<q>")]
1047 ;; -------------------------------------------------------------------
1048 ;; Sign/Zero extension
1049 ;; -------------------------------------------------------------------
1051 (define_expand "<optab>sidi2"
1052   [(set (match_operand:DI 0 "register_operand")
1053         (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1054   ""
1057 (define_insn "*extendsidi2_aarch64"
1058   [(set (match_operand:DI 0 "register_operand" "=r,r")
1059         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1060   ""
1061   "@
1062    sxtw\t%0, %w1
1063    ldrsw\t%0, %1"
1064   [(set_attr "type" "extend,load1")]
1067 (define_insn "*zero_extendsidi2_aarch64"
1068   [(set (match_operand:DI 0 "register_operand" "=r,r")
1069         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1070   ""
1071   "@
1072    uxtw\t%0, %w1
1073    ldr\t%w0, %1"
1074   [(set_attr "type" "extend,load1")]
1077 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1078   [(set (match_operand:GPI 0 "register_operand")
1079         (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1080   ""
1083 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1084   [(set (match_operand:GPI 0 "register_operand" "=r,r")
1085         (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1086   ""
1087   "@
1088    sxt<SHORT:size>\t%<GPI:w>0, %w1
1089    ldrs<SHORT:size>\t%<GPI:w>0, %1"
1090   [(set_attr "type" "extend,load1")]
1093 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1094   [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1095         (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1096   ""
1097   "@
1098    uxt<SHORT:size>\t%<GPI:w>0, %w1
1099    ldr<SHORT:size>\t%w0, %1
1100    ldr\t%<SHORT:size>0, %1"
1101   [(set_attr "type" "extend,load1,load1")]
1104 (define_expand "<optab>qihi2"
1105   [(set (match_operand:HI 0 "register_operand")
1106         (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1107   ""
1110 (define_insn "*<optab>qihi2_aarch64"
1111   [(set (match_operand:HI 0 "register_operand" "=r,r")
1112         (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1113   ""
1114   "@
1115    <su>xtb\t%w0, %w1
1116    <ldrxt>b\t%w0, %1"
1117   [(set_attr "type" "extend,load1")]
1120 ;; -------------------------------------------------------------------
1121 ;; Simple arithmetic
1122 ;; -------------------------------------------------------------------
1124 (define_expand "add<mode>3"
1125   [(set
1126     (match_operand:GPI 0 "register_operand" "")
1127     (plus:GPI (match_operand:GPI 1 "register_operand" "")
1128               (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1129   ""
1130   "
1131   if (! aarch64_plus_operand (operands[2], VOIDmode))
1132     {
1133       rtx subtarget = ((optimize && can_create_pseudo_p ())
1134                        ? gen_reg_rtx (<MODE>mode) : operands[0]);
1135       HOST_WIDE_INT imm = INTVAL (operands[2]);
1137       if (imm < 0)
1138         imm = -(-imm & ~0xfff);
1139       else
1140         imm &= ~0xfff;
1142       emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1143       operands[1] = subtarget;
1144       operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1145     }
1146   "
1149 (define_insn "*addsi3_aarch64"
1150   [(set
1151     (match_operand:SI 0 "register_operand" "=rk,rk,w,rk")
1152     (plus:SI
1153      (match_operand:SI 1 "register_operand" "%rk,rk,w,rk")
1154      (match_operand:SI 2 "aarch64_plus_operand" "I,r,w,J")))]
1155   ""
1156   "@
1157   add\\t%w0, %w1, %2
1158   add\\t%w0, %w1, %w2
1159   add\\t%0.2s, %1.2s, %2.2s
1160   sub\\t%w0, %w1, #%n2"
1161   [(set_attr "type" "alu_imm,alu_reg,neon_add,alu_imm")
1162    (set_attr "simd" "*,*,yes,*")]
1165 ;; zero_extend version of above
1166 (define_insn "*addsi3_aarch64_uxtw"
1167   [(set
1168     (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1169     (zero_extend:DI
1170      (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1171               (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1172   ""
1173   "@
1174   add\\t%w0, %w1, %2
1175   add\\t%w0, %w1, %w2
1176   sub\\t%w0, %w1, #%n2"
1177   [(set_attr "type" "alu_imm,alu_reg,alu_imm")]
1180 (define_insn "*adddi3_aarch64"
1181   [(set
1182     (match_operand:DI 0 "register_operand" "=rk,rk,rk,!w")
1183     (plus:DI
1184      (match_operand:DI 1 "register_operand" "%rk,rk,rk,!w")
1185      (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,!w")))]
1186   ""
1187   "@
1188   add\\t%x0, %x1, %2
1189   add\\t%x0, %x1, %x2
1190   sub\\t%x0, %x1, #%n2
1191   add\\t%d0, %d1, %d2"
1192   [(set_attr "type" "alu_imm,alu_reg,alu_imm,alu_reg")
1193    (set_attr "simd" "*,*,*,yes")]
1196 (define_expand "addti3"
1197   [(set (match_operand:TI 0 "register_operand" "")
1198         (plus:TI (match_operand:TI 1 "register_operand" "")
1199                  (match_operand:TI 2 "register_operand" "")))]
1200   ""
1202   rtx low = gen_reg_rtx (DImode);
1203   emit_insn (gen_adddi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1204                                   gen_lowpart (DImode, operands[2])));
1206   rtx high = gen_reg_rtx (DImode);
1207   emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]),
1208                                  gen_highpart (DImode, operands[2])));
1210   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1211   emit_move_insn (gen_highpart (DImode, operands[0]), high);
1212   DONE;
1215 (define_insn "add<mode>3_compare0"
1216   [(set (reg:CC_NZ CC_REGNUM)
1217         (compare:CC_NZ
1218          (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1219                    (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1220          (const_int 0)))
1221    (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1222         (plus:GPI (match_dup 1) (match_dup 2)))]
1223   ""
1224   "@
1225   adds\\t%<w>0, %<w>1, %<w>2
1226   adds\\t%<w>0, %<w>1, %<w>2
1227   subs\\t%<w>0, %<w>1, #%n2"
1228   [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1231 ;; zero_extend version of above
1232 (define_insn "*addsi3_compare0_uxtw"
1233   [(set (reg:CC_NZ CC_REGNUM)
1234         (compare:CC_NZ
1235          (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1236                   (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1237          (const_int 0)))
1238    (set (match_operand:DI 0 "register_operand" "=r,r,r")
1239         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1240   ""
1241   "@
1242   adds\\t%w0, %w1, %w2
1243   adds\\t%w0, %w1, %w2
1244   subs\\t%w0, %w1, #%n2"
1245   [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1248 (define_insn "*adds_mul_imm_<mode>"
1249   [(set (reg:CC_NZ CC_REGNUM)
1250         (compare:CC_NZ
1251          (plus:GPI (mult:GPI
1252                     (match_operand:GPI 1 "register_operand" "r")
1253                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1254                    (match_operand:GPI 3 "register_operand" "r"))
1255          (const_int 0)))
1256    (set (match_operand:GPI 0 "register_operand" "=r")
1257         (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1258                   (match_dup 3)))]
1259   ""
1260   "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1261   [(set_attr "type" "alus_shift_imm")]
1264 (define_insn "*subs_mul_imm_<mode>"
1265   [(set (reg:CC_NZ CC_REGNUM)
1266         (compare:CC_NZ
1267          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1268                     (mult:GPI
1269                      (match_operand:GPI 2 "register_operand" "r")
1270                      (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1271          (const_int 0)))
1272    (set (match_operand:GPI 0 "register_operand" "=r")
1273         (minus:GPI (match_dup 1)
1274                    (mult:GPI (match_dup 2) (match_dup 3))))]
1275   ""
1276   "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1277   [(set_attr "type" "alus_shift_imm")]
1280 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1281   [(set (reg:CC_NZ CC_REGNUM)
1282         (compare:CC_NZ
1283          (plus:GPI
1284           (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1285           (match_operand:GPI 2 "register_operand" "r"))
1286         (const_int 0)))
1287    (set (match_operand:GPI 0 "register_operand" "=r")
1288         (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1289   ""
1290   "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1291   [(set_attr "type" "alus_ext")]
1294 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1295   [(set (reg:CC_NZ CC_REGNUM)
1296         (compare:CC_NZ
1297          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1298                     (ANY_EXTEND:GPI
1299                      (match_operand:ALLX 2 "register_operand" "r")))
1300         (const_int 0)))
1301    (set (match_operand:GPI 0 "register_operand" "=r")
1302         (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1303   ""
1304   "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1305   [(set_attr "type" "alus_ext")]
1308 (define_insn "*adds_<optab><mode>_multp2"
1309   [(set (reg:CC_NZ CC_REGNUM)
1310         (compare:CC_NZ
1311          (plus:GPI (ANY_EXTRACT:GPI
1312                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1313                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1314                     (match_operand 3 "const_int_operand" "n")
1315                     (const_int 0))
1316                    (match_operand:GPI 4 "register_operand" "r"))
1317         (const_int 0)))
1318    (set (match_operand:GPI 0 "register_operand" "=r")
1319         (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1320                                    (match_dup 3)
1321                                    (const_int 0))
1322                   (match_dup 4)))]
1323   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1324   "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1325   [(set_attr "type" "alus_ext")]
1328 (define_insn "*subs_<optab><mode>_multp2"
1329   [(set (reg:CC_NZ CC_REGNUM)
1330         (compare:CC_NZ
1331          (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1332                     (ANY_EXTRACT:GPI
1333                      (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1334                                (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1335                      (match_operand 3 "const_int_operand" "n")
1336                      (const_int 0)))
1337         (const_int 0)))
1338    (set (match_operand:GPI 0 "register_operand" "=r")
1339         (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1340                                   (mult:GPI (match_dup 1) (match_dup 2))
1341                                   (match_dup 3)
1342                                   (const_int 0))))]
1343   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1344   "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1345   [(set_attr "type" "alus_ext")]
1348 (define_insn "*add<mode>3nr_compare0"
1349   [(set (reg:CC_NZ CC_REGNUM)
1350         (compare:CC_NZ
1351          (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1352                    (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1353          (const_int 0)))]
1354   ""
1355   "@
1356   cmn\\t%<w>0, %<w>1
1357   cmn\\t%<w>0, %<w>1
1358   cmp\\t%<w>0, #%n1"
1359   [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1362 (define_insn "*compare_neg<mode>"
1363   [(set (reg:CC_Z CC_REGNUM)
1364         (compare:CC_Z
1365          (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1366          (match_operand:GPI 1 "register_operand" "r")))]
1367   ""
1368   "cmn\\t%<w>1, %<w>0"
1369   [(set_attr "type" "alus_reg")]
1372 (define_insn "*add_<shift>_<mode>"
1373   [(set (match_operand:GPI 0 "register_operand" "=r")
1374         (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1375                               (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1376                   (match_operand:GPI 3 "register_operand" "r")))]
1377   ""
1378   "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1379   [(set_attr "type" "alu_shift_imm")]
1382 ;; zero_extend version of above
1383 (define_insn "*add_<shift>_si_uxtw"
1384   [(set (match_operand:DI 0 "register_operand" "=r")
1385         (zero_extend:DI
1386          (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1387                              (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1388                   (match_operand:SI 3 "register_operand" "r"))))]
1389   ""
1390   "add\\t%w0, %w3, %w1, <shift> %2"
1391   [(set_attr "type" "alu_shift_imm")]
1394 (define_insn "*add_mul_imm_<mode>"
1395   [(set (match_operand:GPI 0 "register_operand" "=r")
1396         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1397                             (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1398                   (match_operand:GPI 3 "register_operand" "r")))]
1399   ""
1400   "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1401   [(set_attr "type" "alu_shift_imm")]
1404 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1405   [(set (match_operand:GPI 0 "register_operand" "=rk")
1406         (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1407                   (match_operand:GPI 2 "register_operand" "r")))]
1408   ""
1409   "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1410   [(set_attr "type" "alu_ext")]
1413 ;; zero_extend version of above
1414 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1415   [(set (match_operand:DI 0 "register_operand" "=rk")
1416         (zero_extend:DI
1417          (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1418                   (match_operand:GPI 2 "register_operand" "r"))))]
1419   ""
1420   "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1421   [(set_attr "type" "alu_ext")]
1424 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1425   [(set (match_operand:GPI 0 "register_operand" "=rk")
1426         (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1427                                (match_operand:ALLX 1 "register_operand" "r"))
1428                               (match_operand 2 "aarch64_imm3" "Ui3"))
1429                   (match_operand:GPI 3 "register_operand" "r")))]
1430   ""
1431   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1432   [(set_attr "type" "alu_ext")]
1435 ;; zero_extend version of above
1436 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1437   [(set (match_operand:DI 0 "register_operand" "=rk")
1438         (zero_extend:DI
1439          (plus:SI (ashift:SI (ANY_EXTEND:SI
1440                               (match_operand:SHORT 1 "register_operand" "r"))
1441                              (match_operand 2 "aarch64_imm3" "Ui3"))
1442                   (match_operand:SI 3 "register_operand" "r"))))]
1443   ""
1444   "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1445   [(set_attr "type" "alu_ext")]
1448 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1449   [(set (match_operand:GPI 0 "register_operand" "=rk")
1450         (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1451                              (match_operand:ALLX 1 "register_operand" "r"))
1452                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1453                   (match_operand:GPI 3 "register_operand" "r")))]
1454   ""
1455   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1456   [(set_attr "type" "alu_ext")]
1459 ;; zero_extend version of above
1460 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1461   [(set (match_operand:DI 0 "register_operand" "=rk")
1462         (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1463                              (match_operand:SHORT 1 "register_operand" "r"))
1464                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1465                   (match_operand:SI 3 "register_operand" "r"))))]
1466   ""
1467   "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1468   [(set_attr "type" "alu_ext")]
1471 (define_insn "*add_<optab><mode>_multp2"
1472   [(set (match_operand:GPI 0 "register_operand" "=rk")
1473         (plus:GPI (ANY_EXTRACT:GPI
1474                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1475                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1476                    (match_operand 3 "const_int_operand" "n")
1477                    (const_int 0))
1478                   (match_operand:GPI 4 "register_operand" "r")))]
1479   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1480   "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1481   [(set_attr "type" "alu_ext")]
1484 ;; zero_extend version of above
1485 (define_insn "*add_<optab>si_multp2_uxtw"
1486   [(set (match_operand:DI 0 "register_operand" "=rk")
1487         (zero_extend:DI
1488          (plus:SI (ANY_EXTRACT:SI
1489                    (mult:SI (match_operand:SI 1 "register_operand" "r")
1490                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1491                    (match_operand 3 "const_int_operand" "n")
1492                    (const_int 0))
1493                   (match_operand:SI 4 "register_operand" "r"))))]
1494   "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1495   "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1496   [(set_attr "type" "alu_ext")]
1499 (define_insn "add<mode>3_carryin"
1500   [(set
1501     (match_operand:GPI 0 "register_operand" "=r")
1502     (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1503               (plus:GPI
1504                 (match_operand:GPI 1 "register_operand" "r")
1505                 (match_operand:GPI 2 "register_operand" "r"))))]
1506    ""
1507    "adc\\t%<w>0, %<w>1, %<w>2"
1508   [(set_attr "type" "adc_reg")]
1511 ;; zero_extend version of above
1512 (define_insn "*addsi3_carryin_uxtw"
1513   [(set
1514     (match_operand:DI 0 "register_operand" "=r")
1515     (zero_extend:DI
1516      (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1517               (plus:SI
1518                (match_operand:SI 1 "register_operand" "r")
1519                (match_operand:SI 2 "register_operand" "r")))))]
1520    ""
1521    "adc\\t%w0, %w1, %w2"
1522   [(set_attr "type" "adc_reg")]
1525 (define_insn "*add<mode>3_carryin_alt1"
1526   [(set
1527     (match_operand:GPI 0 "register_operand" "=r")
1528     (plus:GPI (plus:GPI
1529                 (match_operand:GPI 1 "register_operand" "r")
1530                 (match_operand:GPI 2 "register_operand" "r"))
1531               (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1532    ""
1533    "adc\\t%<w>0, %<w>1, %<w>2"
1534   [(set_attr "type" "adc_reg")]
1537 ;; zero_extend version of above
1538 (define_insn "*addsi3_carryin_alt1_uxtw"
1539   [(set
1540     (match_operand:DI 0 "register_operand" "=r")
1541     (zero_extend:DI
1542      (plus:SI (plus:SI
1543                (match_operand:SI 1 "register_operand" "r")
1544                (match_operand:SI 2 "register_operand" "r"))
1545               (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1546    ""
1547    "adc\\t%w0, %w1, %w2"
1548   [(set_attr "type" "adc_reg")]
1551 (define_insn "*add<mode>3_carryin_alt2"
1552   [(set
1553     (match_operand:GPI 0 "register_operand" "=r")
1554     (plus:GPI (plus:GPI
1555                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1556                 (match_operand:GPI 1 "register_operand" "r"))
1557               (match_operand:GPI 2 "register_operand" "r")))]
1558    ""
1559    "adc\\t%<w>0, %<w>1, %<w>2"
1560   [(set_attr "type" "adc_reg")]
1563 ;; zero_extend version of above
1564 (define_insn "*addsi3_carryin_alt2_uxtw"
1565   [(set
1566     (match_operand:DI 0 "register_operand" "=r")
1567     (zero_extend:DI
1568      (plus:SI (plus:SI
1569                (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1570                (match_operand:SI 1 "register_operand" "r"))
1571               (match_operand:SI 2 "register_operand" "r"))))]
1572    ""
1573    "adc\\t%w0, %w1, %w2"
1574   [(set_attr "type" "adc_reg")]
1577 (define_insn "*add<mode>3_carryin_alt3"
1578   [(set
1579     (match_operand:GPI 0 "register_operand" "=r")
1580     (plus:GPI (plus:GPI
1581                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1582                 (match_operand:GPI 2 "register_operand" "r"))
1583               (match_operand:GPI 1 "register_operand" "r")))]
1584    ""
1585    "adc\\t%<w>0, %<w>1, %<w>2"
1586   [(set_attr "type" "adc_reg")]
1589 ;; zero_extend version of above
1590 (define_insn "*addsi3_carryin_alt3_uxtw"
1591   [(set
1592     (match_operand:DI 0 "register_operand" "=r")
1593     (zero_extend:DI
1594      (plus:SI (plus:SI
1595                (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1596                (match_operand:SI 2 "register_operand" "r"))
1597               (match_operand:SI 1 "register_operand" "r"))))]
1598    ""
1599    "adc\\t%w0, %w1, %w2"
1600   [(set_attr "type" "adc_reg")]
1603 (define_insn "*add_uxt<mode>_multp2"
1604   [(set (match_operand:GPI 0 "register_operand" "=rk")
1605         (plus:GPI (and:GPI
1606                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1607                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1608                    (match_operand 3 "const_int_operand" "n"))
1609                   (match_operand:GPI 4 "register_operand" "r")))]
1610   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1611   "*
1612   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1613                                            INTVAL (operands[3])));
1614   return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1615   [(set_attr "type" "alu_ext")]
1618 ;; zero_extend version of above
1619 (define_insn "*add_uxtsi_multp2_uxtw"
1620   [(set (match_operand:DI 0 "register_operand" "=rk")
1621         (zero_extend:DI
1622          (plus:SI (and:SI
1623                    (mult:SI (match_operand:SI 1 "register_operand" "r")
1624                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1625                    (match_operand 3 "const_int_operand" "n"))
1626                   (match_operand:SI 4 "register_operand" "r"))))]
1627   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1628   "*
1629   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1630                                            INTVAL (operands[3])));
1631   return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1632   [(set_attr "type" "alu_ext")]
1635 (define_insn "subsi3"
1636   [(set (match_operand:SI 0 "register_operand" "=rk")
1637         (minus:SI (match_operand:SI 1 "register_operand" "r")
1638                    (match_operand:SI 2 "register_operand" "r")))]
1639   ""
1640   "sub\\t%w0, %w1, %w2"
1641   [(set_attr "type" "alu_reg")]
1644 ;; zero_extend version of above
1645 (define_insn "*subsi3_uxtw"
1646   [(set (match_operand:DI 0 "register_operand" "=rk")
1647         (zero_extend:DI
1648          (minus:SI (match_operand:SI 1 "register_operand" "r")
1649                    (match_operand:SI 2 "register_operand" "r"))))]
1650   ""
1651   "sub\\t%w0, %w1, %w2"
1652   [(set_attr "type" "alu_reg")]
1655 (define_insn "subdi3"
1656   [(set (match_operand:DI 0 "register_operand" "=rk,!w")
1657         (minus:DI (match_operand:DI 1 "register_operand" "r,!w")
1658                    (match_operand:DI 2 "register_operand" "r,!w")))]
1659   ""
1660   "@
1661    sub\\t%x0, %x1, %x2
1662    sub\\t%d0, %d1, %d2"
1663   [(set_attr "type" "alu_reg, neon_sub")
1664    (set_attr "simd" "*,yes")]
1667 (define_expand "subti3"
1668   [(set (match_operand:TI 0 "register_operand" "")
1669         (minus:TI (match_operand:TI 1 "register_operand" "")
1670                   (match_operand:TI 2 "register_operand" "")))]
1671   ""
1673   rtx low = gen_reg_rtx (DImode);
1674   emit_insn (gen_subdi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1675                                   gen_lowpart (DImode, operands[2])));
1677   rtx high = gen_reg_rtx (DImode);
1678   emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]),
1679                                  gen_highpart (DImode, operands[2])));
1681   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1682   emit_move_insn (gen_highpart (DImode, operands[0]), high);
1683   DONE;
1686 (define_insn "sub<mode>3_compare0"
1687   [(set (reg:CC_NZ CC_REGNUM)
1688         (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1689                                   (match_operand:GPI 2 "register_operand" "r"))
1690                        (const_int 0)))
1691    (set (match_operand:GPI 0 "register_operand" "=r")
1692         (minus:GPI (match_dup 1) (match_dup 2)))]
1693   ""
1694   "subs\\t%<w>0, %<w>1, %<w>2"
1695   [(set_attr "type" "alus_reg")]
1698 ;; zero_extend version of above
1699 (define_insn "*subsi3_compare0_uxtw"
1700   [(set (reg:CC_NZ CC_REGNUM)
1701         (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1702                                  (match_operand:SI 2 "register_operand" "r"))
1703                        (const_int 0)))
1704    (set (match_operand:DI 0 "register_operand" "=r")
1705         (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1706   ""
1707   "subs\\t%w0, %w1, %w2"
1708   [(set_attr "type" "alus_reg")]
1711 (define_insn "*sub_<shift>_<mode>"
1712   [(set (match_operand:GPI 0 "register_operand" "=r")
1713         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1714                    (ASHIFT:GPI
1715                     (match_operand:GPI 1 "register_operand" "r")
1716                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1717   ""
1718   "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1719   [(set_attr "type" "alu_shift_imm")]
1722 ;; zero_extend version of above
1723 (define_insn "*sub_<shift>_si_uxtw"
1724   [(set (match_operand:DI 0 "register_operand" "=r")
1725         (zero_extend:DI
1726          (minus:SI (match_operand:SI 3 "register_operand" "r")
1727                    (ASHIFT:SI
1728                     (match_operand:SI 1 "register_operand" "r")
1729                     (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1730   ""
1731   "sub\\t%w0, %w3, %w1, <shift> %2"
1732   [(set_attr "type" "alu_shift_imm")]
1735 (define_insn "*sub_mul_imm_<mode>"
1736   [(set (match_operand:GPI 0 "register_operand" "=r")
1737         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1738                    (mult:GPI
1739                     (match_operand:GPI 1 "register_operand" "r")
1740                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1741   ""
1742   "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1743   [(set_attr "type" "alu_shift_imm")]
1746 ;; zero_extend version of above
1747 (define_insn "*sub_mul_imm_si_uxtw"
1748   [(set (match_operand:DI 0 "register_operand" "=r")
1749         (zero_extend:DI
1750          (minus:SI (match_operand:SI 3 "register_operand" "r")
1751                    (mult:SI
1752                     (match_operand:SI 1 "register_operand" "r")
1753                     (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
1754   ""
1755   "sub\\t%w0, %w3, %w1, lsl %p2"
1756   [(set_attr "type" "alu_shift_imm")]
1759 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
1760   [(set (match_operand:GPI 0 "register_operand" "=rk")
1761         (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1762                    (ANY_EXTEND:GPI
1763                     (match_operand:ALLX 2 "register_operand" "r"))))]
1764   ""
1765   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1766   [(set_attr "type" "alu_ext")]
1769 ;; zero_extend version of above
1770 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
1771   [(set (match_operand:DI 0 "register_operand" "=rk")
1772         (zero_extend:DI
1773          (minus:SI (match_operand:SI 1 "register_operand" "r")
1774                    (ANY_EXTEND:SI
1775                     (match_operand:SHORT 2 "register_operand" "r")))))]
1776   ""
1777   "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
1778   [(set_attr "type" "alu_ext")]
1781 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
1782   [(set (match_operand:GPI 0 "register_operand" "=rk")
1783         (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1784                    (ashift:GPI (ANY_EXTEND:GPI
1785                                 (match_operand:ALLX 2 "register_operand" "r"))
1786                                (match_operand 3 "aarch64_imm3" "Ui3"))))]
1787   ""
1788   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1789   [(set_attr "type" "alu_ext")]
1792 ;; zero_extend version of above
1793 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
1794   [(set (match_operand:DI 0 "register_operand" "=rk")
1795         (zero_extend:DI
1796          (minus:SI (match_operand:SI 1 "register_operand" "r")
1797                    (ashift:SI (ANY_EXTEND:SI
1798                                (match_operand:SHORT 2 "register_operand" "r"))
1799                               (match_operand 3 "aarch64_imm3" "Ui3")))))]
1800   ""
1801   "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
1802   [(set_attr "type" "alu_ext")]
1805 (define_insn "*sub_<optab><mode>_multp2"
1806   [(set (match_operand:GPI 0 "register_operand" "=rk")
1807         (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1808                    (ANY_EXTRACT:GPI
1809                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1810                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1811                     (match_operand 3 "const_int_operand" "n")
1812                     (const_int 0))))]
1813   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1814   "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1815   [(set_attr "type" "alu_ext")]
1818 ;; zero_extend version of above
1819 (define_insn "*sub_<optab>si_multp2_uxtw"
1820   [(set (match_operand:DI 0 "register_operand" "=rk")
1821         (zero_extend:DI
1822          (minus:SI (match_operand:SI 4 "register_operand" "r")
1823                    (ANY_EXTRACT:SI
1824                     (mult:SI (match_operand:SI 1 "register_operand" "r")
1825                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1826                     (match_operand 3 "const_int_operand" "n")
1827                     (const_int 0)))))]
1828   "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1829   "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1830   [(set_attr "type" "alu_ext")]
1833 (define_insn "sub<mode>3_carryin"
1834   [(set
1835     (match_operand:GPI 0 "register_operand" "=r")
1836     (minus:GPI (minus:GPI
1837                 (match_operand:GPI 1 "register_operand" "r")
1838                 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
1839                (match_operand:GPI 2 "register_operand" "r")))]
1840    ""
1841    "sbc\\t%<w>0, %<w>1, %<w>2"
1842   [(set_attr "type" "adc_reg")]
1845 ;; zero_extend version of the above
1846 (define_insn "*subsi3_carryin_uxtw"
1847   [(set
1848     (match_operand:DI 0 "register_operand" "=r")
1849     (zero_extend:DI
1850      (minus:SI (minus:SI
1851                 (match_operand:SI 1 "register_operand" "r")
1852                 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
1853                (match_operand:SI 2 "register_operand" "r"))))]
1854    ""
1855    "sbc\\t%w0, %w1, %w2"
1856   [(set_attr "type" "adc_reg")]
1859 (define_insn "*sub_uxt<mode>_multp2"
1860   [(set (match_operand:GPI 0 "register_operand" "=rk")
1861         (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1862                    (and:GPI
1863                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1864                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1865                     (match_operand 3 "const_int_operand" "n"))))]
1866   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1867   "*
1868   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1869                                            INTVAL (operands[3])));
1870   return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1871   [(set_attr "type" "alu_ext")]
1874 ;; zero_extend version of above
1875 (define_insn "*sub_uxtsi_multp2_uxtw"
1876   [(set (match_operand:DI 0 "register_operand" "=rk")
1877         (zero_extend:DI
1878          (minus:SI (match_operand:SI 4 "register_operand" "r")
1879                    (and:SI
1880                     (mult:SI (match_operand:SI 1 "register_operand" "r")
1881                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1882                     (match_operand 3 "const_int_operand" "n")))))]
1883   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1884   "*
1885   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1886                                            INTVAL (operands[3])));
1887   return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
1888   [(set_attr "type" "alu_ext")]
1891 (define_insn_and_split "absdi2"
1892   [(set (match_operand:DI 0 "register_operand" "=r,w")
1893         (abs:DI (match_operand:DI 1 "register_operand" "r,w")))
1894    (clobber (match_scratch:DI 2 "=&r,X"))]
1895   ""
1896   "@
1897    #
1898    abs\\t%d0, %d1"
1899   "reload_completed
1900    && GP_REGNUM_P (REGNO (operands[0]))
1901    && GP_REGNUM_P (REGNO (operands[1]))"
1902   [(const_int 0)]
1903   {
1904     emit_insn (gen_rtx_SET (VOIDmode, operands[2],
1905                             gen_rtx_XOR (DImode,
1906                                          gen_rtx_ASHIFTRT (DImode,
1907                                                            operands[1],
1908                                                            GEN_INT (63)),
1909                                          operands[1])));
1910     emit_insn (gen_rtx_SET (VOIDmode,
1911                             operands[0],
1912                             gen_rtx_MINUS (DImode,
1913                                            operands[2],
1914                                            gen_rtx_ASHIFTRT (DImode,
1915                                                              operands[1],
1916                                                              GEN_INT (63)))));
1917     DONE;
1918   }
1919   [(set_attr "type" "alu_sreg")
1920    (set_attr "simd" "no,yes")]
1923 (define_insn "neg<mode>2"
1924   [(set (match_operand:GPI 0 "register_operand" "=r,w")
1925         (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
1926   ""
1927   "@
1928    neg\\t%<w>0, %<w>1
1929    neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
1930   [(set_attr "type" "alu_reg, neon_neg<q>")
1931    (set_attr "simd" "*,yes")]
1934 ;; zero_extend version of above
1935 (define_insn "*negsi2_uxtw"
1936   [(set (match_operand:DI 0 "register_operand" "=r")
1937         (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
1938   ""
1939   "neg\\t%w0, %w1"
1940   [(set_attr "type" "alu_reg")]
1943 (define_insn "*ngc<mode>"
1944   [(set (match_operand:GPI 0 "register_operand" "=r")
1945         (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
1946                    (match_operand:GPI 1 "register_operand" "r")))]
1947   ""
1948   "ngc\\t%<w>0, %<w>1"
1949   [(set_attr "type" "adc_reg")]
1952 (define_insn "*ngcsi_uxtw"
1953   [(set (match_operand:DI 0 "register_operand" "=r")
1954         (zero_extend:DI
1955          (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
1956                    (match_operand:SI 1 "register_operand" "r"))))]
1957   ""
1958   "ngc\\t%w0, %w1"
1959   [(set_attr "type" "adc_reg")]
1962 (define_insn "*neg<mode>2_compare0"
1963   [(set (reg:CC_NZ CC_REGNUM)
1964         (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
1965                        (const_int 0)))
1966    (set (match_operand:GPI 0 "register_operand" "=r")
1967         (neg:GPI (match_dup 1)))]
1968   ""
1969   "negs\\t%<w>0, %<w>1"
1970   [(set_attr "type" "alus_reg")]
1973 ;; zero_extend version of above
1974 (define_insn "*negsi2_compare0_uxtw"
1975   [(set (reg:CC_NZ CC_REGNUM)
1976         (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
1977                        (const_int 0)))
1978    (set (match_operand:DI 0 "register_operand" "=r")
1979         (zero_extend:DI (neg:SI (match_dup 1))))]
1980   ""
1981   "negs\\t%w0, %w1"
1982   [(set_attr "type" "alus_reg")]
1985 (define_insn "*neg_<shift><mode>3_compare0"
1986   [(set (reg:CC_NZ CC_REGNUM)
1987         (compare:CC_NZ
1988          (neg:GPI (ASHIFT:GPI
1989                    (match_operand:GPI 1 "register_operand" "r")
1990                    (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
1991          (const_int 0)))
1992    (set (match_operand:GPI 0 "register_operand" "=r")
1993         (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
1994   ""
1995   "negs\\t%<w>0, %<w>1, <shift> %2"
1996   [(set_attr "type" "alus_shift_imm")]
1999 (define_insn "*neg_<shift>_<mode>2"
2000   [(set (match_operand:GPI 0 "register_operand" "=r")
2001         (neg:GPI (ASHIFT:GPI
2002                   (match_operand:GPI 1 "register_operand" "r")
2003                   (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2004   ""
2005   "neg\\t%<w>0, %<w>1, <shift> %2"
2006   [(set_attr "type" "alu_shift_imm")]
2009 ;; zero_extend version of above
2010 (define_insn "*neg_<shift>_si2_uxtw"
2011   [(set (match_operand:DI 0 "register_operand" "=r")
2012         (zero_extend:DI
2013          (neg:SI (ASHIFT:SI
2014                   (match_operand:SI 1 "register_operand" "r")
2015                   (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2016   ""
2017   "neg\\t%w0, %w1, <shift> %2"
2018   [(set_attr "type" "alu_shift_imm")]
2021 (define_insn "*neg_mul_imm_<mode>2"
2022   [(set (match_operand:GPI 0 "register_operand" "=r")
2023         (neg:GPI (mult:GPI
2024                   (match_operand:GPI 1 "register_operand" "r")
2025                   (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2026   ""
2027   "neg\\t%<w>0, %<w>1, lsl %p2"
2028   [(set_attr "type" "alu_shift_imm")]
2031 ;; zero_extend version of above
2032 (define_insn "*neg_mul_imm_si2_uxtw"
2033   [(set (match_operand:DI 0 "register_operand" "=r")
2034         (zero_extend:DI
2035          (neg:SI (mult:SI
2036                   (match_operand:SI 1 "register_operand" "r")
2037                   (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2038   ""
2039   "neg\\t%w0, %w1, lsl %p2"
2040   [(set_attr "type" "alu_shift_imm")]
2043 (define_insn "mul<mode>3"
2044   [(set (match_operand:GPI 0 "register_operand" "=r")
2045         (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2046                   (match_operand:GPI 2 "register_operand" "r")))]
2047   ""
2048   "mul\\t%<w>0, %<w>1, %<w>2"
2049   [(set_attr "type" "mul")]
2052 ;; zero_extend version of above
2053 (define_insn "*mulsi3_uxtw"
2054   [(set (match_operand:DI 0 "register_operand" "=r")
2055         (zero_extend:DI
2056          (mult:SI (match_operand:SI 1 "register_operand" "r")
2057                   (match_operand:SI 2 "register_operand" "r"))))]
2058   ""
2059   "mul\\t%w0, %w1, %w2"
2060   [(set_attr "type" "mul")]
2063 (define_insn "madd<mode>"
2064   [(set (match_operand:GPI 0 "register_operand" "=r")
2065         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2066                             (match_operand:GPI 2 "register_operand" "r"))
2067                   (match_operand:GPI 3 "register_operand" "r")))]
2068   ""
2069   "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2070   [(set_attr "type" "mla")]
2073 ;; zero_extend version of above
2074 (define_insn "*maddsi_uxtw"
2075   [(set (match_operand:DI 0 "register_operand" "=r")
2076         (zero_extend:DI
2077          (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2078                            (match_operand:SI 2 "register_operand" "r"))
2079                   (match_operand:SI 3 "register_operand" "r"))))]
2080   ""
2081   "madd\\t%w0, %w1, %w2, %w3"
2082   [(set_attr "type" "mla")]
2085 (define_insn "*msub<mode>"
2086   [(set (match_operand:GPI 0 "register_operand" "=r")
2087         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2088                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2089                              (match_operand:GPI 2 "register_operand" "r"))))]
2091   ""
2092   "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2093   [(set_attr "type" "mla")]
2096 ;; zero_extend version of above
2097 (define_insn "*msubsi_uxtw"
2098   [(set (match_operand:DI 0 "register_operand" "=r")
2099         (zero_extend:DI
2100          (minus:SI (match_operand:SI 3 "register_operand" "r")
2101                    (mult:SI (match_operand:SI 1 "register_operand" "r")
2102                             (match_operand:SI 2 "register_operand" "r")))))]
2104   ""
2105   "msub\\t%w0, %w1, %w2, %w3"
2106   [(set_attr "type" "mla")]
2109 (define_insn "*mul<mode>_neg"
2110   [(set (match_operand:GPI 0 "register_operand" "=r")
2111         (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2112                   (match_operand:GPI 2 "register_operand" "r")))]
2114   ""
2115   "mneg\\t%<w>0, %<w>1, %<w>2"
2116   [(set_attr "type" "mul")]
2119 ;; zero_extend version of above
2120 (define_insn "*mulsi_neg_uxtw"
2121   [(set (match_operand:DI 0 "register_operand" "=r")
2122         (zero_extend:DI
2123          (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2124                   (match_operand:SI 2 "register_operand" "r"))))]
2126   ""
2127   "mneg\\t%w0, %w1, %w2"
2128   [(set_attr "type" "mul")]
2131 (define_insn "<su_optab>mulsidi3"
2132   [(set (match_operand:DI 0 "register_operand" "=r")
2133         (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2134                  (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2135   ""
2136   "<su>mull\\t%0, %w1, %w2"
2137   [(set_attr "type" "<su>mull")]
2140 (define_insn "<su_optab>maddsidi4"
2141   [(set (match_operand:DI 0 "register_operand" "=r")
2142         (plus:DI (mult:DI
2143                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2144                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2145                  (match_operand:DI 3 "register_operand" "r")))]
2146   ""
2147   "<su>maddl\\t%0, %w1, %w2, %3"
2148   [(set_attr "type" "<su>mlal")]
2151 (define_insn "<su_optab>msubsidi4"
2152   [(set (match_operand:DI 0 "register_operand" "=r")
2153         (minus:DI
2154          (match_operand:DI 3 "register_operand" "r")
2155          (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2156                   (ANY_EXTEND:DI
2157                    (match_operand:SI 2 "register_operand" "r")))))]
2158   ""
2159   "<su>msubl\\t%0, %w1, %w2, %3"
2160   [(set_attr "type" "<su>mlal")]
2163 (define_insn "*<su_optab>mulsidi_neg"
2164   [(set (match_operand:DI 0 "register_operand" "=r")
2165         (mult:DI (neg:DI
2166                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2167                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2168   ""
2169   "<su>mnegl\\t%0, %w1, %w2"
2170   [(set_attr "type" "<su>mull")]
2173 (define_expand "<su_optab>mulditi3"
2174   [(set (match_operand:TI 0 "register_operand")
2175         (mult:TI (ANY_EXTEND:TI (match_operand:DI 1 "register_operand"))
2176                  (ANY_EXTEND:TI (match_operand:DI 2 "register_operand"))))]
2177   ""
2179   rtx low = gen_reg_rtx (DImode);
2180   emit_insn (gen_muldi3 (low, operands[1], operands[2]));
2182   rtx high = gen_reg_rtx (DImode);
2183   emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2]));
2185   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2186   emit_move_insn (gen_highpart (DImode, operands[0]), high);
2187   DONE;
2190 ;; The default expansion of multi3 using umuldi3_highpart will perform
2191 ;; the additions in an order that fails to combine into two madd insns.
2192 (define_expand "multi3"
2193   [(set (match_operand:TI 0 "register_operand")
2194         (mult:TI (match_operand:TI 1 "register_operand")
2195                  (match_operand:TI 2 "register_operand")))]
2196   ""
2198   rtx l0 = gen_reg_rtx (DImode);
2199   rtx l1 = gen_lowpart (DImode, operands[1]);
2200   rtx l2 = gen_lowpart (DImode, operands[2]);
2201   rtx h0 = gen_reg_rtx (DImode);
2202   rtx h1 = gen_highpart (DImode, operands[1]);
2203   rtx h2 = gen_highpart (DImode, operands[2]);
2205   emit_insn (gen_muldi3 (l0, l1, l2));
2206   emit_insn (gen_umuldi3_highpart (h0, l1, l2));
2207   emit_insn (gen_madddi (h0, h1, l2, h0));
2208   emit_insn (gen_madddi (h0, l1, h2, h0));
2210   emit_move_insn (gen_lowpart (DImode, operands[0]), l0);
2211   emit_move_insn (gen_highpart (DImode, operands[0]), h0);
2212   DONE;
2215 (define_insn "<su>muldi3_highpart"
2216   [(set (match_operand:DI 0 "register_operand" "=r")
2217         (truncate:DI
2218          (lshiftrt:TI
2219           (mult:TI
2220            (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2221            (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2222           (const_int 64))))]
2223   ""
2224   "<su>mulh\\t%0, %1, %2"
2225   [(set_attr "type" "<su>mull")]
2228 (define_insn "<su_optab>div<mode>3"
2229   [(set (match_operand:GPI 0 "register_operand" "=r")
2230         (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2231                      (match_operand:GPI 2 "register_operand" "r")))]
2232   ""
2233   "<su>div\\t%<w>0, %<w>1, %<w>2"
2234   [(set_attr "type" "<su>div")]
2237 ;; zero_extend version of above
2238 (define_insn "*<su_optab>divsi3_uxtw"
2239   [(set (match_operand:DI 0 "register_operand" "=r")
2240         (zero_extend:DI
2241          (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2242                      (match_operand:SI 2 "register_operand" "r"))))]
2243   ""
2244   "<su>div\\t%w0, %w1, %w2"
2245   [(set_attr "type" "<su>div")]
2248 ;; -------------------------------------------------------------------
2249 ;; Comparison insns
2250 ;; -------------------------------------------------------------------
2252 (define_insn "*cmp<mode>"
2253   [(set (reg:CC CC_REGNUM)
2254         (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2255                     (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2256   ""
2257   "@
2258    cmp\\t%<w>0, %<w>1
2259    cmp\\t%<w>0, %<w>1
2260    cmn\\t%<w>0, #%n1"
2261   [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
2264 (define_insn "*cmp<mode>"
2265   [(set (reg:CCFP CC_REGNUM)
2266         (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2267                       (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2268    "TARGET_FLOAT"
2269    "@
2270     fcmp\\t%<s>0, #0.0
2271     fcmp\\t%<s>0, %<s>1"
2272   [(set_attr "type" "fcmp<s>")]
2275 (define_insn "*cmpe<mode>"
2276   [(set (reg:CCFPE CC_REGNUM)
2277         (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2278                        (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2279    "TARGET_FLOAT"
2280    "@
2281     fcmpe\\t%<s>0, #0.0
2282     fcmpe\\t%<s>0, %<s>1"
2283   [(set_attr "type" "fcmp<s>")]
2286 (define_insn "*cmp_swp_<shift>_reg<mode>"
2287   [(set (reg:CC_SWP CC_REGNUM)
2288         (compare:CC_SWP (ASHIFT:GPI
2289                          (match_operand:GPI 0 "register_operand" "r")
2290                          (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2291                         (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2292   ""
2293   "cmp\\t%<w>2, %<w>0, <shift> %1"
2294   [(set_attr "type" "alus_shift_imm")]
2297 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2298   [(set (reg:CC_SWP CC_REGNUM)
2299         (compare:CC_SWP (ANY_EXTEND:GPI
2300                          (match_operand:ALLX 0 "register_operand" "r"))
2301                         (match_operand:GPI 1 "register_operand" "r")))]
2302   ""
2303   "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2304   [(set_attr "type" "alus_ext")]
2307 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2308   [(set (reg:CC_SWP CC_REGNUM)
2309         (compare:CC_SWP (ashift:GPI
2310                          (ANY_EXTEND:GPI
2311                           (match_operand:ALLX 0 "register_operand" "r"))
2312                          (match_operand 1 "aarch64_imm3" "Ui3"))
2313         (match_operand:GPI 2 "register_operand" "r")))]
2314   ""
2315   "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2316   [(set_attr "type" "alus_ext")]
2319 ;; -------------------------------------------------------------------
2320 ;; Store-flag and conditional select insns
2321 ;; -------------------------------------------------------------------
2323 (define_expand "cstore<mode>4"
2324   [(set (match_operand:SI 0 "register_operand" "")
2325         (match_operator:SI 1 "aarch64_comparison_operator"
2326          [(match_operand:GPI 2 "register_operand" "")
2327           (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2328   ""
2329   "
2330   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2331                                       operands[3]);
2332   operands[3] = const0_rtx;
2333   "
2336 (define_expand "cstore<mode>4"
2337   [(set (match_operand:SI 0 "register_operand" "")
2338         (match_operator:SI 1 "aarch64_comparison_operator"
2339          [(match_operand:GPF 2 "register_operand" "")
2340           (match_operand:GPF 3 "register_operand" "")]))]
2341   ""
2342   "
2343   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2344                                       operands[3]);
2345   operands[3] = const0_rtx;
2346   "
2349 (define_insn "*cstore<mode>_insn"
2350   [(set (match_operand:ALLI 0 "register_operand" "=r")
2351         (match_operator:ALLI 1 "aarch64_comparison_operator"
2352          [(match_operand 2 "cc_register" "") (const_int 0)]))]
2353   ""
2354   "cset\\t%<w>0, %m1"
2355   [(set_attr "type" "csel")]
2358 ;; zero_extend version of the above
2359 (define_insn "*cstoresi_insn_uxtw"
2360   [(set (match_operand:DI 0 "register_operand" "=r")
2361         (zero_extend:DI
2362          (match_operator:SI 1 "aarch64_comparison_operator"
2363           [(match_operand 2 "cc_register" "") (const_int 0)])))]
2364   ""
2365   "cset\\t%w0, %m1"
2366   [(set_attr "type" "csel")]
2369 (define_insn "cstore<mode>_neg"
2370   [(set (match_operand:ALLI 0 "register_operand" "=r")
2371         (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2372                   [(match_operand 2 "cc_register" "") (const_int 0)])))]
2373   ""
2374   "csetm\\t%<w>0, %m1"
2375   [(set_attr "type" "csel")]
2378 ;; zero_extend version of the above
2379 (define_insn "*cstoresi_neg_uxtw"
2380   [(set (match_operand:DI 0 "register_operand" "=r")
2381         (zero_extend:DI
2382          (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2383                   [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2384   ""
2385   "csetm\\t%w0, %m1"
2386   [(set_attr "type" "csel")]
2389 (define_expand "cmov<mode>6"
2390   [(set (match_operand:GPI 0 "register_operand" "")
2391         (if_then_else:GPI
2392          (match_operator 1 "aarch64_comparison_operator"
2393           [(match_operand:GPI 2 "register_operand" "")
2394            (match_operand:GPI 3 "aarch64_plus_operand" "")])
2395          (match_operand:GPI 4 "register_operand" "")
2396          (match_operand:GPI 5 "register_operand" "")))]
2397   ""
2398   "
2399   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2400                                       operands[3]);
2401   operands[3] = const0_rtx;
2402   "
2405 (define_expand "cmov<mode>6"
2406   [(set (match_operand:GPF 0 "register_operand" "")
2407         (if_then_else:GPF
2408          (match_operator 1 "aarch64_comparison_operator"
2409           [(match_operand:GPF 2 "register_operand" "")
2410            (match_operand:GPF 3 "register_operand" "")])
2411          (match_operand:GPF 4 "register_operand" "")
2412          (match_operand:GPF 5 "register_operand" "")))]
2413   ""
2414   "
2415   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2416                                       operands[3]);
2417   operands[3] = const0_rtx;
2418   "
2421 (define_insn "*cmov<mode>_insn"
2422   [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2423         (if_then_else:ALLI
2424          (match_operator 1 "aarch64_comparison_operator"
2425           [(match_operand 2 "cc_register" "") (const_int 0)])
2426          (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2427          (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2428   "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2429      || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2430   ;; Final two alternatives should be unreachable, but included for completeness
2431   "@
2432    csel\\t%<w>0, %<w>3, %<w>4, %m1
2433    csinv\\t%<w>0, %<w>3, <w>zr, %m1
2434    csinv\\t%<w>0, %<w>4, <w>zr, %M1
2435    csinc\\t%<w>0, %<w>3, <w>zr, %m1
2436    csinc\\t%<w>0, %<w>4, <w>zr, %M1
2437    mov\\t%<w>0, -1
2438    mov\\t%<w>0, 1"
2439   [(set_attr "type" "csel")]
2442 ;; zero_extend version of above
2443 (define_insn "*cmovsi_insn_uxtw"
2444   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2445         (zero_extend:DI
2446          (if_then_else:SI
2447           (match_operator 1 "aarch64_comparison_operator"
2448            [(match_operand 2 "cc_register" "") (const_int 0)])
2449           (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2450           (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2451   "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2452      || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2453   ;; Final two alternatives should be unreachable, but included for completeness
2454   "@
2455    csel\\t%w0, %w3, %w4, %m1
2456    csinv\\t%w0, %w3, wzr, %m1
2457    csinv\\t%w0, %w4, wzr, %M1
2458    csinc\\t%w0, %w3, wzr, %m1
2459    csinc\\t%w0, %w4, wzr, %M1
2460    mov\\t%w0, -1
2461    mov\\t%w0, 1"
2462   [(set_attr "type" "csel")]
2465 (define_insn "*cmov<mode>_insn"
2466   [(set (match_operand:GPF 0 "register_operand" "=w")
2467         (if_then_else:GPF
2468          (match_operator 1 "aarch64_comparison_operator"
2469           [(match_operand 2 "cc_register" "") (const_int 0)])
2470          (match_operand:GPF 3 "register_operand" "w")
2471          (match_operand:GPF 4 "register_operand" "w")))]
2472   "TARGET_FLOAT"
2473   "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2474   [(set_attr "type" "fcsel")]
2477 (define_expand "mov<mode>cc"
2478   [(set (match_operand:ALLI 0 "register_operand" "")
2479         (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2480                            (match_operand:ALLI 2 "register_operand" "")
2481                            (match_operand:ALLI 3 "register_operand" "")))]
2482   ""
2483   {
2484     rtx ccreg;
2485     enum rtx_code code = GET_CODE (operands[1]);
2487     if (code == UNEQ || code == LTGT)
2488       FAIL;
2490     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2491                                   XEXP (operands[1], 1));
2492     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2493   }
2496 (define_expand "mov<GPF:mode><GPI:mode>cc"
2497   [(set (match_operand:GPI 0 "register_operand" "")
2498         (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2499                           (match_operand:GPF 2 "register_operand" "")
2500                           (match_operand:GPF 3 "register_operand" "")))]
2501   ""
2502   {
2503     rtx ccreg;
2504     enum rtx_code code = GET_CODE (operands[1]);
2506     if (code == UNEQ || code == LTGT)
2507       FAIL;
2509     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2510                                   XEXP (operands[1], 1));
2511     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2512   }
2515 (define_expand "mov<mode>cc"
2516   [(set (match_operand:GPF 0 "register_operand" "")
2517         (if_then_else:GPF (match_operand 1 "aarch64_comparison_operator" "")
2518                           (match_operand:GPF 2 "register_operand" "")
2519                           (match_operand:GPF 3 "register_operand" "")))]
2520   ""
2521   {
2522     rtx ccreg;
2523     enum rtx_code code = GET_CODE (operands[1]);
2525     if (code == UNEQ || code == LTGT)
2526       FAIL;
2528     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2529                                   XEXP (operands[1], 1));
2530     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2531   }
2535 ;; CRC32 instructions.
2536 (define_insn "aarch64_<crc_variant>"
2537   [(set (match_operand:SI 0 "register_operand" "=r")
2538         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2539                     (match_operand:<crc_mode> 2 "register_operand" "r")]
2540          CRC))]
2541   "TARGET_CRC32"
2542   {
2543     if (GET_MODE_BITSIZE (GET_MODE (operands[2])) >= 64)
2544       return "<crc_variant>\\t%w0, %w1, %x2";
2545     else
2546       return "<crc_variant>\\t%w0, %w1, %w2";
2547   }
2548   [(set_attr "type" "crc")]
2551 (define_insn "*csinc2<mode>_insn"
2552   [(set (match_operand:GPI 0 "register_operand" "=r")
2553         (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator"
2554                   [(match_operand:CC 3 "cc_register" "") (const_int 0)])
2555                  (match_operand:GPI 1 "register_operand" "r")))]
2556   ""
2557   "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2558   [(set_attr "type" "csel")]
2561 (define_insn "csinc3<mode>_insn"
2562   [(set (match_operand:GPI 0 "register_operand" "=r")
2563         (if_then_else:GPI
2564           (match_operator:GPI 1 "aarch64_comparison_operator"
2565            [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2566           (plus:GPI (match_operand:GPI 3 "register_operand" "r")
2567                     (const_int 1))
2568           (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2569   ""
2570   "csinc\\t%<w>0, %<w>4, %<w>3, %M1"
2571   [(set_attr "type" "csel")]
2574 (define_insn "*csinv3<mode>_insn"
2575   [(set (match_operand:GPI 0 "register_operand" "=r")
2576         (if_then_else:GPI
2577           (match_operator:GPI 1 "aarch64_comparison_operator"
2578            [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2579           (not:GPI (match_operand:GPI 3 "register_operand" "r"))
2580           (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2581   ""
2582   "csinv\\t%<w>0, %<w>4, %<w>3, %M1"
2583   [(set_attr "type" "csel")]
2586 (define_insn "*csneg3<mode>_insn"
2587   [(set (match_operand:GPI 0 "register_operand" "=r")
2588         (if_then_else:GPI
2589           (match_operator:GPI 1 "aarch64_comparison_operator"
2590            [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2591           (neg:GPI (match_operand:GPI 3 "register_operand" "r"))
2592           (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2593   ""
2594   "csneg\\t%<w>0, %<w>4, %<w>3, %M1"
2595   [(set_attr "type" "csel")]
2598 ;; -------------------------------------------------------------------
2599 ;; Logical operations
2600 ;; -------------------------------------------------------------------
2602 (define_insn "<optab><mode>3"
2603   [(set (match_operand:GPI 0 "register_operand" "=r,rk")
2604         (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2605                      (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
2606   ""
2607   "<logical>\\t%<w>0, %<w>1, %<w>2"
2608   [(set_attr "type" "logic_reg,logic_imm")]
2611 ;; zero_extend version of above
2612 (define_insn "*<optab>si3_uxtw"
2613   [(set (match_operand:DI 0 "register_operand" "=r,rk")
2614         (zero_extend:DI
2615          (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2616                      (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2617   ""
2618   "<logical>\\t%w0, %w1, %w2"
2619   [(set_attr "type" "logic_reg,logic_imm")]
2622 (define_insn "*and<mode>3_compare0"
2623   [(set (reg:CC_NZ CC_REGNUM)
2624         (compare:CC_NZ
2625          (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2626                   (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2627          (const_int 0)))
2628    (set (match_operand:GPI 0 "register_operand" "=r,r")
2629         (and:GPI (match_dup 1) (match_dup 2)))]
2630   ""
2631   "ands\\t%<w>0, %<w>1, %<w>2"
2632   [(set_attr "type" "logics_reg,logics_imm")]
2635 ;; zero_extend version of above
2636 (define_insn "*andsi3_compare0_uxtw"
2637   [(set (reg:CC_NZ CC_REGNUM)
2638         (compare:CC_NZ
2639          (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2640                  (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2641          (const_int 0)))
2642    (set (match_operand:DI 0 "register_operand" "=r,r")
2643         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2644   ""
2645   "ands\\t%w0, %w1, %w2"
2646   [(set_attr "type" "logics_reg,logics_imm")]
2649 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2650   [(set (reg:CC_NZ CC_REGNUM)
2651         (compare:CC_NZ
2652          (and:GPI (SHIFT: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          (const_int 0)))
2657    (set (match_operand:GPI 0 "register_operand" "=r")
2658         (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2659   ""
2660   "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2661   [(set_attr "type" "logics_shift_imm")]
2664 ;; zero_extend version of above
2665 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2666   [(set (reg:CC_NZ CC_REGNUM)
2667         (compare:CC_NZ
2668          (and:SI (SHIFT:SI
2669                   (match_operand:SI 1 "register_operand" "r")
2670                   (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2671                  (match_operand:SI 3 "register_operand" "r"))
2672          (const_int 0)))
2673    (set (match_operand:DI 0 "register_operand" "=r")
2674         (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2675                                 (match_dup 3))))]
2676   ""
2677   "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2678   [(set_attr "type" "logics_shift_imm")]
2681 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2682   [(set (match_operand:GPI 0 "register_operand" "=r")
2683         (LOGICAL:GPI (SHIFT:GPI
2684                       (match_operand:GPI 1 "register_operand" "r")
2685                       (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2686                      (match_operand:GPI 3 "register_operand" "r")))]
2687   ""
2688   "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2689   [(set_attr "type" "logic_shift_imm")]
2692 (define_insn "*<optab>_rol<mode>3"
2693   [(set (match_operand:GPI 0 "register_operand" "=r")
2694         (LOGICAL:GPI (rotate:GPI
2695                       (match_operand:GPI 1 "register_operand" "r")
2696                       (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2697                      (match_operand:GPI 3 "register_operand" "r")))]
2698   ""
2699   "<logical>\\t%<w>0, %<w>3, %<w>1, ror (<sizen> - %2)"
2700   [(set_attr "type" "logic_shift_imm")]
2703 ;; zero_extend versions of above
2704 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
2705   [(set (match_operand:DI 0 "register_operand" "=r")
2706         (zero_extend:DI
2707          (LOGICAL:SI (SHIFT:SI
2708                       (match_operand:SI 1 "register_operand" "r")
2709                       (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2710                      (match_operand:SI 3 "register_operand" "r"))))]
2711   ""
2712   "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2713   [(set_attr "type" "logic_shift_imm")]
2716 (define_insn "*<optab>_rolsi3_uxtw"
2717   [(set (match_operand:DI 0 "register_operand" "=r")
2718         (zero_extend:DI
2719          (LOGICAL:SI (rotate:SI
2720                       (match_operand:SI 1 "register_operand" "r")
2721                       (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2722                      (match_operand:SI 3 "register_operand" "r"))))]
2723   ""
2724   "<logical>\\t%w0, %w3, %w1, ror (32 - %2)"
2725   [(set_attr "type" "logic_shift_imm")]
2728 (define_insn "one_cmpl<mode>2"
2729   [(set (match_operand:GPI 0 "register_operand" "=r")
2730         (not:GPI (match_operand:GPI 1 "register_operand" "r")))]
2731   ""
2732   "mvn\\t%<w>0, %<w>1"
2733   [(set_attr "type" "logic_reg")]
2736 (define_insn "*one_cmpl_<optab><mode>2"
2737   [(set (match_operand:GPI 0 "register_operand" "=r")
2738         (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
2739                             (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2740   ""
2741   "mvn\\t%<w>0, %<w>1, <shift> %2"
2742   [(set_attr "type" "logic_shift_imm")]
2745 (define_insn "*<LOGICAL:optab>_one_cmpl<mode>3"
2746   [(set (match_operand:GPI 0 "register_operand" "=r")
2747         (LOGICAL:GPI (not:GPI
2748                       (match_operand:GPI 1 "register_operand" "r"))
2749                      (match_operand:GPI 2 "register_operand" "r")))]
2750   ""
2751   "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1"
2752   [(set_attr "type" "logic_reg")]
2755 (define_insn "*and_one_cmpl<mode>3_compare0"
2756   [(set (reg:CC_NZ CC_REGNUM)
2757         (compare:CC_NZ
2758          (and:GPI (not:GPI
2759                    (match_operand:GPI 1 "register_operand" "r"))
2760                   (match_operand:GPI 2 "register_operand" "r"))
2761          (const_int 0)))
2762    (set (match_operand:GPI 0 "register_operand" "=r")
2763         (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
2764   ""
2765   "bics\\t%<w>0, %<w>2, %<w>1"
2766   [(set_attr "type" "logics_reg")]
2769 ;; zero_extend version of above
2770 (define_insn "*and_one_cmplsi3_compare0_uxtw"
2771   [(set (reg:CC_NZ CC_REGNUM)
2772         (compare:CC_NZ
2773          (and:SI (not:SI
2774                   (match_operand:SI 1 "register_operand" "r"))
2775                  (match_operand:SI 2 "register_operand" "r"))
2776          (const_int 0)))
2777    (set (match_operand:DI 0 "register_operand" "=r")
2778         (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
2779   ""
2780   "bics\\t%w0, %w2, %w1"
2781   [(set_attr "type" "logics_reg")]
2784 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
2785   [(set (match_operand:GPI 0 "register_operand" "=r")
2786         (LOGICAL:GPI (not:GPI
2787                       (SHIFT:GPI
2788                        (match_operand:GPI 1 "register_operand" "r")
2789                        (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2790                      (match_operand:GPI 3 "register_operand" "r")))]
2791   ""
2792   "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2793   [(set_attr "type" "logics_shift_imm")]
2796 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
2797   [(set (reg:CC_NZ CC_REGNUM)
2798         (compare:CC_NZ
2799          (and:GPI (not:GPI
2800                    (SHIFT:GPI
2801                     (match_operand:GPI 1 "register_operand" "r")
2802                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2803                   (match_operand:GPI 3 "register_operand" "r"))
2804          (const_int 0)))
2805    (set (match_operand:GPI 0 "register_operand" "=r")
2806         (and:GPI (not:GPI
2807                   (SHIFT:GPI
2808                    (match_dup 1) (match_dup 2))) (match_dup 3)))]
2809   ""
2810   "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2811   [(set_attr "type" "logics_shift_imm")]
2814 ;; zero_extend version of above
2815 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
2816   [(set (reg:CC_NZ CC_REGNUM)
2817         (compare:CC_NZ
2818          (and:SI (not:SI
2819                   (SHIFT:SI
2820                    (match_operand:SI 1 "register_operand" "r")
2821                    (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
2822                  (match_operand:SI 3 "register_operand" "r"))
2823          (const_int 0)))
2824    (set (match_operand:DI 0 "register_operand" "=r")
2825         (zero_extend:DI (and:SI
2826                          (not:SI
2827                           (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
2828   ""
2829   "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2830   [(set_attr "type" "logics_shift_imm")]
2833 (define_insn "clz<mode>2"
2834   [(set (match_operand:GPI 0 "register_operand" "=r")
2835         (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
2836   ""
2837   "clz\\t%<w>0, %<w>1"
2838   [(set_attr "type" "clz")]
2841 (define_expand "ffs<mode>2"
2842   [(match_operand:GPI 0 "register_operand")
2843    (match_operand:GPI 1 "register_operand")]
2844   ""
2845   {
2846     rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
2847     rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
2849     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2850     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2851     emit_insn (gen_csinc3<mode>_insn (operands[0], x, ccreg, operands[0], const0_rtx));
2852     DONE;
2853   }
2856 (define_insn "clrsb<mode>2"
2857   [(set (match_operand:GPI 0 "register_operand" "=r")
2858         (clrsb:GPI (match_operand:GPI 1 "register_operand" "r")))]
2859   ""
2860   "cls\\t%<w>0, %<w>1"
2861   [(set_attr "type" "clz")]
2864 (define_insn "rbit<mode>2"
2865   [(set (match_operand:GPI 0 "register_operand" "=r")
2866         (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
2867   ""
2868   "rbit\\t%<w>0, %<w>1"
2869   [(set_attr "type" "rbit")]
2872 (define_expand "ctz<mode>2"
2873   [(match_operand:GPI 0 "register_operand")
2874    (match_operand:GPI 1 "register_operand")]
2875   ""
2876   {
2877     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2878     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2879     DONE;
2880   }
2883 (define_insn "*and<mode>3nr_compare0"
2884   [(set (reg:CC_NZ CC_REGNUM)
2885         (compare:CC_NZ
2886          (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
2887                   (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
2888          (const_int 0)))]
2889   ""
2890   "tst\\t%<w>0, %<w>1"
2891   [(set_attr "type" "logics_reg")]
2894 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
2895   [(set (reg:CC_NZ CC_REGNUM)
2896         (compare:CC_NZ
2897          (and:GPI (SHIFT:GPI
2898                    (match_operand:GPI 0 "register_operand" "r")
2899                    (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2900                   (match_operand:GPI 2 "register_operand" "r"))
2901         (const_int 0)))]
2902   ""
2903   "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
2904   [(set_attr "type" "logics_shift_imm")]
2907 ;; -------------------------------------------------------------------
2908 ;; Shifts
2909 ;; -------------------------------------------------------------------
2911 (define_expand "<optab><mode>3"
2912   [(set (match_operand:GPI 0 "register_operand")
2913         (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
2914                     (match_operand:QI 2 "nonmemory_operand")))]
2915   ""
2916   {
2917     if (CONST_INT_P (operands[2]))
2918       {
2919         operands[2] = GEN_INT (INTVAL (operands[2])
2920                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2922         if (operands[2] == const0_rtx)
2923           {
2924             emit_insn (gen_mov<mode> (operands[0], operands[1]));
2925             DONE;
2926           }
2927       }
2928   }
2931 (define_expand "ashl<mode>3"
2932   [(set (match_operand:SHORT 0 "register_operand")
2933         (ashift:SHORT (match_operand:SHORT 1 "register_operand")
2934                       (match_operand:QI 2 "nonmemory_operand")))]
2935   ""
2936   {
2937     if (CONST_INT_P (operands[2]))
2938       {
2939         operands[2] = GEN_INT (INTVAL (operands[2])
2940                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2942         if (operands[2] == const0_rtx)
2943           {
2944             emit_insn (gen_mov<mode> (operands[0], operands[1]));
2945             DONE;
2946           }
2947       }
2948   }
2951 (define_expand "rotr<mode>3"
2952   [(set (match_operand:GPI 0 "register_operand")
2953         (rotatert:GPI (match_operand:GPI 1 "register_operand")
2954                       (match_operand:QI 2 "nonmemory_operand")))]
2955   ""
2956   {
2957     if (CONST_INT_P (operands[2]))
2958       {
2959         operands[2] = GEN_INT (INTVAL (operands[2])
2960                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2962         if (operands[2] == const0_rtx)
2963           {
2964             emit_insn (gen_mov<mode> (operands[0], operands[1]));
2965             DONE;
2966           }
2967       }
2968   }
2971 (define_expand "rotl<mode>3"
2972   [(set (match_operand:GPI 0 "register_operand")
2973         (rotatert:GPI (match_operand:GPI 1 "register_operand")
2974                       (match_operand:QI 2 "nonmemory_operand")))]
2975   ""
2976   {
2977     /* (SZ - cnt) % SZ == -cnt % SZ */
2978     if (CONST_INT_P (operands[2]))
2979       {
2980         operands[2] = GEN_INT ((-INTVAL (operands[2]))
2981                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2982         if (operands[2] == const0_rtx)
2983           {
2984             emit_insn (gen_mov<mode> (operands[0], operands[1]));
2985             DONE;
2986           }
2987       }
2988     else
2989       operands[2] = expand_simple_unop (QImode, NEG, operands[2],
2990                                         NULL_RTX, 1);
2991   }
2994 ;; Logical left shift using SISD or Integer instruction
2995 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
2996   [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
2997         (ashift:GPI
2998           (match_operand:GPI 1 "register_operand" "w,w,r")
2999           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3000   ""
3001   "@
3002    shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3003    ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
3004    lsl\t%<w>0, %<w>1, %<w>2"
3005   [(set_attr "simd" "yes,yes,no")
3006    (set_attr "type" "neon_shift_imm<q>, neon_shift_reg<q>,shift_reg")]
3009 ;; Logical right shift using SISD or Integer instruction
3010 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3011   [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3012         (lshiftrt:GPI
3013           (match_operand:GPI 1 "register_operand" "w,w,r")
3014           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3015   ""
3016   "@
3017    ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3018    #
3019    lsr\t%<w>0, %<w>1, %<w>2"
3020   [(set_attr "simd" "yes,yes,no")
3021    (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")]
3024 (define_split
3025   [(set (match_operand:DI 0 "aarch64_simd_register")
3026         (lshiftrt:DI
3027            (match_operand:DI 1 "aarch64_simd_register")
3028            (match_operand:QI 2 "aarch64_simd_register")))]
3029   "TARGET_SIMD && reload_completed"
3030   [(set (match_dup 2)
3031         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3032    (set (match_dup 0)
3033         (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_USHL))]
3034   ""
3037 (define_split
3038   [(set (match_operand:SI 0 "aarch64_simd_register")
3039         (lshiftrt:SI
3040            (match_operand:SI 1 "aarch64_simd_register")
3041            (match_operand:QI 2 "aarch64_simd_register")))]
3042   "TARGET_SIMD && reload_completed"
3043   [(set (match_dup 2)
3044         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3045    (set (match_dup 0)
3046         (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_USHL_2S))]
3047   ""
3050 ;; Arithmetic right shift using SISD or Integer instruction
3051 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3052   [(set (match_operand:GPI 0 "register_operand" "=w,&w,&w,r")
3053         (ashiftrt:GPI
3054           (match_operand:GPI 1 "register_operand" "w,w,w,r")
3055           (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,0,rUs<cmode>")))]
3056   ""
3057   "@
3058    sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3059    #
3060    #
3061    asr\t%<w>0, %<w>1, %<w>2"
3062   [(set_attr "simd" "yes,yes,yes,no")
3063    (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>,shift_reg")]
3066 (define_split
3067   [(set (match_operand:DI 0 "aarch64_simd_register")
3068         (ashiftrt:DI
3069            (match_operand:DI 1 "aarch64_simd_register")
3070            (match_operand:QI 2 "aarch64_simd_register")))]
3071   "TARGET_SIMD && reload_completed"
3072   [(set (match_dup 3)
3073         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3074    (set (match_dup 0)
3075         (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_SSHL))]
3077   operands[3] = gen_lowpart (QImode, operands[0]);
3081 (define_split
3082   [(set (match_operand:SI 0 "aarch64_simd_register")
3083         (ashiftrt:SI
3084            (match_operand:SI 1 "aarch64_simd_register")
3085            (match_operand:QI 2 "aarch64_simd_register")))]
3086   "TARGET_SIMD && reload_completed"
3087   [(set (match_dup 3)
3088         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3089    (set (match_dup 0)
3090         (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_SSHL_2S))]
3092   operands[3] = gen_lowpart (QImode, operands[0]);
3096 (define_insn "*aarch64_sisd_ushl"
3097   [(set (match_operand:DI 0 "register_operand" "=w")
3098         (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3099                     (match_operand:QI 2 "register_operand" "w")]
3100                    UNSPEC_SISD_USHL))]
3101   "TARGET_SIMD"
3102   "ushl\t%d0, %d1, %d2"
3103   [(set_attr "simd" "yes")
3104    (set_attr "type" "neon_shift_reg")]
3107 (define_insn "*aarch64_ushl_2s"
3108   [(set (match_operand:SI 0 "register_operand" "=w")
3109         (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3110                     (match_operand:QI 2 "register_operand" "w")]
3111                    UNSPEC_USHL_2S))]
3112   "TARGET_SIMD"
3113   "ushl\t%0.2s, %1.2s, %2.2s"
3114   [(set_attr "simd" "yes")
3115    (set_attr "type" "neon_shift_reg")]
3118 (define_insn "*aarch64_sisd_sshl"
3119   [(set (match_operand:DI 0 "register_operand" "=w")
3120         (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3121                     (match_operand:QI 2 "register_operand" "w")]
3122                    UNSPEC_SISD_SSHL))]
3123   "TARGET_SIMD"
3124   "sshl\t%d0, %d1, %d2"
3125   [(set_attr "simd" "yes")
3126    (set_attr "type" "neon_shift_reg")]
3129 (define_insn "*aarch64_sshl_2s"
3130   [(set (match_operand:SI 0 "register_operand" "=w")
3131         (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3132                     (match_operand:QI 2 "register_operand" "w")]
3133                    UNSPEC_SSHL_2S))]
3134   "TARGET_SIMD"
3135   "sshl\t%0.2s, %1.2s, %2.2s"
3136   [(set_attr "simd" "yes")
3137    (set_attr "type" "neon_shift_reg")]
3140 (define_insn "*aarch64_sisd_neg_qi"
3141   [(set (match_operand:QI 0 "register_operand" "=w")
3142         (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3143                    UNSPEC_SISD_NEG))]
3144   "TARGET_SIMD"
3145   "neg\t%d0, %d1"
3146   [(set_attr "simd" "yes")
3147    (set_attr "type" "neon_neg")]
3150 ;; Rotate right
3151 (define_insn "*ror<mode>3_insn"
3152   [(set (match_operand:GPI 0 "register_operand" "=r")
3153         (rotatert:GPI
3154           (match_operand:GPI 1 "register_operand" "r")
3155           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3156   ""
3157   "ror\\t%<w>0, %<w>1, %<w>2"
3158   [(set_attr "type" "shift_reg")]
3161 ;; zero_extend version of above
3162 (define_insn "*<optab>si3_insn_uxtw"
3163   [(set (match_operand:DI 0 "register_operand" "=r")
3164         (zero_extend:DI (SHIFT:SI
3165          (match_operand:SI 1 "register_operand" "r")
3166          (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3167   ""
3168   "<shift>\\t%w0, %w1, %w2"
3169   [(set_attr "type" "shift_reg")]
3172 (define_insn "*ashl<mode>3_insn"
3173   [(set (match_operand:SHORT 0 "register_operand" "=r")
3174         (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3175                       (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
3176   ""
3177   "lsl\\t%<w>0, %<w>1, %<w>2"
3178   [(set_attr "type" "shift_reg")]
3181 (define_insn "*<optab><mode>3_insn"
3182   [(set (match_operand:SHORT 0 "register_operand" "=r")
3183         (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3184                       (match_operand 2 "const_int_operand" "n")))]
3185   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3187   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3188   return "<bfshift>\t%w0, %w1, %2, %3";
3190   [(set_attr "type" "bfm")]
3193 (define_insn "*extr<mode>5_insn"
3194   [(set (match_operand:GPI 0 "register_operand" "=r")
3195         (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3196                              (match_operand 3 "const_int_operand" "n"))
3197                  (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3198                                (match_operand 4 "const_int_operand" "n"))))]
3199   "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3200    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3201   "extr\\t%<w>0, %<w>1, %<w>2, %4"
3202   [(set_attr "type" "shift_imm")]
3205 ;; zero_extend version of the above
3206 (define_insn "*extrsi5_insn_uxtw"
3207   [(set (match_operand:DI 0 "register_operand" "=r")
3208         (zero_extend:DI
3209          (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3210                             (match_operand 3 "const_int_operand" "n"))
3211                  (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3212                               (match_operand 4 "const_int_operand" "n")))))]
3213   "UINTVAL (operands[3]) < 32 &&
3214    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3215   "extr\\t%w0, %w1, %w2, %4"
3216   [(set_attr "type" "shift_imm")]
3219 (define_insn "*ror<mode>3_insn"
3220   [(set (match_operand:GPI 0 "register_operand" "=r")
3221         (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3222                     (match_operand 2 "const_int_operand" "n")))]
3223   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3225   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3226   return "ror\\t%<w>0, %<w>1, %3";
3228   [(set_attr "type" "shift_imm")]
3231 ;; zero_extend version of the above
3232 (define_insn "*rorsi3_insn_uxtw"
3233   [(set (match_operand:DI 0 "register_operand" "=r")
3234         (zero_extend:DI
3235          (rotate:SI (match_operand:SI 1 "register_operand" "r")
3236                     (match_operand 2 "const_int_operand" "n"))))]
3237   "UINTVAL (operands[2]) < 32"
3239   operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3240   return "ror\\t%w0, %w1, %3";
3242   [(set_attr "type" "shift_imm")]
3245 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3246   [(set (match_operand:GPI 0 "register_operand" "=r")
3247         (ANY_EXTEND:GPI
3248          (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3249                        (match_operand 2 "const_int_operand" "n"))))]
3250   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3252   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3253   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3255   [(set_attr "type" "bfm")]
3258 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3259   [(set (match_operand:GPI 0 "register_operand" "=r")
3260         (zero_extend:GPI
3261          (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3262                          (match_operand 2 "const_int_operand" "n"))))]
3263   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3265   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3266   return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3268   [(set_attr "type" "bfm")]
3271 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3272   [(set (match_operand:GPI 0 "register_operand" "=r")
3273         (sign_extend:GPI
3274          (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3275                          (match_operand 2 "const_int_operand" "n"))))]
3276   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3278   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3279   return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3281   [(set_attr "type" "bfm")]
3284 ;; -------------------------------------------------------------------
3285 ;; Bitfields
3286 ;; -------------------------------------------------------------------
3288 (define_expand "<optab>"
3289   [(set (match_operand:DI 0 "register_operand" "=r")
3290         (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3291                         (match_operand 2 "const_int_operand" "n")
3292                         (match_operand 3 "const_int_operand" "n")))]
3293   ""
3294   ""
3297 (define_insn "*<optab><mode>"
3298   [(set (match_operand:GPI 0 "register_operand" "=r")
3299         (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3300                          (match_operand 2 "const_int_operand" "n")
3301                          (match_operand 3 "const_int_operand" "n")))]
3302   ""
3303   "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3304   [(set_attr "type" "bfm")]
3307 ;; Bitfield Insert (insv)
3308 (define_expand "insv<mode>"
3309   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3310                           (match_operand 1 "const_int_operand")
3311                           (match_operand 2 "const_int_operand"))
3312         (match_operand:GPI 3 "general_operand"))]
3313   ""
3315   unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3316   unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3317   rtx value = operands[3];
3319   if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3320     FAIL;
3322   if (CONST_INT_P (value))
3323     {
3324       unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3326       /* Prefer AND/OR for inserting all zeros or all ones.  */
3327       if ((UINTVAL (value) & mask) == 0
3328            || (UINTVAL (value) & mask) == mask)
3329         FAIL;
3331       /* 16-bit aligned 16-bit wide insert is handled by insv_imm.  */
3332       if (width == 16 && (pos % 16) == 0)
3333         DONE;
3334     }
3335   operands[3] = force_reg (<MODE>mode, value);
3338 (define_insn "*insv_reg<mode>"
3339   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3340                           (match_operand 1 "const_int_operand" "n")
3341                           (match_operand 2 "const_int_operand" "n"))
3342         (match_operand:GPI 3 "register_operand" "r"))]
3343   "!(UINTVAL (operands[1]) == 0
3344      || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3345          > GET_MODE_BITSIZE (<MODE>mode)))"
3346   "bfi\\t%<w>0, %<w>3, %2, %1"
3347   [(set_attr "type" "bfm")]
3350 (define_insn "*extr_insv_lower_reg<mode>"
3351   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3352                           (match_operand 1 "const_int_operand" "n")
3353                           (const_int 0))
3354         (zero_extract:GPI (match_operand:GPI 2 "register_operand" "+r")
3355                           (match_dup 1)
3356                           (match_operand 3 "const_int_operand" "n")))]
3357   "!(UINTVAL (operands[1]) == 0
3358      || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3359          > GET_MODE_BITSIZE (<MODE>mode)))"
3360   "bfxil\\t%<w>0, %<w>2, %3, %1"
3361   [(set_attr "type" "bfm")]
3364 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3365   [(set (match_operand:GPI 0 "register_operand" "=r")
3366         (ashift:GPI (ANY_EXTEND:GPI
3367                      (match_operand:ALLX 1 "register_operand" "r"))
3368                     (match_operand 2 "const_int_operand" "n")))]
3369   "UINTVAL (operands[2]) < <GPI:sizen>"
3371   operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3372               ? GEN_INT (<ALLX:sizen>)
3373               : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3374   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3376   [(set_attr "type" "bfm")]
3379 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3381 (define_insn "*andim_ashift<mode>_bfiz"
3382   [(set (match_operand:GPI 0 "register_operand" "=r")
3383         (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3384                              (match_operand 2 "const_int_operand" "n"))
3385                  (match_operand 3 "const_int_operand" "n")))]
3386   "exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3387    && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3388   "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3389   [(set_attr "type" "bfm")]
3392 (define_insn "bswap<mode>2"
3393   [(set (match_operand:GPI 0 "register_operand" "=r")
3394         (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3395   ""
3396   "rev\\t%<w>0, %<w>1"
3397   [(set_attr "type" "rev")]
3400 (define_insn "bswaphi2"
3401   [(set (match_operand:HI 0 "register_operand" "=r")
3402         (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3403   ""
3404   "rev16\\t%w0, %w1"
3405   [(set_attr "type" "rev")]
3408 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
3409 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
3410 ;; each valid permutation.
3412 (define_insn "rev16<mode>2"
3413   [(set (match_operand:GPI 0 "register_operand" "=r")
3414         (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3415                                       (const_int 8))
3416                           (match_operand:GPI 3 "const_int_operand" "n"))
3417                  (and:GPI (lshiftrt:GPI (match_dup 1)
3418                                         (const_int 8))
3419                           (match_operand:GPI 2 "const_int_operand" "n"))))]
3420   "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3421    && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3422   "rev16\\t%<w>0, %<w>1"
3423   [(set_attr "type" "rev")]
3426 (define_insn "rev16<mode>2_alt"
3427   [(set (match_operand:GPI 0 "register_operand" "=r")
3428         (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r")
3429                                         (const_int 8))
3430                           (match_operand:GPI 2 "const_int_operand" "n"))
3431                  (and:GPI (ashift:GPI (match_dup 1)
3432                                       (const_int 8))
3433                           (match_operand:GPI 3 "const_int_operand" "n"))))]
3434   "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3435    && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3436   "rev16\\t%<w>0, %<w>1"
3437   [(set_attr "type" "rev")]
3440 ;; zero_extend version of above
3441 (define_insn "*bswapsi2_uxtw"
3442   [(set (match_operand:DI 0 "register_operand" "=r")
3443         (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3444   ""
3445   "rev\\t%w0, %w1"
3446   [(set_attr "type" "rev")]
3449 ;; -------------------------------------------------------------------
3450 ;; Floating-point intrinsics
3451 ;; -------------------------------------------------------------------
3453 ;; frint floating-point round to integral standard patterns.
3454 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round, frintn.
3456 (define_insn "<frint_pattern><mode>2"
3457   [(set (match_operand:GPF 0 "register_operand" "=w")
3458         (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3459          FRINT))]
3460   "TARGET_FLOAT"
3461   "frint<frint_suffix>\\t%<s>0, %<s>1"
3462   [(set_attr "type" "f_rint<s>")]
3465 ;; frcvt floating-point round to integer and convert standard patterns.
3466 ;; Expands to lbtrunc, lceil, lfloor, lround.
3467 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3468   [(set (match_operand:GPI 0 "register_operand" "=r")
3469         (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3470                       FCVT)))]
3471   "TARGET_FLOAT"
3472   "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3473   [(set_attr "type" "f_cvtf2i")]
3476 ;; fma - no throw
3478 (define_insn "fma<mode>4"
3479   [(set (match_operand:GPF 0 "register_operand" "=w")
3480         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3481                  (match_operand:GPF 2 "register_operand" "w")
3482                  (match_operand:GPF 3 "register_operand" "w")))]
3483   "TARGET_FLOAT"
3484   "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3485   [(set_attr "type" "fmac<s>")]
3488 (define_insn "fnma<mode>4"
3489   [(set (match_operand:GPF 0 "register_operand" "=w")
3490         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3491                  (match_operand:GPF 2 "register_operand" "w")
3492                  (match_operand:GPF 3 "register_operand" "w")))]
3493   "TARGET_FLOAT"
3494   "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3495   [(set_attr "type" "fmac<s>")]
3498 (define_insn "fms<mode>4"
3499   [(set (match_operand:GPF 0 "register_operand" "=w")
3500         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3501                  (match_operand:GPF 2 "register_operand" "w")
3502                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3503   "TARGET_FLOAT"
3504   "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3505   [(set_attr "type" "fmac<s>")]
3508 (define_insn "fnms<mode>4"
3509   [(set (match_operand:GPF 0 "register_operand" "=w")
3510         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3511                  (match_operand:GPF 2 "register_operand" "w")
3512                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3513   "TARGET_FLOAT"
3514   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3515   [(set_attr "type" "fmac<s>")]
3518 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3519 (define_insn "*fnmadd<mode>4"
3520   [(set (match_operand:GPF 0 "register_operand" "=w")
3521         (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3522                           (match_operand:GPF 2 "register_operand" "w")
3523                           (match_operand:GPF 3 "register_operand" "w"))))]
3524   "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3525   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3526   [(set_attr "type" "fmac<s>")]
3529 ;; -------------------------------------------------------------------
3530 ;; Floating-point conversions
3531 ;; -------------------------------------------------------------------
3533 (define_insn "extendsfdf2"
3534   [(set (match_operand:DF 0 "register_operand" "=w")
3535         (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3536   "TARGET_FLOAT"
3537   "fcvt\\t%d0, %s1"
3538   [(set_attr "type" "f_cvt")]
3541 (define_insn "truncdfsf2"
3542   [(set (match_operand:SF 0 "register_operand" "=w")
3543         (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3544   "TARGET_FLOAT"
3545   "fcvt\\t%s0, %d1"
3546   [(set_attr "type" "f_cvt")]
3549 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3550   [(set (match_operand:GPI 0 "register_operand" "=r")
3551         (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3552   "TARGET_FLOAT"
3553   "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3554   [(set_attr "type" "f_cvtf2i")]
3557 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3558   [(set (match_operand:GPI 0 "register_operand" "=r")
3559         (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3560   "TARGET_FLOAT"
3561   "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3562   [(set_attr "type" "f_cvtf2i")]
3565 (define_insn "float<GPI:mode><GPF:mode>2"
3566   [(set (match_operand:GPF 0 "register_operand" "=w")
3567         (float:GPF (match_operand:GPI 1 "register_operand" "r")))]
3568   "TARGET_FLOAT"
3569   "scvtf\\t%<GPF:s>0, %<GPI:w>1"
3570   [(set_attr "type" "f_cvti2f")]
3573 (define_insn "floatuns<GPI:mode><GPF:mode>2"
3574   [(set (match_operand:GPF 0 "register_operand" "=w")
3575         (unsigned_float:GPF (match_operand:GPI 1 "register_operand" "r")))]
3576   "TARGET_FLOAT"
3577   "ucvtf\\t%<GPF:s>0, %<GPI:w>1"
3578   [(set_attr "type" "f_cvt")]
3581 ;; -------------------------------------------------------------------
3582 ;; Floating-point arithmetic
3583 ;; -------------------------------------------------------------------
3585 (define_insn "add<mode>3"
3586   [(set (match_operand:GPF 0 "register_operand" "=w")
3587         (plus:GPF
3588          (match_operand:GPF 1 "register_operand" "w")
3589          (match_operand:GPF 2 "register_operand" "w")))]
3590   "TARGET_FLOAT"
3591   "fadd\\t%<s>0, %<s>1, %<s>2"
3592   [(set_attr "type" "fadd<s>")]
3595 (define_insn "sub<mode>3"
3596   [(set (match_operand:GPF 0 "register_operand" "=w")
3597         (minus:GPF
3598          (match_operand:GPF 1 "register_operand" "w")
3599          (match_operand:GPF 2 "register_operand" "w")))]
3600   "TARGET_FLOAT"
3601   "fsub\\t%<s>0, %<s>1, %<s>2"
3602   [(set_attr "type" "fadd<s>")]
3605 (define_insn "mul<mode>3"
3606   [(set (match_operand:GPF 0 "register_operand" "=w")
3607         (mult:GPF
3608          (match_operand:GPF 1 "register_operand" "w")
3609          (match_operand:GPF 2 "register_operand" "w")))]
3610   "TARGET_FLOAT"
3611   "fmul\\t%<s>0, %<s>1, %<s>2"
3612   [(set_attr "type" "fmul<s>")]
3615 (define_insn "*fnmul<mode>3"
3616   [(set (match_operand:GPF 0 "register_operand" "=w")
3617         (mult:GPF
3618                  (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3619                  (match_operand:GPF 2 "register_operand" "w")))]
3620   "TARGET_FLOAT"
3621   "fnmul\\t%<s>0, %<s>1, %<s>2"
3622   [(set_attr "type" "fmul<s>")]
3625 (define_insn "div<mode>3"
3626   [(set (match_operand:GPF 0 "register_operand" "=w")
3627         (div:GPF
3628          (match_operand:GPF 1 "register_operand" "w")
3629          (match_operand:GPF 2 "register_operand" "w")))]
3630   "TARGET_FLOAT"
3631   "fdiv\\t%<s>0, %<s>1, %<s>2"
3632   [(set_attr "type" "fdiv<s>")]
3635 (define_insn "neg<mode>2"
3636   [(set (match_operand:GPF 0 "register_operand" "=w")
3637         (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
3638   "TARGET_FLOAT"
3639   "fneg\\t%<s>0, %<s>1"
3640   [(set_attr "type" "ffarith<s>")]
3643 (define_insn "sqrt<mode>2"
3644   [(set (match_operand:GPF 0 "register_operand" "=w")
3645         (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
3646   "TARGET_FLOAT"
3647   "fsqrt\\t%<s>0, %<s>1"
3648   [(set_attr "type" "fsqrt<s>")]
3651 (define_insn "abs<mode>2"
3652   [(set (match_operand:GPF 0 "register_operand" "=w")
3653         (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
3654   "TARGET_FLOAT"
3655   "fabs\\t%<s>0, %<s>1"
3656   [(set_attr "type" "ffarith<s>")]
3659 ;; Given that smax/smin do not specify the result when either input is NaN,
3660 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
3661 ;; for smin.
3663 (define_insn "smax<mode>3"
3664   [(set (match_operand:GPF 0 "register_operand" "=w")
3665         (smax:GPF (match_operand:GPF 1 "register_operand" "w")
3666                   (match_operand:GPF 2 "register_operand" "w")))]
3667   "TARGET_FLOAT"
3668   "fmaxnm\\t%<s>0, %<s>1, %<s>2"
3669   [(set_attr "type" "f_minmax<s>")]
3672 (define_insn "smin<mode>3"
3673   [(set (match_operand:GPF 0 "register_operand" "=w")
3674         (smin:GPF (match_operand:GPF 1 "register_operand" "w")
3675                   (match_operand:GPF 2 "register_operand" "w")))]
3676   "TARGET_FLOAT"
3677   "fminnm\\t%<s>0, %<s>1, %<s>2"
3678   [(set_attr "type" "f_minmax<s>")]
3681 ;; -------------------------------------------------------------------
3682 ;; Reload support
3683 ;; -------------------------------------------------------------------
3685 (define_expand "aarch64_reload_mov<mode>"
3686   [(set (match_operand:TX 0 "register_operand" "=w")
3687         (match_operand:TX 1 "register_operand" "w"))
3688    (clobber (match_operand:DI 2 "register_operand" "=&r"))
3689   ]
3690   "TARGET_FLOAT"
3691   {
3692     rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
3693     rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
3694     gen_aarch64_movtilow_tilow (op0, op1);
3695     gen_aarch64_movdi_tihigh (operands[2], op1);
3696     gen_aarch64_movtihigh_di (op0, operands[2]);
3697     DONE;
3698   }
3701 ;; The following secondary reload helpers patterns are invoked
3702 ;; after or during reload as we don't want these patterns to start
3703 ;; kicking in during the combiner.
3705 (define_insn "aarch64_movdi_<mode>low"
3706   [(set (match_operand:DI 0 "register_operand" "=r")
3707         (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
3708   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
3709   "fmov\\t%x0, %d1"
3710   [(set_attr "type" "f_mrc")
3711    (set_attr "length" "4")
3712   ])
3714 (define_insn "aarch64_movdi_<mode>high"
3715   [(set (match_operand:DI 0 "register_operand" "=r")
3716         (truncate:DI
3717           (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
3718                        (const_int 64))))]
3719   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
3720   "fmov\\t%x0, %1.d[1]"
3721   [(set_attr "type" "f_mrc")
3722    (set_attr "length" "4")
3723   ])
3725 (define_insn "aarch64_mov<mode>high_di"
3726   [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
3727                          (const_int 64) (const_int 64))
3728         (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
3729   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
3730   "fmov\\t%0.d[1], %x1"
3731   [(set_attr "type" "f_mcr")
3732    (set_attr "length" "4")
3733   ])
3735 (define_insn "aarch64_mov<mode>low_di"
3736   [(set (match_operand:TX 0 "register_operand" "=w")
3737         (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
3738   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
3739   "fmov\\t%d0, %x1"
3740   [(set_attr "type" "f_mcr")
3741    (set_attr "length" "4")
3742   ])
3744 (define_insn "aarch64_movtilow_tilow"
3745   [(set (match_operand:TI 0 "register_operand" "=w")
3746         (zero_extend:TI
3747           (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
3748   "TARGET_FLOAT && (reload_completed || reload_in_progress)"
3749   "fmov\\t%d0, %d1"
3750   [(set_attr "type" "fmov")
3751    (set_attr "length" "4")
3752   ])
3754 ;; There is a deliberate reason why the parameters of high and lo_sum's
3755 ;; don't have modes for ADRP and ADD instructions.  This is to allow high
3756 ;; and lo_sum's to be used with the labels defining the jump tables in
3757 ;; rodata section.
3759 (define_expand "add_losym"
3760   [(set (match_operand 0 "register_operand" "=r")
3761         (lo_sum (match_operand 1 "register_operand" "r")
3762                 (match_operand 2 "aarch64_valid_symref" "S")))]
3763   ""
3765   enum machine_mode mode = GET_MODE (operands[0]);
3767   emit_insn ((mode == DImode
3768               ? gen_add_losym_di
3769               : gen_add_losym_si) (operands[0],
3770                                    operands[1],
3771                                    operands[2]));
3772   DONE;
3775 (define_insn "add_losym_<mode>"
3776   [(set (match_operand:P 0 "register_operand" "=r")
3777         (lo_sum:P (match_operand:P 1 "register_operand" "r")
3778                   (match_operand 2 "aarch64_valid_symref" "S")))]
3779   ""
3780   "add\\t%<w>0, %<w>1, :lo12:%a2"
3781   [(set_attr "type" "alu_reg")]
3784 (define_insn "ldr_got_small_<mode>"
3785   [(set (match_operand:PTR 0 "register_operand" "=r")
3786         (unspec:PTR [(mem:PTR (lo_sum:PTR
3787                               (match_operand:PTR 1 "register_operand" "r")
3788                               (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
3789                     UNSPEC_GOTSMALLPIC))]
3790   ""
3791   "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
3792   [(set_attr "type" "load1")]
3795 (define_insn "ldr_got_small_sidi"
3796   [(set (match_operand:DI 0 "register_operand" "=r")
3797         (zero_extend:DI
3798          (unspec:SI [(mem:SI (lo_sum:DI
3799                              (match_operand:DI 1 "register_operand" "r")
3800                              (match_operand:DI 2 "aarch64_valid_symref" "S")))]
3801                     UNSPEC_GOTSMALLPIC)))]
3802   "TARGET_ILP32"
3803   "ldr\\t%w0, [%1, #:got_lo12:%a2]"
3804   [(set_attr "type" "load1")]
3807 (define_insn "ldr_got_tiny"
3808   [(set (match_operand:DI 0 "register_operand" "=r")
3809         (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
3810                    UNSPEC_GOTTINYPIC))]
3811   ""
3812   "ldr\\t%0, %L1"
3813   [(set_attr "type" "load1")]
3816 (define_insn "aarch64_load_tp_hard"
3817   [(set (match_operand:DI 0 "register_operand" "=r")
3818         (unspec:DI [(const_int 0)] UNSPEC_TLS))]
3819   ""
3820   "mrs\\t%0, tpidr_el0"
3821   [(set_attr "type" "mrs")]
3824 ;; The TLS ABI specifically requires that the compiler does not schedule
3825 ;; instructions in the TLS stubs, in order to enable linker relaxation.
3826 ;; Therefore we treat the stubs as an atomic sequence.
3827 (define_expand "tlsgd_small"
3828  [(parallel [(set (match_operand 0 "register_operand" "")
3829                   (call (mem:DI (match_dup 2)) (const_int 1)))
3830              (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
3831              (clobber (reg:DI LR_REGNUM))])]
3832  ""
3834   operands[2] = aarch64_tls_get_addr ();
3837 (define_insn "*tlsgd_small"
3838   [(set (match_operand 0 "register_operand" "")
3839         (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
3840    (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
3841    (clobber (reg:DI LR_REGNUM))
3842   ]
3843   ""
3844   "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
3845   [(set_attr "type" "call")
3846    (set_attr "length" "16")])
3848 (define_insn "tlsie_small_<mode>"
3849   [(set (match_operand:PTR 0 "register_operand" "=r")
3850         (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
3851                    UNSPEC_GOTSMALLTLS))]
3852   ""
3853   "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
3854   [(set_attr "type" "load1")
3855    (set_attr "length" "8")]
3858 (define_insn "tlsie_small_sidi"
3859   [(set (match_operand:DI 0 "register_operand" "=r")
3860         (zero_extend:DI
3861           (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")]
3862                       UNSPEC_GOTSMALLTLS)))]
3863   ""
3864   "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
3865   [(set_attr "type" "load1")
3866    (set_attr "length" "8")]
3869 (define_expand "tlsle_small"
3870   [(set (match_operand 0 "register_operand" "=r")
3871         (unspec [(match_operand 1 "register_operand" "r")
3872                    (match_operand 2 "aarch64_tls_le_symref" "S")]
3873                    UNSPEC_GOTSMALLTLS))]
3874   ""
3876   enum machine_mode mode = GET_MODE (operands[0]);
3877   emit_insn ((mode == DImode
3878               ? gen_tlsle_small_di
3879               : gen_tlsle_small_si) (operands[0],
3880                                      operands[1],
3881                                      operands[2]));
3882   DONE;
3885 (define_insn "tlsle_small_<mode>"
3886   [(set (match_operand:P 0 "register_operand" "=r")
3887         (unspec:P [(match_operand:P 1 "register_operand" "r")
3888                    (match_operand 2 "aarch64_tls_le_symref" "S")]
3889                    UNSPEC_GOTSMALLTLS))]
3890   ""
3891   "add\\t%<w>0, %<w>1, #%G2\;add\\t%<w>0, %<w>0, #%L2"
3892   [(set_attr "type" "alu_reg")
3893    (set_attr "length" "8")]
3896 (define_insn "tlsdesc_small_<mode>"
3897   [(set (reg:PTR R0_REGNUM)
3898         (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
3899                    UNSPEC_TLSDESC))
3900    (clobber (reg:DI LR_REGNUM))
3901    (clobber (reg:CC CC_REGNUM))
3902    (clobber (match_scratch:DI 1 "=r"))]
3903   "TARGET_TLS_DESC"
3904   "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
3905   [(set_attr "type" "call")
3906    (set_attr "length" "16")])
3908 (define_insn "stack_tie"
3909   [(set (mem:BLK (scratch))
3910         (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
3911                      (match_operand:DI 1 "register_operand" "rk")]
3912                     UNSPEC_PRLG_STK))]
3913   ""
3914   ""
3915   [(set_attr "length" "0")]
3918 ;; Named pattern for expanding thread pointer reference.
3919 (define_expand "get_thread_pointerdi"
3920   [(match_operand:DI 0 "register_operand" "=r")]
3921   ""
3923   rtx tmp = aarch64_load_tp (operands[0]);
3924   if (tmp != operands[0])
3925     emit_move_insn (operands[0], tmp);
3926   DONE;
3929 ;; Named patterns for stack smashing protection.
3930 (define_expand "stack_protect_set"
3931   [(match_operand 0 "memory_operand")
3932    (match_operand 1 "memory_operand")]
3933   ""
3935   enum machine_mode mode = GET_MODE (operands[0]);
3937   emit_insn ((mode == DImode
3938               ? gen_stack_protect_set_di
3939               : gen_stack_protect_set_si) (operands[0], operands[1]));
3940   DONE;
3943 (define_insn "stack_protect_set_<mode>"
3944   [(set (match_operand:PTR 0 "memory_operand" "=m")
3945         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
3946          UNSPEC_SP_SET))
3947    (set (match_scratch:PTR 2 "=&r") (const_int 0))]
3948   ""
3949   "ldr\\t%<w>2, %1\;str\\t%<w>2, %0\;mov\t%<w>2,0"
3950   [(set_attr "length" "12")
3951    (set_attr "type" "multiple")])
3953 (define_expand "stack_protect_test"
3954   [(match_operand 0 "memory_operand")
3955    (match_operand 1 "memory_operand")
3956    (match_operand 2)]
3957   ""
3959   rtx result;
3960   enum machine_mode mode = GET_MODE (operands[0]);
3962   result = gen_reg_rtx(mode);
3964   emit_insn ((mode == DImode
3965               ? gen_stack_protect_test_di
3966               : gen_stack_protect_test_si) (result,
3967                                             operands[0],
3968                                             operands[1]));
3970   if (mode == DImode)
3971     emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
3972                                     result, const0_rtx, operands[2]));
3973   else
3974     emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
3975                                     result, const0_rtx, operands[2]));
3976   DONE;
3979 (define_insn "stack_protect_test_<mode>"
3980   [(set (match_operand:PTR 0 "register_operand")
3981         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
3982                      (match_operand:PTR 2 "memory_operand" "m")]
3983          UNSPEC_SP_TEST))
3984    (clobber (match_scratch:PTR 3 "=&r"))]
3985   ""
3986   "ldr\t%<w>3, %x1\;ldr\t%<w>0, %x2\;eor\t%<w>0, %<w>3, %<w>0"
3987   [(set_attr "length" "12")
3988    (set_attr "type" "multiple")])
3990 ;; Write Floating-point Control Register.
3991 (define_insn "set_fpcr"
3992   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
3993   ""
3994   "msr\\tfpcr, %0"
3995   [(set_attr "type" "mrs")])
3997 ;; Read Floating-point Control Register.
3998 (define_insn "get_fpcr"
3999   [(set (match_operand:SI 0 "register_operand" "=r")
4000         (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
4001   ""
4002   "mrs\\t%0, fpcr"
4003   [(set_attr "type" "mrs")])
4005 ;; Write Floating-point Status Register.
4006 (define_insn "set_fpsr"
4007   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
4008   ""
4009   "msr\\tfpsr, %0"
4010   [(set_attr "type" "mrs")])
4012 ;; Read Floating-point Status Register.
4013 (define_insn "get_fpsr"
4014   [(set (match_operand:SI 0 "register_operand" "=r")
4015         (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
4016   ""
4017   "mrs\\t%0, fpsr"
4018   [(set_attr "type" "mrs")])
4021 ;; AdvSIMD Stuff
4022 (include "aarch64-simd.md")
4024 ;; Atomic Operations
4025 (include "atomics.md")