Merge branches/gcc-4_9-branch rev 225109.
[official-gcc.git] / gcc-4_9-branch / gcc / config / aarch64 / aarch64.md
blobbf06a400c7e507d0707074a6f5c37f9e3fbbc811
1 ;; Machine description for AArch64 architecture.
2 ;; Copyright (C) 2009-2014 Free Software Foundation, Inc.
3 ;; Contributed by ARM Ltd.
4 ;;
5 ;; This file is part of GCC.
6 ;;
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
12 ;; GCC is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 ;; General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;; Register numbers
22 (define_constants
23   [
24     (R0_REGNUM          0)
25     (R1_REGNUM          1)
26     (R2_REGNUM          2)
27     (R3_REGNUM          3)
28     (R4_REGNUM          4)
29     (R5_REGNUM          5)
30     (R6_REGNUM          6)
31     (R7_REGNUM          7)
32     (R8_REGNUM          8)
33     (R9_REGNUM          9)
34     (R10_REGNUM         10)
35     (R11_REGNUM         11)
36     (R12_REGNUM         12)
37     (R13_REGNUM         13)
38     (R14_REGNUM         14)
39     (R15_REGNUM         15)
40     (R16_REGNUM         16)
41     (IP0_REGNUM         16)
42     (R17_REGNUM         17)
43     (IP1_REGNUM         17)
44     (R18_REGNUM         18)
45     (R19_REGNUM         19)
46     (R20_REGNUM         20)
47     (R21_REGNUM         21)
48     (R22_REGNUM         22)
49     (R23_REGNUM         23)
50     (R24_REGNUM         24)
51     (R25_REGNUM         25)
52     (R26_REGNUM         26)
53     (R27_REGNUM         27)
54     (R28_REGNUM         28)
55     (R29_REGNUM         29)
56     (R30_REGNUM         30)
57     (LR_REGNUM          30)
58     (SP_REGNUM          31)
59     (V0_REGNUM          32)
60     (V15_REGNUM         47)
61     (V31_REGNUM         63)
62     (SFP_REGNUM         64)
63     (AP_REGNUM          65)
64     (CC_REGNUM          66)
65   ]
68 (define_c_enum "unspec" [
69     UNSPEC_CASESI
70     UNSPEC_CRC32B
71     UNSPEC_CRC32CB
72     UNSPEC_CRC32CH
73     UNSPEC_CRC32CW
74     UNSPEC_CRC32CX
75     UNSPEC_CRC32H
76     UNSPEC_CRC32W
77     UNSPEC_CRC32X
78     UNSPEC_FRECPE
79     UNSPEC_FRECPS
80     UNSPEC_FRECPX
81     UNSPEC_FRINTA
82     UNSPEC_FRINTI
83     UNSPEC_FRINTM
84     UNSPEC_FRINTN
85     UNSPEC_FRINTP
86     UNSPEC_FRINTX
87     UNSPEC_FRINTZ
88     UNSPEC_GOTSMALLPIC
89     UNSPEC_GOTSMALLTLS
90     UNSPEC_GOTTINYPIC
91     UNSPEC_LD1
92     UNSPEC_LD2
93     UNSPEC_LD2_DUP
94     UNSPEC_LD3
95     UNSPEC_LD3_DUP
96     UNSPEC_LD4
97     UNSPEC_LD4_DUP
98     UNSPEC_LD2_LANE
99     UNSPEC_LD3_LANE
100     UNSPEC_LD4_LANE
101     UNSPEC_MB
102     UNSPEC_NOP
103     UNSPEC_PRLG_STK
104     UNSPEC_RBIT
105     UNSPEC_SISD_NEG
106     UNSPEC_SISD_SSHL
107     UNSPEC_SISD_USHL
108     UNSPEC_SSHL_2S
109     UNSPEC_ST1
110     UNSPEC_ST2
111     UNSPEC_ST3
112     UNSPEC_ST4
113     UNSPEC_ST2_LANE
114     UNSPEC_ST3_LANE
115     UNSPEC_ST4_LANE
116     UNSPEC_TLS
117     UNSPEC_TLSDESC
118     UNSPEC_USHL_2S
119     UNSPEC_VSTRUCTDUMMY
120     UNSPEC_SP_SET
121     UNSPEC_SP_TEST
124 (define_c_enum "unspecv" [
125     UNSPECV_EH_RETURN           ; Represent EH_RETURN
126     UNSPECV_GET_FPCR            ; Represent fetch of FPCR content.
127     UNSPECV_SET_FPCR            ; Represent assign of FPCR content.
128     UNSPECV_GET_FPSR            ; Represent fetch of FPSR content.
129     UNSPECV_SET_FPSR            ; Represent assign of FPSR content.
130   ]
133 ;; If further include files are added the defintion of MD_INCLUDES
134 ;; must be updated.
136 (include "constraints.md")
137 (include "predicates.md")
138 (include "iterators.md")
140 ;; -------------------------------------------------------------------
141 ;; Instruction types and attributes
142 ;; -------------------------------------------------------------------
144 ; The "type" attribute is is included here from AArch32 backend to be able
145 ; to share pipeline descriptions.
146 (include "../arm/types.md")
148 ;; Attribute that specifies whether or not the instruction touches fp
149 ;; registers.
150 (define_attr "fp" "no,yes" (const_string "no"))
152 ;; Attribute that specifies whether or not the instruction touches simd
153 ;; registers.
154 (define_attr "simd" "no,yes" (const_string "no"))
156 (define_attr "length" ""
157   (const_int 4))
159 ;; Attribute that controls whether an alternative is enabled or not.
160 ;; Currently it is only used to disable alternatives which touch fp or simd
161 ;; registers when -mgeneral-regs-only is specified.
162 (define_attr "enabled" "no,yes"
163   (cond [(ior
164         (and (eq_attr "fp" "yes")
165              (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
166         (and (eq_attr "simd" "yes")
167              (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
168              (const_string "no")
169         ] (const_string "yes")))
171 ;; -------------------------------------------------------------------
172 ;; Pipeline descriptions and scheduling
173 ;; -------------------------------------------------------------------
175 ;; Processor types.
176 (include "aarch64-tune.md")
178 ;; Scheduling
179 (include "../arm/cortex-a53.md")
180 (include "../arm/cortex-a57.md")
181 (include "thunderx.md")
182 (include "../arm/xgene1.md")
184 ;; -------------------------------------------------------------------
185 ;; Jumps and other miscellaneous insns
186 ;; -------------------------------------------------------------------
188 (define_insn "indirect_jump"
189   [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
190   ""
191   "br\\t%0"
192   [(set_attr "type" "branch")]
195 (define_insn "jump"
196   [(set (pc) (label_ref (match_operand 0 "" "")))]
197   ""
198   "b\\t%l0"
199   [(set_attr "type" "branch")]
202 (define_expand "cbranch<mode>4"
203   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
204                             [(match_operand:GPI 1 "register_operand" "")
205                              (match_operand:GPI 2 "aarch64_plus_operand" "")])
206                            (label_ref (match_operand 3 "" ""))
207                            (pc)))]
208   ""
209   "
210   operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
211                                          operands[2]);
212   operands[2] = const0_rtx;
213   "
216 (define_expand "cbranch<mode>4"
217   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
218                             [(match_operand:GPF 1 "register_operand" "")
219                              (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
220                            (label_ref (match_operand 3 "" ""))
221                            (pc)))]
222   ""
223   "
224   operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
225                                          operands[2]);
226   operands[2] = const0_rtx;
227   "
230 (define_insn "*condjump"
231   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
232                             [(match_operand 1 "cc_register" "") (const_int 0)])
233                            (label_ref (match_operand 2 "" ""))
234                            (pc)))]
235   ""
236   "b%m0\\t%l2"
237   [(set_attr "type" "branch")]
240 (define_expand "casesi"
241   [(match_operand:SI 0 "register_operand" "")   ; Index
242    (match_operand:SI 1 "const_int_operand" "")  ; Lower bound
243    (match_operand:SI 2 "const_int_operand" "")  ; Total range
244    (match_operand:DI 3 "" "")                   ; Table label
245    (match_operand:DI 4 "" "")]                  ; Out of range label
246   ""
247   {
248     if (operands[1] != const0_rtx)
249       {
250         rtx reg = gen_reg_rtx (SImode);
252         /* Canonical RTL says that if you have:
254            (minus (X) (CONST))
256            then this should be emitted as:
258            (plus (X) (-CONST))
260            The use of trunc_int_for_mode ensures that the resulting
261            constant can be represented in SImode, this is important
262            for the corner case where operand[1] is INT_MIN.  */
264         operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
266         if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
267               (operands[1], SImode))
268           operands[1] = force_reg (SImode, operands[1]);
269         emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
270         operands[0] = reg;
271       }
273     if (!aarch64_plus_operand (operands[2], SImode))
274       operands[2] = force_reg (SImode, operands[2]);
275     emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
276                                                  const0_rtx),
277                                     operands[0], operands[2], operands[4]));
279     operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
280     emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
281                                          operands[3]));
282     DONE;
283   }
286 (define_insn "casesi_dispatch"
287   [(parallel
288     [(set (pc)
289           (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
290                            (match_operand:SI 1 "register_operand" "r")]
291                         UNSPEC_CASESI)))
292      (clobber (reg:CC CC_REGNUM))
293      (clobber (match_scratch:DI 3 "=r"))
294      (clobber (match_scratch:DI 4 "=r"))
295      (use (label_ref (match_operand 2 "" "")))])]
296   ""
297   "*
298   return aarch64_output_casesi (operands);
299   "
300   [(set_attr "length" "16")
301    (set_attr "type" "branch")]
304 (define_insn "nop"
305   [(unspec[(const_int 0)] UNSPEC_NOP)]
306   ""
307   "nop"
308   [(set_attr "type" "no_insn")]
311 (define_insn "trap"
312   [(trap_if (const_int 1) (const_int 8))]
313   ""
314   "brk #1000"
315   [(set_attr "type" "trap")])
317 (define_expand "prologue"
318   [(clobber (const_int 0))]
319   ""
320   "
321   aarch64_expand_prologue ();
322   DONE;
323   "
326 (define_expand "epilogue"
327   [(clobber (const_int 0))]
328   ""
329   "
330   aarch64_expand_epilogue (false);
331   DONE;
332   "
335 (define_expand "sibcall_epilogue"
336   [(clobber (const_int 0))]
337   ""
338   "
339   aarch64_expand_epilogue (true);
340   DONE;
341   "
344 (define_insn "*do_return"
345   [(return)]
346   ""
347   "ret"
348   [(set_attr "type" "branch")]
351 (define_insn "eh_return"
352   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
353     UNSPECV_EH_RETURN)]
354   ""
355   "#"
356   [(set_attr "type" "branch")]
360 (define_split
361   [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
362     UNSPECV_EH_RETURN)]
363   "reload_completed"
364   [(set (match_dup 1) (match_dup 0))]
365   {
366     operands[1] = aarch64_final_eh_return_addr ();
367   }
370 (define_insn "*cb<optab><mode>1"
371   [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
372                                 (const_int 0))
373                            (label_ref (match_operand 1 "" ""))
374                            (pc)))]
375   ""
376   "<cbz>\\t%<w>0, %l1"
377   [(set_attr "type" "branch")]
381 (define_insn "*tb<optab><mode>1"
382   [(set (pc) (if_then_else
383               (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
384                                     (const_int 1)
385                                     (match_operand 1 "const_int_operand" "n"))
386                    (const_int 0))
387              (label_ref (match_operand 2 "" ""))
388              (pc)))
389    (clobber (match_scratch:DI 3 "=r"))]
390   ""
391   "*
392   if (get_attr_length (insn) == 8)
393     return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
394   return \"<tbz>\\t%<w>0, %1, %l2\";
395   "
396   [(set_attr "type" "branch")
397    (set (attr "length")
398         (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
399                            (lt (minus (match_dup 2) (pc)) (const_int 32764)))
400                       (const_int 4)
401                       (const_int 8)))]
404 (define_insn "*cb<optab><mode>1"
405   [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
406                                  (const_int 0))
407                            (label_ref (match_operand 1 "" ""))
408                            (pc)))
409    (clobber (match_scratch:DI 2 "=r"))]
410   ""
411   "*
412   if (get_attr_length (insn) == 8)
413     return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
414   return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
415   "
416   [(set_attr "type" "branch")
417    (set (attr "length")
418         (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
419                            (lt (minus (match_dup 1) (pc)) (const_int 32764)))
420                       (const_int 4)
421                       (const_int 8)))]
424 ;; -------------------------------------------------------------------
425 ;; Subroutine calls and sibcalls
426 ;; -------------------------------------------------------------------
428 (define_expand "call"
429   [(parallel [(call (match_operand 0 "memory_operand" "")
430                     (match_operand 1 "general_operand" ""))
431               (use (match_operand 2 "" ""))
432               (clobber (reg:DI LR_REGNUM))])]
433   ""
434   "
435   {
436     rtx callee;
438     /* In an untyped call, we can get NULL for operand 2.  */
439     if (operands[2] == NULL)
440       operands[2] = const0_rtx;
442     /* Decide if we should generate indirect calls by loading the
443        64-bit address of the callee into a register before performing
444        the branch-and-link.  */
445     callee = XEXP (operands[0], 0);
446     if (GET_CODE (callee) == SYMBOL_REF
447         ? aarch64_is_long_call_p (callee)
448         : !REG_P (callee))
449       XEXP (operands[0], 0) = force_reg (Pmode, callee);
450   }"
453 (define_insn "*call_reg"
454   [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
455          (match_operand 1 "" ""))
456    (use (match_operand 2 "" ""))
457    (clobber (reg:DI LR_REGNUM))]
458   ""
459   "blr\\t%0"
460   [(set_attr "type" "call")]
463 (define_insn "*call_symbol"
464   [(call (mem:DI (match_operand:DI 0 "" ""))
465          (match_operand 1 "" ""))
466    (use (match_operand 2 "" ""))
467    (clobber (reg:DI LR_REGNUM))]
468   "GET_CODE (operands[0]) == SYMBOL_REF
469    && !aarch64_is_long_call_p (operands[0])"
470   "bl\\t%a0"
471   [(set_attr "type" "call")]
474 (define_expand "call_value"
475   [(parallel [(set (match_operand 0 "" "")
476                    (call (match_operand 1 "memory_operand" "")
477                          (match_operand 2 "general_operand" "")))
478               (use (match_operand 3 "" ""))
479               (clobber (reg:DI LR_REGNUM))])]
480   ""
481   "
482   {
483     rtx callee;
485     /* In an untyped call, we can get NULL for operand 3.  */
486     if (operands[3] == NULL)
487       operands[3] = const0_rtx;
489     /* Decide if we should generate indirect calls by loading the
490        64-bit address of the callee into a register before performing
491        the branch-and-link.  */
492     callee = XEXP (operands[1], 0);
493     if (GET_CODE (callee) == SYMBOL_REF
494         ? aarch64_is_long_call_p (callee)
495         : !REG_P (callee))
496       XEXP (operands[1], 0) = force_reg (Pmode, callee);
497   }"
500 (define_insn "*call_value_reg"
501   [(set (match_operand 0 "" "")
502         (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
503                       (match_operand 2 "" "")))
504    (use (match_operand 3 "" ""))
505    (clobber (reg:DI LR_REGNUM))]
506   ""
507   "blr\\t%1"
508   [(set_attr "type" "call")]
512 (define_insn "*call_value_symbol"
513   [(set (match_operand 0 "" "")
514         (call (mem:DI (match_operand:DI 1 "" ""))
515               (match_operand 2 "" "")))
516    (use (match_operand 3 "" ""))
517    (clobber (reg:DI LR_REGNUM))]
518   "GET_CODE (operands[1]) == SYMBOL_REF
519    && !aarch64_is_long_call_p (operands[1])"
520   "bl\\t%a1"
521   [(set_attr "type" "call")]
524 (define_expand "sibcall"
525   [(parallel [(call (match_operand 0 "memory_operand" "")
526                     (match_operand 1 "general_operand" ""))
527               (return)
528               (use (match_operand 2 "" ""))])]
529   ""
530   {
531     if (!REG_P (XEXP (operands[0], 0))
532        && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
533      XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
535     if (operands[2] == NULL_RTX)
536       operands[2] = const0_rtx;
537   }
540 (define_expand "sibcall_value"
541   [(parallel [(set (match_operand 0 "" "")
542                    (call (match_operand 1 "memory_operand" "")
543                          (match_operand 2 "general_operand" "")))
544               (return)
545               (use (match_operand 3 "" ""))])]
546   ""
547   {
548     if (!REG_P (XEXP (operands[1], 0))
549        && (GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF))
550      XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
552     if (operands[3] == NULL_RTX)
553       operands[3] = const0_rtx;
554   }
557 (define_insn "*sibcall_insn"
558   [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucs, Usf"))
559          (match_operand 1 "" ""))
560    (return)
561    (use (match_operand 2 "" ""))]
562   "SIBLING_CALL_P (insn)"
563   "@
564    br\\t%0
565    b\\t%a0"
566   [(set_attr "type" "branch, branch")]
569 (define_insn "*sibcall_value_insn"
570   [(set (match_operand 0 "" "")
571         (call (mem:DI
572                 (match_operand:DI 1 "aarch64_call_insn_operand" "Ucs, Usf"))
573               (match_operand 2 "" "")))
574    (return)
575    (use (match_operand 3 "" ""))]
576   "SIBLING_CALL_P (insn)"
577   "@
578    br\\t%1
579    b\\t%a1"
580   [(set_attr "type" "branch, branch")]
583 ;; Call subroutine returning any type.
585 (define_expand "untyped_call"
586   [(parallel [(call (match_operand 0 "")
587                     (const_int 0))
588               (match_operand 1 "")
589               (match_operand 2 "")])]
590   ""
592   int i;
594   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
596   for (i = 0; i < XVECLEN (operands[2], 0); i++)
597     {
598       rtx set = XVECEXP (operands[2], 0, i);
599       emit_move_insn (SET_DEST (set), SET_SRC (set));
600     }
602   /* The optimizer does not know that the call sets the function value
603      registers we stored in the result block.  We avoid problems by
604      claiming that all hard registers are used and clobbered at this
605      point.  */
606   emit_insn (gen_blockage ());
607   DONE;
610 ;; -------------------------------------------------------------------
611 ;; Moves
612 ;; -------------------------------------------------------------------
614 (define_expand "mov<mode>"
615   [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
616         (match_operand:SHORT 1 "general_operand" ""))]
617   ""
618   "
619     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
620       operands[1] = force_reg (<MODE>mode, operands[1]);
621   "
624 (define_insn "*mov<mode>_aarch64"
625   [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r,   *w,r,*w, m, m, r,*w,*w")
626         (match_operand:SHORT 1 "general_operand"      " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
627   "(register_operand (operands[0], <MODE>mode)
628     || aarch64_reg_or_zero (operands[1], <MODE>mode))"
630    switch (which_alternative)
631      {
632      case 0:
633        return "mov\t%w0, %w1";
634      case 1:
635        return "mov\t%w0, %1";
636      case 2:
637        return aarch64_output_scalar_simd_mov_immediate (operands[1],
638                                                         <MODE>mode);
639      case 3:
640        return "ldr<size>\t%w0, %1";
641      case 4:
642        return "ldr\t%<size>0, %1";
643      case 5:
644        return "str<size>\t%w1, %0";
645      case 6:
646        return "str\t%<size>1, %0";
647      case 7:
648        return "umov\t%w0, %1.<v>[0]";
649      case 8:
650        return "dup\t%0.<Vallxd>, %w1";
651      case 9:
652        return "dup\t%<Vetype>0, %1.<v>[0]";
653      default:
654        gcc_unreachable ();
655      }
657   [(set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
658                      neon_from_gp<q>,neon_from_gp<q>, neon_dup")
659    (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")]
662 (define_expand "mov<mode>"
663   [(set (match_operand:GPI 0 "nonimmediate_operand" "")
664         (match_operand:GPI 1 "general_operand" ""))]
665   ""
666   "
667     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
668       operands[1] = force_reg (<MODE>mode, operands[1]);
670     /* FIXME: RR we still need to fix up what we are doing with
671        symbol_refs and other types of constants.  */
672     if (CONSTANT_P (operands[1])
673         && !CONST_INT_P (operands[1]))
674      {
675        aarch64_expand_mov_immediate (operands[0], operands[1]);
676        DONE;
677      }
678   "
681 (define_insn_and_split "*movsi_aarch64"
682   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,r,*w,m,  m,r,r  ,*w, r,*w")
683         (match_operand:SI 1 "aarch64_mov_operand"  " r,r,k,M,n,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
684   "(register_operand (operands[0], SImode)
685     || aarch64_reg_or_zero (operands[1], SImode))"
686   "@
687    mov\\t%w0, %w1
688    mov\\t%w0, %w1
689    mov\\t%w0, %w1
690    mov\\t%w0, %1
691    #
692    ldr\\t%w0, %1
693    ldr\\t%s0, %1
694    str\\t%w1, %0
695    str\\t%s1, %0
696    adr\\t%x0, %a1
697    adrp\\t%x0, %A1
698    fmov\\t%s0, %w1
699    fmov\\t%w0, %s1
700    fmov\\t%s0, %s1"
701    "CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), SImode)
702     && GP_REGNUM_P (REGNO (operands[0]))"
703    [(const_int 0)]
704    "{
705        aarch64_expand_mov_immediate (operands[0], operands[1]);
706        DONE;
707     }"
708   [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,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_and_split "*movdi_aarch64"
714   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,r,*w,m,  m,r,r,  *w, r,*w,w")
715         (match_operand:DI 1 "aarch64_mov_operand"  " r,r,k,N,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    #
724    ldr\\t%x0, %1
725    ldr\\t%d0, %1
726    str\\t%x1, %0
727    str\\t%d1, %0
728    adr\\t%x0, %a1
729    adrp\\t%x0, %A1
730    fmov\\t%d0, %x1
731    fmov\\t%x0, %d1
732    fmov\\t%d0, %d1
733    movi\\t%d0, %1"
734    "(CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), DImode))
735     && GP_REGNUM_P (REGNO (operands[0]))"
736    [(const_int 0)]
737    "{
738        aarch64_expand_mov_immediate (operands[0], operands[1]);
739        DONE;
740     }"
741   [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
742                      adr,adr,f_mcr,f_mrc,fmov,fmov")
743    (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
744    (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
747 (define_insn "insv_imm<mode>"
748   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
749                           (const_int 16)
750                           (match_operand:GPI 1 "const_int_operand" "n"))
751         (match_operand:GPI 2 "const_int_operand" "n"))]
752   "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
753    && UINTVAL (operands[1]) % 16 == 0"
754   "movk\\t%<w>0, %X2, lsl %1"
755   [(set_attr "type" "mov_imm")]
758 (define_expand "movti"
759   [(set (match_operand:TI 0 "nonimmediate_operand" "")
760         (match_operand:TI 1 "general_operand" ""))]
761   ""
762   "
763     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
764       operands[1] = force_reg (TImode, operands[1]);
765   "
768 (define_insn "*movti_aarch64"
769   [(set (match_operand:TI 0
770          "nonimmediate_operand"  "=r, *w,r ,*w,r  ,Ump,Ump,*w,m")
771         (match_operand:TI 1
772          "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r  ,Z  , m,*w"))]
773   "(register_operand (operands[0], TImode)
774     || aarch64_reg_or_zero (operands[1], TImode))"
775   "@
776    #
777    #
778    #
779    orr\\t%0.16b, %1.16b, %1.16b
780    ldp\\t%0, %H0, %1
781    stp\\t%1, %H1, %0
782    stp\\txzr, xzr, %0
783    ldr\\t%q0, %1
784    str\\t%q1, %0"
785   [(set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \
786                              load2,store2,store2,f_loadd,f_stored")
787    (set_attr "length" "8,8,8,4,4,4,4,4,4")
788    (set_attr "simd" "*,*,*,yes,*,*,*,*,*")
789    (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
792 ;; Split a TImode register-register or register-immediate move into
793 ;; its component DImode pieces, taking care to handle overlapping
794 ;; source and dest registers.
795 (define_split
796    [(set (match_operand:TI 0 "register_operand" "")
797          (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
798   "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
799   [(const_int 0)]
801   aarch64_split_128bit_move (operands[0], operands[1]);
802   DONE;
805 (define_expand "mov<mode>"
806   [(set (match_operand:GPF 0 "nonimmediate_operand" "")
807         (match_operand:GPF 1 "general_operand" ""))]
808   ""
809   "
810     if (!TARGET_FLOAT)
811      {
812         sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
813         FAIL;
814      }
816     if (GET_CODE (operands[0]) == MEM)
817       operands[1] = force_reg (<MODE>mode, operands[1]);
818   "
821 (define_insn "*movsf_aarch64"
822   [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w  ,w,m,r,m ,r")
823         (match_operand:SF 1 "general_operand"      "?rY, w,w,Ufc,m,w,m,rY,r"))]
824   "TARGET_FLOAT && (register_operand (operands[0], SFmode)
825     || register_operand (operands[1], SFmode))"
826   "@
827    fmov\\t%s0, %w1
828    fmov\\t%w0, %s1
829    fmov\\t%s0, %s1
830    fmov\\t%s0, %1
831    ldr\\t%s0, %1
832    str\\t%s1, %0
833    ldr\\t%w0, %1
834    str\\t%w1, %0
835    mov\\t%w0, %w1"
836   [(set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
837                      f_loads,f_stores,f_loads,f_stores,mov_reg")]
840 (define_insn "*movdf_aarch64"
841   [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w  ,w,m,r,m ,r")
842         (match_operand:DF 1 "general_operand"      "?rY, w,w,Ufc,m,w,m,rY,r"))]
843   "TARGET_FLOAT && (register_operand (operands[0], DFmode)
844     || register_operand (operands[1], DFmode))"
845   "@
846    fmov\\t%d0, %x1
847    fmov\\t%x0, %d1
848    fmov\\t%d0, %d1
849    fmov\\t%d0, %1
850    ldr\\t%d0, %1
851    str\\t%d1, %0
852    ldr\\t%x0, %1
853    str\\t%x1, %0
854    mov\\t%x0, %x1"
855   [(set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
856                      f_loadd,f_stored,f_loadd,f_stored,mov_reg")]
859 (define_expand "movtf"
860   [(set (match_operand:TF 0 "nonimmediate_operand" "")
861         (match_operand:TF 1 "general_operand" ""))]
862   ""
863   "
864     if (!TARGET_FLOAT)
865      {
866         sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
867         FAIL;
868      }
870     if (GET_CODE (operands[0]) == MEM)
871       operands[1] = force_reg (TFmode, operands[1]);
872   "
875 (define_insn "*movtf_aarch64"
876   [(set (match_operand:TF 0
877          "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
878         (match_operand:TF 1
879          "general_operand"      " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
880   "TARGET_FLOAT && (register_operand (operands[0], TFmode)
881     || register_operand (operands[1], TFmode))"
882   "@
883    orr\\t%0.16b, %1.16b, %1.16b
884    #
885    #
886    #
887    movi\\t%0.2d, #0
888    fmov\\t%s0, wzr
889    ldr\\t%q0, %1
890    str\\t%q1, %0
891    ldp\\t%0, %H0, %1
892    stp\\t%1, %H1, %0"
893   [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,fconstd,fconstd,\
894                      f_loadd,f_stored,neon_load1_2reg,neon_store1_2reg")
895    (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
896    (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
897    (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
900 (define_split
901    [(set (match_operand:TF 0 "register_operand" "")
902          (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
903   "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
904   [(const_int 0)]
905   {
906     aarch64_split_128bit_move (operands[0], operands[1]);
907     DONE;
908   }
911 ;; 0 is dst
912 ;; 1 is src
913 ;; 2 is size of move in bytes
914 ;; 3 is alignment
916 (define_expand "movmemdi"
917   [(match_operand:BLK 0 "memory_operand")
918    (match_operand:BLK 1 "memory_operand")
919    (match_operand:DI 2 "immediate_operand")
920    (match_operand:DI 3 "immediate_operand")]
921    "!STRICT_ALIGNMENT"
923   if (aarch64_expand_movmem (operands))
924     DONE;
925   FAIL;
929 ;; Operands 1 and 3 are tied together by the final condition; so we allow
930 ;; fairly lax checking on the second memory operation.
931 (define_insn "load_pair<mode>"
932   [(set (match_operand:GPI 0 "register_operand" "=r")
933         (match_operand:GPI 1 "aarch64_mem_pair_operand" "Ump"))
934    (set (match_operand:GPI 2 "register_operand" "=r")
935         (match_operand:GPI 3 "memory_operand" "m"))]
936   "rtx_equal_p (XEXP (operands[3], 0),
937                 plus_constant (Pmode,
938                                XEXP (operands[1], 0),
939                                GET_MODE_SIZE (<MODE>mode)))"
940   "ldp\\t%<w>0, %<w>2, %1"
941   [(set_attr "type" "load2")]
944 ;; Operands 0 and 2 are tied together by the final condition; so we allow
945 ;; fairly lax checking on the second memory operation.
946 (define_insn "store_pair<mode>"
947   [(set (match_operand:GPI 0 "aarch64_mem_pair_operand" "=Ump")
948         (match_operand:GPI 1 "register_operand" "r"))
949    (set (match_operand:GPI 2 "memory_operand" "=m")
950         (match_operand:GPI 3 "register_operand" "r"))]
951   "rtx_equal_p (XEXP (operands[2], 0),
952                 plus_constant (Pmode,
953                                XEXP (operands[0], 0),
954                                GET_MODE_SIZE (<MODE>mode)))"
955   "stp\\t%<w>1, %<w>3, %0"
956   [(set_attr "type" "store2")]
959 ;; Operands 1 and 3 are tied together by the final condition; so we allow
960 ;; fairly lax checking on the second memory operation.
961 (define_insn "load_pair<mode>"
962   [(set (match_operand:GPF 0 "register_operand" "=w")
963         (match_operand:GPF 1 "aarch64_mem_pair_operand" "Ump"))
964    (set (match_operand:GPF 2 "register_operand" "=w")
965         (match_operand:GPF 3 "memory_operand" "m"))]
966   "rtx_equal_p (XEXP (operands[3], 0),
967                 plus_constant (Pmode,
968                                XEXP (operands[1], 0),
969                                GET_MODE_SIZE (<MODE>mode)))"
970   "ldp\\t%<w>0, %<w>2, %1"
971   [(set_attr "type" "neon_load1_2reg<q>")]
974 ;; Operands 0 and 2 are tied together by the final condition; so we allow
975 ;; fairly lax checking on the second memory operation.
976 (define_insn "store_pair<mode>"
977   [(set (match_operand:GPF 0 "aarch64_mem_pair_operand" "=Ump")
978         (match_operand:GPF 1 "register_operand" "w"))
979    (set (match_operand:GPF 2 "memory_operand" "=m")
980         (match_operand:GPF 3 "register_operand" "w"))]
981   "rtx_equal_p (XEXP (operands[2], 0),
982                 plus_constant (Pmode,
983                                XEXP (operands[0], 0),
984                                GET_MODE_SIZE (<MODE>mode)))"
985   "stp\\t%<w>1, %<w>3, %0"
986   [(set_attr "type" "neon_store1_2reg<q>")]
989 ;; Load pair with post-index writeback.  This is primarily used in function
990 ;; epilogues.
991 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
992   [(parallel
993     [(set (match_operand:P 0 "register_operand" "=k")
994           (plus:P (match_operand:P 1 "register_operand" "0")
995                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
996      (set (match_operand:GPI 2 "register_operand" "=r")
997           (mem:GPI (match_dup 1)))
998      (set (match_operand:GPI 3 "register_operand" "=r")
999           (mem:GPI (plus:P (match_dup 1)
1000                    (match_operand:P 5 "const_int_operand" "n"))))])]
1001   "INTVAL (operands[5]) == GET_MODE_SIZE (<GPI:MODE>mode)"
1002   "ldp\\t%<w>2, %<w>3, [%1], %4"
1003   [(set_attr "type" "load2")]
1006 (define_insn "loadwb_pair<GPF:mode>_<P:mode>"
1007   [(parallel
1008     [(set (match_operand:P 0 "register_operand" "=k")
1009           (plus:P (match_operand:P 1 "register_operand" "0")
1010                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1011      (set (match_operand:GPF 2 "register_operand" "=w")
1012           (mem:GPF (match_dup 1)))
1013      (set (match_operand:GPF 3 "register_operand" "=w")
1014           (mem:GPF (plus:P (match_dup 1)
1015                    (match_operand:P 5 "const_int_operand" "n"))))])]
1016   "INTVAL (operands[5]) == GET_MODE_SIZE (<GPF:MODE>mode)"
1017   "ldp\\t%<w>2, %<w>3, [%1], %4"
1018   [(set_attr "type" "neon_load1_2reg")]
1021 ;; Store pair with pre-index writeback.  This is primarily used in function
1022 ;; prologues.
1023 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
1024   [(parallel
1025     [(set (match_operand:P 0 "register_operand" "=&k")
1026           (plus:P (match_operand:P 1 "register_operand" "0")
1027                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1028      (set (mem:GPI (plus:P (match_dup 0)
1029                    (match_dup 4)))
1030           (match_operand:GPI 2 "register_operand" "r"))
1031      (set (mem:GPI (plus:P (match_dup 0)
1032                    (match_operand:P 5 "const_int_operand" "n")))
1033           (match_operand:GPI 3 "register_operand" "r"))])]
1034   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1035   "stp\\t%<w>2, %<w>3, [%0, %4]!"
1036   [(set_attr "type" "store2")]
1039 (define_insn "storewb_pair<GPF:mode>_<P:mode>"
1040   [(parallel
1041     [(set (match_operand:P 0 "register_operand" "=&k")
1042           (plus:P (match_operand:P 1 "register_operand" "0")
1043                   (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1044      (set (mem:GPF (plus:P (match_dup 0)
1045                    (match_dup 4)))
1046           (match_operand:GPF 2 "register_operand" "w"))
1047      (set (mem:GPF (plus:P (match_dup 0)
1048                    (match_operand:P 5 "const_int_operand" "n")))
1049           (match_operand:GPF 3 "register_operand" "w"))])]
1050   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPF:MODE>mode)"
1051   "stp\\t%<w>2, %<w>3, [%0, %4]!"
1052   [(set_attr "type" "neon_store1_2reg<q>")]
1055 ;; -------------------------------------------------------------------
1056 ;; Sign/Zero extension
1057 ;; -------------------------------------------------------------------
1059 (define_expand "<optab>sidi2"
1060   [(set (match_operand:DI 0 "register_operand")
1061         (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1062   ""
1065 (define_insn "*extendsidi2_aarch64"
1066   [(set (match_operand:DI 0 "register_operand" "=r,r")
1067         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1068   ""
1069   "@
1070    sxtw\t%0, %w1
1071    ldrsw\t%0, %1"
1072   [(set_attr "type" "extend,load1")]
1075 (define_insn "*zero_extendsidi2_aarch64"
1076   [(set (match_operand:DI 0 "register_operand" "=r,r")
1077         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1078   ""
1079   "@
1080    uxtw\t%0, %w1
1081    ldr\t%w0, %1"
1082   [(set_attr "type" "extend,load1")]
1085 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1086   [(set (match_operand:GPI 0 "register_operand")
1087         (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1088   ""
1091 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1092   [(set (match_operand:GPI 0 "register_operand" "=r,r")
1093         (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1094   ""
1095   "@
1096    sxt<SHORT:size>\t%<GPI:w>0, %w1
1097    ldrs<SHORT:size>\t%<GPI:w>0, %1"
1098   [(set_attr "type" "extend,load1")]
1101 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1102   [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1103         (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1104   ""
1105   "@
1106    uxt<SHORT:size>\t%<GPI:w>0, %w1
1107    ldr<SHORT:size>\t%w0, %1
1108    ldr\t%<SHORT:size>0, %1"
1109   [(set_attr "type" "extend,load1,load1")]
1112 (define_expand "<optab>qihi2"
1113   [(set (match_operand:HI 0 "register_operand")
1114         (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1115   ""
1118 (define_insn "*<optab>qihi2_aarch64"
1119   [(set (match_operand:HI 0 "register_operand" "=r,r")
1120         (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1121   ""
1122   "@
1123    <su>xtb\t%w0, %w1
1124    <ldrxt>b\t%w0, %1"
1125   [(set_attr "type" "extend,load1")]
1128 ;; -------------------------------------------------------------------
1129 ;; Simple arithmetic
1130 ;; -------------------------------------------------------------------
1132 (define_expand "add<mode>3"
1133   [(set
1134     (match_operand:GPI 0 "register_operand" "")
1135     (plus:GPI (match_operand:GPI 1 "register_operand" "")
1136               (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1137   ""
1138   "
1139   if (! aarch64_plus_operand (operands[2], VOIDmode))
1140     {
1141       rtx subtarget = ((optimize && can_create_pseudo_p ())
1142                        ? gen_reg_rtx (<MODE>mode) : operands[0]);
1143       HOST_WIDE_INT imm = INTVAL (operands[2]);
1145       if (imm < 0)
1146         imm = -(-imm & ~0xfff);
1147       else
1148         imm &= ~0xfff;
1150       emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1151       operands[1] = subtarget;
1152       operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1153     }
1154   "
1157 (define_insn "*addsi3_aarch64"
1158   [(set
1159     (match_operand:SI 0 "register_operand" "=rk,rk,w,rk")
1160     (plus:SI
1161      (match_operand:SI 1 "register_operand" "%rk,rk,w,rk")
1162      (match_operand:SI 2 "aarch64_plus_operand" "I,r,w,J")))]
1163   ""
1164   "@
1165   add\\t%w0, %w1, %2
1166   add\\t%w0, %w1, %w2
1167   add\\t%0.2s, %1.2s, %2.2s
1168   sub\\t%w0, %w1, #%n2"
1169   [(set_attr "type" "alu_imm,alu_reg,neon_add,alu_imm")
1170    (set_attr "simd" "*,*,yes,*")]
1173 ;; zero_extend version of above
1174 (define_insn "*addsi3_aarch64_uxtw"
1175   [(set
1176     (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1177     (zero_extend:DI
1178      (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1179               (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1180   ""
1181   "@
1182   add\\t%w0, %w1, %2
1183   add\\t%w0, %w1, %w2
1184   sub\\t%w0, %w1, #%n2"
1185   [(set_attr "type" "alu_imm,alu_reg,alu_imm")]
1188 (define_insn "*adddi3_aarch64"
1189   [(set
1190     (match_operand:DI 0 "register_operand" "=rk,rk,rk,w")
1191     (plus:DI
1192      (match_operand:DI 1 "register_operand" "%rk,rk,rk,w")
1193      (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,w")))]
1194   ""
1195   "@
1196   add\\t%x0, %x1, %2
1197   add\\t%x0, %x1, %x2
1198   sub\\t%x0, %x1, #%n2
1199   add\\t%d0, %d1, %d2"
1200   [(set_attr "type" "alu_imm,alu_reg,alu_imm,neon_add")
1201    (set_attr "simd" "*,*,*,yes")]
1204 (define_expand "addti3"
1205   [(set (match_operand:TI 0 "register_operand" "")
1206         (plus:TI (match_operand:TI 1 "register_operand" "")
1207                  (match_operand:TI 2 "register_operand" "")))]
1208   ""
1210   rtx low = gen_reg_rtx (DImode);
1211   emit_insn (gen_adddi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1212                                   gen_lowpart (DImode, operands[2])));
1214   rtx high = gen_reg_rtx (DImode);
1215   emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]),
1216                                  gen_highpart (DImode, operands[2])));
1218   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1219   emit_move_insn (gen_highpart (DImode, operands[0]), high);
1220   DONE;
1223 (define_insn "add<mode>3_compare0"
1224   [(set (reg:CC_NZ CC_REGNUM)
1225         (compare:CC_NZ
1226          (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1227                    (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1228          (const_int 0)))
1229    (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1230         (plus:GPI (match_dup 1) (match_dup 2)))]
1231   ""
1232   "@
1233   adds\\t%<w>0, %<w>1, %<w>2
1234   adds\\t%<w>0, %<w>1, %<w>2
1235   subs\\t%<w>0, %<w>1, #%n2"
1236   [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1239 ;; zero_extend version of above
1240 (define_insn "*addsi3_compare0_uxtw"
1241   [(set (reg:CC_NZ CC_REGNUM)
1242         (compare:CC_NZ
1243          (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1244                   (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1245          (const_int 0)))
1246    (set (match_operand:DI 0 "register_operand" "=r,r,r")
1247         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1248   ""
1249   "@
1250   adds\\t%w0, %w1, %w2
1251   adds\\t%w0, %w1, %w2
1252   subs\\t%w0, %w1, #%n2"
1253   [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1256 (define_insn "*adds_mul_imm_<mode>"
1257   [(set (reg:CC_NZ CC_REGNUM)
1258         (compare:CC_NZ
1259          (plus:GPI (mult:GPI
1260                     (match_operand:GPI 1 "register_operand" "r")
1261                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1262                    (match_operand:GPI 3 "register_operand" "r"))
1263          (const_int 0)))
1264    (set (match_operand:GPI 0 "register_operand" "=r")
1265         (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1266                   (match_dup 3)))]
1267   ""
1268   "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1269   [(set_attr "type" "alus_shift_imm")]
1272 (define_insn "*subs_mul_imm_<mode>"
1273   [(set (reg:CC_NZ CC_REGNUM)
1274         (compare:CC_NZ
1275          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1276                     (mult:GPI
1277                      (match_operand:GPI 2 "register_operand" "r")
1278                      (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1279          (const_int 0)))
1280    (set (match_operand:GPI 0 "register_operand" "=r")
1281         (minus:GPI (match_dup 1)
1282                    (mult:GPI (match_dup 2) (match_dup 3))))]
1283   ""
1284   "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1285   [(set_attr "type" "alus_shift_imm")]
1288 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1289   [(set (reg:CC_NZ CC_REGNUM)
1290         (compare:CC_NZ
1291          (plus:GPI
1292           (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1293           (match_operand:GPI 2 "register_operand" "r"))
1294         (const_int 0)))
1295    (set (match_operand:GPI 0 "register_operand" "=r")
1296         (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1297   ""
1298   "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1299   [(set_attr "type" "alus_ext")]
1302 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1303   [(set (reg:CC_NZ CC_REGNUM)
1304         (compare:CC_NZ
1305          (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1306                     (ANY_EXTEND:GPI
1307                      (match_operand:ALLX 2 "register_operand" "r")))
1308         (const_int 0)))
1309    (set (match_operand:GPI 0 "register_operand" "=r")
1310         (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1311   ""
1312   "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1313   [(set_attr "type" "alus_ext")]
1316 (define_insn "*adds_<optab><mode>_multp2"
1317   [(set (reg:CC_NZ CC_REGNUM)
1318         (compare:CC_NZ
1319          (plus:GPI (ANY_EXTRACT:GPI
1320                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1321                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1322                     (match_operand 3 "const_int_operand" "n")
1323                     (const_int 0))
1324                    (match_operand:GPI 4 "register_operand" "r"))
1325         (const_int 0)))
1326    (set (match_operand:GPI 0 "register_operand" "=r")
1327         (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1328                                    (match_dup 3)
1329                                    (const_int 0))
1330                   (match_dup 4)))]
1331   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1332   "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1333   [(set_attr "type" "alus_ext")]
1336 (define_insn "*subs_<optab><mode>_multp2"
1337   [(set (reg:CC_NZ CC_REGNUM)
1338         (compare:CC_NZ
1339          (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1340                     (ANY_EXTRACT:GPI
1341                      (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1342                                (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1343                      (match_operand 3 "const_int_operand" "n")
1344                      (const_int 0)))
1345         (const_int 0)))
1346    (set (match_operand:GPI 0 "register_operand" "=r")
1347         (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1348                                   (mult:GPI (match_dup 1) (match_dup 2))
1349                                   (match_dup 3)
1350                                   (const_int 0))))]
1351   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1352   "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1353   [(set_attr "type" "alus_ext")]
1356 (define_insn "*add<mode>3nr_compare0"
1357   [(set (reg:CC_NZ CC_REGNUM)
1358         (compare:CC_NZ
1359          (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1360                    (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1361          (const_int 0)))]
1362   ""
1363   "@
1364   cmn\\t%<w>0, %<w>1
1365   cmn\\t%<w>0, %<w>1
1366   cmp\\t%<w>0, #%n1"
1367   [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1370 (define_insn "*compare_neg<mode>"
1371   [(set (reg:CC_Z CC_REGNUM)
1372         (compare:CC_Z
1373          (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1374          (match_operand:GPI 1 "register_operand" "r")))]
1375   ""
1376   "cmn\\t%<w>1, %<w>0"
1377   [(set_attr "type" "alus_reg")]
1380 (define_insn "*add_<shift>_<mode>"
1381   [(set (match_operand:GPI 0 "register_operand" "=r")
1382         (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1383                               (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1384                   (match_operand:GPI 3 "register_operand" "r")))]
1385   ""
1386   "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1387   [(set_attr "type" "alu_shift_imm")]
1390 ;; zero_extend version of above
1391 (define_insn "*add_<shift>_si_uxtw"
1392   [(set (match_operand:DI 0 "register_operand" "=r")
1393         (zero_extend:DI
1394          (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1395                              (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1396                   (match_operand:SI 3 "register_operand" "r"))))]
1397   ""
1398   "add\\t%w0, %w3, %w1, <shift> %2"
1399   [(set_attr "type" "alu_shift_imm")]
1402 (define_insn "*add_mul_imm_<mode>"
1403   [(set (match_operand:GPI 0 "register_operand" "=r")
1404         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1405                             (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1406                   (match_operand:GPI 3 "register_operand" "r")))]
1407   ""
1408   "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1409   [(set_attr "type" "alu_shift_imm")]
1412 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1413   [(set (match_operand:GPI 0 "register_operand" "=rk")
1414         (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1415                   (match_operand:GPI 2 "register_operand" "r")))]
1416   ""
1417   "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1418   [(set_attr "type" "alu_ext")]
1421 ;; zero_extend version of above
1422 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1423   [(set (match_operand:DI 0 "register_operand" "=rk")
1424         (zero_extend:DI
1425          (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1426                   (match_operand:GPI 2 "register_operand" "r"))))]
1427   ""
1428   "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1429   [(set_attr "type" "alu_ext")]
1432 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1433   [(set (match_operand:GPI 0 "register_operand" "=rk")
1434         (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1435                                (match_operand:ALLX 1 "register_operand" "r"))
1436                               (match_operand 2 "aarch64_imm3" "Ui3"))
1437                   (match_operand:GPI 3 "register_operand" "r")))]
1438   ""
1439   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1440   [(set_attr "type" "alu_ext")]
1443 ;; zero_extend version of above
1444 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1445   [(set (match_operand:DI 0 "register_operand" "=rk")
1446         (zero_extend:DI
1447          (plus:SI (ashift:SI (ANY_EXTEND:SI
1448                               (match_operand:SHORT 1 "register_operand" "r"))
1449                              (match_operand 2 "aarch64_imm3" "Ui3"))
1450                   (match_operand:SI 3 "register_operand" "r"))))]
1451   ""
1452   "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1453   [(set_attr "type" "alu_ext")]
1456 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1457   [(set (match_operand:GPI 0 "register_operand" "=rk")
1458         (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1459                              (match_operand:ALLX 1 "register_operand" "r"))
1460                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1461                   (match_operand:GPI 3 "register_operand" "r")))]
1462   ""
1463   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1464   [(set_attr "type" "alu_ext")]
1467 ;; zero_extend version of above
1468 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1469   [(set (match_operand:DI 0 "register_operand" "=rk")
1470         (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1471                              (match_operand:SHORT 1 "register_operand" "r"))
1472                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1473                   (match_operand:SI 3 "register_operand" "r"))))]
1474   ""
1475   "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1476   [(set_attr "type" "alu_ext")]
1479 (define_insn "*add_<optab><mode>_multp2"
1480   [(set (match_operand:GPI 0 "register_operand" "=rk")
1481         (plus:GPI (ANY_EXTRACT:GPI
1482                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1483                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1484                    (match_operand 3 "const_int_operand" "n")
1485                    (const_int 0))
1486                   (match_operand:GPI 4 "register_operand" "r")))]
1487   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1488   "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1489   [(set_attr "type" "alu_ext")]
1492 ;; zero_extend version of above
1493 (define_insn "*add_<optab>si_multp2_uxtw"
1494   [(set (match_operand:DI 0 "register_operand" "=rk")
1495         (zero_extend:DI
1496          (plus:SI (ANY_EXTRACT:SI
1497                    (mult:SI (match_operand:SI 1 "register_operand" "r")
1498                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1499                    (match_operand 3 "const_int_operand" "n")
1500                    (const_int 0))
1501                   (match_operand:SI 4 "register_operand" "r"))))]
1502   "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1503   "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1504   [(set_attr "type" "alu_ext")]
1507 (define_insn "add<mode>3_carryin"
1508   [(set
1509     (match_operand:GPI 0 "register_operand" "=r")
1510     (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1511               (plus:GPI
1512                 (match_operand:GPI 1 "register_operand" "r")
1513                 (match_operand:GPI 2 "register_operand" "r"))))]
1514    ""
1515    "adc\\t%<w>0, %<w>1, %<w>2"
1516   [(set_attr "type" "adc_reg")]
1519 ;; zero_extend version of above
1520 (define_insn "*addsi3_carryin_uxtw"
1521   [(set
1522     (match_operand:DI 0 "register_operand" "=r")
1523     (zero_extend:DI
1524      (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1525               (plus:SI
1526                (match_operand:SI 1 "register_operand" "r")
1527                (match_operand:SI 2 "register_operand" "r")))))]
1528    ""
1529    "adc\\t%w0, %w1, %w2"
1530   [(set_attr "type" "adc_reg")]
1533 (define_insn "*add<mode>3_carryin_alt1"
1534   [(set
1535     (match_operand:GPI 0 "register_operand" "=r")
1536     (plus:GPI (plus:GPI
1537                 (match_operand:GPI 1 "register_operand" "r")
1538                 (match_operand:GPI 2 "register_operand" "r"))
1539               (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1540    ""
1541    "adc\\t%<w>0, %<w>1, %<w>2"
1542   [(set_attr "type" "adc_reg")]
1545 ;; zero_extend version of above
1546 (define_insn "*addsi3_carryin_alt1_uxtw"
1547   [(set
1548     (match_operand:DI 0 "register_operand" "=r")
1549     (zero_extend:DI
1550      (plus:SI (plus:SI
1551                (match_operand:SI 1 "register_operand" "r")
1552                (match_operand:SI 2 "register_operand" "r"))
1553               (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1554    ""
1555    "adc\\t%w0, %w1, %w2"
1556   [(set_attr "type" "adc_reg")]
1559 (define_insn "*add<mode>3_carryin_alt2"
1560   [(set
1561     (match_operand:GPI 0 "register_operand" "=r")
1562     (plus:GPI (plus:GPI
1563                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1564                 (match_operand:GPI 1 "register_operand" "r"))
1565               (match_operand:GPI 2 "register_operand" "r")))]
1566    ""
1567    "adc\\t%<w>0, %<w>1, %<w>2"
1568   [(set_attr "type" "adc_reg")]
1571 ;; zero_extend version of above
1572 (define_insn "*addsi3_carryin_alt2_uxtw"
1573   [(set
1574     (match_operand:DI 0 "register_operand" "=r")
1575     (zero_extend:DI
1576      (plus:SI (plus:SI
1577                (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1578                (match_operand:SI 1 "register_operand" "r"))
1579               (match_operand:SI 2 "register_operand" "r"))))]
1580    ""
1581    "adc\\t%w0, %w1, %w2"
1582   [(set_attr "type" "adc_reg")]
1585 (define_insn "*add<mode>3_carryin_alt3"
1586   [(set
1587     (match_operand:GPI 0 "register_operand" "=r")
1588     (plus:GPI (plus:GPI
1589                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1590                 (match_operand:GPI 2 "register_operand" "r"))
1591               (match_operand:GPI 1 "register_operand" "r")))]
1592    ""
1593    "adc\\t%<w>0, %<w>1, %<w>2"
1594   [(set_attr "type" "adc_reg")]
1597 ;; zero_extend version of above
1598 (define_insn "*addsi3_carryin_alt3_uxtw"
1599   [(set
1600     (match_operand:DI 0 "register_operand" "=r")
1601     (zero_extend:DI
1602      (plus:SI (plus:SI
1603                (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1604                (match_operand:SI 2 "register_operand" "r"))
1605               (match_operand:SI 1 "register_operand" "r"))))]
1606    ""
1607    "adc\\t%w0, %w1, %w2"
1608   [(set_attr "type" "adc_reg")]
1611 (define_insn "*add_uxt<mode>_multp2"
1612   [(set (match_operand:GPI 0 "register_operand" "=rk")
1613         (plus:GPI (and:GPI
1614                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1615                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1616                    (match_operand 3 "const_int_operand" "n"))
1617                   (match_operand:GPI 4 "register_operand" "r")))]
1618   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1619   "*
1620   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1621                                            INTVAL (operands[3])));
1622   return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1623   [(set_attr "type" "alu_ext")]
1626 ;; zero_extend version of above
1627 (define_insn "*add_uxtsi_multp2_uxtw"
1628   [(set (match_operand:DI 0 "register_operand" "=rk")
1629         (zero_extend:DI
1630          (plus:SI (and:SI
1631                    (mult:SI (match_operand:SI 1 "register_operand" "r")
1632                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1633                    (match_operand 3 "const_int_operand" "n"))
1634                   (match_operand:SI 4 "register_operand" "r"))))]
1635   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1636   "*
1637   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1638                                            INTVAL (operands[3])));
1639   return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1640   [(set_attr "type" "alu_ext")]
1643 (define_insn "subsi3"
1644   [(set (match_operand:SI 0 "register_operand" "=rk")
1645         (minus:SI (match_operand:SI 1 "register_operand" "r")
1646                    (match_operand:SI 2 "register_operand" "r")))]
1647   ""
1648   "sub\\t%w0, %w1, %w2"
1649   [(set_attr "type" "alu_reg")]
1652 ;; zero_extend version of above
1653 (define_insn "*subsi3_uxtw"
1654   [(set (match_operand:DI 0 "register_operand" "=rk")
1655         (zero_extend:DI
1656          (minus:SI (match_operand:SI 1 "register_operand" "r")
1657                    (match_operand:SI 2 "register_operand" "r"))))]
1658   ""
1659   "sub\\t%w0, %w1, %w2"
1660   [(set_attr "type" "alu_reg")]
1663 (define_insn "subdi3"
1664   [(set (match_operand:DI 0 "register_operand" "=rk,w")
1665         (minus:DI (match_operand:DI 1 "register_operand" "r,w")
1666                    (match_operand:DI 2 "register_operand" "r,w")))]
1667   ""
1668   "@
1669    sub\\t%x0, %x1, %x2
1670    sub\\t%d0, %d1, %d2"
1671   [(set_attr "type" "alu_reg, neon_sub")
1672    (set_attr "simd" "*,yes")]
1675 (define_expand "subti3"
1676   [(set (match_operand:TI 0 "register_operand" "")
1677         (minus:TI (match_operand:TI 1 "register_operand" "")
1678                   (match_operand:TI 2 "register_operand" "")))]
1679   ""
1681   rtx low = gen_reg_rtx (DImode);
1682   emit_insn (gen_subdi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1683                                   gen_lowpart (DImode, operands[2])));
1685   rtx high = gen_reg_rtx (DImode);
1686   emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]),
1687                                  gen_highpart (DImode, operands[2])));
1689   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1690   emit_move_insn (gen_highpart (DImode, operands[0]), high);
1691   DONE;
1694 (define_insn "sub<mode>3_compare0"
1695   [(set (reg:CC_NZ CC_REGNUM)
1696         (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1697                                   (match_operand:GPI 2 "register_operand" "r"))
1698                        (const_int 0)))
1699    (set (match_operand:GPI 0 "register_operand" "=r")
1700         (minus:GPI (match_dup 1) (match_dup 2)))]
1701   ""
1702   "subs\\t%<w>0, %<w>1, %<w>2"
1703   [(set_attr "type" "alus_reg")]
1706 ;; zero_extend version of above
1707 (define_insn "*subsi3_compare0_uxtw"
1708   [(set (reg:CC_NZ CC_REGNUM)
1709         (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1710                                  (match_operand:SI 2 "register_operand" "r"))
1711                        (const_int 0)))
1712    (set (match_operand:DI 0 "register_operand" "=r")
1713         (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1714   ""
1715   "subs\\t%w0, %w1, %w2"
1716   [(set_attr "type" "alus_reg")]
1719 (define_insn "*sub_<shift>_<mode>"
1720   [(set (match_operand:GPI 0 "register_operand" "=r")
1721         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1722                    (ASHIFT:GPI
1723                     (match_operand:GPI 1 "register_operand" "r")
1724                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1725   ""
1726   "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1727   [(set_attr "type" "alu_shift_imm")]
1730 ;; zero_extend version of above
1731 (define_insn "*sub_<shift>_si_uxtw"
1732   [(set (match_operand:DI 0 "register_operand" "=r")
1733         (zero_extend:DI
1734          (minus:SI (match_operand:SI 3 "register_operand" "r")
1735                    (ASHIFT:SI
1736                     (match_operand:SI 1 "register_operand" "r")
1737                     (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1738   ""
1739   "sub\\t%w0, %w3, %w1, <shift> %2"
1740   [(set_attr "type" "alu_shift_imm")]
1743 (define_insn "*sub_mul_imm_<mode>"
1744   [(set (match_operand:GPI 0 "register_operand" "=r")
1745         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1746                    (mult:GPI
1747                     (match_operand:GPI 1 "register_operand" "r")
1748                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1749   ""
1750   "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1751   [(set_attr "type" "alu_shift_imm")]
1754 ;; zero_extend version of above
1755 (define_insn "*sub_mul_imm_si_uxtw"
1756   [(set (match_operand:DI 0 "register_operand" "=r")
1757         (zero_extend:DI
1758          (minus:SI (match_operand:SI 3 "register_operand" "r")
1759                    (mult:SI
1760                     (match_operand:SI 1 "register_operand" "r")
1761                     (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
1762   ""
1763   "sub\\t%w0, %w3, %w1, lsl %p2"
1764   [(set_attr "type" "alu_shift_imm")]
1767 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
1768   [(set (match_operand:GPI 0 "register_operand" "=rk")
1769         (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1770                    (ANY_EXTEND:GPI
1771                     (match_operand:ALLX 2 "register_operand" "r"))))]
1772   ""
1773   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1774   [(set_attr "type" "alu_ext")]
1777 ;; zero_extend version of above
1778 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
1779   [(set (match_operand:DI 0 "register_operand" "=rk")
1780         (zero_extend:DI
1781          (minus:SI (match_operand:SI 1 "register_operand" "r")
1782                    (ANY_EXTEND:SI
1783                     (match_operand:SHORT 2 "register_operand" "r")))))]
1784   ""
1785   "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
1786   [(set_attr "type" "alu_ext")]
1789 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
1790   [(set (match_operand:GPI 0 "register_operand" "=rk")
1791         (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1792                    (ashift:GPI (ANY_EXTEND:GPI
1793                                 (match_operand:ALLX 2 "register_operand" "r"))
1794                                (match_operand 3 "aarch64_imm3" "Ui3"))))]
1795   ""
1796   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1797   [(set_attr "type" "alu_ext")]
1800 ;; zero_extend version of above
1801 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
1802   [(set (match_operand:DI 0 "register_operand" "=rk")
1803         (zero_extend:DI
1804          (minus:SI (match_operand:SI 1 "register_operand" "r")
1805                    (ashift:SI (ANY_EXTEND:SI
1806                                (match_operand:SHORT 2 "register_operand" "r"))
1807                               (match_operand 3 "aarch64_imm3" "Ui3")))))]
1808   ""
1809   "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
1810   [(set_attr "type" "alu_ext")]
1813 (define_insn "*sub_<optab><mode>_multp2"
1814   [(set (match_operand:GPI 0 "register_operand" "=rk")
1815         (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1816                    (ANY_EXTRACT:GPI
1817                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1818                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1819                     (match_operand 3 "const_int_operand" "n")
1820                     (const_int 0))))]
1821   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1822   "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1823   [(set_attr "type" "alu_ext")]
1826 ;; zero_extend version of above
1827 (define_insn "*sub_<optab>si_multp2_uxtw"
1828   [(set (match_operand:DI 0 "register_operand" "=rk")
1829         (zero_extend:DI
1830          (minus:SI (match_operand:SI 4 "register_operand" "r")
1831                    (ANY_EXTRACT:SI
1832                     (mult:SI (match_operand:SI 1 "register_operand" "r")
1833                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1834                     (match_operand 3 "const_int_operand" "n")
1835                     (const_int 0)))))]
1836   "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1837   "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1838   [(set_attr "type" "alu_ext")]
1841 (define_insn "sub<mode>3_carryin"
1842   [(set
1843     (match_operand:GPI 0 "register_operand" "=r")
1844     (minus:GPI (minus:GPI
1845                 (match_operand:GPI 1 "register_operand" "r")
1846                 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
1847                (match_operand:GPI 2 "register_operand" "r")))]
1848    ""
1849    "sbc\\t%<w>0, %<w>1, %<w>2"
1850   [(set_attr "type" "adc_reg")]
1853 ;; zero_extend version of the above
1854 (define_insn "*subsi3_carryin_uxtw"
1855   [(set
1856     (match_operand:DI 0 "register_operand" "=r")
1857     (zero_extend:DI
1858      (minus:SI (minus:SI
1859                 (match_operand:SI 1 "register_operand" "r")
1860                 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
1861                (match_operand:SI 2 "register_operand" "r"))))]
1862    ""
1863    "sbc\\t%w0, %w1, %w2"
1864   [(set_attr "type" "adc_reg")]
1867 (define_insn "*sub_uxt<mode>_multp2"
1868   [(set (match_operand:GPI 0 "register_operand" "=rk")
1869         (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1870                    (and:GPI
1871                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1872                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1873                     (match_operand 3 "const_int_operand" "n"))))]
1874   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1875   "*
1876   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1877                                            INTVAL (operands[3])));
1878   return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1879   [(set_attr "type" "alu_ext")]
1882 ;; zero_extend version of above
1883 (define_insn "*sub_uxtsi_multp2_uxtw"
1884   [(set (match_operand:DI 0 "register_operand" "=rk")
1885         (zero_extend:DI
1886          (minus:SI (match_operand:SI 4 "register_operand" "r")
1887                    (and:SI
1888                     (mult:SI (match_operand:SI 1 "register_operand" "r")
1889                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1890                     (match_operand 3 "const_int_operand" "n")))))]
1891   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1892   "*
1893   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1894                                            INTVAL (operands[3])));
1895   return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
1896   [(set_attr "type" "alu_ext")]
1899 (define_insn_and_split "absdi2"
1900   [(set (match_operand:DI 0 "register_operand" "=&r,w")
1901         (abs:DI (match_operand:DI 1 "register_operand" "r,w")))]
1902   ""
1903   "@
1904    #
1905    abs\\t%d0, %d1"
1906   "reload_completed
1907    && GP_REGNUM_P (REGNO (operands[0]))
1908    && GP_REGNUM_P (REGNO (operands[1]))"
1909   [(const_int 0)]
1910   {
1911     emit_insn (gen_rtx_SET (VOIDmode, operands[0],
1912                             gen_rtx_XOR (DImode,
1913                                          gen_rtx_ASHIFTRT (DImode,
1914                                                            operands[1],
1915                                                            GEN_INT (63)),
1916                                          operands[1])));
1917     emit_insn (gen_rtx_SET (VOIDmode,
1918                             operands[0],
1919                             gen_rtx_MINUS (DImode,
1920                                            operands[0],
1921                                            gen_rtx_ASHIFTRT (DImode,
1922                                                              operands[1],
1923                                                              GEN_INT (63)))));
1924     DONE;
1925   }
1926   [(set_attr "type" "alu_reg")]
1929 (define_insn "neg<mode>2"
1930   [(set (match_operand:GPI 0 "register_operand" "=r,w")
1931         (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
1932   ""
1933   "@
1934    neg\\t%<w>0, %<w>1
1935    neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
1936   [(set_attr "type" "alu_reg, neon_neg<q>")
1937    (set_attr "simd" "*,yes")]
1940 ;; zero_extend version of above
1941 (define_insn "*negsi2_uxtw"
1942   [(set (match_operand:DI 0 "register_operand" "=r")
1943         (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
1944   ""
1945   "neg\\t%w0, %w1"
1946   [(set_attr "type" "alu_reg")]
1949 (define_insn "*ngc<mode>"
1950   [(set (match_operand:GPI 0 "register_operand" "=r")
1951         (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
1952                    (match_operand:GPI 1 "register_operand" "r")))]
1953   ""
1954   "ngc\\t%<w>0, %<w>1"
1955   [(set_attr "type" "adc_reg")]
1958 (define_insn "*ngcsi_uxtw"
1959   [(set (match_operand:DI 0 "register_operand" "=r")
1960         (zero_extend:DI
1961          (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
1962                    (match_operand:SI 1 "register_operand" "r"))))]
1963   ""
1964   "ngc\\t%w0, %w1"
1965   [(set_attr "type" "adc_reg")]
1968 (define_insn "*neg<mode>2_compare0"
1969   [(set (reg:CC_NZ CC_REGNUM)
1970         (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
1971                        (const_int 0)))
1972    (set (match_operand:GPI 0 "register_operand" "=r")
1973         (neg:GPI (match_dup 1)))]
1974   ""
1975   "negs\\t%<w>0, %<w>1"
1976   [(set_attr "type" "alus_reg")]
1979 ;; zero_extend version of above
1980 (define_insn "*negsi2_compare0_uxtw"
1981   [(set (reg:CC_NZ CC_REGNUM)
1982         (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
1983                        (const_int 0)))
1984    (set (match_operand:DI 0 "register_operand" "=r")
1985         (zero_extend:DI (neg:SI (match_dup 1))))]
1986   ""
1987   "negs\\t%w0, %w1"
1988   [(set_attr "type" "alus_reg")]
1991 (define_insn "*neg_<shift><mode>3_compare0"
1992   [(set (reg:CC_NZ CC_REGNUM)
1993         (compare:CC_NZ
1994          (neg:GPI (ASHIFT:GPI
1995                    (match_operand:GPI 1 "register_operand" "r")
1996                    (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
1997          (const_int 0)))
1998    (set (match_operand:GPI 0 "register_operand" "=r")
1999         (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2000   ""
2001   "negs\\t%<w>0, %<w>1, <shift> %2"
2002   [(set_attr "type" "alus_shift_imm")]
2005 (define_insn "*neg_<shift>_<mode>2"
2006   [(set (match_operand:GPI 0 "register_operand" "=r")
2007         (neg:GPI (ASHIFT:GPI
2008                   (match_operand:GPI 1 "register_operand" "r")
2009                   (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2010   ""
2011   "neg\\t%<w>0, %<w>1, <shift> %2"
2012   [(set_attr "type" "alu_shift_imm")]
2015 ;; zero_extend version of above
2016 (define_insn "*neg_<shift>_si2_uxtw"
2017   [(set (match_operand:DI 0 "register_operand" "=r")
2018         (zero_extend:DI
2019          (neg:SI (ASHIFT:SI
2020                   (match_operand:SI 1 "register_operand" "r")
2021                   (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2022   ""
2023   "neg\\t%w0, %w1, <shift> %2"
2024   [(set_attr "type" "alu_shift_imm")]
2027 (define_insn "*neg_mul_imm_<mode>2"
2028   [(set (match_operand:GPI 0 "register_operand" "=r")
2029         (neg:GPI (mult:GPI
2030                   (match_operand:GPI 1 "register_operand" "r")
2031                   (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2032   ""
2033   "neg\\t%<w>0, %<w>1, lsl %p2"
2034   [(set_attr "type" "alu_shift_imm")]
2037 ;; zero_extend version of above
2038 (define_insn "*neg_mul_imm_si2_uxtw"
2039   [(set (match_operand:DI 0 "register_operand" "=r")
2040         (zero_extend:DI
2041          (neg:SI (mult:SI
2042                   (match_operand:SI 1 "register_operand" "r")
2043                   (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2044   ""
2045   "neg\\t%w0, %w1, lsl %p2"
2046   [(set_attr "type" "alu_shift_imm")]
2049 (define_insn "mul<mode>3"
2050   [(set (match_operand:GPI 0 "register_operand" "=r")
2051         (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2052                   (match_operand:GPI 2 "register_operand" "r")))]
2053   ""
2054   "mul\\t%<w>0, %<w>1, %<w>2"
2055   [(set_attr "type" "mul")]
2058 ;; zero_extend version of above
2059 (define_insn "*mulsi3_uxtw"
2060   [(set (match_operand:DI 0 "register_operand" "=r")
2061         (zero_extend:DI
2062          (mult:SI (match_operand:SI 1 "register_operand" "r")
2063                   (match_operand:SI 2 "register_operand" "r"))))]
2064   ""
2065   "mul\\t%w0, %w1, %w2"
2066   [(set_attr "type" "mul")]
2069 (define_insn "madd<mode>"
2070   [(set (match_operand:GPI 0 "register_operand" "=r")
2071         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2072                             (match_operand:GPI 2 "register_operand" "r"))
2073                   (match_operand:GPI 3 "register_operand" "r")))]
2074   ""
2075   "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2076   [(set_attr "type" "mla")]
2079 ;; zero_extend version of above
2080 (define_insn "*maddsi_uxtw"
2081   [(set (match_operand:DI 0 "register_operand" "=r")
2082         (zero_extend:DI
2083          (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2084                            (match_operand:SI 2 "register_operand" "r"))
2085                   (match_operand:SI 3 "register_operand" "r"))))]
2086   ""
2087   "madd\\t%w0, %w1, %w2, %w3"
2088   [(set_attr "type" "mla")]
2091 (define_insn "*msub<mode>"
2092   [(set (match_operand:GPI 0 "register_operand" "=r")
2093         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2094                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2095                              (match_operand:GPI 2 "register_operand" "r"))))]
2097   ""
2098   "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2099   [(set_attr "type" "mla")]
2102 ;; zero_extend version of above
2103 (define_insn "*msubsi_uxtw"
2104   [(set (match_operand:DI 0 "register_operand" "=r")
2105         (zero_extend:DI
2106          (minus:SI (match_operand:SI 3 "register_operand" "r")
2107                    (mult:SI (match_operand:SI 1 "register_operand" "r")
2108                             (match_operand:SI 2 "register_operand" "r")))))]
2110   ""
2111   "msub\\t%w0, %w1, %w2, %w3"
2112   [(set_attr "type" "mla")]
2115 (define_insn "*mul<mode>_neg"
2116   [(set (match_operand:GPI 0 "register_operand" "=r")
2117         (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2118                   (match_operand:GPI 2 "register_operand" "r")))]
2120   ""
2121   "mneg\\t%<w>0, %<w>1, %<w>2"
2122   [(set_attr "type" "mul")]
2125 ;; zero_extend version of above
2126 (define_insn "*mulsi_neg_uxtw"
2127   [(set (match_operand:DI 0 "register_operand" "=r")
2128         (zero_extend:DI
2129          (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2130                   (match_operand:SI 2 "register_operand" "r"))))]
2132   ""
2133   "mneg\\t%w0, %w1, %w2"
2134   [(set_attr "type" "mul")]
2137 (define_insn "<su_optab>mulsidi3"
2138   [(set (match_operand:DI 0 "register_operand" "=r")
2139         (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2140                  (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2141   ""
2142   "<su>mull\\t%0, %w1, %w2"
2143   [(set_attr "type" "<su>mull")]
2146 (define_insn "<su_optab>maddsidi4"
2147   [(set (match_operand:DI 0 "register_operand" "=r")
2148         (plus:DI (mult:DI
2149                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2150                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2151                  (match_operand:DI 3 "register_operand" "r")))]
2152   ""
2153   "<su>maddl\\t%0, %w1, %w2, %3"
2154   [(set_attr "type" "<su>mlal")]
2157 (define_insn "<su_optab>msubsidi4"
2158   [(set (match_operand:DI 0 "register_operand" "=r")
2159         (minus:DI
2160          (match_operand:DI 3 "register_operand" "r")
2161          (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2162                   (ANY_EXTEND:DI
2163                    (match_operand:SI 2 "register_operand" "r")))))]
2164   ""
2165   "<su>msubl\\t%0, %w1, %w2, %3"
2166   [(set_attr "type" "<su>mlal")]
2169 (define_insn "*<su_optab>mulsidi_neg"
2170   [(set (match_operand:DI 0 "register_operand" "=r")
2171         (mult:DI (neg:DI
2172                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2173                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2174   ""
2175   "<su>mnegl\\t%0, %w1, %w2"
2176   [(set_attr "type" "<su>mull")]
2179 (define_expand "<su_optab>mulditi3"
2180   [(set (match_operand:TI 0 "register_operand")
2181         (mult:TI (ANY_EXTEND:TI (match_operand:DI 1 "register_operand"))
2182                  (ANY_EXTEND:TI (match_operand:DI 2 "register_operand"))))]
2183   ""
2185   rtx low = gen_reg_rtx (DImode);
2186   emit_insn (gen_muldi3 (low, operands[1], operands[2]));
2188   rtx high = gen_reg_rtx (DImode);
2189   emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2]));
2191   emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2192   emit_move_insn (gen_highpart (DImode, operands[0]), high);
2193   DONE;
2196 ;; The default expansion of multi3 using umuldi3_highpart will perform
2197 ;; the additions in an order that fails to combine into two madd insns.
2198 (define_expand "multi3"
2199   [(set (match_operand:TI 0 "register_operand")
2200         (mult:TI (match_operand:TI 1 "register_operand")
2201                  (match_operand:TI 2 "register_operand")))]
2202   ""
2204   rtx l0 = gen_reg_rtx (DImode);
2205   rtx l1 = gen_lowpart (DImode, operands[1]);
2206   rtx l2 = gen_lowpart (DImode, operands[2]);
2207   rtx h0 = gen_reg_rtx (DImode);
2208   rtx h1 = gen_highpart (DImode, operands[1]);
2209   rtx h2 = gen_highpart (DImode, operands[2]);
2211   emit_insn (gen_muldi3 (l0, l1, l2));
2212   emit_insn (gen_umuldi3_highpart (h0, l1, l2));
2213   emit_insn (gen_madddi (h0, h1, l2, h0));
2214   emit_insn (gen_madddi (h0, l1, h2, h0));
2216   emit_move_insn (gen_lowpart (DImode, operands[0]), l0);
2217   emit_move_insn (gen_highpart (DImode, operands[0]), h0);
2218   DONE;
2221 (define_insn "<su>muldi3_highpart"
2222   [(set (match_operand:DI 0 "register_operand" "=r")
2223         (truncate:DI
2224          (lshiftrt:TI
2225           (mult:TI
2226            (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2227            (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2228           (const_int 64))))]
2229   ""
2230   "<su>mulh\\t%0, %1, %2"
2231   [(set_attr "type" "<su>mull")]
2234 (define_insn "<su_optab>div<mode>3"
2235   [(set (match_operand:GPI 0 "register_operand" "=r")
2236         (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2237                      (match_operand:GPI 2 "register_operand" "r")))]
2238   ""
2239   "<su>div\\t%<w>0, %<w>1, %<w>2"
2240   [(set_attr "type" "<su>div")]
2243 ;; zero_extend version of above
2244 (define_insn "*<su_optab>divsi3_uxtw"
2245   [(set (match_operand:DI 0 "register_operand" "=r")
2246         (zero_extend:DI
2247          (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2248                      (match_operand:SI 2 "register_operand" "r"))))]
2249   ""
2250   "<su>div\\t%w0, %w1, %w2"
2251   [(set_attr "type" "<su>div")]
2254 ;; -------------------------------------------------------------------
2255 ;; Comparison insns
2256 ;; -------------------------------------------------------------------
2258 (define_insn "*cmp<mode>"
2259   [(set (reg:CC CC_REGNUM)
2260         (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2261                     (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2262   ""
2263   "@
2264    cmp\\t%<w>0, %<w>1
2265    cmp\\t%<w>0, %<w>1
2266    cmn\\t%<w>0, #%n1"
2267   [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
2270 (define_insn "*cmp<mode>"
2271   [(set (reg:CCFP CC_REGNUM)
2272         (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2273                       (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2274    "TARGET_FLOAT"
2275    "@
2276     fcmp\\t%<s>0, #0.0
2277     fcmp\\t%<s>0, %<s>1"
2278   [(set_attr "type" "fcmp<s>")]
2281 (define_insn "*cmpe<mode>"
2282   [(set (reg:CCFPE CC_REGNUM)
2283         (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2284                        (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2285    "TARGET_FLOAT"
2286    "@
2287     fcmpe\\t%<s>0, #0.0
2288     fcmpe\\t%<s>0, %<s>1"
2289   [(set_attr "type" "fcmp<s>")]
2292 (define_insn "*cmp_swp_<shift>_reg<mode>"
2293   [(set (reg:CC_SWP CC_REGNUM)
2294         (compare:CC_SWP (ASHIFT:GPI
2295                          (match_operand:GPI 0 "register_operand" "r")
2296                          (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2297                         (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2298   ""
2299   "cmp\\t%<w>2, %<w>0, <shift> %1"
2300   [(set_attr "type" "alus_shift_imm")]
2303 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2304   [(set (reg:CC_SWP CC_REGNUM)
2305         (compare:CC_SWP (ANY_EXTEND:GPI
2306                          (match_operand:ALLX 0 "register_operand" "r"))
2307                         (match_operand:GPI 1 "register_operand" "r")))]
2308   ""
2309   "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2310   [(set_attr "type" "alus_ext")]
2313 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2314   [(set (reg:CC_SWP CC_REGNUM)
2315         (compare:CC_SWP (ashift:GPI
2316                          (ANY_EXTEND:GPI
2317                           (match_operand:ALLX 0 "register_operand" "r"))
2318                          (match_operand 1 "aarch64_imm3" "Ui3"))
2319         (match_operand:GPI 2 "register_operand" "r")))]
2320   ""
2321   "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2322   [(set_attr "type" "alus_ext")]
2325 ;; -------------------------------------------------------------------
2326 ;; Store-flag and conditional select insns
2327 ;; -------------------------------------------------------------------
2329 (define_expand "cstore<mode>4"
2330   [(set (match_operand:SI 0 "register_operand" "")
2331         (match_operator:SI 1 "aarch64_comparison_operator"
2332          [(match_operand:GPI 2 "register_operand" "")
2333           (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2334   ""
2335   "
2336   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2337                                       operands[3]);
2338   operands[3] = const0_rtx;
2339   "
2342 (define_expand "cstore<mode>4"
2343   [(set (match_operand:SI 0 "register_operand" "")
2344         (match_operator:SI 1 "aarch64_comparison_operator"
2345          [(match_operand:GPF 2 "register_operand" "")
2346           (match_operand:GPF 3 "register_operand" "")]))]
2347   ""
2348   "
2349   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2350                                       operands[3]);
2351   operands[3] = const0_rtx;
2352   "
2355 (define_insn "*cstore<mode>_insn"
2356   [(set (match_operand:ALLI 0 "register_operand" "=r")
2357         (match_operator:ALLI 1 "aarch64_comparison_operator"
2358          [(match_operand 2 "cc_register" "") (const_int 0)]))]
2359   ""
2360   "cset\\t%<w>0, %m1"
2361   [(set_attr "type" "csel")]
2364 ;; zero_extend version of the above
2365 (define_insn "*cstoresi_insn_uxtw"
2366   [(set (match_operand:DI 0 "register_operand" "=r")
2367         (zero_extend:DI
2368          (match_operator:SI 1 "aarch64_comparison_operator"
2369           [(match_operand 2 "cc_register" "") (const_int 0)])))]
2370   ""
2371   "cset\\t%w0, %m1"
2372   [(set_attr "type" "csel")]
2375 (define_insn "cstore<mode>_neg"
2376   [(set (match_operand:ALLI 0 "register_operand" "=r")
2377         (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2378                   [(match_operand 2 "cc_register" "") (const_int 0)])))]
2379   ""
2380   "csetm\\t%<w>0, %m1"
2381   [(set_attr "type" "csel")]
2384 ;; zero_extend version of the above
2385 (define_insn "*cstoresi_neg_uxtw"
2386   [(set (match_operand:DI 0 "register_operand" "=r")
2387         (zero_extend:DI
2388          (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2389                   [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2390   ""
2391   "csetm\\t%w0, %m1"
2392   [(set_attr "type" "csel")]
2395 (define_expand "cmov<mode>6"
2396   [(set (match_operand:GPI 0 "register_operand" "")
2397         (if_then_else:GPI
2398          (match_operator 1 "aarch64_comparison_operator"
2399           [(match_operand:GPI 2 "register_operand" "")
2400            (match_operand:GPI 3 "aarch64_plus_operand" "")])
2401          (match_operand:GPI 4 "register_operand" "")
2402          (match_operand:GPI 5 "register_operand" "")))]
2403   ""
2404   "
2405   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2406                                       operands[3]);
2407   operands[3] = const0_rtx;
2408   "
2411 (define_expand "cmov<mode>6"
2412   [(set (match_operand:GPF 0 "register_operand" "")
2413         (if_then_else:GPF
2414          (match_operator 1 "aarch64_comparison_operator"
2415           [(match_operand:GPF 2 "register_operand" "")
2416            (match_operand:GPF 3 "register_operand" "")])
2417          (match_operand:GPF 4 "register_operand" "")
2418          (match_operand:GPF 5 "register_operand" "")))]
2419   ""
2420   "
2421   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2422                                       operands[3]);
2423   operands[3] = const0_rtx;
2424   "
2427 (define_insn "*cmov<mode>_insn"
2428   [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2429         (if_then_else:ALLI
2430          (match_operator 1 "aarch64_comparison_operator"
2431           [(match_operand 2 "cc_register" "") (const_int 0)])
2432          (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2433          (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2434   "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2435      || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2436   ;; Final two alternatives should be unreachable, but included for completeness
2437   "@
2438    csel\\t%<w>0, %<w>3, %<w>4, %m1
2439    csinv\\t%<w>0, %<w>3, <w>zr, %m1
2440    csinv\\t%<w>0, %<w>4, <w>zr, %M1
2441    csinc\\t%<w>0, %<w>3, <w>zr, %m1
2442    csinc\\t%<w>0, %<w>4, <w>zr, %M1
2443    mov\\t%<w>0, -1
2444    mov\\t%<w>0, 1"
2445   [(set_attr "type" "csel")]
2448 ;; zero_extend version of above
2449 (define_insn "*cmovsi_insn_uxtw"
2450   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2451         (zero_extend:DI
2452          (if_then_else:SI
2453           (match_operator 1 "aarch64_comparison_operator"
2454            [(match_operand 2 "cc_register" "") (const_int 0)])
2455           (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2456           (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2457   "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2458      || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2459   ;; Final two alternatives should be unreachable, but included for completeness
2460   "@
2461    csel\\t%w0, %w3, %w4, %m1
2462    csinv\\t%w0, %w3, wzr, %m1
2463    csinv\\t%w0, %w4, wzr, %M1
2464    csinc\\t%w0, %w3, wzr, %m1
2465    csinc\\t%w0, %w4, wzr, %M1
2466    mov\\t%w0, -1
2467    mov\\t%w0, 1"
2468   [(set_attr "type" "csel")]
2471 (define_insn "*cmov<mode>_insn"
2472   [(set (match_operand:GPF 0 "register_operand" "=w")
2473         (if_then_else:GPF
2474          (match_operator 1 "aarch64_comparison_operator"
2475           [(match_operand 2 "cc_register" "") (const_int 0)])
2476          (match_operand:GPF 3 "register_operand" "w")
2477          (match_operand:GPF 4 "register_operand" "w")))]
2478   "TARGET_FLOAT"
2479   "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2480   [(set_attr "type" "fcsel")]
2483 (define_expand "mov<mode>cc"
2484   [(set (match_operand:ALLI 0 "register_operand" "")
2485         (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2486                            (match_operand:ALLI 2 "register_operand" "")
2487                            (match_operand:ALLI 3 "register_operand" "")))]
2488   ""
2489   {
2490     rtx ccreg;
2491     enum rtx_code code = GET_CODE (operands[1]);
2493     if (code == UNEQ || code == LTGT)
2494       FAIL;
2496     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2497                                   XEXP (operands[1], 1));
2498     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2499   }
2502 (define_expand "mov<GPF:mode><GPI:mode>cc"
2503   [(set (match_operand:GPI 0 "register_operand" "")
2504         (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2505                           (match_operand:GPF 2 "register_operand" "")
2506                           (match_operand:GPF 3 "register_operand" "")))]
2507   ""
2508   {
2509     rtx ccreg;
2510     enum rtx_code code = GET_CODE (operands[1]);
2512     if (code == UNEQ || code == LTGT)
2513       FAIL;
2515     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2516                                   XEXP (operands[1], 1));
2517     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2518   }
2521 (define_expand "mov<mode>cc"
2522   [(set (match_operand:GPF 0 "register_operand" "")
2523         (if_then_else:GPF (match_operand 1 "aarch64_comparison_operator" "")
2524                           (match_operand:GPF 2 "register_operand" "")
2525                           (match_operand:GPF 3 "register_operand" "")))]
2526   ""
2527   {
2528     rtx ccreg;
2529     enum rtx_code code = GET_CODE (operands[1]);
2531     if (code == UNEQ || code == LTGT)
2532       FAIL;
2534     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2535                                   XEXP (operands[1], 1));
2536     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2537   }
2541 ;; CRC32 instructions.
2542 (define_insn "aarch64_<crc_variant>"
2543   [(set (match_operand:SI 0 "register_operand" "=r")
2544         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2545                     (match_operand:<crc_mode> 2 "register_operand" "r")]
2546          CRC))]
2547   "TARGET_CRC32"
2548   {
2549     if (GET_MODE_BITSIZE (GET_MODE (operands[2])) >= 64)
2550       return "<crc_variant>\\t%w0, %w1, %x2";
2551     else
2552       return "<crc_variant>\\t%w0, %w1, %w2";
2553   }
2554   [(set_attr "type" "crc")]
2557 (define_insn "*csinc2<mode>_insn"
2558   [(set (match_operand:GPI 0 "register_operand" "=r")
2559         (plus:GPI (match_operand 2 "aarch64_comparison_operation" "")
2560                   (match_operand:GPI 1 "register_operand" "r")))]
2561   ""
2562   "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2563   [(set_attr "type" "csel")]
2566 (define_insn "csinc3<mode>_insn"
2567   [(set (match_operand:GPI 0 "register_operand" "=r")
2568         (if_then_else:GPI
2569           (match_operand 1 "aarch64_comparison_operation" "")
2570           (plus:GPI (match_operand:GPI 2 "register_operand" "r")
2571                     (const_int 1))
2572           (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2573   ""
2574   "csinc\\t%<w>0, %<w>3, %<w>2, %M1"
2575   [(set_attr "type" "csel")]
2578 (define_insn "*csinv3<mode>_insn"
2579   [(set (match_operand:GPI 0 "register_operand" "=r")
2580         (if_then_else:GPI
2581           (match_operand 1 "aarch64_comparison_operation" "")
2582           (not:GPI (match_operand:GPI 2 "register_operand" "r"))
2583           (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2584   ""
2585   "csinv\\t%<w>0, %<w>3, %<w>2, %M1"
2586   [(set_attr "type" "csel")]
2589 (define_insn "*csneg3<mode>_insn"
2590   [(set (match_operand:GPI 0 "register_operand" "=r")
2591         (if_then_else:GPI
2592           (match_operand 1 "aarch64_comparison_operation" "")
2593           (neg:GPI (match_operand:GPI 2 "register_operand" "r"))
2594           (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2595   ""
2596   "csneg\\t%<w>0, %<w>3, %<w>2, %M1"
2597   [(set_attr "type" "csel")]
2600 ;; -------------------------------------------------------------------
2601 ;; Logical operations
2602 ;; -------------------------------------------------------------------
2604 (define_insn "<optab><mode>3"
2605   [(set (match_operand:GPI 0 "register_operand" "=r,rk,w")
2606         (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r,w")
2607                      (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>,w")))]
2608   ""
2609   "@
2610   <logical>\\t%<w>0, %<w>1, %<w>2
2611   <logical>\\t%<w>0, %<w>1, %<w>2
2612   <logical>\\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
2613   [(set_attr "type" "logic_reg,logic_imm,neon_logic")
2614    (set_attr "simd" "*,*,yes")]
2617 ;; zero_extend version of above
2618 (define_insn "*<optab>si3_uxtw"
2619   [(set (match_operand:DI 0 "register_operand" "=r,rk")
2620         (zero_extend:DI
2621          (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2622                      (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2623   ""
2624   "<logical>\\t%w0, %w1, %w2"
2625   [(set_attr "type" "logic_reg,logic_imm")]
2628 (define_insn "*and<mode>3_compare0"
2629   [(set (reg:CC_NZ CC_REGNUM)
2630         (compare:CC_NZ
2631          (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2632                   (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2633          (const_int 0)))
2634    (set (match_operand:GPI 0 "register_operand" "=r,r")
2635         (and:GPI (match_dup 1) (match_dup 2)))]
2636   ""
2637   "ands\\t%<w>0, %<w>1, %<w>2"
2638   [(set_attr "type" "logics_reg,logics_imm")]
2641 ;; zero_extend version of above
2642 (define_insn "*andsi3_compare0_uxtw"
2643   [(set (reg:CC_NZ CC_REGNUM)
2644         (compare:CC_NZ
2645          (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2646                  (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2647          (const_int 0)))
2648    (set (match_operand:DI 0 "register_operand" "=r,r")
2649         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2650   ""
2651   "ands\\t%w0, %w1, %w2"
2652   [(set_attr "type" "logics_reg,logics_imm")]
2655 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2656   [(set (reg:CC_NZ CC_REGNUM)
2657         (compare:CC_NZ
2658          (and:GPI (SHIFT:GPI
2659                    (match_operand:GPI 1 "register_operand" "r")
2660                    (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2661                   (match_operand:GPI 3 "register_operand" "r"))
2662          (const_int 0)))
2663    (set (match_operand:GPI 0 "register_operand" "=r")
2664         (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2665   ""
2666   "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2667   [(set_attr "type" "logics_shift_imm")]
2670 ;; zero_extend version of above
2671 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2672   [(set (reg:CC_NZ CC_REGNUM)
2673         (compare:CC_NZ
2674          (and:SI (SHIFT:SI
2675                   (match_operand:SI 1 "register_operand" "r")
2676                   (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2677                  (match_operand:SI 3 "register_operand" "r"))
2678          (const_int 0)))
2679    (set (match_operand:DI 0 "register_operand" "=r")
2680         (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2681                                 (match_dup 3))))]
2682   ""
2683   "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2684   [(set_attr "type" "logics_shift_imm")]
2687 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2688   [(set (match_operand:GPI 0 "register_operand" "=r")
2689         (LOGICAL:GPI (SHIFT:GPI
2690                       (match_operand:GPI 1 "register_operand" "r")
2691                       (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2692                      (match_operand:GPI 3 "register_operand" "r")))]
2693   ""
2694   "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2695   [(set_attr "type" "logic_shift_imm")]
2698 (define_insn "*<optab>_rol<mode>3"
2699   [(set (match_operand:GPI 0 "register_operand" "=r")
2700         (LOGICAL:GPI (rotate:GPI
2701                       (match_operand:GPI 1 "register_operand" "r")
2702                       (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2703                      (match_operand:GPI 3 "register_operand" "r")))]
2704   ""
2705   "<logical>\\t%<w>0, %<w>3, %<w>1, ror (<sizen> - %2)"
2706   [(set_attr "type" "logic_shift_imm")]
2709 ;; zero_extend versions of above
2710 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
2711   [(set (match_operand:DI 0 "register_operand" "=r")
2712         (zero_extend:DI
2713          (LOGICAL:SI (SHIFT:SI
2714                       (match_operand:SI 1 "register_operand" "r")
2715                       (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2716                      (match_operand:SI 3 "register_operand" "r"))))]
2717   ""
2718   "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2719   [(set_attr "type" "logic_shift_imm")]
2722 (define_insn "*<optab>_rolsi3_uxtw"
2723   [(set (match_operand:DI 0 "register_operand" "=r")
2724         (zero_extend:DI
2725          (LOGICAL:SI (rotate:SI
2726                       (match_operand:SI 1 "register_operand" "r")
2727                       (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2728                      (match_operand:SI 3 "register_operand" "r"))))]
2729   ""
2730   "<logical>\\t%w0, %w3, %w1, ror (32 - %2)"
2731   [(set_attr "type" "logic_shift_imm")]
2734 (define_insn "one_cmpl<mode>2"
2735   [(set (match_operand:GPI 0 "register_operand" "=r,w")
2736         (not:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
2737   ""
2738   "@
2739   mvn\\t%<w>0, %<w>1
2740   mvn\\t%0.8b, %1.8b"
2741   [(set_attr "type" "logic_reg,neon_logic")
2742    (set_attr "simd" "*,yes")]
2745 (define_insn "*one_cmpl_<optab><mode>2"
2746   [(set (match_operand:GPI 0 "register_operand" "=r")
2747         (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
2748                             (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2749   ""
2750   "mvn\\t%<w>0, %<w>1, <shift> %2"
2751   [(set_attr "type" "logic_shift_imm")]
2754 ;; Binary logical operators negating one operand, i.e. (a & !b), (a | !b).
2756 (define_insn "*<NLOGICAL:optab>_one_cmpl<mode>3"
2757   [(set (match_operand:GPI 0 "register_operand" "=r,w")
2758         (NLOGICAL:GPI (not:GPI (match_operand:GPI 1 "register_operand" "r,w"))
2759                      (match_operand:GPI 2 "register_operand" "r,w")))]
2760   ""
2761   "@
2762   <NLOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1
2763   <NLOGICAL:nlogical>\\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>"
2764   [(set_attr "type" "logic_reg,neon_logic")
2765    (set_attr "simd" "*,yes")]
2768 ;; (xor (not a) b) is simplify_rtx-ed down to (not (xor a b)).
2769 ;; eon does not operate on SIMD registers so the vector variant must be split.
2770 (define_insn_and_split "*xor_one_cmpl<mode>3"
2771   [(set (match_operand:GPI 0 "register_operand" "=r,w")
2772         (not:GPI (xor:GPI (match_operand:GPI 1 "register_operand" "r,?w")
2773                           (match_operand:GPI 2 "register_operand" "r,w"))))]
2774   ""
2775   "eon\\t%<w>0, %<w>1, %<w>2" ;; For GPR registers (only).
2776   "reload_completed && (which_alternative == 1)" ;; For SIMD registers.
2777   [(set (match_operand:GPI 0 "register_operand" "=w")
2778         (xor:GPI (match_operand:GPI 1 "register_operand" "w")
2779                  (match_operand:GPI 2 "register_operand" "w")))
2780    (set (match_dup 0) (not:GPI (match_dup 0)))]
2781   ""
2782   [(set_attr "type" "logic_reg,multiple")
2783    (set_attr "simd" "*,yes")]
2786 (define_insn "*and_one_cmpl<mode>3_compare0"
2787   [(set (reg:CC_NZ CC_REGNUM)
2788         (compare:CC_NZ
2789          (and:GPI (not:GPI
2790                    (match_operand:GPI 1 "register_operand" "r"))
2791                   (match_operand:GPI 2 "register_operand" "r"))
2792          (const_int 0)))
2793    (set (match_operand:GPI 0 "register_operand" "=r")
2794         (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
2795   ""
2796   "bics\\t%<w>0, %<w>2, %<w>1"
2797   [(set_attr "type" "logics_reg")]
2800 ;; zero_extend version of above
2801 (define_insn "*and_one_cmplsi3_compare0_uxtw"
2802   [(set (reg:CC_NZ CC_REGNUM)
2803         (compare:CC_NZ
2804          (and:SI (not:SI
2805                   (match_operand:SI 1 "register_operand" "r"))
2806                  (match_operand:SI 2 "register_operand" "r"))
2807          (const_int 0)))
2808    (set (match_operand:DI 0 "register_operand" "=r")
2809         (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
2810   ""
2811   "bics\\t%w0, %w2, %w1"
2812   [(set_attr "type" "logics_reg")]
2815 (define_insn "*and_one_cmpl<mode>3_compare0_no_reuse"
2816   [(set (reg:CC_NZ CC_REGNUM)
2817     (compare:CC_NZ
2818      (and:GPI (not:GPI
2819            (match_operand:GPI 0 "register_operand" "r"))
2820           (match_operand:GPI 1 "register_operand" "r"))
2821      (const_int 0)))]
2822   ""
2823   "bics\\t<w>zr, %<w>1, %<w>0"
2824   [(set_attr "type" "logics_reg")]
2827 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
2828   [(set (match_operand:GPI 0 "register_operand" "=r")
2829         (LOGICAL:GPI (not:GPI
2830                       (SHIFT:GPI
2831                        (match_operand:GPI 1 "register_operand" "r")
2832                        (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2833                      (match_operand:GPI 3 "register_operand" "r")))]
2834   ""
2835   "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2836   [(set_attr "type" "logics_shift_imm")]
2839 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
2840   [(set (reg:CC_NZ CC_REGNUM)
2841         (compare:CC_NZ
2842          (and:GPI (not:GPI
2843                    (SHIFT:GPI
2844                     (match_operand:GPI 1 "register_operand" "r")
2845                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2846                   (match_operand:GPI 3 "register_operand" "r"))
2847          (const_int 0)))
2848    (set (match_operand:GPI 0 "register_operand" "=r")
2849         (and:GPI (not:GPI
2850                   (SHIFT:GPI
2851                    (match_dup 1) (match_dup 2))) (match_dup 3)))]
2852   ""
2853   "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2854   [(set_attr "type" "logics_shift_imm")]
2857 ;; zero_extend version of above
2858 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
2859   [(set (reg:CC_NZ CC_REGNUM)
2860         (compare:CC_NZ
2861          (and:SI (not:SI
2862                   (SHIFT:SI
2863                    (match_operand:SI 1 "register_operand" "r")
2864                    (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
2865                  (match_operand:SI 3 "register_operand" "r"))
2866          (const_int 0)))
2867    (set (match_operand:DI 0 "register_operand" "=r")
2868         (zero_extend:DI (and:SI
2869                          (not:SI
2870                           (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
2871   ""
2872   "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2873   [(set_attr "type" "logics_shift_imm")]
2876 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0_no_reuse"
2877   [(set (reg:CC_NZ CC_REGNUM)
2878     (compare:CC_NZ
2879      (and:GPI (not:GPI
2880            (SHIFT:GPI
2881             (match_operand:GPI 0 "register_operand" "r")
2882             (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n")))
2883           (match_operand:GPI 2 "register_operand" "r"))
2884      (const_int 0)))]
2885   ""
2886   "bics\\t<w>zr, %<w>2, %<w>0, <SHIFT:shift> %1"
2887   [(set_attr "type" "logics_shift_imm")]
2890 (define_insn "clz<mode>2"
2891   [(set (match_operand:GPI 0 "register_operand" "=r")
2892         (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
2893   ""
2894   "clz\\t%<w>0, %<w>1"
2895   [(set_attr "type" "clz")]
2898 (define_expand "ffs<mode>2"
2899   [(match_operand:GPI 0 "register_operand")
2900    (match_operand:GPI 1 "register_operand")]
2901   ""
2902   {
2903     rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
2904     rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
2906     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2907     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2908     emit_insn (gen_csinc3<mode>_insn (operands[0], x, operands[0], const0_rtx));
2909     DONE;
2910   }
2913 (define_insn "clrsb<mode>2"
2914   [(set (match_operand:GPI 0 "register_operand" "=r")
2915         (clrsb:GPI (match_operand:GPI 1 "register_operand" "r")))]
2916   ""
2917   "cls\\t%<w>0, %<w>1"
2918   [(set_attr "type" "clz")]
2921 (define_insn "rbit<mode>2"
2922   [(set (match_operand:GPI 0 "register_operand" "=r")
2923         (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
2924   ""
2925   "rbit\\t%<w>0, %<w>1"
2926   [(set_attr "type" "rbit")]
2929 (define_expand "ctz<mode>2"
2930   [(match_operand:GPI 0 "register_operand")
2931    (match_operand:GPI 1 "register_operand")]
2932   ""
2933   {
2934     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2935     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2936     DONE;
2937   }
2940 (define_insn "*and<mode>3nr_compare0"
2941   [(set (reg:CC_NZ CC_REGNUM)
2942         (compare:CC_NZ
2943          (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
2944                   (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
2945          (const_int 0)))]
2946   ""
2947   "tst\\t%<w>0, %<w>1"
2948   [(set_attr "type" "logics_reg")]
2951 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
2952   [(set (reg:CC_NZ CC_REGNUM)
2953         (compare:CC_NZ
2954          (and:GPI (SHIFT:GPI
2955                    (match_operand:GPI 0 "register_operand" "r")
2956                    (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2957                   (match_operand:GPI 2 "register_operand" "r"))
2958         (const_int 0)))]
2959   ""
2960   "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
2961   [(set_attr "type" "logics_shift_imm")]
2964 ;; -------------------------------------------------------------------
2965 ;; Shifts
2966 ;; -------------------------------------------------------------------
2968 (define_expand "<optab><mode>3"
2969   [(set (match_operand:GPI 0 "register_operand")
2970         (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
2971                     (match_operand:QI 2 "nonmemory_operand")))]
2972   ""
2973   {
2974     if (CONST_INT_P (operands[2]))
2975       {
2976         operands[2] = GEN_INT (INTVAL (operands[2])
2977                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2979         if (operands[2] == const0_rtx)
2980           {
2981             emit_insn (gen_mov<mode> (operands[0], operands[1]));
2982             DONE;
2983           }
2984       }
2985   }
2988 (define_expand "ashl<mode>3"
2989   [(set (match_operand:SHORT 0 "register_operand")
2990         (ashift:SHORT (match_operand:SHORT 1 "register_operand")
2991                       (match_operand:QI 2 "nonmemory_operand")))]
2992   ""
2993   {
2994     if (CONST_INT_P (operands[2]))
2995       {
2996         operands[2] = GEN_INT (INTVAL (operands[2])
2997                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2999         if (operands[2] == const0_rtx)
3000           {
3001             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3002             DONE;
3003           }
3004       }
3005     else
3006       FAIL;
3007   }
3010 (define_expand "rotr<mode>3"
3011   [(set (match_operand:GPI 0 "register_operand")
3012         (rotatert:GPI (match_operand:GPI 1 "register_operand")
3013                       (match_operand:QI 2 "nonmemory_operand")))]
3014   ""
3015   {
3016     if (CONST_INT_P (operands[2]))
3017       {
3018         operands[2] = GEN_INT (INTVAL (operands[2])
3019                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3021         if (operands[2] == const0_rtx)
3022           {
3023             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3024             DONE;
3025           }
3026       }
3027   }
3030 (define_expand "rotl<mode>3"
3031   [(set (match_operand:GPI 0 "register_operand")
3032         (rotatert:GPI (match_operand:GPI 1 "register_operand")
3033                       (match_operand:QI 2 "nonmemory_operand")))]
3034   ""
3035   {
3036     /* (SZ - cnt) % SZ == -cnt % SZ */
3037     if (CONST_INT_P (operands[2]))
3038       {
3039         operands[2] = GEN_INT ((-INTVAL (operands[2]))
3040                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3041         if (operands[2] == const0_rtx)
3042           {
3043             emit_insn (gen_mov<mode> (operands[0], operands[1]));
3044             DONE;
3045           }
3046       }
3047     else
3048       operands[2] = expand_simple_unop (QImode, NEG, operands[2],
3049                                         NULL_RTX, 1);
3050   }
3053 ;; Logical left shift using SISD or Integer instruction
3054 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
3055   [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3056         (ashift:GPI
3057           (match_operand:GPI 1 "register_operand" "w,w,r")
3058           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3059   ""
3060   "@
3061    shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3062    ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
3063    lsl\t%<w>0, %<w>1, %<w>2"
3064   [(set_attr "simd" "yes,yes,no")
3065    (set_attr "type" "neon_shift_imm<q>, neon_shift_reg<q>,shift_reg")]
3068 ;; Logical right shift using SISD or Integer instruction
3069 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3070   [(set (match_operand:GPI 0 "register_operand" "=w,&w,r")
3071         (lshiftrt:GPI
3072           (match_operand:GPI 1 "register_operand" "w,w,r")
3073           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3074   ""
3075   "@
3076    ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3077    #
3078    lsr\t%<w>0, %<w>1, %<w>2"
3079   [(set_attr "simd" "yes,yes,no")
3080    (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")]
3083 (define_split
3084   [(set (match_operand:DI 0 "aarch64_simd_register")
3085         (lshiftrt:DI
3086            (match_operand:DI 1 "aarch64_simd_register")
3087            (match_operand:QI 2 "aarch64_simd_register")))]
3088   "TARGET_SIMD && reload_completed"
3089   [(set (match_dup 3)
3090         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3091    (set (match_dup 0)
3092         (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_USHL))]
3093   {
3094     operands[3] = gen_lowpart (QImode, operands[0]);
3095   }
3098 (define_split
3099   [(set (match_operand:SI 0 "aarch64_simd_register")
3100         (lshiftrt:SI
3101            (match_operand:SI 1 "aarch64_simd_register")
3102            (match_operand:QI 2 "aarch64_simd_register")))]
3103   "TARGET_SIMD && reload_completed"
3104   [(set (match_dup 3)
3105         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3106    (set (match_dup 0)
3107         (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_USHL_2S))]
3108   {
3109     operands[3] = gen_lowpart (QImode, operands[0]);
3110   }
3113 ;; Arithmetic right shift using SISD or Integer instruction
3114 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3115   [(set (match_operand:GPI 0 "register_operand" "=w,&w,&w,r")
3116         (ashiftrt:GPI
3117           (match_operand:GPI 1 "register_operand" "w,w,w,r")
3118           (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,0,rUs<cmode>")))]
3119   ""
3120   "@
3121    sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3122    #
3123    #
3124    asr\t%<w>0, %<w>1, %<w>2"
3125   [(set_attr "simd" "yes,yes,yes,no")
3126    (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>,shift_reg")]
3129 (define_split
3130   [(set (match_operand:DI 0 "aarch64_simd_register")
3131         (ashiftrt:DI
3132            (match_operand:DI 1 "aarch64_simd_register")
3133            (match_operand:QI 2 "aarch64_simd_register")))]
3134   "TARGET_SIMD && reload_completed"
3135   [(set (match_dup 3)
3136         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3137    (set (match_dup 0)
3138         (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_SSHL))]
3140   operands[3] = gen_lowpart (QImode, operands[0]);
3144 (define_split
3145   [(set (match_operand:SI 0 "aarch64_simd_register")
3146         (ashiftrt:SI
3147            (match_operand:SI 1 "aarch64_simd_register")
3148            (match_operand:QI 2 "aarch64_simd_register")))]
3149   "TARGET_SIMD && reload_completed"
3150   [(set (match_dup 3)
3151         (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3152    (set (match_dup 0)
3153         (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_SSHL_2S))]
3155   operands[3] = gen_lowpart (QImode, operands[0]);
3159 (define_insn "*aarch64_sisd_ushl"
3160   [(set (match_operand:DI 0 "register_operand" "=w")
3161         (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3162                     (match_operand:QI 2 "register_operand" "w")]
3163                    UNSPEC_SISD_USHL))]
3164   "TARGET_SIMD"
3165   "ushl\t%d0, %d1, %d2"
3166   [(set_attr "simd" "yes")
3167    (set_attr "type" "neon_shift_reg")]
3170 (define_insn "*aarch64_ushl_2s"
3171   [(set (match_operand:SI 0 "register_operand" "=w")
3172         (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3173                     (match_operand:QI 2 "register_operand" "w")]
3174                    UNSPEC_USHL_2S))]
3175   "TARGET_SIMD"
3176   "ushl\t%0.2s, %1.2s, %2.2s"
3177   [(set_attr "simd" "yes")
3178    (set_attr "type" "neon_shift_reg")]
3181 (define_insn "*aarch64_sisd_sshl"
3182   [(set (match_operand:DI 0 "register_operand" "=w")
3183         (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3184                     (match_operand:QI 2 "register_operand" "w")]
3185                    UNSPEC_SISD_SSHL))]
3186   "TARGET_SIMD"
3187   "sshl\t%d0, %d1, %d2"
3188   [(set_attr "simd" "yes")
3189    (set_attr "type" "neon_shift_reg")]
3192 (define_insn "*aarch64_sshl_2s"
3193   [(set (match_operand:SI 0 "register_operand" "=w")
3194         (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3195                     (match_operand:QI 2 "register_operand" "w")]
3196                    UNSPEC_SSHL_2S))]
3197   "TARGET_SIMD"
3198   "sshl\t%0.2s, %1.2s, %2.2s"
3199   [(set_attr "simd" "yes")
3200    (set_attr "type" "neon_shift_reg")]
3203 (define_insn "*aarch64_sisd_neg_qi"
3204   [(set (match_operand:QI 0 "register_operand" "=w")
3205         (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3206                    UNSPEC_SISD_NEG))]
3207   "TARGET_SIMD"
3208   "neg\t%d0, %d1"
3209   [(set_attr "simd" "yes")
3210    (set_attr "type" "neon_neg")]
3213 ;; Rotate right
3214 (define_insn "*ror<mode>3_insn"
3215   [(set (match_operand:GPI 0 "register_operand" "=r")
3216         (rotatert:GPI
3217           (match_operand:GPI 1 "register_operand" "r")
3218           (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3219   ""
3220   "ror\\t%<w>0, %<w>1, %<w>2"
3221   [(set_attr "type" "shift_reg")]
3224 ;; zero_extend version of above
3225 (define_insn "*<optab>si3_insn_uxtw"
3226   [(set (match_operand:DI 0 "register_operand" "=r")
3227         (zero_extend:DI (SHIFT:SI
3228          (match_operand:SI 1 "register_operand" "r")
3229          (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3230   ""
3231   "<shift>\\t%w0, %w1, %w2"
3232   [(set_attr "type" "shift_reg")]
3235 (define_insn "*<optab><mode>3_insn"
3236   [(set (match_operand:SHORT 0 "register_operand" "=r")
3237         (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3238                       (match_operand 2 "const_int_operand" "n")))]
3239   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3241   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3242   return "<bfshift>\t%w0, %w1, %2, %3";
3244   [(set_attr "type" "bfm")]
3247 (define_insn "*extr<mode>5_insn"
3248   [(set (match_operand:GPI 0 "register_operand" "=r")
3249         (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3250                              (match_operand 3 "const_int_operand" "n"))
3251                  (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3252                                (match_operand 4 "const_int_operand" "n"))))]
3253   "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3254    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3255   "extr\\t%<w>0, %<w>1, %<w>2, %4"
3256   [(set_attr "type" "shift_imm")]
3259 ;; zero_extend version of the above
3260 (define_insn "*extrsi5_insn_uxtw"
3261   [(set (match_operand:DI 0 "register_operand" "=r")
3262         (zero_extend:DI
3263          (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3264                             (match_operand 3 "const_int_operand" "n"))
3265                  (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3266                               (match_operand 4 "const_int_operand" "n")))))]
3267   "UINTVAL (operands[3]) < 32 &&
3268    (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3269   "extr\\t%w0, %w1, %w2, %4"
3270   [(set_attr "type" "shift_imm")]
3273 (define_insn "*ror<mode>3_insn"
3274   [(set (match_operand:GPI 0 "register_operand" "=r")
3275         (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3276                     (match_operand 2 "const_int_operand" "n")))]
3277   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3279   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3280   return "ror\\t%<w>0, %<w>1, %3";
3282   [(set_attr "type" "shift_imm")]
3285 ;; zero_extend version of the above
3286 (define_insn "*rorsi3_insn_uxtw"
3287   [(set (match_operand:DI 0 "register_operand" "=r")
3288         (zero_extend:DI
3289          (rotate:SI (match_operand:SI 1 "register_operand" "r")
3290                     (match_operand 2 "const_int_operand" "n"))))]
3291   "UINTVAL (operands[2]) < 32"
3293   operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3294   return "ror\\t%w0, %w1, %3";
3296   [(set_attr "type" "shift_imm")]
3299 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3300   [(set (match_operand:GPI 0 "register_operand" "=r")
3301         (ANY_EXTEND:GPI
3302          (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3303                        (match_operand 2 "const_int_operand" "n"))))]
3304   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3306   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3307   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3309   [(set_attr "type" "bfm")]
3312 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3313   [(set (match_operand:GPI 0 "register_operand" "=r")
3314         (zero_extend:GPI
3315          (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3316                          (match_operand 2 "const_int_operand" "n"))))]
3317   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3319   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3320   return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3322   [(set_attr "type" "bfm")]
3325 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3326   [(set (match_operand:GPI 0 "register_operand" "=r")
3327         (sign_extend:GPI
3328          (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3329                          (match_operand 2 "const_int_operand" "n"))))]
3330   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3332   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3333   return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3335   [(set_attr "type" "bfm")]
3338 ;; -------------------------------------------------------------------
3339 ;; Bitfields
3340 ;; -------------------------------------------------------------------
3342 (define_expand "<optab>"
3343   [(set (match_operand:DI 0 "register_operand" "=r")
3344         (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3345                         (match_operand 2 "const_int_operand" "n")
3346                         (match_operand 3 "const_int_operand" "n")))]
3347   ""
3348   ""
3351 (define_insn "*<optab><mode>"
3352   [(set (match_operand:GPI 0 "register_operand" "=r")
3353         (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3354                          (match_operand 2 "const_int_operand" "n")
3355                          (match_operand 3 "const_int_operand" "n")))]
3356   ""
3357   "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3358   [(set_attr "type" "bfm")]
3361 ;; Bitfield Insert (insv)
3362 (define_expand "insv<mode>"
3363   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3364                           (match_operand 1 "const_int_operand")
3365                           (match_operand 2 "const_int_operand"))
3366         (match_operand:GPI 3 "general_operand"))]
3367   ""
3369   unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3370   unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3371   rtx value = operands[3];
3373   if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3374     FAIL;
3376   if (CONST_INT_P (value))
3377     {
3378       unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3380       /* Prefer AND/OR for inserting all zeros or all ones.  */
3381       if ((UINTVAL (value) & mask) == 0
3382            || (UINTVAL (value) & mask) == mask)
3383         FAIL;
3385       /* 16-bit aligned 16-bit wide insert is handled by insv_imm.  */
3386       if (width == 16 && (pos % 16) == 0)
3387         DONE;
3388     }
3389   operands[3] = force_reg (<MODE>mode, value);
3392 (define_insn "*insv_reg<mode>"
3393   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3394                           (match_operand 1 "const_int_operand" "n")
3395                           (match_operand 2 "const_int_operand" "n"))
3396         (match_operand:GPI 3 "register_operand" "r"))]
3397   "!(UINTVAL (operands[1]) == 0
3398      || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3399          > GET_MODE_BITSIZE (<MODE>mode)))"
3400   "bfi\\t%<w>0, %<w>3, %2, %1"
3401   [(set_attr "type" "bfm")]
3404 (define_insn "*extr_insv_lower_reg<mode>"
3405   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3406                           (match_operand 1 "const_int_operand" "n")
3407                           (const_int 0))
3408         (zero_extract:GPI (match_operand:GPI 2 "register_operand" "r")
3409                           (match_dup 1)
3410                           (match_operand 3 "const_int_operand" "n")))]
3411   "!(UINTVAL (operands[1]) == 0
3412      || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3413          > GET_MODE_BITSIZE (<MODE>mode)))"
3414   "bfxil\\t%<w>0, %<w>2, %3, %1"
3415   [(set_attr "type" "bfm")]
3418 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3419   [(set (match_operand:GPI 0 "register_operand" "=r")
3420         (ashift:GPI (ANY_EXTEND:GPI
3421                      (match_operand:ALLX 1 "register_operand" "r"))
3422                     (match_operand 2 "const_int_operand" "n")))]
3423   "UINTVAL (operands[2]) < <GPI:sizen>"
3425   operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3426               ? GEN_INT (<ALLX:sizen>)
3427               : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3428   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3430   [(set_attr "type" "bfm")]
3433 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3435 (define_insn "*andim_ashift<mode>_bfiz"
3436   [(set (match_operand:GPI 0 "register_operand" "=r")
3437         (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3438                              (match_operand 2 "const_int_operand" "n"))
3439                  (match_operand 3 "const_int_operand" "n")))]
3440   "(INTVAL (operands[2]) < (<GPI:sizen>))
3441    && exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3442    && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3443   "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3444   [(set_attr "type" "bfm")]
3447 (define_insn "bswap<mode>2"
3448   [(set (match_operand:GPI 0 "register_operand" "=r")
3449         (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3450   ""
3451   "rev\\t%<w>0, %<w>1"
3452   [(set_attr "type" "rev")]
3455 (define_insn "bswaphi2"
3456   [(set (match_operand:HI 0 "register_operand" "=r")
3457         (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3458   ""
3459   "rev16\\t%w0, %w1"
3460   [(set_attr "type" "rev")]
3463 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
3464 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
3465 ;; each valid permutation.
3467 (define_insn "rev16<mode>2"
3468   [(set (match_operand:GPI 0 "register_operand" "=r")
3469         (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3470                                       (const_int 8))
3471                           (match_operand:GPI 3 "const_int_operand" "n"))
3472                  (and:GPI (lshiftrt:GPI (match_dup 1)
3473                                         (const_int 8))
3474                           (match_operand:GPI 2 "const_int_operand" "n"))))]
3475   "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3476    && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3477   "rev16\\t%<w>0, %<w>1"
3478   [(set_attr "type" "rev")]
3481 (define_insn "rev16<mode>2_alt"
3482   [(set (match_operand:GPI 0 "register_operand" "=r")
3483         (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r")
3484                                         (const_int 8))
3485                           (match_operand:GPI 2 "const_int_operand" "n"))
3486                  (and:GPI (ashift:GPI (match_dup 1)
3487                                       (const_int 8))
3488                           (match_operand:GPI 3 "const_int_operand" "n"))))]
3489   "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3490    && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3491   "rev16\\t%<w>0, %<w>1"
3492   [(set_attr "type" "rev")]
3495 ;; zero_extend version of above
3496 (define_insn "*bswapsi2_uxtw"
3497   [(set (match_operand:DI 0 "register_operand" "=r")
3498         (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3499   ""
3500   "rev\\t%w0, %w1"
3501   [(set_attr "type" "rev")]
3504 ;; -------------------------------------------------------------------
3505 ;; Floating-point intrinsics
3506 ;; -------------------------------------------------------------------
3508 ;; frint floating-point round to integral standard patterns.
3509 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round, frintn.
3511 (define_insn "<frint_pattern><mode>2"
3512   [(set (match_operand:GPF 0 "register_operand" "=w")
3513         (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3514          FRINT))]
3515   "TARGET_FLOAT"
3516   "frint<frint_suffix>\\t%<s>0, %<s>1"
3517   [(set_attr "type" "f_rint<s>")]
3520 ;; frcvt floating-point round to integer and convert standard patterns.
3521 ;; Expands to lbtrunc, lceil, lfloor, lround.
3522 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3523   [(set (match_operand:GPI 0 "register_operand" "=r")
3524         (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3525                       FCVT)))]
3526   "TARGET_FLOAT"
3527   "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3528   [(set_attr "type" "f_cvtf2i")]
3531 ;; fma - no throw
3533 (define_insn "fma<mode>4"
3534   [(set (match_operand:GPF 0 "register_operand" "=w")
3535         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3536                  (match_operand:GPF 2 "register_operand" "w")
3537                  (match_operand:GPF 3 "register_operand" "w")))]
3538   "TARGET_FLOAT"
3539   "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3540   [(set_attr "type" "fmac<s>")]
3543 (define_insn "fnma<mode>4"
3544   [(set (match_operand:GPF 0 "register_operand" "=w")
3545         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3546                  (match_operand:GPF 2 "register_operand" "w")
3547                  (match_operand:GPF 3 "register_operand" "w")))]
3548   "TARGET_FLOAT"
3549   "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3550   [(set_attr "type" "fmac<s>")]
3553 (define_insn "fms<mode>4"
3554   [(set (match_operand:GPF 0 "register_operand" "=w")
3555         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3556                  (match_operand:GPF 2 "register_operand" "w")
3557                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3558   "TARGET_FLOAT"
3559   "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3560   [(set_attr "type" "fmac<s>")]
3563 (define_insn "fnms<mode>4"
3564   [(set (match_operand:GPF 0 "register_operand" "=w")
3565         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3566                  (match_operand:GPF 2 "register_operand" "w")
3567                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3568   "TARGET_FLOAT"
3569   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3570   [(set_attr "type" "fmac<s>")]
3573 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3574 (define_insn "*fnmadd<mode>4"
3575   [(set (match_operand:GPF 0 "register_operand" "=w")
3576         (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3577                           (match_operand:GPF 2 "register_operand" "w")
3578                           (match_operand:GPF 3 "register_operand" "w"))))]
3579   "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3580   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3581   [(set_attr "type" "fmac<s>")]
3584 ;; -------------------------------------------------------------------
3585 ;; Floating-point conversions
3586 ;; -------------------------------------------------------------------
3588 (define_insn "extendsfdf2"
3589   [(set (match_operand:DF 0 "register_operand" "=w")
3590         (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3591   "TARGET_FLOAT"
3592   "fcvt\\t%d0, %s1"
3593   [(set_attr "type" "f_cvt")]
3596 (define_insn "truncdfsf2"
3597   [(set (match_operand:SF 0 "register_operand" "=w")
3598         (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3599   "TARGET_FLOAT"
3600   "fcvt\\t%s0, %d1"
3601   [(set_attr "type" "f_cvt")]
3604 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3605   [(set (match_operand:GPI 0 "register_operand" "=r")
3606         (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3607   "TARGET_FLOAT"
3608   "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3609   [(set_attr "type" "f_cvtf2i")]
3612 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3613   [(set (match_operand:GPI 0 "register_operand" "=r")
3614         (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3615   "TARGET_FLOAT"
3616   "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3617   [(set_attr "type" "f_cvtf2i")]
3620 (define_insn "<optab><fcvt_target><GPF:mode>2"
3621   [(set (match_operand:GPF 0 "register_operand" "=w,w")
3622         (FLOATUORS:GPF (match_operand:<FCVT_TARGET> 1 "register_operand" "w,r")))]
3623   ""
3624   "@
3625    <su_optab>cvtf\t%<GPF:s>0, %<s>1
3626    <su_optab>cvtf\t%<GPF:s>0, %<w1>1"
3627   [(set_attr "simd" "yes,no")
3628    (set_attr "fp" "no,yes")
3629    (set_attr "type" "neon_int_to_fp_<Vetype>,f_cvti2f")]
3632 (define_insn "<optab><fcvt_iesize><GPF:mode>2"
3633   [(set (match_operand:GPF 0 "register_operand" "=w")
3634         (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand" "r")))]
3635   "TARGET_FLOAT"
3636   "<su_optab>cvtf\t%<GPF:s>0, %<w2>1"
3637   [(set_attr "type" "f_cvti2f")]
3640 ;; -------------------------------------------------------------------
3641 ;; Floating-point arithmetic
3642 ;; -------------------------------------------------------------------
3644 (define_insn "add<mode>3"
3645   [(set (match_operand:GPF 0 "register_operand" "=w")
3646         (plus:GPF
3647          (match_operand:GPF 1 "register_operand" "w")
3648          (match_operand:GPF 2 "register_operand" "w")))]
3649   "TARGET_FLOAT"
3650   "fadd\\t%<s>0, %<s>1, %<s>2"
3651   [(set_attr "type" "fadd<s>")]
3654 (define_insn "sub<mode>3"
3655   [(set (match_operand:GPF 0 "register_operand" "=w")
3656         (minus:GPF
3657          (match_operand:GPF 1 "register_operand" "w")
3658          (match_operand:GPF 2 "register_operand" "w")))]
3659   "TARGET_FLOAT"
3660   "fsub\\t%<s>0, %<s>1, %<s>2"
3661   [(set_attr "type" "fadd<s>")]
3664 (define_insn "mul<mode>3"
3665   [(set (match_operand:GPF 0 "register_operand" "=w")
3666         (mult:GPF
3667          (match_operand:GPF 1 "register_operand" "w")
3668          (match_operand:GPF 2 "register_operand" "w")))]
3669   "TARGET_FLOAT"
3670   "fmul\\t%<s>0, %<s>1, %<s>2"
3671   [(set_attr "type" "fmul<s>")]
3674 (define_insn "*fnmul<mode>3"
3675   [(set (match_operand:GPF 0 "register_operand" "=w")
3676         (mult:GPF
3677                  (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3678                  (match_operand:GPF 2 "register_operand" "w")))]
3679   "TARGET_FLOAT"
3680   "fnmul\\t%<s>0, %<s>1, %<s>2"
3681   [(set_attr "type" "fmul<s>")]
3684 (define_insn "div<mode>3"
3685   [(set (match_operand:GPF 0 "register_operand" "=w")
3686         (div:GPF
3687          (match_operand:GPF 1 "register_operand" "w")
3688          (match_operand:GPF 2 "register_operand" "w")))]
3689   "TARGET_FLOAT"
3690   "fdiv\\t%<s>0, %<s>1, %<s>2"
3691   [(set_attr "type" "fdiv<s>")]
3694 (define_insn "neg<mode>2"
3695   [(set (match_operand:GPF 0 "register_operand" "=w")
3696         (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
3697   "TARGET_FLOAT"
3698   "fneg\\t%<s>0, %<s>1"
3699   [(set_attr "type" "ffarith<s>")]
3702 (define_insn "sqrt<mode>2"
3703   [(set (match_operand:GPF 0 "register_operand" "=w")
3704         (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
3705   "TARGET_FLOAT"
3706   "fsqrt\\t%<s>0, %<s>1"
3707   [(set_attr "type" "fsqrt<s>")]
3710 (define_insn "abs<mode>2"
3711   [(set (match_operand:GPF 0 "register_operand" "=w")
3712         (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
3713   "TARGET_FLOAT"
3714   "fabs\\t%<s>0, %<s>1"
3715   [(set_attr "type" "ffarith<s>")]
3718 ;; Given that smax/smin do not specify the result when either input is NaN,
3719 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
3720 ;; for smin.
3722 (define_insn "smax<mode>3"
3723   [(set (match_operand:GPF 0 "register_operand" "=w")
3724         (smax:GPF (match_operand:GPF 1 "register_operand" "w")
3725                   (match_operand:GPF 2 "register_operand" "w")))]
3726   "TARGET_FLOAT"
3727   "fmaxnm\\t%<s>0, %<s>1, %<s>2"
3728   [(set_attr "type" "f_minmax<s>")]
3731 (define_insn "smin<mode>3"
3732   [(set (match_operand:GPF 0 "register_operand" "=w")
3733         (smin:GPF (match_operand:GPF 1 "register_operand" "w")
3734                   (match_operand:GPF 2 "register_operand" "w")))]
3735   "TARGET_FLOAT"
3736   "fminnm\\t%<s>0, %<s>1, %<s>2"
3737   [(set_attr "type" "f_minmax<s>")]
3740 ;; -------------------------------------------------------------------
3741 ;; Reload support
3742 ;; -------------------------------------------------------------------
3744 (define_expand "aarch64_reload_mov<mode>"
3745   [(set (match_operand:TX 0 "register_operand" "=w")
3746         (match_operand:TX 1 "register_operand" "w"))
3747    (clobber (match_operand:DI 2 "register_operand" "=&r"))
3748   ]
3749   ""
3750   {
3751     rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
3752     rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
3753     gen_aarch64_movtilow_tilow (op0, op1);
3754     gen_aarch64_movdi_tihigh (operands[2], op1);
3755     gen_aarch64_movtihigh_di (op0, operands[2]);
3756     DONE;
3757   }
3760 ;; The following secondary reload helpers patterns are invoked
3761 ;; after or during reload as we don't want these patterns to start
3762 ;; kicking in during the combiner.
3764 (define_insn "aarch64_movdi_<mode>low"
3765   [(set (match_operand:DI 0 "register_operand" "=r")
3766         (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
3767   "reload_completed || reload_in_progress"
3768   "fmov\\t%x0, %d1"
3769   [(set_attr "type" "f_mrc")
3770    (set_attr "length" "4")
3771   ])
3773 (define_insn "aarch64_movdi_<mode>high"
3774   [(set (match_operand:DI 0 "register_operand" "=r")
3775         (truncate:DI
3776           (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
3777                        (const_int 64))))]
3778   "reload_completed || reload_in_progress"
3779   "fmov\\t%x0, %1.d[1]"
3780   [(set_attr "type" "f_mrc")
3781    (set_attr "length" "4")
3782   ])
3784 (define_insn "aarch64_mov<mode>high_di"
3785   [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
3786                          (const_int 64) (const_int 64))
3787         (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
3788   "reload_completed || reload_in_progress"
3789   "fmov\\t%0.d[1], %x1"
3790   [(set_attr "type" "f_mcr")
3791    (set_attr "length" "4")
3792   ])
3794 (define_insn "aarch64_mov<mode>low_di"
3795   [(set (match_operand:TX 0 "register_operand" "=w")
3796         (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
3797   "reload_completed || reload_in_progress"
3798   "fmov\\t%d0, %x1"
3799   [(set_attr "type" "f_mcr")
3800    (set_attr "length" "4")
3801   ])
3803 (define_insn "aarch64_movtilow_tilow"
3804   [(set (match_operand:TI 0 "register_operand" "=w")
3805         (zero_extend:TI 
3806           (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
3807   "reload_completed || reload_in_progress"
3808   "fmov\\t%d0, %d1"
3809   [(set_attr "type" "fmov")
3810    (set_attr "length" "4")
3811   ])
3813 ;; There is a deliberate reason why the parameters of high and lo_sum's
3814 ;; don't have modes for ADRP and ADD instructions.  This is to allow high
3815 ;; and lo_sum's to be used with the labels defining the jump tables in
3816 ;; rodata section.
3818 (define_expand "add_losym"
3819   [(set (match_operand 0 "register_operand" "=r")
3820         (lo_sum (match_operand 1 "register_operand" "r")
3821                 (match_operand 2 "aarch64_valid_symref" "S")))]
3822   ""
3824   enum machine_mode mode = GET_MODE (operands[0]);
3826   emit_insn ((mode == DImode
3827               ? gen_add_losym_di
3828               : gen_add_losym_si) (operands[0],
3829                                    operands[1],
3830                                    operands[2]));
3831   DONE;
3834 (define_insn "add_losym_<mode>"
3835   [(set (match_operand:P 0 "register_operand" "=r")
3836         (lo_sum:P (match_operand:P 1 "register_operand" "r")
3837                   (match_operand 2 "aarch64_valid_symref" "S")))]
3838   ""
3839   "add\\t%<w>0, %<w>1, :lo12:%a2"
3840   [(set_attr "type" "alu_reg")]
3843 (define_insn "ldr_got_small_<mode>"
3844   [(set (match_operand:PTR 0 "register_operand" "=r")
3845         (unspec:PTR [(mem:PTR (lo_sum:PTR
3846                               (match_operand:PTR 1 "register_operand" "r")
3847                               (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
3848                     UNSPEC_GOTSMALLPIC))]
3849   ""
3850   "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
3851   [(set_attr "type" "load1")]
3854 (define_insn "ldr_got_small_sidi"
3855   [(set (match_operand:DI 0 "register_operand" "=r")
3856         (zero_extend:DI
3857          (unspec:SI [(mem:SI (lo_sum:DI
3858                              (match_operand:DI 1 "register_operand" "r")
3859                              (match_operand:DI 2 "aarch64_valid_symref" "S")))]
3860                     UNSPEC_GOTSMALLPIC)))]
3861   "TARGET_ILP32"
3862   "ldr\\t%w0, [%1, #:got_lo12:%a2]"
3863   [(set_attr "type" "load1")]
3866 (define_insn "ldr_got_tiny"
3867   [(set (match_operand:DI 0 "register_operand" "=r")
3868         (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
3869                    UNSPEC_GOTTINYPIC))]
3870   ""
3871   "ldr\\t%0, %L1"
3872   [(set_attr "type" "load1")]
3875 (define_insn "aarch64_load_tp_hard"
3876   [(set (match_operand:DI 0 "register_operand" "=r")
3877         (unspec:DI [(const_int 0)] UNSPEC_TLS))]
3878   ""
3879   "mrs\\t%0, tpidr_el0"
3880   [(set_attr "type" "mrs")]
3883 ;; The TLS ABI specifically requires that the compiler does not schedule
3884 ;; instructions in the TLS stubs, in order to enable linker relaxation.
3885 ;; Therefore we treat the stubs as an atomic sequence.
3886 (define_expand "tlsgd_small"
3887  [(parallel [(set (match_operand 0 "register_operand" "")
3888                   (call (mem:DI (match_dup 2)) (const_int 1)))
3889              (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
3890              (clobber (reg:DI LR_REGNUM))])]
3891  ""
3893   operands[2] = aarch64_tls_get_addr ();
3896 (define_insn "*tlsgd_small"
3897   [(set (match_operand 0 "register_operand" "")
3898         (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
3899    (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
3900    (clobber (reg:DI LR_REGNUM))
3901   ]
3902   ""
3903   "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
3904   [(set_attr "type" "call")
3905    (set_attr "length" "16")])
3907 (define_insn "tlsie_small_<mode>"
3908   [(set (match_operand:PTR 0 "register_operand" "=r")
3909         (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
3910                    UNSPEC_GOTSMALLTLS))]
3911   ""
3912   "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
3913   [(set_attr "type" "load1")
3914    (set_attr "length" "8")]
3917 (define_insn "tlsie_small_sidi"
3918   [(set (match_operand:DI 0 "register_operand" "=r")
3919         (zero_extend:DI
3920           (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")]
3921                       UNSPEC_GOTSMALLTLS)))]
3922   ""
3923   "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
3924   [(set_attr "type" "load1")
3925    (set_attr "length" "8")]
3928 (define_expand "tlsle_small"
3929   [(set (match_operand 0 "register_operand" "=r")
3930         (unspec [(match_operand 1 "register_operand" "r")
3931                    (match_operand 2 "aarch64_tls_le_symref" "S")]
3932                    UNSPEC_GOTSMALLTLS))]
3933   ""
3935   enum machine_mode mode = GET_MODE (operands[0]);
3936   emit_insn ((mode == DImode
3937               ? gen_tlsle_small_di
3938               : gen_tlsle_small_si) (operands[0],
3939                                      operands[1],
3940                                      operands[2]));
3941   DONE;
3944 (define_insn "tlsle_small_<mode>"
3945   [(set (match_operand:P 0 "register_operand" "=r")
3946         (unspec:P [(match_operand:P 1 "register_operand" "r")
3947                    (match_operand 2 "aarch64_tls_le_symref" "S")]
3948                    UNSPEC_GOTSMALLTLS))]
3949   ""
3950   "add\\t%<w>0, %<w>1, #%G2\;add\\t%<w>0, %<w>0, #%L2"
3951   [(set_attr "type" "alu_reg")
3952    (set_attr "length" "8")]
3955 (define_insn "tlsdesc_small_<mode>"
3956   [(set (reg:PTR R0_REGNUM)
3957         (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
3958                    UNSPEC_TLSDESC))
3959    (clobber (reg:DI LR_REGNUM))
3960    (clobber (reg:CC CC_REGNUM))
3961    (clobber (match_scratch:DI 1 "=r"))]
3962   "TARGET_TLS_DESC"
3963   "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
3964   [(set_attr "type" "call")
3965    (set_attr "length" "16")])
3967 (define_insn "stack_tie"
3968   [(set (mem:BLK (scratch))
3969         (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
3970                      (match_operand:DI 1 "register_operand" "rk")]
3971                     UNSPEC_PRLG_STK))]
3972   ""
3973   ""
3974   [(set_attr "length" "0")]
3977 ;; Named pattern for expanding thread pointer reference.
3978 (define_expand "get_thread_pointerdi"
3979   [(match_operand:DI 0 "register_operand" "=r")]
3980   ""
3982   rtx tmp = aarch64_load_tp (operands[0]);
3983   if (tmp != operands[0])
3984     emit_move_insn (operands[0], tmp);
3985   DONE;
3988 ;; Named patterns for stack smashing protection.
3989 (define_expand "stack_protect_set"
3990   [(match_operand 0 "memory_operand")
3991    (match_operand 1 "memory_operand")]
3992   ""
3994   enum machine_mode mode = GET_MODE (operands[0]);
3996   emit_insn ((mode == DImode
3997               ? gen_stack_protect_set_di
3998               : gen_stack_protect_set_si) (operands[0], operands[1]));
3999   DONE;
4002 (define_insn "stack_protect_set_<mode>"
4003   [(set (match_operand:PTR 0 "memory_operand" "=m")
4004         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
4005          UNSPEC_SP_SET))
4006    (set (match_scratch:PTR 2 "=&r") (const_int 0))]
4007   ""
4008   "ldr\\t%<w>2, %1\;str\\t%<w>2, %0\;mov\t%<w>2,0"
4009   [(set_attr "length" "12")
4010    (set_attr "type" "multiple")])
4012 (define_expand "stack_protect_test"
4013   [(match_operand 0 "memory_operand")
4014    (match_operand 1 "memory_operand")
4015    (match_operand 2)]
4016   ""
4018   rtx result;
4019   enum machine_mode mode = GET_MODE (operands[0]);
4021   result = gen_reg_rtx(mode);
4023   emit_insn ((mode == DImode
4024               ? gen_stack_protect_test_di
4025               : gen_stack_protect_test_si) (result,
4026                                             operands[0],
4027                                             operands[1]));
4029   if (mode == DImode)
4030     emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4031                                     result, const0_rtx, operands[2]));
4032   else
4033     emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4034                                     result, const0_rtx, operands[2]));
4035   DONE;
4038 (define_insn "stack_protect_test_<mode>"
4039   [(set (match_operand:PTR 0 "register_operand" "=r")
4040         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
4041                      (match_operand:PTR 2 "memory_operand" "m")]
4042          UNSPEC_SP_TEST))
4043    (clobber (match_scratch:PTR 3 "=&r"))]
4044   ""
4045   "ldr\t%<w>3, %x1\;ldr\t%<w>0, %x2\;eor\t%<w>0, %<w>3, %<w>0"
4046   [(set_attr "length" "12")
4047    (set_attr "type" "multiple")])
4049 ;; Write Floating-point Control Register.
4050 (define_insn "set_fpcr"
4051   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
4052   ""
4053   "msr\\tfpcr, %0"
4054   [(set_attr "type" "mrs")])
4056 ;; Read Floating-point Control Register.
4057 (define_insn "get_fpcr"
4058   [(set (match_operand:SI 0 "register_operand" "=r")
4059         (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
4060   ""
4061   "mrs\\t%0, fpcr"
4062   [(set_attr "type" "mrs")])
4064 ;; Write Floating-point Status Register.
4065 (define_insn "set_fpsr"
4066   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
4067   ""
4068   "msr\\tfpsr, %0"
4069   [(set_attr "type" "mrs")])
4071 ;; Read Floating-point Status Register.
4072 (define_insn "get_fpsr"
4073   [(set (match_operand:SI 0 "register_operand" "=r")
4074         (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
4075   ""
4076   "mrs\\t%0, fpsr"
4077   [(set_attr "type" "mrs")])
4080 ;; Define the subtract-one-and-jump insns so loop.c
4081 ;; knows what to generate.
4082 (define_expand "doloop_end"
4083   [(use (match_operand 0 "" ""))      ; loop pseudo
4084    (use (match_operand 1 "" ""))]     ; label
4085   "optimize > 0 && flag_modulo_sched"
4087   rtx s0;
4088   rtx bcomp;
4089   rtx loc_ref;
4090   rtx cc_reg;
4091   rtx insn;
4092   rtx cmp;
4094   /* Currently SMS relies on the do-loop pattern to recognize loops
4095      where (1) the control part consists of all insns defining and/or
4096      using a certain 'count' register and (2) the loop count can be
4097      adjusted by modifying this register prior to the loop.
4098      ??? The possible introduction of a new block to initialize the
4099      new IV can potentially affect branch optimizations.  */
4101   if (GET_MODE (operands[0]) != DImode)
4102     FAIL;
4104   s0 = operands [0];
4105   insn = emit_insn (gen_adddi3_compare0 (s0, s0, GEN_INT (-1)));
4107   cmp = XVECEXP (PATTERN (insn), 0, 0);
4108   cc_reg = SET_DEST (cmp);
4109   bcomp = gen_rtx_NE (VOIDmode, cc_reg, const0_rtx);
4110   loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
4111   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4112                                gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
4113                                                      loc_ref, pc_rtx)));
4114   DONE;
4117 ;; AdvSIMD Stuff
4118 (include "aarch64-simd.md")
4120 ;; Atomic Operations
4121 (include "atomics.md")