2012-10-29 Andrew Pinski <apinski@cavium.com>
[official-gcc.git] / gcc / config / aarch64 / aarch64.md
blob804d7e746d258771708f7b3c90d6b0ea8ba083da
1 ;; Machine description for AArch64 architecture.
2 ;; Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
3 ;; Contributed by ARM Ltd.
4 ;;
5 ;; This file is part of GCC.
6 ;;
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
12 ;; GCC is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 ;; General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;; Register numbers
22 (define_constants
23   [
24     (R0_REGNUM          0)
25     (R1_REGNUM          1)
26     (R2_REGNUM          2)
27     (R3_REGNUM          3)
28     (R4_REGNUM          4)
29     (R5_REGNUM          5)
30     (R6_REGNUM          6)
31     (R7_REGNUM          7)
32     (R8_REGNUM          8)
33     (R9_REGNUM          9)
34     (R10_REGNUM         10)
35     (R11_REGNUM         11)
36     (R12_REGNUM         12)
37     (R13_REGNUM         13)
38     (R14_REGNUM         14)
39     (R15_REGNUM         15)
40     (R16_REGNUM         16)
41     (IP0_REGNUM         16)
42     (R17_REGNUM         17)
43     (IP1_REGNUM         17)
44     (R18_REGNUM         18)
45     (R19_REGNUM         19)
46     (R20_REGNUM         20)
47     (R21_REGNUM         21)
48     (R22_REGNUM         22)
49     (R23_REGNUM         23)
50     (R24_REGNUM         24)
51     (R25_REGNUM         25)
52     (R26_REGNUM         26)
53     (R27_REGNUM         27)
54     (R28_REGNUM         28)
55     (R29_REGNUM         29)
56     (R30_REGNUM         30)
57     (LR_REGNUM          30)
58     (SP_REGNUM          31)
59     (V0_REGNUM          32)
60     (V15_REGNUM         47)
61     (V31_REGNUM         63)
62     (SFP_REGNUM         64)
63     (AP_REGNUM          65)
64     (CC_REGNUM          66)
65   ]
68 (define_c_enum "unspec" [
69     UNSPEC_CASESI
70     UNSPEC_CLS
71     UNSPEC_FRINTA
72     UNSPEC_FRINTI
73     UNSPEC_FRINTM
74     UNSPEC_FRINTP
75     UNSPEC_FRINTX
76     UNSPEC_FRINTZ
77     UNSPEC_GOTSMALLPIC
78     UNSPEC_GOTSMALLTLS
79     UNSPEC_LD2
80     UNSPEC_LD3
81     UNSPEC_LD4
82     UNSPEC_MB
83     UNSPEC_NOP
84     UNSPEC_PRLG_STK
85     UNSPEC_RBIT
86     UNSPEC_ST2
87     UNSPEC_ST3
88     UNSPEC_ST4
89     UNSPEC_TLS
90     UNSPEC_TLSDESC
91     UNSPEC_VSTRUCTDUMMY
94 (define_c_enum "unspecv" [
95     UNSPECV_EH_RETURN           ; Represent EH_RETURN
96   ]
99 ;; If further include files are added the defintion of MD_INCLUDES
100 ;; must be updated.
102 (include "constraints.md")
103 (include "predicates.md")
104 (include "iterators.md")
106 ;; -------------------------------------------------------------------
107 ;; Synchronization Builtins
108 ;; -------------------------------------------------------------------
110 ;; The following sync_* attributes are applied to sychronization
111 ;; instruction patterns to control the way in which the
112 ;; synchronization loop is expanded.
113 ;; All instruction patterns that call aarch64_output_sync_insn ()
114 ;; should define these attributes.  Refer to the comment above
115 ;; aarch64.c:aarch64_output_sync_loop () for more detail on the use of
116 ;; these attributes.
118 ;; Attribute specifies the operand number which contains the
119 ;; result of a synchronization operation.  The result is the old value
120 ;; loaded from SYNC_MEMORY.
121 (define_attr "sync_result"          "none,0,1,2,3,4,5" (const_string "none"))
123 ;; Attribute specifies the operand number which contains the memory
124 ;; address to which the synchronization operation is being applied.
125 (define_attr "sync_memory"          "none,0,1,2,3,4,5" (const_string "none"))
127 ;; Attribute specifies the operand number which contains the required
128 ;; old value expected in the memory location.  This attribute may be
129 ;; none if no required value test should be performed in the expanded
130 ;; code.
131 (define_attr "sync_required_value"  "none,0,1,2,3,4,5" (const_string "none"))
133 ;; Attribute specifies the operand number of the new value to be stored
134 ;; into the memory location identitifed by the sync_memory attribute.
135 (define_attr "sync_new_value"       "none,0,1,2,3,4,5" (const_string "none"))
137 ;; Attribute specifies the operand number of a temporary register
138 ;; which can be clobbered by the synchronization instruction sequence.
139 ;; The register provided byn SYNC_T1 may be the same as SYNC_RESULT is
140 ;; which case the result value will be clobbered and not available
141 ;; after the synchronization loop exits.
142 (define_attr "sync_t1"              "none,0,1,2,3,4,5" (const_string "none"))
144 ;; Attribute specifies the operand number of a temporary register
145 ;; which can be clobbered by the synchronization instruction sequence.
146 ;; This register is used to collect the result of a store exclusive
147 ;; instruction.
148 (define_attr "sync_t2"              "none,0,1,2,3,4,5" (const_string "none"))
150 ;; Attribute that specifies whether or not the emitted synchronization
151 ;; loop must contain a release barrier.
152 (define_attr "sync_release_barrier" "yes,no"           (const_string "yes"))
154 ;; Attribute that specifies the operation that the synchronization
155 ;; loop should apply to the old and new values to generate the value
156 ;; written back to memory.
157 (define_attr "sync_op"              "none,add,sub,ior,xor,and,nand"
158                                     (const_string "none"))
160 ;; -------------------------------------------------------------------
161 ;; Instruction types and attributes
162 ;; -------------------------------------------------------------------
164 ;; Main data types used by the insntructions
166 (define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
167   (const_string "unknown"))
169 (define_attr "mode2" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
170   (const_string "unknown"))
172 ; The "v8type" attribute is used to for fine grained classification of
173 ; AArch64 instructions.  This table briefly explains the meaning of each type.
175 ; adc              add/subtract with carry.
176 ; adcs             add/subtract with carry (setting condition flags).
177 ; adr              calculate address.
178 ; alu              simple alu instruction (no memory or fp regs access).
179 ; alu_ext          simple alu instruction (sign/zero-extended register).
180 ; alu_shift        simple alu instruction, with a source operand shifted by a constant.
181 ; alus             simple alu instruction (setting condition flags).
182 ; alus_ext         simple alu instruction (sign/zero-extended register, setting condition flags).
183 ; alus_shift       simple alu instruction, with a source operand shifted by a constant (setting condition flags).
184 ; bfm              bitfield move operation.
185 ; branch           branch.
186 ; call             subroutine call.
187 ; ccmp             conditional compare.
188 ; clz              count leading zeros/sign bits.
189 ; csel             conditional select.
190 ; dmb              data memory barrier.
191 ; extend           sign/zero-extend (specialised bitfield move).
192 ; extr             extract register-sized bitfield encoding.
193 ; fpsimd_load      load single floating point / simd scalar register from memory.
194 ; fpsimd_load2     load pair of floating point / simd scalar registers from memory.
195 ; fpsimd_store     store single floating point / simd scalar register to memory.
196 ; fpsimd_store2    store pair floating point / simd scalar registers to memory.
197 ; fadd             floating point add/sub.
198 ; fccmp            floating point conditional compare.
199 ; fcmp             floating point comparison.
200 ; fconst           floating point load immediate.
201 ; fcsel            floating point conditional select.
202 ; fcvt             floating point convert (float to float).
203 ; fcvtf2i          floating point convert (float to integer).
204 ; fcvti2f          floating point convert (integer to float).
205 ; fdiv             floating point division operation.
206 ; ffarith          floating point abs, neg or cpy.
207 ; fmadd            floating point multiply-add/sub.
208 ; fminmax          floating point min/max.
209 ; fmov             floating point move (float to float).
210 ; fmovf2i          floating point move (float to integer).
211 ; fmovi2f          floating point move (integer to float).
212 ; fmul             floating point multiply.
213 ; frint            floating point round to integral.
214 ; fsqrt            floating point square root.
215 ; load_acq         load-acquire.
216 ; load             load single general register from memory
217 ; load2            load pair of general registers from memory
218 ; logic            logical operation (register).
219 ; logic_imm        and/or/xor operation (immediate).
220 ; logic_shift      logical operation with shift.
221 ; logics           logical operation (register, setting condition flags).
222 ; logics_imm       and/or/xor operation (immediate, setting condition flags).
223 ; logics_shift     logical operation with shift (setting condition flags).
224 ; madd             integer multiply-add/sub.
225 ; maddl            widening integer multiply-add/sub.
226 ; misc             miscellaneous - any type that doesn't fit into the rest.
227 ; move             integer move operation.
228 ; move2            double integer move operation.
229 ; movk             move 16-bit immediate with keep.
230 ; movz             move 16-bit immmediate with zero/one.
231 ; mrs              system/special register move.
232 ; mulh             64x64 to 128-bit multiply (high part).
233 ; mull             widening multiply.
234 ; mult             integer multiply instruction.
235 ; prefetch         memory prefetch.
236 ; rbit             reverse bits.
237 ; rev              reverse bytes.
238 ; sdiv             integer division operation (signed).
239 ; shift            variable shift operation.
240 ; shift_imm        immediate shift operation (specialised bitfield move).
241 ; store_rel        store-release.
242 ; store            store single general register to memory.
243 ; store2           store pair of general registers to memory.
244 ; udiv             integer division operation (unsigned).
246 (define_attr "v8type"
247    "adc,\
248    adcs,\
249    adr,\
250    alu,\
251    alu_ext,\
252    alu_shift,\
253    alus,\
254    alus_ext,\
255    alus_shift,\
256    bfm,\
257    branch,\
258    call,\
259    ccmp,\
260    clz,\
261    csel,\
262    dmb,\
263    div,\
264    div64,\
265    extend,\
266    extr,\
267    fpsimd_load,\
268    fpsimd_load2,\
269    fpsimd_store2,\
270    fpsimd_store,\
271    fadd,\
272    fccmp,\
273    fcvt,\
274    fcvtf2i,\
275    fcvti2f,\
276    fcmp,\
277    fconst,\
278    fcsel,\
279    fdiv,\
280    ffarith,\
281    fmadd,\
282    fminmax,\
283    fmov,\
284    fmovf2i,\
285    fmovi2f,\
286    fmul,\
287    frint,\
288    fsqrt,\
289    load_acq,\
290    load1,\
291    load2,\
292    logic,\
293    logic_imm,\
294    logic_shift,\
295    logics,\
296    logics_imm,\
297    logics_shift,\
298    madd,\
299    maddl,\
300    misc,\
301    move,\
302    move2,\
303    movk,\
304    movz,\
305    mrs,\
306    mulh,\
307    mull,\
308    mult,\
309    prefetch,\
310    rbit,\
311    rev,\
312    sdiv,\
313    shift,\
314    shift_imm,\
315    store_rel,\
316    store1,\
317    store2,\
318    udiv"
319   (const_string "alu"))
322 ; The "type" attribute is used by the AArch32 backend.  Below is a mapping
323 ; from "v8type" to "type".
325 (define_attr "type"
326   "alu,alu_shift,block,branch,call,f_2_r,f_cvt,f_flag,f_loads,
327    f_loadd,f_stored,f_stores,faddd,fadds,fcmpd,fcmps,fconstd,fconsts,
328    fcpys,fdivd,fdivs,ffarithd,ffariths,fmacd,fmacs,fmuld,fmuls,load_byte,
329    load1,load2,mult,r_2_f,store1,store2"
330   (cond [
331           (eq_attr "v8type" "alu_shift,alus_shift,logic_shift,logics_shift") (const_string "alu_shift")
332           (eq_attr "v8type" "branch") (const_string "branch")
333           (eq_attr "v8type" "call") (const_string "call")
334           (eq_attr "v8type" "fmovf2i") (const_string "f_2_r")
335           (eq_attr "v8type" "fcvt,fcvtf2i,fcvti2f") (const_string "f_cvt")
336           (and (eq_attr "v8type" "fpsimd_load") (eq_attr "mode" "SF")) (const_string "f_loads")
337           (and (eq_attr "v8type" "fpsimd_load") (eq_attr "mode" "DF")) (const_string "f_loadd")
338           (and (eq_attr "v8type" "fpsimd_store") (eq_attr "mode" "SF")) (const_string "f_stores")
339           (and (eq_attr "v8type" "fpsimd_store") (eq_attr "mode" "DF")) (const_string "f_stored")
340           (and (eq_attr "v8type" "fadd,fminmax") (eq_attr "mode" "DF")) (const_string "faddd")
341           (and (eq_attr "v8type" "fadd,fminmax") (eq_attr "mode" "SF")) (const_string "fadds")
342           (and (eq_attr "v8type" "fcmp,fccmp") (eq_attr "mode" "DF")) (const_string "fcmpd")
343           (and (eq_attr "v8type" "fcmp,fccmp") (eq_attr "mode" "SF")) (const_string "fcmps")
344           (and (eq_attr "v8type" "fconst") (eq_attr "mode" "DF")) (const_string "fconstd")
345           (and (eq_attr "v8type" "fconst") (eq_attr "mode" "SF")) (const_string "fconsts")
346           (and (eq_attr "v8type" "fdiv,fsqrt") (eq_attr "mode" "DF")) (const_string "fdivd")
347           (and (eq_attr "v8type" "fdiv,fsqrt") (eq_attr "mode" "SF")) (const_string "fdivs")
348           (and (eq_attr "v8type" "ffarith") (eq_attr "mode" "DF")) (const_string "ffarithd")
349           (and (eq_attr "v8type" "ffarith") (eq_attr "mode" "SF")) (const_string "ffariths")
350           (and (eq_attr "v8type" "fmadd") (eq_attr "mode" "DF")) (const_string "fmacd")
351           (and (eq_attr "v8type" "fmadd") (eq_attr "mode" "SF")) (const_string "fmacs")
352           (and (eq_attr "v8type" "fmul") (eq_attr "mode" "DF")) (const_string "fmuld")
353           (and (eq_attr "v8type" "fmul") (eq_attr "mode" "SF")) (const_string "fmuls")
354           (and (eq_attr "v8type" "load1") (eq_attr "mode" "QI,HI")) (const_string "load_byte")
355           (and (eq_attr "v8type" "load1") (eq_attr "mode" "SI,DI,TI")) (const_string "load1")
356           (eq_attr "v8type" "load2") (const_string "load2")
357           (and (eq_attr "v8type" "mulh,mult,mull,madd,sdiv,udiv") (eq_attr "mode" "SI")) (const_string "mult")
358           (eq_attr "v8type" "fmovi2f") (const_string "r_2_f")
359           (eq_attr "v8type" "store1") (const_string "store1")
360           (eq_attr "v8type" "store2") (const_string "store2")
361   ]
362   (const_string "alu")))
364 ;; Attribute that specifies whether or not the instruction touches fp
365 ;; registers.
366 (define_attr "fp" "no,yes" (const_string "no"))
368 ;; Attribute that specifies whether or not the instruction touches simd
369 ;; registers.
370 (define_attr "simd" "no,yes" (const_string "no"))
372 (define_attr "length" ""
373   (cond [(not (eq_attr "sync_memory" "none"))
374            (symbol_ref "aarch64_sync_loop_insns (insn, operands) * 4")
375         ] (const_int 4)))
377 ;; Attribute that controls whether an alternative is enabled or not.
378 ;; Currently it is only used to disable alternatives which touch fp or simd
379 ;; registers when -mgeneral-regs-only is specified.
380 (define_attr "enabled" "no,yes"
381   (cond [(ior
382         (and (eq_attr "fp" "yes")
383              (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
384         (and (eq_attr "simd" "yes")
385              (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
386              (const_string "no")
387         ] (const_string "yes")))
389 ;; -------------------------------------------------------------------
390 ;; Pipeline descriptions and scheduling
391 ;; -------------------------------------------------------------------
393 ;; Processor types.
394 (include "aarch64-tune.md")
396 ;; Scheduling
397 (include "aarch64-generic.md")
398 (include "large.md")
399 (include "small.md")
401 ;; -------------------------------------------------------------------
402 ;; Jumps and other miscellaneous insns
403 ;; -------------------------------------------------------------------
405 (define_insn "indirect_jump"
406   [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
407   ""
408   "br\\t%0"
409   [(set_attr "v8type" "branch")]
412 (define_insn "jump"
413   [(set (pc) (label_ref (match_operand 0 "" "")))]
414   ""
415   "b\\t%l0"
416   [(set_attr "v8type" "branch")]
419 (define_expand "cbranch<mode>4"
420   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
421                             [(match_operand:GPI 1 "register_operand" "")
422                              (match_operand:GPI 2 "aarch64_plus_operand" "")])
423                            (label_ref (match_operand 3 "" ""))
424                            (pc)))]
425   ""
426   "
427   operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
428                                          operands[2]);
429   operands[2] = const0_rtx;
430   "
433 (define_expand "cbranch<mode>4"
434   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
435                             [(match_operand:GPF 1 "register_operand" "")
436                              (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
437                            (label_ref (match_operand 3 "" ""))
438                            (pc)))]
439   ""
440   "
441   operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
442                                          operands[2]);
443   operands[2] = const0_rtx;
444   "
447 (define_insn "*condjump"
448   [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
449                             [(match_operand 1 "cc_register" "") (const_int 0)])
450                            (label_ref (match_operand 2 "" ""))
451                            (pc)))]
452   ""
453   "b%m0\\t%l2"
454   [(set_attr "v8type" "branch")]
457 (define_expand "casesi"
458   [(match_operand:SI 0 "register_operand" "")   ; Index
459    (match_operand:SI 1 "const_int_operand" "")  ; Lower bound
460    (match_operand:SI 2 "const_int_operand" "")  ; Total range
461    (match_operand:DI 3 "" "")                   ; Table label
462    (match_operand:DI 4 "" "")]                  ; Out of range label
463   ""
464   {
465     if (operands[1] != const0_rtx)
466       {
467         rtx reg = gen_reg_rtx (SImode);
469         /* Canonical RTL says that if you have:
471            (minus (X) (CONST))
473            then this should be emitted as:
475            (plus (X) (-CONST))
477            The use of trunc_int_for_mode ensures that the resulting
478            constant can be represented in SImode, this is important
479            for the corner case where operand[1] is INT_MIN.  */
481         operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
483         if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
484               (operands[1], SImode))
485           operands[1] = force_reg (SImode, operands[1]);
486         emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
487         operands[0] = reg;
488       }
490     if (!aarch64_plus_operand (operands[2], SImode))
491       operands[2] = force_reg (SImode, operands[2]);
492     emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
493                                                  const0_rtx),
494                                     operands[0], operands[2], operands[4]));
496     operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
497     emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
498                                          operands[3]));
499     DONE;
500   }
503 (define_insn "casesi_dispatch"
504   [(parallel
505     [(set (pc)
506           (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
507                            (match_operand:SI 1 "register_operand" "r")]
508                         UNSPEC_CASESI)))
509      (clobber (reg:CC CC_REGNUM))
510      (clobber (match_scratch:DI 3 "=r"))
511      (clobber (match_scratch:DI 4 "=r"))
512      (use (label_ref (match_operand 2 "" "")))])]
513   ""
514   "*
515   return aarch64_output_casesi (operands);
516   "
517   [(set_attr "length" "16")
518    (set_attr "v8type" "branch")]
521 (define_insn "nop"
522   [(unspec[(const_int 0)] UNSPEC_NOP)]
523   ""
524   "nop"
525   [(set_attr "v8type" "misc")]
528 (define_expand "prologue"
529   [(clobber (const_int 0))]
530   ""
531   "
532   aarch64_expand_prologue ();
533   DONE;
534   "
537 (define_expand "epilogue"
538   [(clobber (const_int 0))]
539   ""
540   "
541   aarch64_expand_epilogue (false);
542   DONE;
543   "
546 (define_expand "sibcall_epilogue"
547   [(clobber (const_int 0))]
548   ""
549   "
550   aarch64_expand_epilogue (true);
551   DONE;
552   "
555 (define_insn "*do_return"
556   [(return)]
557   ""
558   "ret"
559   [(set_attr "v8type" "branch")]
562 (define_insn "eh_return"
563   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
564     UNSPECV_EH_RETURN)]
565   ""
566   "#"
567   [(set_attr "v8type" "branch")]
570 (define_split
571   [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
572     UNSPECV_EH_RETURN)]
573   "reload_completed"
574   [(set (match_dup 1) (match_dup 0))]
575   {
576     operands[1] = aarch64_final_eh_return_addr ();
577   }
580 (define_insn "*cb<optab><mode>1"
581   [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
582                                 (const_int 0))
583                            (label_ref (match_operand 1 "" ""))
584                            (pc)))]
585   ""
586   "<cbz>\\t%<w>0, %l1"
587   [(set_attr "v8type" "branch")]
590 (define_insn "*tb<optab><mode>1"
591   [(set (pc) (if_then_else
592               (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
593                                     (const_int 1)
594                                     (match_operand 1 "const_int_operand" "n"))
595                    (const_int 0))
596              (label_ref (match_operand 2 "" ""))
597              (pc)))
598    (clobber (match_scratch:DI 3 "=r"))]
599   ""
600   "*
601   if (get_attr_length (insn) == 8)
602     return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
603   return \"<tbz>\\t%<w>0, %1, %l2\";
604   "
605   [(set_attr "v8type" "branch")
606    (set_attr "mode" "<MODE>")
607    (set (attr "length")
608         (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
609                            (lt (minus (match_dup 2) (pc)) (const_int 32764)))
610                       (const_int 4)
611                       (const_int 8)))]
614 (define_insn "*cb<optab><mode>1"
615   [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
616                                  (const_int 0))
617                            (label_ref (match_operand 1 "" ""))
618                            (pc)))
619    (clobber (match_scratch:DI 2 "=r"))]
620   ""
621   "*
622   if (get_attr_length (insn) == 8)
623     return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
624   return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
625   "
626   [(set_attr "v8type" "branch")
627    (set_attr "mode" "<MODE>")
628    (set (attr "length")
629         (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
630                            (lt (minus (match_dup 1) (pc)) (const_int 32764)))
631                       (const_int 4)
632                       (const_int 8)))]
635 ;; -------------------------------------------------------------------
636 ;; Subroutine calls and sibcalls
637 ;; -------------------------------------------------------------------
639 (define_expand "call"
640   [(parallel [(call (match_operand 0 "memory_operand" "")
641                     (match_operand 1 "general_operand" ""))
642               (use (match_operand 2 "" ""))
643               (clobber (reg:DI LR_REGNUM))])]
644   ""
645   "
646   {
647     rtx callee;
649     /* In an untyped call, we can get NULL for operand 2.  */
650     if (operands[2] == NULL)
651       operands[2] = const0_rtx;
653     /* Decide if we should generate indirect calls by loading the
654        64-bit address of the callee into a register before performing
655        the branch-and-link.  */
656     callee = XEXP (operands[0], 0);
657     if (GET_CODE (callee) == SYMBOL_REF
658         ? aarch64_is_long_call_p (callee)
659         : !REG_P (callee))
660       XEXP (operands[0], 0) = force_reg (Pmode, callee);
661   }"
664 (define_insn "*call_reg"
665   [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
666          (match_operand 1 "" ""))
667    (use (match_operand 2 "" ""))
668    (clobber (reg:DI LR_REGNUM))]
669   ""
670   "blr\\t%0"
671   [(set_attr "v8type" "call")]
674 (define_insn "*call_symbol"
675   [(call (mem:DI (match_operand:DI 0 "" ""))
676          (match_operand 1 "" ""))
677    (use (match_operand 2 "" ""))
678    (clobber (reg:DI LR_REGNUM))]
679   "GET_CODE (operands[0]) == SYMBOL_REF
680    && !aarch64_is_long_call_p (operands[0])"
681   "bl\\t%a0"
682   [(set_attr "v8type" "call")]
685 (define_expand "call_value"
686   [(parallel [(set (match_operand 0 "" "")
687                    (call (match_operand 1 "memory_operand" "")
688                          (match_operand 2 "general_operand" "")))
689               (use (match_operand 3 "" ""))
690               (clobber (reg:DI LR_REGNUM))])]
691   ""
692   "
693   {
694     rtx callee;
696     /* In an untyped call, we can get NULL for operand 3.  */
697     if (operands[3] == NULL)
698       operands[3] = const0_rtx;
700     /* Decide if we should generate indirect calls by loading the
701        64-bit address of the callee into a register before performing
702        the branch-and-link.  */
703     callee = XEXP (operands[1], 0);
704     if (GET_CODE (callee) == SYMBOL_REF
705         ? aarch64_is_long_call_p (callee)
706         : !REG_P (callee))
707       XEXP (operands[1], 0) = force_reg (Pmode, callee);
708   }"
711 (define_insn "*call_value_reg"
712   [(set (match_operand 0 "" "")
713         (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
714                       (match_operand 2 "" "")))
715    (use (match_operand 3 "" ""))
716    (clobber (reg:DI LR_REGNUM))]
717   ""
718   "blr\\t%1"
719   [(set_attr "v8type" "call")]
722 (define_insn "*call_value_symbol"
723   [(set (match_operand 0 "" "")
724         (call (mem:DI (match_operand:DI 1 "" ""))
725               (match_operand 2 "" "")))
726    (use (match_operand 3 "" ""))
727    (clobber (reg:DI LR_REGNUM))]
728   "GET_CODE (operands[1]) == SYMBOL_REF
729    && !aarch64_is_long_call_p (operands[1])"
730   "bl\\t%a1"
731   [(set_attr "v8type" "call")]
734 (define_expand "sibcall"
735   [(parallel [(call (match_operand 0 "memory_operand" "")
736                     (match_operand 1 "general_operand" ""))
737               (return)
738               (use (match_operand 2 "" ""))])]
739   ""
740   {
741     if (operands[2] == NULL_RTX)
742       operands[2] = const0_rtx;
743   }
746 (define_expand "sibcall_value"
747   [(parallel [(set (match_operand 0 "" "")
748                    (call (match_operand 1 "memory_operand" "")
749                          (match_operand 2 "general_operand" "")))
750               (return)
751               (use (match_operand 3 "" ""))])]
752   ""
753   {
754     if (operands[3] == NULL_RTX)
755       operands[3] = const0_rtx;
756   }
759 (define_insn "*sibcall_insn"
760   [(call (mem:DI (match_operand:DI 0 "" "X"))
761          (match_operand 1 "" ""))
762    (return)
763    (use (match_operand 2 "" ""))]
764   "GET_CODE (operands[0]) == SYMBOL_REF"
765   "b\\t%a0"
766   [(set_attr "v8type" "branch")]
769 (define_insn "*sibcall_value_insn"
770   [(set (match_operand 0 "" "")
771         (call (mem:DI (match_operand 1 "" "X"))
772               (match_operand 2 "" "")))
773    (return)
774    (use (match_operand 3 "" ""))]
775   "GET_CODE (operands[1]) == SYMBOL_REF"
776   "b\\t%a1"
777   [(set_attr "v8type" "branch")]
780 ;; Call subroutine returning any type.
782 (define_expand "untyped_call"
783   [(parallel [(call (match_operand 0 "")
784                     (const_int 0))
785               (match_operand 1 "")
786               (match_operand 2 "")])]
787   ""
789   int i;
791   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
793   for (i = 0; i < XVECLEN (operands[2], 0); i++)
794     {
795       rtx set = XVECEXP (operands[2], 0, i);
796       emit_move_insn (SET_DEST (set), SET_SRC (set));
797     }
799   /* The optimizer does not know that the call sets the function value
800      registers we stored in the result block.  We avoid problems by
801      claiming that all hard registers are used and clobbered at this
802      point.  */
803   emit_insn (gen_blockage ());
804   DONE;
807 ;; -------------------------------------------------------------------
808 ;; Moves
809 ;; -------------------------------------------------------------------
811 (define_expand "mov<mode>"
812   [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
813         (match_operand:SHORT 1 "general_operand" ""))]
814   ""
815   "
816     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
817       operands[1] = force_reg (<MODE>mode, operands[1]);
818   "
821 (define_insn "*mov<mode>_aarch64"
822   [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r,r,m,  r,*w")
823         (match_operand:SHORT 1 "general_operand"      " r,M,m,rZ,*w,r"))]
824   "(register_operand (operands[0], <MODE>mode)
825     || aarch64_reg_or_zero (operands[1], <MODE>mode))"
826   "@
827    mov\\t%w0, %w1
828    mov\\t%w0, %1
829    ldr<size>\\t%w0, %1
830    str<size>\\t%w1, %0
831    umov\\t%w0, %1.<v>[0]
832    dup\\t%0.<Vallxd>, %w1"
833   [(set_attr "v8type" "move,alu,load1,store1,*,*")
834    (set_attr "simd_type" "*,*,*,*,simd_movgp,simd_dupgp")
835    (set_attr "mode" "<MODE>")
836    (set_attr "simd_mode" "<MODE>")]
839 (define_expand "mov<mode>"
840   [(set (match_operand:GPI 0 "nonimmediate_operand" "")
841         (match_operand:GPI 1 "general_operand" ""))]
842   ""
843   "
844     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
845       operands[1] = force_reg (<MODE>mode, operands[1]);
847     if (CONSTANT_P (operands[1]))
848       {
849         aarch64_expand_mov_immediate (operands[0], operands[1]);
850         DONE;
851       }
852   "
855 (define_insn "*movsi_aarch64"
856   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m, *w, r,*w")
857         (match_operand:SI 1 "aarch64_mov_operand"     " r,M,m,rZ,rZ,*w,*w"))]
858   "(register_operand (operands[0], SImode)
859     || aarch64_reg_or_zero (operands[1], SImode))"
860   "@
861    mov\\t%w0, %w1
862    mov\\t%w0, %1
863    ldr\\t%w0, %1
864    str\\t%w1, %0
865    fmov\\t%s0, %w1
866    fmov\\t%w0, %s1
867    fmov\\t%s0, %s1"
868   [(set_attr "v8type" "move,alu,load1,store1,fmov,fmov,fmov")
869    (set_attr "mode" "SI")
870    (set_attr "fp" "*,*,*,*,yes,yes,yes")]
873 (define_insn "*movdi_aarch64"
874   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,m, r,  r,  *w, r,*w,w")
875         (match_operand:DI 1 "aarch64_mov_operand"  " r,r,k,N,m,rZ,Usa,Ush,rZ,*w,*w,Dd"))]
876   "(register_operand (operands[0], DImode)
877     || aarch64_reg_or_zero (operands[1], DImode))"
878   "@
879    mov\\t%x0, %x1
880    mov\\t%0, %x1
881    mov\\t%x0, %1
882    mov\\t%x0, %1
883    ldr\\t%x0, %1
884    str\\t%x1, %0
885    adr\\t%x0, %a1
886    adrp\\t%x0, %A1
887    fmov\\t%d0, %x1
888    fmov\\t%x0, %d1
889    fmov\\t%d0, %d1
890    movi\\t%d0, %1"
891   [(set_attr "v8type" "move,move,move,alu,load1,store1,adr,adr,fmov,fmov,fmov,fmov")
892    (set_attr "mode" "DI")
893    (set_attr "fp" "*,*,*,*,*,*,*,*,yes,yes,yes,yes")]
896 (define_insn "insv_imm<mode>"
897   [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
898                           (const_int 16)
899                           (match_operand 1 "const_int_operand" "n"))
900         (match_operand 2 "const_int_operand" "n"))]
901   "INTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
902    && INTVAL (operands[1]) % 16 == 0
903    && INTVAL (operands[2]) <= 0xffff"
904   "movk\\t%<w>0, %2, lsl %1"
905   [(set_attr "v8type" "movk")
906    (set_attr "mode" "<MODE>")]
909 (define_expand "movti"
910   [(set (match_operand:TI 0 "nonimmediate_operand" "")
911         (match_operand:TI 1 "general_operand" ""))]
912   ""
913   "
914     if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
915       operands[1] = force_reg (TImode, operands[1]);
916   "
919 (define_insn "*movti_aarch64"
920   [(set (match_operand:TI 0
921          "nonimmediate_operand"  "=r, *w,r ,*w,r  ,Ump,Ump,*w,m")
922         (match_operand:TI 1
923          "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r  ,Z  , m,*w"))]
924   "(register_operand (operands[0], TImode)
925     || aarch64_reg_or_zero (operands[1], TImode))"
926   "@
927    #
928    #
929    #
930    orr\\t%0.16b, %1.16b, %1.16b
931    ldp\\t%0, %H0, %1
932    stp\\t%1, %H1, %0
933    stp\\txzr, xzr, %0
934    ldr\\t%q0, %1
935    str\\t%q1, %0"
936   [(set_attr "v8type" "move2,fmovi2f,fmovf2i,*, \
937                        load2,store2,store2,fpsimd_load,fpsimd_store")
938    (set_attr "simd_type" "*,*,*,simd_move,*,*,*,*,*")
939    (set_attr "mode" "DI,DI,DI,TI,DI,DI,DI,TI,TI")
940    (set_attr "length" "8,8,8,4,4,4,4,4,4")
941    (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")
942    (set_attr "simd" "*,*,*,yes,*,*,*,*,*")])
944 ;; Split a TImode register-register or register-immediate move into
945 ;; its component DImode pieces, taking care to handle overlapping
946 ;; source and dest registers.
947 (define_split
948    [(set (match_operand:TI 0 "register_operand" "")
949          (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
950   "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
951   [(const_int 0)]
953   aarch64_split_128bit_move (operands[0], operands[1]);
954   DONE;
957 (define_expand "mov<mode>"
958   [(set (match_operand:GPF 0 "nonimmediate_operand" "")
959         (match_operand:GPF 1 "general_operand" ""))]
960   ""
961   "
962     if (!TARGET_FLOAT)
963      {
964         sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
965         FAIL;
966      }
968     if (GET_CODE (operands[0]) == MEM)
969       operands[1] = force_reg (<MODE>mode, operands[1]);
970   "
973 (define_insn "*movsf_aarch64"
974   [(set (match_operand:SF 0 "nonimmediate_operand" "= w,?r,w,w,m,r,m ,r")
975         (match_operand:SF 1 "general_operand"      "?rY, w,w,m,w,m,rY,r"))]
976   "TARGET_FLOAT && (register_operand (operands[0], SFmode)
977     || register_operand (operands[1], SFmode))"
978   "@
979    fmov\\t%s0, %w1
980    fmov\\t%w0, %s1
981    fmov\\t%s0, %s1
982    ldr\\t%s0, %1
983    str\\t%s1, %0
984    ldr\\t%w0, %1
985    str\\t%w1, %0
986    mov\\t%w0, %w1"
987   [(set_attr "v8type" "fmovi2f,fmovf2i,fmov,fpsimd_load,fpsimd_store,fpsimd_load,fpsimd_store,fmov")
988    (set_attr "mode" "SF")]
991 (define_insn "*movdf_aarch64"
992   [(set (match_operand:DF 0 "nonimmediate_operand" "= w,?r,w,w,m,r,m ,r")
993         (match_operand:DF 1 "general_operand"      "?rY, w,w,m,w,m,rY,r"))]
994   "TARGET_FLOAT && (register_operand (operands[0], DFmode)
995     || register_operand (operands[1], DFmode))"
996   "@
997    fmov\\t%d0, %x1
998    fmov\\t%x0, %d1
999    fmov\\t%d0, %d1
1000    ldr\\t%d0, %1
1001    str\\t%d1, %0
1002    ldr\\t%x0, %1
1003    str\\t%x1, %0
1004    mov\\t%x0, %x1"
1005   [(set_attr "v8type" "fmovi2f,fmovf2i,fmov,fpsimd_load,fpsimd_store,fpsimd_load,fpsimd_store,move")
1006    (set_attr "mode" "DF")]
1009 (define_expand "movtf"
1010   [(set (match_operand:TF 0 "nonimmediate_operand" "")
1011         (match_operand:TF 1 "general_operand" ""))]
1012   ""
1013   "
1014     if (!TARGET_FLOAT)
1015      {
1016         sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
1017         FAIL;
1018      }
1020     if (GET_CODE (operands[0]) == MEM)
1021       operands[1] = force_reg (TFmode, operands[1]);
1022   "
1025 (define_insn "*movtf_aarch64"
1026   [(set (match_operand:TF 0
1027          "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
1028         (match_operand:TF 1
1029          "general_operand"      " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
1030   "TARGET_FLOAT && (register_operand (operands[0], TFmode)
1031     || register_operand (operands[1], TFmode))"
1032   "@
1033    orr\\t%0.16b, %1.16b, %1.16b
1034    mov\\t%0, %1\;mov\\t%H0, %H1
1035    fmov\\t%d0, %Q1\;fmov\\t%0.d[1], %R1
1036    fmov\\t%Q0, %d1\;fmov\\t%R0, %1.d[1]
1037    movi\\t%0.2d, #0
1038    fmov\\t%s0, wzr
1039    ldr\\t%q0, %1
1040    str\\t%q1, %0
1041    ldp\\t%0, %H0, %1
1042    stp\\t%1, %H1, %0"
1043   [(set_attr "v8type" "logic,move2,fmovi2f,fmovf2i,fconst,fconst,fpsimd_load,fpsimd_store,fpsimd_load2,fpsimd_store2")
1044    (set_attr "mode" "DF,DF,DF,DF,DF,DF,TF,TF,DF,DF")
1045    (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
1046    (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
1047    (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
1051 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1052 ;; fairly lax checking on the second memory operation.
1053 (define_insn "load_pair<mode>"
1054   [(set (match_operand:GPI 0 "register_operand" "=r")
1055         (match_operand:GPI 1 "aarch64_mem_pair_operand" "Ump"))
1056    (set (match_operand:GPI 2 "register_operand" "=r")
1057         (match_operand:GPI 3 "memory_operand" "m"))]
1058   "rtx_equal_p (XEXP (operands[3], 0),
1059                 plus_constant (Pmode,
1060                                XEXP (operands[1], 0),
1061                                GET_MODE_SIZE (<MODE>mode)))"
1062   "ldp\\t%<w>0, %<w>2, %1"
1063   [(set_attr "v8type" "load2")
1064    (set_attr "mode" "<MODE>")]
1067 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1068 ;; fairly lax checking on the second memory operation.
1069 (define_insn "store_pair<mode>"
1070   [(set (match_operand:GPI 0 "aarch64_mem_pair_operand" "=Ump")
1071         (match_operand:GPI 1 "register_operand" "r"))
1072    (set (match_operand:GPI 2 "memory_operand" "=m")
1073         (match_operand:GPI 3 "register_operand" "r"))]
1074   "rtx_equal_p (XEXP (operands[2], 0),
1075                 plus_constant (Pmode,
1076                                XEXP (operands[0], 0),
1077                                GET_MODE_SIZE (<MODE>mode)))"
1078   "stp\\t%<w>1, %<w>3, %0"
1079   [(set_attr "v8type" "store2")
1080    (set_attr "mode" "<MODE>")]
1083 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1084 ;; fairly lax checking on the second memory operation.
1085 (define_insn "load_pair<mode>"
1086   [(set (match_operand:GPF 0 "register_operand" "=w")
1087         (match_operand:GPF 1 "aarch64_mem_pair_operand" "Ump"))
1088    (set (match_operand:GPF 2 "register_operand" "=w")
1089         (match_operand:GPF 3 "memory_operand" "m"))]
1090   "rtx_equal_p (XEXP (operands[3], 0),
1091                 plus_constant (Pmode,
1092                                XEXP (operands[1], 0),
1093                                GET_MODE_SIZE (<MODE>mode)))"
1094   "ldp\\t%<w>0, %<w>2, %1"
1095   [(set_attr "v8type" "fpsimd_load2")
1096    (set_attr "mode" "<MODE>")]
1099 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1100 ;; fairly lax checking on the second memory operation.
1101 (define_insn "store_pair<mode>"
1102   [(set (match_operand:GPF 0 "aarch64_mem_pair_operand" "=Ump")
1103         (match_operand:GPF 1 "register_operand" "w"))
1104    (set (match_operand:GPF 2 "memory_operand" "=m")
1105         (match_operand:GPF 3 "register_operand" "w"))]
1106   "rtx_equal_p (XEXP (operands[2], 0),
1107                 plus_constant (Pmode,
1108                                XEXP (operands[0], 0),
1109                                GET_MODE_SIZE (<MODE>mode)))"
1110   "stp\\t%<w>1, %<w>3, %0"
1111   [(set_attr "v8type" "fpsimd_load2")
1112    (set_attr "mode" "<MODE>")]
1115 ;; Load pair with writeback.  This is primarily used in function epilogues
1116 ;; when restoring [fp,lr]
1117 (define_insn "loadwb_pair<GPI:mode>_<PTR:mode>"
1118   [(parallel
1119     [(set (match_operand:PTR 0 "register_operand" "=k")
1120           (plus:PTR (match_operand:PTR 1 "register_operand" "0")
1121                   (match_operand:PTR 4 "const_int_operand" "n")))
1122      (set (match_operand:GPI 2 "register_operand" "=r")
1123           (mem:GPI (plus:PTR (match_dup 1)
1124                    (match_dup 4))))
1125      (set (match_operand:GPI 3 "register_operand" "=r")
1126           (mem:GPI (plus:PTR (match_dup 1)
1127                    (match_operand:PTR 5 "const_int_operand" "n"))))])]
1128   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1129   "ldp\\t%<w>2, %<w>3, [%1], %4"
1130   [(set_attr "v8type" "load2")
1131    (set_attr "mode" "<GPI:MODE>")]
1134 ;; Store pair with writeback.  This is primarily used in function prologues
1135 ;; when saving [fp,lr]
1136 (define_insn "storewb_pair<GPI:mode>_<PTR:mode>"
1137   [(parallel
1138     [(set (match_operand:PTR 0 "register_operand" "=&k")
1139           (plus:PTR (match_operand:PTR 1 "register_operand" "0")
1140                   (match_operand:PTR 4 "const_int_operand" "n")))
1141      (set (mem:GPI (plus:PTR (match_dup 0)
1142                    (match_dup 4)))
1143           (match_operand:GPI 2 "register_operand" "r"))
1144      (set (mem:GPI (plus:PTR (match_dup 0)
1145                    (match_operand:PTR 5 "const_int_operand" "n")))
1146           (match_operand:GPI 3 "register_operand" "r"))])]
1147   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1148   "stp\\t%<w>2, %<w>3, [%0, %4]!"
1149   [(set_attr "v8type" "store2")
1150    (set_attr "mode" "<GPI:MODE>")]
1153 ;; -------------------------------------------------------------------
1154 ;; Sign/Zero extension
1155 ;; -------------------------------------------------------------------
1157 (define_expand "<optab>sidi2"
1158   [(set (match_operand:DI 0 "register_operand")
1159         (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1160   ""
1163 (define_insn "*extendsidi2_aarch64"
1164   [(set (match_operand:DI 0 "register_operand" "=r,r")
1165         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1166   ""
1167   "@
1168    sxtw\t%0, %w1
1169    ldrsw\t%0, %1"
1170   [(set_attr "v8type" "extend,load1")
1171    (set_attr "mode" "DI")]
1174 (define_insn "*zero_extendsidi2_aarch64"
1175   [(set (match_operand:DI 0 "register_operand" "=r,r")
1176         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1177   ""
1178   "@
1179    uxtw\t%0, %w1
1180    ldr\t%w0, %1"
1181   [(set_attr "v8type" "extend,load1")
1182    (set_attr "mode" "DI")]
1185 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1186   [(set (match_operand:GPI 0 "register_operand")
1187         (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1188   ""
1191 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1192   [(set (match_operand:GPI 0 "register_operand" "=r,r")
1193         (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1194   ""
1195   "@
1196    sxt<SHORT:size>\t%<GPI:w>0, %w1
1197    ldrs<SHORT:size>\t%<GPI:w>0, %1"
1198   [(set_attr "v8type" "extend,load1")
1199    (set_attr "mode" "<GPI:MODE>")]
1202 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1203   [(set (match_operand:GPI 0 "register_operand" "=r,r")
1204         (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1205   ""
1206   "@
1207    uxt<SHORT:size>\t%<GPI:w>0, %w1
1208    ldr<SHORT:size>\t%w0, %1"
1209   [(set_attr "v8type" "extend,load1")
1210    (set_attr "mode" "<GPI:MODE>")]
1213 (define_expand "<optab>qihi2"
1214   [(set (match_operand:HI 0 "register_operand")
1215         (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1216   ""
1219 (define_insn "*<optab>qihi2_aarch64"
1220   [(set (match_operand:HI 0 "register_operand" "=r,r")
1221         (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1222   ""
1223   "@
1224    <su>xtb\t%w0, %w1
1225    <ldrxt>b\t%w0, %1"
1226   [(set_attr "v8type" "extend,load1")
1227    (set_attr "mode" "HI")]
1230 ;; -------------------------------------------------------------------
1231 ;; Simple arithmetic
1232 ;; -------------------------------------------------------------------
1234 (define_expand "add<mode>3"
1235   [(set
1236     (match_operand:GPI 0 "register_operand" "")
1237     (plus:GPI (match_operand:GPI 1 "register_operand" "")
1238               (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1239   ""
1240   "
1241   if (! aarch64_plus_operand (operands[2], VOIDmode))
1242     {
1243       rtx subtarget = ((optimize && can_create_pseudo_p ())
1244                        ? gen_reg_rtx (<MODE>mode) : operands[0]);
1245       HOST_WIDE_INT imm = INTVAL (operands[2]);
1247       if (imm < 0)
1248         imm = -(-imm & ~0xfff);
1249       else
1250         imm &= ~0xfff;
1252       emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1253       operands[1] = subtarget;
1254       operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1255     }
1256   "
1259 (define_insn "*addsi3_aarch64"
1260   [(set
1261     (match_operand:SI 0 "register_operand" "=rk,rk,rk")
1262     (plus:SI
1263      (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1264      (match_operand:SI 2 "aarch64_plus_operand" "I,r,J")))]
1265   ""
1266   "@
1267   add\\t%w0, %w1, %2
1268   add\\t%w0, %w1, %w2
1269   sub\\t%w0, %w1, #%n2"
1270   [(set_attr "v8type" "alu")
1271    (set_attr "mode" "SI")]
1274 (define_insn "*adddi3_aarch64"
1275   [(set
1276     (match_operand:DI 0 "register_operand" "=rk,rk,rk,!w")
1277     (plus:DI
1278      (match_operand:DI 1 "register_operand" "%rk,rk,rk,!w")
1279      (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,!w")))]
1280   ""
1281   "@
1282   add\\t%x0, %x1, %2
1283   add\\t%x0, %x1, %x2
1284   sub\\t%x0, %x1, #%n2
1285   add\\t%d0, %d1, %d2"
1286   [(set_attr "v8type" "alu")
1287    (set_attr "mode" "DI")
1288    (set_attr "simd" "*,*,*,yes")]
1291 (define_insn "*add<mode>3_compare0"
1292   [(set (reg:CC_NZ CC_REGNUM)
1293         (compare:CC_NZ
1294          (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r")
1295                    (match_operand:GPI 2 "aarch64_plus_operand" "rI,J"))
1296          (const_int 0)))
1297    (set (match_operand:GPI 0 "register_operand" "=r,r")
1298         (plus:GPI (match_dup 1) (match_dup 2)))]
1299   ""
1300   "@
1301   adds\\t%<w>0, %<w>1, %<w>2
1302   subs\\t%<w>0, %<w>1, #%n2"
1303   [(set_attr "v8type" "alus")
1304    (set_attr "mode" "<MODE>")]
1307 (define_insn "*add<mode>3nr_compare0"
1308   [(set (reg:CC_NZ CC_REGNUM)
1309         (compare:CC_NZ
1310          (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r")
1311                    (match_operand:GPI 1 "aarch64_plus_operand" "rI,J"))
1312          (const_int 0)))]
1313   ""
1314   "@
1315   cmn\\t%<w>0, %<w>1
1316   cmp\\t%<w>0, #%n1"
1317   [(set_attr "v8type" "alus")
1318    (set_attr "mode" "<MODE>")]
1321 (define_insn "*add_<shift>_<mode>"
1322   [(set (match_operand:GPI 0 "register_operand" "=rk")
1323         (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1324                               (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1325                   (match_operand:GPI 3 "register_operand" "r")))]
1326   ""
1327   "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1328   [(set_attr "v8type" "alu_shift")
1329    (set_attr "mode" "<MODE>")]
1332 (define_insn "*add_mul_imm_<mode>"
1333   [(set (match_operand:GPI 0 "register_operand" "=rk")
1334         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1335                             (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1336                   (match_operand:GPI 3 "register_operand" "r")))]
1337   ""
1338   "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1339   [(set_attr "v8type" "alu_shift")
1340    (set_attr "mode" "<MODE>")]
1343 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1344   [(set (match_operand:GPI 0 "register_operand" "=rk")
1345         (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1346                   (match_operand:GPI 2 "register_operand" "r")))]
1347   ""
1348   "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1349   [(set_attr "v8type" "alu_ext")
1350    (set_attr "mode" "<GPI:MODE>")]
1353 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1354   [(set (match_operand:GPI 0 "register_operand" "=rk")
1355         (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1356                                (match_operand:ALLX 1 "register_operand" "r"))
1357                               (match_operand 2 "aarch64_imm3" "Ui3"))
1358                   (match_operand:GPI 3 "register_operand" "r")))]
1359   ""
1360   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1361   [(set_attr "v8type" "alu_ext")
1362    (set_attr "mode" "<GPI:MODE>")]
1365 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1366   [(set (match_operand:GPI 0 "register_operand" "=rk")
1367         (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1368                              (match_operand:ALLX 1 "register_operand" "r"))
1369                             (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1370                   (match_operand:GPI 3 "register_operand" "r")))]
1371   ""
1372   "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1373   [(set_attr "v8type" "alu_ext")
1374    (set_attr "mode" "<GPI:MODE>")]
1377 (define_insn "*add_<optab><mode>_multp2"
1378   [(set (match_operand:GPI 0 "register_operand" "=rk")
1379         (plus:GPI (ANY_EXTRACT:GPI
1380                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1381                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1382                    (match_operand 3 "const_int_operand" "n")
1383                    (const_int 0))
1384                   (match_operand:GPI 4 "register_operand" "r")))]
1385   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1386   "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1387   [(set_attr "v8type" "alu_ext")
1388    (set_attr "mode" "<MODE>")]
1391 (define_insn "*add<mode>3_carryin"
1392   [(set
1393     (match_operand:GPI 0 "register_operand" "=r")
1394     (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1395               (plus:GPI
1396                 (match_operand:GPI 1 "register_operand" "r")
1397                 (match_operand:GPI 2 "register_operand" "r"))))]
1398    ""
1399    "adc\\t%<w>0, %<w>1, %<w>2"
1400   [(set_attr "v8type" "adc")
1401    (set_attr "mode" "<MODE>")]
1404 (define_insn "*add<mode>3_carryin_alt1"
1405   [(set
1406     (match_operand:GPI 0 "register_operand" "=r")
1407     (plus:GPI (plus:GPI
1408                 (match_operand:GPI 1 "register_operand" "r")
1409                 (match_operand:GPI 2 "register_operand" "r"))
1410               (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1411    ""
1412    "adc\\t%<w>0, %<w>1, %<w>2"
1413   [(set_attr "v8type" "adc")
1414    (set_attr "mode" "<MODE>")]
1417 (define_insn "*add<mode>3_carryin_alt2"
1418   [(set
1419     (match_operand:GPI 0 "register_operand" "=r")
1420     (plus:GPI (plus:GPI
1421                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1422                 (match_operand:GPI 1 "register_operand" "r"))
1423               (match_operand:GPI 2 "register_operand" "r")))]
1424    ""
1425    "adc\\t%<w>0, %<w>1, %<w>2"
1426   [(set_attr "v8type" "adc")
1427    (set_attr "mode" "<MODE>")]
1430 (define_insn "*add<mode>3_carryin_alt3"
1431   [(set
1432     (match_operand:GPI 0 "register_operand" "=r")
1433     (plus:GPI (plus:GPI
1434                 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1435                 (match_operand:GPI 2 "register_operand" "r"))
1436               (match_operand:GPI 1 "register_operand" "r")))]
1437    ""
1438    "adc\\t%<w>0, %<w>1, %<w>2"
1439   [(set_attr "v8type" "adc")
1440    (set_attr "mode" "<MODE>")]
1443 (define_insn "*add_uxt<mode>_multp2"
1444   [(set (match_operand:GPI 0 "register_operand" "=rk")
1445         (plus:GPI (and:GPI
1446                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1447                              (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1448                    (match_operand 3 "const_int_operand" "n"))
1449                   (match_operand:GPI 4 "register_operand" "r")))]
1450   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1451   "*
1452   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1453                                            INTVAL (operands[3])));
1454   return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1455   [(set_attr "v8type" "alu_ext")
1456    (set_attr "mode" "<MODE>")]
1459 (define_insn "subsi3"
1460   [(set (match_operand:SI 0 "register_operand" "=rk")
1461         (minus:SI (match_operand:SI 1 "register_operand" "r")
1462                    (match_operand:SI 2 "register_operand" "r")))]
1463   ""
1464   "sub\\t%w0, %w1, %w2"
1465   [(set_attr "v8type" "alu")
1466    (set_attr "mode" "SI")]
1469 (define_insn "subdi3"
1470   [(set (match_operand:DI 0 "register_operand" "=rk,!w")
1471         (minus:DI (match_operand:DI 1 "register_operand" "r,!w")
1472                    (match_operand:DI 2 "register_operand" "r,!w")))]
1473   ""
1474   "@
1475    sub\\t%x0, %x1, %x2
1476    sub\\t%d0, %d1, %d2"
1477   [(set_attr "v8type" "alu")
1478    (set_attr "mode" "DI")
1479    (set_attr "simd" "*,yes")]
1483 (define_insn "*sub<mode>3_compare0"
1484   [(set (reg:CC_NZ CC_REGNUM)
1485         (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1486                                   (match_operand:GPI 2 "register_operand" "r"))
1487                        (const_int 0)))
1488    (set (match_operand:GPI 0 "register_operand" "=r")
1489         (minus:GPI (match_dup 1) (match_dup 2)))]
1490   ""
1491   "subs\\t%<w>0, %<w>1, %<w>2"
1492   [(set_attr "v8type" "alus")
1493    (set_attr "mode" "<MODE>")]
1496 (define_insn "*sub_<shift>_<mode>"
1497   [(set (match_operand:GPI 0 "register_operand" "=rk")
1498         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1499                    (ASHIFT:GPI
1500                     (match_operand:GPI 1 "register_operand" "r")
1501                     (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1502   ""
1503   "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1504   [(set_attr "v8type" "alu_shift")
1505    (set_attr "mode" "<MODE>")]
1508 (define_insn "*sub_mul_imm_<mode>"
1509   [(set (match_operand:GPI 0 "register_operand" "=rk")
1510         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1511                    (mult:GPI
1512                     (match_operand:GPI 1 "register_operand" "r")
1513                     (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1514   ""
1515   "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1516   [(set_attr "v8type" "alu_shift")
1517    (set_attr "mode" "<MODE>")]
1520 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
1521   [(set (match_operand:GPI 0 "register_operand" "=rk")
1522         (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1523                    (ANY_EXTEND:GPI
1524                     (match_operand:ALLX 2 "register_operand" "r"))))]
1525   ""
1526   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1527   [(set_attr "v8type" "alu_ext")
1528    (set_attr "mode" "<GPI:MODE>")]
1531 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
1532   [(set (match_operand:GPI 0 "register_operand" "=rk")
1533         (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1534                    (ashift:GPI (ANY_EXTEND:GPI
1535                                 (match_operand:ALLX 2 "register_operand" "r"))
1536                                (match_operand 3 "aarch64_imm3" "Ui3"))))]
1537   ""
1538   "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1539   [(set_attr "v8type" "alu_ext")
1540    (set_attr "mode" "<GPI:MODE>")]
1543 (define_insn "*sub_<optab><mode>_multp2"
1544   [(set (match_operand:GPI 0 "register_operand" "=rk")
1545         (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1546                    (ANY_EXTRACT:GPI
1547                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1548                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1549                     (match_operand 3 "const_int_operand" "n")
1550                     (const_int 0))))]
1551   "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1552   "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1553   [(set_attr "v8type" "alu_ext")
1554    (set_attr "mode" "<MODE>")]
1557 (define_insn "*sub_uxt<mode>_multp2"
1558   [(set (match_operand:GPI 0 "register_operand" "=rk")
1559         (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1560                    (and:GPI
1561                     (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1562                               (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1563                     (match_operand 3 "const_int_operand" "n"))))]
1564   "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1565   "*
1566   operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1567                                            INTVAL (operands[3])));
1568   return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1569   [(set_attr "v8type" "alu_ext")
1570    (set_attr "mode" "<MODE>")]
1573 (define_insn "neg<mode>2"
1574   [(set (match_operand:GPI 0 "register_operand" "=r")
1575         (neg:GPI (match_operand:GPI 1 "register_operand" "r")))]
1576   ""
1577   "neg\\t%<w>0, %<w>1"
1578   [(set_attr "v8type" "alu")
1579    (set_attr "mode" "<MODE>")]
1582 (define_insn "*neg<mode>2_compare0"
1583   [(set (reg:CC_NZ CC_REGNUM)
1584         (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
1585                        (const_int 0)))
1586    (set (match_operand:GPI 0 "register_operand" "=r")
1587         (neg:GPI (match_dup 1)))]
1588   ""
1589   "negs\\t%<w>0, %<w>1"
1590   [(set_attr "v8type" "alus")
1591    (set_attr "mode" "<MODE>")]
1594 (define_insn "*neg_<shift>_<mode>2"
1595   [(set (match_operand:GPI 0 "register_operand" "=r")
1596         (neg:GPI (ASHIFT:GPI
1597                   (match_operand:GPI 1 "register_operand" "r")
1598                   (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1599   ""
1600   "neg\\t%<w>0, %<w>1, <shift> %2"
1601   [(set_attr "v8type" "alu_shift")
1602    (set_attr "mode" "<MODE>")]
1605 (define_insn "*neg_mul_imm_<mode>2"
1606   [(set (match_operand:GPI 0 "register_operand" "=r")
1607         (neg:GPI (mult:GPI
1608                   (match_operand:GPI 1 "register_operand" "r")
1609                   (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1610   ""
1611   "neg\\t%<w>0, %<w>1, lsl %p2"
1612   [(set_attr "v8type" "alu_shift")
1613    (set_attr "mode" "<MODE>")]
1616 (define_insn "mul<mode>3"
1617   [(set (match_operand:GPI 0 "register_operand" "=r")
1618         (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1619                   (match_operand:GPI 2 "register_operand" "r")))]
1620   ""
1621   "mul\\t%<w>0, %<w>1, %<w>2"
1622   [(set_attr "v8type" "mult")
1623    (set_attr "mode" "<MODE>")]
1626 (define_insn "*madd<mode>"
1627   [(set (match_operand:GPI 0 "register_operand" "=r")
1628         (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1629                             (match_operand:GPI 2 "register_operand" "r"))
1630                   (match_operand:GPI 3 "register_operand" "r")))]
1631   ""
1632   "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
1633   [(set_attr "v8type" "madd")
1634    (set_attr "mode" "<MODE>")]
1637 (define_insn "*msub<mode>"
1638   [(set (match_operand:GPI 0 "register_operand" "=r")
1639         (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1640                    (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1641                              (match_operand:GPI 2 "register_operand" "r"))))]
1643   ""
1644   "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
1645   [(set_attr "v8type" "madd")
1646    (set_attr "mode" "<MODE>")]
1649 (define_insn "*mul<mode>_neg"
1650   [(set (match_operand:GPI 0 "register_operand" "=r")
1651         (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
1652                   (match_operand:GPI 2 "register_operand" "r")))]
1654   ""
1655   "mneg\\t%<w>0, %<w>1, %<w>2"
1656   [(set_attr "v8type" "mult")
1657    (set_attr "mode" "<MODE>")]
1660 (define_insn "<su_optab>mulsidi3"
1661   [(set (match_operand:DI 0 "register_operand" "=r")
1662         (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
1663                  (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
1664   ""
1665   "<su>mull\\t%0, %w1, %w2"
1666   [(set_attr "v8type" "mull")
1667    (set_attr "mode" "DI")]
1670 (define_insn "<su_optab>maddsidi4"
1671   [(set (match_operand:DI 0 "register_operand" "=r")
1672         (plus:DI (mult:DI
1673                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
1674                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
1675                  (match_operand:DI 3 "register_operand" "r")))]
1676   ""
1677   "<su>maddl\\t%0, %w1, %w2, %3"
1678   [(set_attr "v8type" "maddl")
1679    (set_attr "mode" "DI")]
1682 (define_insn "<su_optab>msubsidi4"
1683   [(set (match_operand:DI 0 "register_operand" "=r")
1684         (minus:DI
1685          (match_operand:DI 3 "register_operand" "r")
1686          (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
1687                   (ANY_EXTEND:DI
1688                    (match_operand:SI 2 "register_operand" "r")))))]
1689   ""
1690   "<su>msubl\\t%0, %w1, %w2, %3"
1691   [(set_attr "v8type" "maddl")
1692    (set_attr "mode" "DI")]
1695 (define_insn "*<su_optab>mulsidi_neg"
1696   [(set (match_operand:DI 0 "register_operand" "=r")
1697         (mult:DI (neg:DI
1698                   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
1699                   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
1700   ""
1701   "<su>mnegl\\t%0, %w1, %w2"
1702   [(set_attr "v8type" "mull")
1703    (set_attr "mode" "DI")]
1706 (define_insn "<su>muldi3_highpart"
1707   [(set (match_operand:DI 0 "register_operand" "=r")
1708         (truncate:DI
1709          (lshiftrt:TI
1710           (mult:TI
1711            (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
1712            (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
1713           (const_int 64))))]
1714   ""
1715   "<su>mulh\\t%0, %1, %2"
1716   [(set_attr "v8type" "mulh")
1717    (set_attr "mode" "DI")]
1720 (define_insn "<su_optab>div<mode>3"
1721   [(set (match_operand:GPI 0 "register_operand" "=r")
1722         (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
1723                      (match_operand:GPI 2 "register_operand" "r")))]
1724   ""
1725   "<su>div\\t%<w>0, %<w>1, %<w>2"
1726   [(set_attr "v8type" "<su>div")
1727    (set_attr "mode" "<MODE>")]
1730 ;; -------------------------------------------------------------------
1731 ;; Comparison insns
1732 ;; -------------------------------------------------------------------
1734 (define_insn "*cmp<mode>"
1735   [(set (reg:CC CC_REGNUM)
1736         (compare:CC (match_operand:GPI 0 "register_operand" "r,r")
1737                     (match_operand:GPI 1 "aarch64_plus_operand" "rI,J")))]
1738   ""
1739   "@
1740    cmp\\t%<w>0, %<w>1
1741    cmn\\t%<w>0, #%n1"
1742   [(set_attr "v8type" "alus")
1743    (set_attr "mode" "<MODE>")]
1746 (define_insn "*cmp<mode>"
1747   [(set (reg:CCFP CC_REGNUM)
1748         (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
1749                       (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
1750    "TARGET_FLOAT"
1751    "@
1752     fcmp\\t%<s>0, #0.0
1753     fcmp\\t%<s>0, %<s>1"
1754   [(set_attr "v8type" "fcmp")
1755    (set_attr "mode" "<MODE>")]
1758 (define_insn "*cmpe<mode>"
1759   [(set (reg:CCFPE CC_REGNUM)
1760         (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
1761                        (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
1762    "TARGET_FLOAT"
1763    "@
1764     fcmpe\\t%<s>0, #0.0
1765     fcmpe\\t%<s>0, %<s>1"
1766   [(set_attr "v8type" "fcmp")
1767    (set_attr "mode" "<MODE>")]
1770 (define_insn "*cmp_swp_<shift>_reg<mode>"
1771   [(set (reg:CC_SWP CC_REGNUM)
1772         (compare:CC_SWP (ASHIFT:GPI
1773                          (match_operand:GPI 0 "register_operand" "r")
1774                          (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
1775                         (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
1776   ""
1777   "cmp\\t%<w>2, %<w>0, <shift> %1"
1778   [(set_attr "v8type" "alus_shift")
1779    (set_attr "mode" "<MODE>")]
1782 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
1783   [(set (reg:CC_SWP CC_REGNUM)
1784         (compare:CC_SWP (ANY_EXTEND:GPI
1785                          (match_operand:ALLX 0 "register_operand" "r"))
1786                         (match_operand:GPI 1 "register_operand" "r")))]
1787   ""
1788   "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
1789   [(set_attr "v8type" "alus_ext")
1790    (set_attr "mode" "<GPI:MODE>")]
1794 ;; -------------------------------------------------------------------
1795 ;; Store-flag and conditional select insns
1796 ;; -------------------------------------------------------------------
1798 (define_expand "cstore<mode>4"
1799   [(set (match_operand:SI 0 "register_operand" "")
1800         (match_operator:SI 1 "aarch64_comparison_operator"
1801          [(match_operand:GPI 2 "register_operand" "")
1802           (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
1803   ""
1804   "
1805   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
1806                                       operands[3]);
1807   operands[3] = const0_rtx;
1808   "
1811 (define_expand "cstore<mode>4"
1812   [(set (match_operand:SI 0 "register_operand" "")
1813         (match_operator:SI 1 "aarch64_comparison_operator"
1814          [(match_operand:GPF 2 "register_operand" "")
1815           (match_operand:GPF 3 "register_operand" "")]))]
1816   ""
1817   "
1818   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
1819                                       operands[3]);
1820   operands[3] = const0_rtx;
1821   "
1824 (define_insn "*cstore<mode>_insn"
1825   [(set (match_operand:ALLI 0 "register_operand" "=r")
1826         (match_operator:ALLI 1 "aarch64_comparison_operator"
1827          [(match_operand 2 "cc_register" "") (const_int 0)]))]
1828   ""
1829   "cset\\t%<w>0, %m1"
1830   [(set_attr "v8type" "csel")
1831    (set_attr "mode" "<MODE>")]
1834 (define_insn "*cstore<mode>_neg"
1835   [(set (match_operand:ALLI 0 "register_operand" "=r")
1836         (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
1837                   [(match_operand 2 "cc_register" "") (const_int 0)])))]
1838   ""
1839   "csetm\\t%<w>0, %m1"
1840   [(set_attr "v8type" "csel")
1841    (set_attr "mode" "<MODE>")]
1844 (define_expand "cmov<mode>6"
1845   [(set (match_operand:GPI 0 "register_operand" "")
1846         (if_then_else:GPI
1847          (match_operator 1 "aarch64_comparison_operator"
1848           [(match_operand:GPI 2 "register_operand" "")
1849            (match_operand:GPI 3 "aarch64_plus_operand" "")])
1850          (match_operand:GPI 4 "register_operand" "")
1851          (match_operand:GPI 5 "register_operand" "")))]
1852   ""
1853   "
1854   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
1855                                       operands[3]);
1856   operands[3] = const0_rtx;
1857   "
1860 (define_expand "cmov<mode>6"
1861   [(set (match_operand:GPF 0 "register_operand" "")
1862         (if_then_else:GPF
1863          (match_operator 1 "aarch64_comparison_operator"
1864           [(match_operand:GPF 2 "register_operand" "")
1865            (match_operand:GPF 3 "register_operand" "")])
1866          (match_operand:GPF 4 "register_operand" "")
1867          (match_operand:GPF 5 "register_operand" "")))]
1868   ""
1869   "
1870   operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
1871                                       operands[3]);
1872   operands[3] = const0_rtx;
1873   "
1876 (define_insn "*cmov<mode>_insn"
1877   [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r")
1878         (if_then_else:ALLI
1879          (match_operator 1 "aarch64_comparison_operator"
1880           [(match_operand 2 "cc_register" "") (const_int 0)])
1881          (match_operand:ALLI 3 "aarch64_reg_zero_or_m1" "rZ,rZ,UsM,UsM")
1882          (match_operand:ALLI 4 "aarch64_reg_zero_or_m1" "rZ,UsM,rZ,UsM")))]
1883   ""
1884   ;; Final alternative should be unreachable, but included for completeness
1885   "@
1886    csel\\t%<w>0, %<w>3, %<w>4, %m1
1887    csinv\\t%<w>0, %<w>3, <w>zr, %m1
1888    csinv\\t%<w>0, %<w>4, <w>zr, %M1
1889    mov\\t%<w>0, -1"
1890   [(set_attr "v8type" "csel")
1891    (set_attr "mode" "<MODE>")]
1894 (define_insn "*cmov<mode>_insn"
1895   [(set (match_operand:GPF 0 "register_operand" "=w")
1896         (if_then_else:GPF
1897          (match_operator 1 "aarch64_comparison_operator"
1898           [(match_operand 2 "cc_register" "") (const_int 0)])
1899          (match_operand:GPF 3 "register_operand" "w")
1900          (match_operand:GPF 4 "register_operand" "w")))]
1901   "TARGET_FLOAT"
1902   "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
1903   [(set_attr "v8type" "fcsel")
1904    (set_attr "mode" "<MODE>")]
1907 (define_expand "mov<mode>cc"
1908   [(set (match_operand:ALLI 0 "register_operand" "")
1909         (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
1910                            (match_operand:ALLI 2 "register_operand" "")
1911                            (match_operand:ALLI 3 "register_operand" "")))]
1912   ""
1913   {
1914     rtx ccreg;
1915     enum rtx_code code = GET_CODE (operands[1]);
1917     if (code == UNEQ || code == LTGT)
1918       FAIL;
1920     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
1921                                   XEXP (operands[1], 1));
1922     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
1923   }
1926 (define_expand "mov<GPF:mode><GPI:mode>cc"
1927   [(set (match_operand:GPI 0 "register_operand" "")
1928         (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
1929                           (match_operand:GPF 2 "register_operand" "")
1930                           (match_operand:GPF 3 "register_operand" "")))]
1931   ""
1932   {
1933     rtx ccreg;
1934     enum rtx_code code = GET_CODE (operands[1]);
1936     if (code == UNEQ || code == LTGT)
1937       FAIL;
1939     ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
1940                                   XEXP (operands[1], 1));
1941     operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
1942   }
1945 (define_insn "*csinc2<mode>_insn"
1946   [(set (match_operand:GPI 0 "register_operand" "=r")
1947         (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator"
1948                   [(match_operand:CC 3 "cc_register" "") (const_int 0)])
1949                  (match_operand:GPI 1 "register_operand" "r")))]
1950   ""
1951   "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
1952   [(set_attr "v8type" "csel")
1953    (set_attr "mode" "<MODE>")])
1955 (define_insn "csinc3<mode>_insn"
1956   [(set (match_operand:GPI 0 "register_operand" "=r")
1957         (if_then_else:GPI
1958           (match_operator:GPI 1 "aarch64_comparison_operator"
1959            [(match_operand:CC 2 "cc_register" "") (const_int 0)])
1960           (plus:GPI (match_operand:GPI 3 "register_operand" "r")
1961                     (const_int 1))
1962           (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
1963   ""
1964   "csinc\\t%<w>0, %<w>4, %<w>3, %M1"
1965   [(set_attr "v8type" "csel")
1966    (set_attr "mode" "<MODE>")]
1969 (define_insn "*csinv3<mode>_insn"
1970   [(set (match_operand:GPI 0 "register_operand" "=r")
1971         (if_then_else:GPI
1972           (match_operator:GPI 1 "aarch64_comparison_operator"
1973            [(match_operand:CC 2 "cc_register" "") (const_int 0)])
1974           (not:GPI (match_operand:GPI 3 "register_operand" "r"))
1975           (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
1976   ""
1977   "csinv\\t%<w>0, %<w>4, %<w>3, %M1"
1978   [(set_attr "v8type" "csel")
1979    (set_attr "mode" "<MODE>")])
1981 (define_insn "*csneg3<mode>_insn"
1982   [(set (match_operand:GPI 0 "register_operand" "=r")
1983         (if_then_else:GPI
1984           (match_operator:GPI 1 "aarch64_comparison_operator"
1985            [(match_operand:CC 2 "cc_register" "") (const_int 0)])
1986           (neg:GPI (match_operand:GPI 3 "register_operand" "r"))
1987           (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
1988   ""
1989   "csneg\\t%<w>0, %<w>4, %<w>3, %M1"
1990   [(set_attr "v8type" "csel")
1991    (set_attr "mode" "<MODE>")])
1993 ;; -------------------------------------------------------------------
1994 ;; Logical operations
1995 ;; -------------------------------------------------------------------
1997 (define_insn "<optab><mode>3"
1998   [(set (match_operand:GPI 0 "register_operand" "=r,rk")
1999         (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2000                      (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
2001   ""
2002   "<logical>\\t%<w>0, %<w>1, %<w>2"
2003   [(set_attr "v8type" "logic,logic_imm")
2004    (set_attr "mode" "<MODE>")])
2006 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2007   [(set (match_operand:GPI 0 "register_operand" "=r")
2008         (LOGICAL:GPI (SHIFT:GPI
2009                       (match_operand:GPI 1 "register_operand" "r")
2010                       (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2011                      (match_operand:GPI 3 "register_operand" "r")))]
2012   ""
2013   "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2014   [(set_attr "v8type" "logic_shift")
2015    (set_attr "mode" "<MODE>")])
2017 (define_insn "one_cmpl<mode>2"
2018   [(set (match_operand:GPI 0 "register_operand" "=r")
2019         (not:GPI (match_operand:GPI 1 "register_operand" "r")))]
2020   ""
2021   "mvn\\t%<w>0, %<w>1"
2022   [(set_attr "v8type" "logic")
2023    (set_attr "mode" "<MODE>")])
2025 (define_insn "*one_cmpl_<optab><mode>2"
2026   [(set (match_operand:GPI 0 "register_operand" "=r")
2027         (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
2028                             (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2029   ""
2030   "mvn\\t%<w>0, %<w>1, <shift> %2"
2031   [(set_attr "v8type" "logic_shift")
2032    (set_attr "mode" "<MODE>")])
2034 (define_insn "*<LOGICAL:optab>_one_cmpl<mode>3"
2035   [(set (match_operand:GPI 0 "register_operand" "=r")
2036         (LOGICAL:GPI (not:GPI
2037                       (match_operand:GPI 1 "register_operand" "r"))
2038                      (match_operand:GPI 2 "register_operand" "r")))]
2039   ""
2040   "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1"
2041   [(set_attr "v8type" "logic")
2042    (set_attr "mode" "<MODE>")])
2044 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
2045   [(set (match_operand:GPI 0 "register_operand" "=r")
2046         (LOGICAL:GPI (not:GPI
2047                       (SHIFT:GPI
2048                        (match_operand:GPI 1 "register_operand" "r")
2049                        (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2050                      (match_operand:GPI 3 "register_operand" "r")))]
2051   ""
2052   "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2053   [(set_attr "v8type" "logic_shift")
2054    (set_attr "mode" "<MODE>")])
2056 (define_insn "clz<mode>2"
2057   [(set (match_operand:GPI 0 "register_operand" "=r")
2058         (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
2059   ""
2060   "clz\\t%<w>0, %<w>1"
2061   [(set_attr "v8type" "clz")
2062    (set_attr "mode" "<MODE>")])
2064 (define_expand "ffs<mode>2"
2065   [(match_operand:GPI 0 "register_operand")
2066    (match_operand:GPI 1 "register_operand")]
2067   ""
2068   {
2069     rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
2070     rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
2072     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2073     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2074     emit_insn (gen_csinc3<mode>_insn (operands[0], x, ccreg, operands[0], const0_rtx));
2075     DONE;
2076   }
2079 (define_insn "clrsb<mode>2"
2080   [(set (match_operand:GPI 0 "register_operand" "=r")
2081         (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_CLS))]
2082   ""
2083   "cls\\t%<w>0, %<w>1"
2084   [(set_attr "v8type" "clz")
2085    (set_attr "mode" "<MODE>")])
2087 (define_insn "rbit<mode>2"
2088   [(set (match_operand:GPI 0 "register_operand" "=r")
2089         (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
2090   ""
2091   "rbit\\t%<w>0, %<w>1"
2092   [(set_attr "v8type" "rbit")
2093    (set_attr "mode" "<MODE>")])
2095 (define_expand "ctz<mode>2"
2096   [(match_operand:GPI 0 "register_operand")
2097    (match_operand:GPI 1 "register_operand")]
2098   ""
2099   {
2100     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2101     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2102     DONE;
2103   }
2106 (define_insn "*and<mode>3nr_compare0"
2107   [(set (reg:CC CC_REGNUM)
2108         (compare:CC
2109          (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
2110                   (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
2111          (const_int 0)))]
2112   ""
2113   "tst\\t%<w>0, %<w>1"
2114   [(set_attr "v8type" "logics")
2115    (set_attr "mode" "<MODE>")])
2117 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
2118   [(set (reg:CC CC_REGNUM)
2119         (compare:CC
2120          (and:GPI (SHIFT:GPI
2121                    (match_operand:GPI 0 "register_operand" "r")
2122                    (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2123                   (match_operand:GPI 2 "register_operand" "r"))
2124         (const_int 0)))]
2125   ""
2126   "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
2127   [(set_attr "v8type" "logics_shift")
2128    (set_attr "mode" "<MODE>")])
2130 ;; -------------------------------------------------------------------
2131 ;; Shifts
2132 ;; -------------------------------------------------------------------
2134 (define_expand "<optab><mode>3"
2135   [(set (match_operand:GPI 0 "register_operand")
2136         (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
2137                     (match_operand:QI 2 "nonmemory_operand")))]
2138   ""
2139   {
2140     if (CONST_INT_P (operands[2]))
2141       {
2142         operands[2] = GEN_INT (INTVAL (operands[2])
2143                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2145         if (operands[2] == const0_rtx)
2146           {
2147             emit_insn (gen_mov<mode> (operands[0], operands[1]));
2148             DONE;
2149           }
2150       }
2151   }
2154 (define_expand "ashl<mode>3"
2155   [(set (match_operand:SHORT 0 "register_operand")
2156         (ashift:SHORT (match_operand:SHORT 1 "register_operand")
2157                       (match_operand:QI 2 "nonmemory_operand")))]
2158   ""
2159   {
2160     if (CONST_INT_P (operands[2]))
2161       {
2162         operands[2] = GEN_INT (INTVAL (operands[2])
2163                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2165         if (operands[2] == const0_rtx)
2166           {
2167             emit_insn (gen_mov<mode> (operands[0], operands[1]));
2168             DONE;
2169           }
2170       }
2171   }
2174 (define_expand "rotr<mode>3"
2175   [(set (match_operand:GPI 0 "register_operand")
2176         (rotatert:GPI (match_operand:GPI 1 "register_operand")
2177                       (match_operand:QI 2 "nonmemory_operand")))]
2178   ""
2179   {
2180     if (CONST_INT_P (operands[2]))
2181       {
2182         operands[2] = GEN_INT (INTVAL (operands[2])
2183                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2185         if (operands[2] == const0_rtx)
2186           {
2187             emit_insn (gen_mov<mode> (operands[0], operands[1]));
2188             DONE;
2189           }
2190       }
2191   }
2194 (define_expand "rotl<mode>3"
2195   [(set (match_operand:GPI 0 "register_operand")
2196         (rotatert:GPI (match_operand:GPI 1 "register_operand")
2197                       (match_operand:QI 2 "nonmemory_operand")))]
2198   ""
2199   {
2200     /* (SZ - cnt) % SZ == -cnt % SZ */
2201     if (CONST_INT_P (operands[2]))
2202       {
2203         operands[2] = GEN_INT ((-INTVAL (operands[2]))
2204                                & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2205         if (operands[2] == const0_rtx)
2206           {
2207             emit_insn (gen_mov<mode> (operands[0], operands[1]));
2208             DONE;
2209           }
2210       }
2211     else
2212       operands[2] = expand_simple_unop (QImode, NEG, operands[2],
2213                                         NULL_RTX, 1);
2214   }
2217 (define_insn "*<optab><mode>3_insn"
2218   [(set (match_operand:GPI 0 "register_operand" "=r")
2219         (SHIFT:GPI
2220          (match_operand:GPI 1 "register_operand" "r")
2221          (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
2222   ""
2223   "<shift>\\t%<w>0, %<w>1, %<w>2"
2224   [(set_attr "v8type" "shift")
2225    (set_attr "mode" "<MODE>")]
2228 (define_insn "*ashl<mode>3_insn"
2229   [(set (match_operand:SHORT 0 "register_operand" "=r")
2230         (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
2231                       (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
2232   ""
2233   "lsl\\t%<w>0, %<w>1, %<w>2"
2234   [(set_attr "v8type" "shift")
2235    (set_attr "mode" "<MODE>")]
2238 (define_insn "*<optab><mode>3_insn"
2239   [(set (match_operand:SHORT 0 "register_operand" "=r")
2240         (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
2241                       (match_operand 2 "const_int_operand" "n")))]
2242   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
2244   operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
2245   return "<bfshift>\t%w0, %w1, %2, %3";
2247   [(set_attr "v8type" "bfm")
2248    (set_attr "mode" "<MODE>")]
2251 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
2252   [(set (match_operand:GPI 0 "register_operand" "=r")
2253         (ANY_EXTEND:GPI
2254          (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
2255                        (match_operand 2 "const_int_operand" "n"))))]
2256   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
2258   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
2259   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
2261   [(set_attr "v8type" "bfm")
2262    (set_attr "mode" "<GPI:MODE>")]
2265 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
2266   [(set (match_operand:GPI 0 "register_operand" "=r")
2267         (zero_extend:GPI
2268          (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
2269                          (match_operand 2 "const_int_operand" "n"))))]
2270   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
2272   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
2273   return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
2275   [(set_attr "v8type" "bfm")
2276    (set_attr "mode" "<GPI:MODE>")]
2279 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
2280   [(set (match_operand:GPI 0 "register_operand" "=r")
2281         (sign_extend:GPI
2282          (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
2283                          (match_operand 2 "const_int_operand" "n"))))]
2284   "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
2286   operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
2287   return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
2289   [(set_attr "v8type" "bfm")
2290    (set_attr "mode" "<GPI:MODE>")]
2293 ;; -------------------------------------------------------------------
2294 ;; Bitfields
2295 ;; -------------------------------------------------------------------
2297 (define_expand "<optab>"
2298   [(set (match_operand:DI 0 "register_operand" "=r")
2299         (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
2300                         (match_operand 2 "const_int_operand" "n")
2301                         (match_operand 3 "const_int_operand" "n")))]
2302   ""
2303   ""
2306 (define_insn "*<optab><mode>"
2307   [(set (match_operand:GPI 0 "register_operand" "=r")
2308         (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
2309                          (match_operand 2 "const_int_operand" "n")
2310                          (match_operand 3 "const_int_operand" "n")))]
2311   ""
2312   "<su>bfx\\t%<w>0, %<w>1, %3, %2"
2313   [(set_attr "v8type" "bfm")
2314    (set_attr "mode" "<MODE>")]
2317 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
2318   [(set (match_operand:GPI 0 "register_operand" "=r")
2319         (ashift:GPI (ANY_EXTEND:GPI
2320                      (match_operand:ALLX 1 "register_operand" "r"))
2321                     (match_operand 2 "const_int_operand" "n")))]
2322   "UINTVAL (operands[2]) < <GPI:sizen>"
2324   operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
2325               ? GEN_INT (<ALLX:sizen>)
2326               : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
2327   return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
2329   [(set_attr "v8type" "bfm")
2330    (set_attr "mode" "<GPI:MODE>")]
2333 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
2335 (define_insn "*andim_ashift<mode>_bfiz"
2336   [(set (match_operand:GPI 0 "register_operand" "=r")
2337         (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
2338                              (match_operand 2 "const_int_operand" "n"))
2339                  (match_operand 3 "const_int_operand" "n")))]
2340   "exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
2341    && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
2342   "ubfiz\\t%<w>0, %<w>1, %2, %P3"
2343   [(set_attr "v8type" "bfm")
2344    (set_attr "mode" "<MODE>")]
2347 (define_insn "bswap<mode>2"
2348   [(set (match_operand:GPI 0 "register_operand" "=r")
2349         (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
2350   ""
2351   "rev\\t%<w>0, %<w>1"
2352   [(set_attr "v8type" "rev")
2353    (set_attr "mode" "<MODE>")]
2356 ;; -------------------------------------------------------------------
2357 ;; Floating-point intrinsics
2358 ;; -------------------------------------------------------------------
2360 ;; trunc - nothrow
2362 (define_insn "btrunc<mode>2"
2363   [(set (match_operand:GPF 0 "register_operand" "=w")
2364         (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2365          UNSPEC_FRINTZ))]
2366   "TARGET_FLOAT"
2367   "frintz\\t%<s>0, %<s>1"
2368   [(set_attr "v8type" "frint")
2369    (set_attr "mode" "<MODE>")]
2372 (define_insn "*lbtrunc<su_optab><GPF:mode><GPI:mode>2"
2373   [(set (match_operand:GPI 0 "register_operand" "=r")
2374         (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2375                       UNSPEC_FRINTZ)))]
2376   "TARGET_FLOAT"
2377   "fcvtz<su>\\t%<GPI:w>0, %<GPF:s>1"
2378   [(set_attr "v8type" "fcvtf2i")
2379    (set_attr "mode" "<GPF:MODE>")
2380    (set_attr "mode2" "<GPI:MODE>")]
2383 ;; ceil - nothrow
2385 (define_insn "ceil<mode>2"
2386   [(set (match_operand:GPF 0 "register_operand" "=w")
2387         (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2388          UNSPEC_FRINTP))]
2389   "TARGET_FLOAT"
2390   "frintp\\t%<s>0, %<s>1"
2391   [(set_attr "v8type" "frint")
2392    (set_attr "mode" "<MODE>")]
2395 (define_insn "lceil<su_optab><GPF:mode><GPI:mode>2"
2396   [(set (match_operand:GPI 0 "register_operand" "=r")
2397         (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2398                       UNSPEC_FRINTP)))]
2399   "TARGET_FLOAT"
2400   "fcvtp<su>\\t%<GPI:w>0, %<GPF:s>1"
2401   [(set_attr "v8type" "fcvtf2i")
2402    (set_attr "mode" "<GPF:MODE>")
2403    (set_attr "mode2" "<GPI:MODE>")]
2406 ;; floor - nothrow
2408 (define_insn "floor<mode>2"
2409   [(set (match_operand:GPF 0 "register_operand" "=w")
2410         (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2411          UNSPEC_FRINTM))]
2412   "TARGET_FLOAT"
2413   "frintm\\t%<s>0, %<s>1"
2414   [(set_attr "v8type" "frint")
2415    (set_attr "mode" "<MODE>")]
2418 (define_insn "lfloor<su_optab><GPF:mode><GPI:mode>2"
2419   [(set (match_operand:GPI 0 "register_operand" "=r")
2420         (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2421                       UNSPEC_FRINTM)))]
2422   "TARGET_FLOAT"
2423   "fcvtm<su>\\t%<GPI:w>0, %<GPF:s>1"
2424   [(set_attr "v8type" "fcvtf2i")
2425    (set_attr "mode" "<GPF:MODE>")
2426    (set_attr "mode2" "<GPI:MODE>")]
2429 ;; nearbyint - nothrow
2431 (define_insn "nearbyint<mode>2"
2432   [(set (match_operand:GPF 0 "register_operand" "=w")
2433         (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2434          UNSPEC_FRINTI))]
2435   "TARGET_FLOAT"
2436   "frinti\\t%<s>0, %<s>1"
2437   [(set_attr "v8type" "frint")
2438    (set_attr "mode" "<MODE>")]
2441 ;; rint
2443 (define_insn "rint<mode>2"
2444   [(set (match_operand:GPF 0 "register_operand" "=w")
2445         (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2446          UNSPEC_FRINTX))]
2447   "TARGET_FLOAT"
2448   "frintx\\t%<s>0, %<s>1"
2449   [(set_attr "v8type" "frint")
2450    (set_attr "mode" "<MODE>")]
2453 ;; round - nothrow
2455 (define_insn "round<mode>2"
2456   [(set (match_operand:GPF 0 "register_operand" "=w")
2457         (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2458          UNSPEC_FRINTA))]
2459   "TARGET_FLOAT"
2460   "frinta\\t%<s>0, %<s>1"
2461   [(set_attr "v8type" "frint")
2462    (set_attr "mode" "<MODE>")]
2465 (define_insn "lround<su_optab><GPF:mode><GPI:mode>2"
2466   [(set (match_operand:GPI 0 "register_operand" "=r")
2467         (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2468                       UNSPEC_FRINTA)))]
2469   "TARGET_FLOAT"
2470   "fcvta<su>\\t%<GPI:w>0, %<GPF:s>1"
2471   [(set_attr "v8type" "fcvtf2i")
2472    (set_attr "mode" "<GPF:MODE>")
2473    (set_attr "mode2" "<GPI:MODE>")]
2476 ;; fma - no throw
2478 (define_insn "fma<mode>4"
2479   [(set (match_operand:GPF 0 "register_operand" "=w")
2480         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
2481                  (match_operand:GPF 2 "register_operand" "w")
2482                  (match_operand:GPF 3 "register_operand" "w")))]
2483   "TARGET_FLOAT"
2484   "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
2485   [(set_attr "v8type" "fmadd")
2486    (set_attr "mode" "<MODE>")]
2489 (define_insn "fnma<mode>4"
2490   [(set (match_operand:GPF 0 "register_operand" "=w")
2491         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
2492                  (match_operand:GPF 2 "register_operand" "w")
2493                  (match_operand:GPF 3 "register_operand" "w")))]
2494   "TARGET_FLOAT"
2495   "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
2496   [(set_attr "v8type" "fmadd")
2497    (set_attr "mode" "<MODE>")]
2500 (define_insn "fms<mode>4"
2501   [(set (match_operand:GPF 0 "register_operand" "=w")
2502         (fma:GPF (match_operand:GPF 1 "register_operand" "w")
2503                  (match_operand:GPF 2 "register_operand" "w")
2504                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
2505   "TARGET_FLOAT"
2506   "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
2507   [(set_attr "v8type" "fmadd")
2508    (set_attr "mode" "<MODE>")]
2511 (define_insn "fnms<mode>4"
2512   [(set (match_operand:GPF 0 "register_operand" "=w")
2513         (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
2514                  (match_operand:GPF 2 "register_operand" "w")
2515                  (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
2516   "TARGET_FLOAT"
2517   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
2518   [(set_attr "v8type" "fmadd")
2519    (set_attr "mode" "<MODE>")]
2522 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
2523 (define_insn "*fnmadd<mode>4"
2524   [(set (match_operand:GPF 0 "register_operand" "=w")
2525         (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
2526                           (match_operand:GPF 2 "register_operand" "w")
2527                           (match_operand:GPF 3 "register_operand" "w"))))]
2528   "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
2529   "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
2530   [(set_attr "v8type" "fmadd")
2531    (set_attr "mode" "<MODE>")]
2534 ;; -------------------------------------------------------------------
2535 ;; Floating-point conversions
2536 ;; -------------------------------------------------------------------
2538 (define_insn "extendsfdf2"
2539   [(set (match_operand:DF 0 "register_operand" "=w")
2540         (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
2541   "TARGET_FLOAT"
2542   "fcvt\\t%d0, %s1"
2543   [(set_attr "v8type" "fcvt")
2544    (set_attr "mode" "DF")
2545    (set_attr "mode2" "SF")]
2548 (define_insn "truncdfsf2"
2549   [(set (match_operand:SF 0 "register_operand" "=w")
2550         (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
2551   "TARGET_FLOAT"
2552   "fcvt\\t%s0, %d1"
2553   [(set_attr "v8type" "fcvt")
2554    (set_attr "mode" "SF")
2555    (set_attr "mode2" "DF")]
2558 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
2559   [(set (match_operand:GPI 0 "register_operand" "=r")
2560         (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
2561   "TARGET_FLOAT"
2562   "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
2563   [(set_attr "v8type" "fcvtf2i")
2564    (set_attr "mode" "<GPF:MODE>")
2565    (set_attr "mode2" "<GPI:MODE>")]
2568 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
2569   [(set (match_operand:GPI 0 "register_operand" "=r")
2570         (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
2571   "TARGET_FLOAT"
2572   "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
2573   [(set_attr "v8type" "fcvtf2i")
2574    (set_attr "mode" "<GPF:MODE>")
2575    (set_attr "mode2" "<GPI:MODE>")]
2578 (define_insn "float<GPI:mode><GPF:mode>2"
2579   [(set (match_operand:GPF 0 "register_operand" "=w")
2580         (float:GPF (match_operand:GPI 1 "register_operand" "r")))]
2581   "TARGET_FLOAT"
2582   "scvtf\\t%<GPF:s>0, %<GPI:w>1"
2583   [(set_attr "v8type" "fcvti2f")
2584    (set_attr "mode" "<GPF:MODE>")
2585    (set_attr "mode2" "<GPI:MODE>")]
2588 (define_insn "floatuns<GPI:mode><GPF:mode>2"
2589   [(set (match_operand:GPF 0 "register_operand" "=w")
2590         (unsigned_float:GPF (match_operand:GPI 1 "register_operand" "r")))]
2591   "TARGET_FLOAT"
2592   "ucvtf\\t%<GPF:s>0, %<GPI:w>1"
2593   [(set_attr "v8type" "fcvt")
2594    (set_attr "mode" "<GPF:MODE>")
2595    (set_attr "mode2" "<GPI:MODE>")]
2598 ;; -------------------------------------------------------------------
2599 ;; Floating-point arithmetic
2600 ;; -------------------------------------------------------------------
2602 (define_insn "add<mode>3"
2603   [(set (match_operand:GPF 0 "register_operand" "=w")
2604         (plus:GPF
2605          (match_operand:GPF 1 "register_operand" "w")
2606          (match_operand:GPF 2 "register_operand" "w")))]
2607   "TARGET_FLOAT"
2608   "fadd\\t%<s>0, %<s>1, %<s>2"
2609   [(set_attr "v8type" "fadd")
2610    (set_attr "mode" "<MODE>")]
2613 (define_insn "sub<mode>3"
2614   [(set (match_operand:GPF 0 "register_operand" "=w")
2615         (minus:GPF
2616          (match_operand:GPF 1 "register_operand" "w")
2617          (match_operand:GPF 2 "register_operand" "w")))]
2618   "TARGET_FLOAT"
2619   "fsub\\t%<s>0, %<s>1, %<s>2"
2620   [(set_attr "v8type" "fadd")
2621    (set_attr "mode" "<MODE>")]
2624 (define_insn "mul<mode>3"
2625   [(set (match_operand:GPF 0 "register_operand" "=w")
2626         (mult:GPF
2627          (match_operand:GPF 1 "register_operand" "w")
2628          (match_operand:GPF 2 "register_operand" "w")))]
2629   "TARGET_FLOAT"
2630   "fmul\\t%<s>0, %<s>1, %<s>2"
2631   [(set_attr "v8type" "fmul")
2632    (set_attr "mode" "<MODE>")]
2635 (define_insn "*fnmul<mode>3"
2636   [(set (match_operand:GPF 0 "register_operand" "=w")
2637         (mult:GPF
2638                  (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
2639                  (match_operand:GPF 2 "register_operand" "w")))]
2640   "TARGET_FLOAT"
2641   "fnmul\\t%<s>0, %<s>1, %<s>2"
2642   [(set_attr "v8type" "fmul")
2643    (set_attr "mode" "<MODE>")]
2646 (define_insn "div<mode>3"
2647   [(set (match_operand:GPF 0 "register_operand" "=w")
2648         (div:GPF
2649          (match_operand:GPF 1 "register_operand" "w")
2650          (match_operand:GPF 2 "register_operand" "w")))]
2651   "TARGET_FLOAT"
2652   "fdiv\\t%<s>0, %<s>1, %<s>2"
2653   [(set_attr "v8type" "fdiv")
2654    (set_attr "mode" "<MODE>")]
2657 (define_insn "neg<mode>2"
2658   [(set (match_operand:GPF 0 "register_operand" "=w")
2659         (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
2660   "TARGET_FLOAT"
2661   "fneg\\t%<s>0, %<s>1"
2662   [(set_attr "v8type" "ffarith")
2663    (set_attr "mode" "<MODE>")]
2666 (define_insn "sqrt<mode>2"
2667   [(set (match_operand:GPF 0 "register_operand" "=w")
2668         (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
2669   "TARGET_FLOAT"
2670   "fsqrt\\t%<s>0, %<s>1"
2671   [(set_attr "v8type" "fsqrt")
2672    (set_attr "mode" "<MODE>")]
2675 (define_insn "abs<mode>2"
2676   [(set (match_operand:GPF 0 "register_operand" "=w")
2677         (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
2678   "TARGET_FLOAT"
2679   "fabs\\t%<s>0, %<s>1"
2680   [(set_attr "v8type" "ffarith")
2681    (set_attr "mode" "<MODE>")]
2684 ;; Given that smax/smin do not specify the result when either input is NaN,
2685 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
2686 ;; for smin.
2688 (define_insn "smax<mode>3"
2689   [(set (match_operand:GPF 0 "register_operand" "=w")
2690         (smax:GPF (match_operand:GPF 1 "register_operand" "w")
2691                   (match_operand:GPF 2 "register_operand" "w")))]
2692   "TARGET_FLOAT"
2693   "fmaxnm\\t%<s>0, %<s>1, %<s>2"
2694   [(set_attr "v8type" "fminmax")
2695    (set_attr "mode" "<MODE>")]
2698 (define_insn "smin<mode>3"
2699   [(set (match_operand:GPF 0 "register_operand" "=w")
2700         (smin:GPF (match_operand:GPF 1 "register_operand" "w")
2701                   (match_operand:GPF 2 "register_operand" "w")))]
2702   "TARGET_FLOAT"
2703   "fminnm\\t%<s>0, %<s>1, %<s>2"
2704   [(set_attr "v8type" "fminmax")
2705    (set_attr "mode" "<MODE>")]
2708 ;; -------------------------------------------------------------------
2709 ;; Reload support
2710 ;; -------------------------------------------------------------------
2712 ;; Reload SP+imm where imm cannot be handled by a single ADD instruction.  
2713 ;; Must load imm into a scratch register and copy SP to the dest reg before
2714 ;; adding, since SP cannot be used as a source register in an ADD
2715 ;; instruction.
2716 (define_expand "reload_sp_immediate"
2717   [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
2718                    (match_operand:DI 1 "" ""))
2719              (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
2720   ""
2721   {
2722     rtx sp = XEXP (operands[1], 0);
2723     rtx val = XEXP (operands[1], 1);
2724     unsigned regno = REGNO (operands[2]);
2725     rtx scratch = operands[1];
2726     gcc_assert (GET_CODE (operands[1]) == PLUS);
2727     gcc_assert (sp == stack_pointer_rtx);
2728     gcc_assert (CONST_INT_P (val));
2730     /* It is possible that one of the registers we got for operands[2]
2731        might coincide with that of operands[0] (which is why we made
2732        it TImode).  Pick the other one to use as our scratch.  */
2733     if (regno == REGNO (operands[0]))
2734       regno++;
2735     scratch = gen_rtx_REG (DImode, regno);
2737     emit_move_insn (scratch, val);
2738     emit_move_insn (operands[0], sp);
2739     emit_insn (gen_adddi3 (operands[0], operands[0], scratch));
2740     DONE;
2741   }
2744 (define_expand "aarch64_reload_mov<mode>"
2745   [(set (match_operand:TX 0 "register_operand" "=w")
2746         (match_operand:TX 1 "register_operand" "w"))
2747    (clobber (match_operand:DI 2 "register_operand" "=&r"))
2748   ]
2749   ""
2750   {
2751     rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
2752     rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
2753     gen_aarch64_movtilow_tilow (op0, op1);
2754     gen_aarch64_movdi_tihigh (operands[2], op1);
2755     gen_aarch64_movtihigh_di (op0, operands[2]);
2756     DONE;
2757   }
2760 ;; The following secondary reload helpers patterns are invoked
2761 ;; after or during reload as we don't want these patterns to start
2762 ;; kicking in during the combiner.
2764 (define_insn "aarch64_movdi_tilow"
2765   [(set (match_operand:DI 0 "register_operand" "=r")
2766         (truncate:DI (match_operand:TI 1 "register_operand" "w")))]
2767   "reload_completed || reload_in_progress"
2768   "fmov\\t%x0, %d1"
2769   [(set_attr "v8type" "fmovf2i")
2770    (set_attr "mode"   "DI")
2771    (set_attr "length" "4")
2772   ])
2774 (define_insn "aarch64_movdi_tihigh"
2775   [(set (match_operand:DI 0 "register_operand" "=r")
2776         (truncate:DI
2777           (lshiftrt:TI (match_operand:TI 1 "register_operand" "w")
2778                        (const_int 64))))]
2779   "reload_completed || reload_in_progress"
2780   "fmov\\t%x0, %1.d[1]"
2781   [(set_attr "v8type" "fmovf2i")
2782    (set_attr "mode"   "DI")
2783    (set_attr "length" "4")
2784   ])
2786 (define_insn "aarch64_movtihigh_di"
2787   [(set (zero_extract:TI (match_operand:TI 0 "register_operand" "+w")
2788                          (const_int 64) (const_int 64))
2789         (zero_extend:TI (match_operand:DI 1 "register_operand" "r")))]
2790   "reload_completed || reload_in_progress"
2791   "fmov\\t%0.d[1], %x1"
2793   [(set_attr "v8type" "fmovi2f")
2794    (set_attr "mode"   "DI")
2795    (set_attr "length" "4")
2796   ])
2798 (define_insn "aarch64_movtilow_di"
2799   [(set (match_operand:TI 0 "register_operand" "=w")
2800         (zero_extend:TI (match_operand:DI 1 "register_operand" "r")))]
2801   "reload_completed || reload_in_progress"
2802   "fmov\\t%d0, %x1"
2804   [(set_attr "v8type" "fmovi2f")
2805    (set_attr "mode"   "DI")
2806    (set_attr "length" "4")
2807   ])
2809 (define_insn "aarch64_movtilow_tilow"
2810   [(set (match_operand:TI 0 "register_operand" "=w")
2811         (zero_extend:TI 
2812           (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
2813   "reload_completed || reload_in_progress"
2814   "fmov\\t%d0, %d1"
2816   [(set_attr "v8type" "fmovi2f")
2817    (set_attr "mode"   "DI")
2818    (set_attr "length" "4")
2819   ])
2821 ;; There is a deliberate reason why the parameters of high and lo_sum's
2822 ;; don't have modes for ADRP and ADD instructions.  This is to allow high
2823 ;; and lo_sum's to be used with the labels defining the jump tables in
2824 ;; rodata section.
2826 (define_insn "add_losym"
2827   [(set (match_operand:DI 0 "register_operand" "=r")
2828         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2829                    (match_operand 2 "aarch64_valid_symref" "S")))]
2830   ""
2831   "add\\t%0, %1, :lo12:%a2"
2832   [(set_attr "v8type" "alu")
2833    (set_attr "mode" "DI")]
2837 (define_insn "ldr_got_small"
2838   [(set (match_operand:DI 0 "register_operand" "=r")
2839         (unspec:DI [(mem:DI (lo_sum:DI
2840                               (match_operand:DI 1 "register_operand" "r")
2841                               (match_operand:DI 2 "aarch64_valid_symref" "S")))]
2842                    UNSPEC_GOTSMALLPIC))]
2843   ""
2844   "ldr\\t%0, [%1, #:got_lo12:%a2]"
2845   [(set_attr "v8type" "load1")
2846    (set_attr "mode" "DI")]
2849 (define_insn "aarch64_load_tp_hard"
2850   [(set (match_operand:DI 0 "register_operand" "=r")
2851         (unspec:DI [(const_int 0)] UNSPEC_TLS))]
2852   ""
2853   "mrs\\t%0, tpidr_el0"
2854   [(set_attr "v8type" "mrs")
2855    (set_attr "mode" "DI")]
2858 ;; The TLS ABI specifically requires that the compiler does not schedule
2859 ;; instructions in the TLS stubs, in order to enable linker relaxation.
2860 ;; Therefore we treat the stubs as an atomic sequence.
2861 (define_expand "tlsgd_small"
2862  [(parallel [(set (match_operand 0 "register_operand" "")
2863                   (call (mem:DI (match_dup 2)) (const_int 1)))
2864              (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
2865              (clobber (reg:DI LR_REGNUM))])]
2866  ""
2868   operands[2] = aarch64_tls_get_addr ();
2871 (define_insn "*tlsgd_small"
2872   [(set (match_operand 0 "register_operand" "")
2873         (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
2874    (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
2875    (clobber (reg:DI LR_REGNUM))
2876   ]
2877   ""
2878   "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
2879   [(set_attr "v8type" "call")
2880    (set_attr "length" "16")])
2882 (define_insn "tlsie_small"
2883   [(set (match_operand:DI 0 "register_operand" "=r")
2884         (unspec:DI [(match_operand:DI 1 "aarch64_tls_ie_symref" "S")]
2885                    UNSPEC_GOTSMALLTLS))]
2886   ""
2887   "adrp\\t%0, %A1\;ldr\\t%0, [%0, #%L1]"
2888   [(set_attr "v8type" "load1")
2889    (set_attr "mode" "DI")
2890    (set_attr "length" "8")]
2893 (define_insn "tlsle_small"
2894   [(set (match_operand:DI 0 "register_operand" "=r")
2895         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
2896                    (match_operand:DI 2 "aarch64_tls_le_symref" "S")]
2897                    UNSPEC_GOTSMALLTLS))]
2898   ""
2899   "add\\t%0, %1, #%G2\;add\\t%0, %0, #%L2"
2900   [(set_attr "v8type" "alu")
2901    (set_attr "mode" "DI")
2902    (set_attr "length" "8")]
2905 (define_insn "tlsdesc_small"
2906   [(set (reg:DI R0_REGNUM)
2907         (unspec:DI [(match_operand:DI 0 "aarch64_valid_symref" "S")]
2908                    UNSPEC_TLSDESC))
2909    (clobber (reg:DI LR_REGNUM))
2910    (clobber (match_scratch:DI 1 "=r"))]
2911   "TARGET_TLS_DESC"
2912   "adrp\\tx0, %A0\;ldr\\t%1, [x0, #%L0]\;add\\tx0, x0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
2913   [(set_attr "v8type" "call")
2914    (set_attr "length" "16")])
2916 (define_insn "stack_tie"
2917   [(set (mem:BLK (scratch))
2918         (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
2919                      (match_operand:DI 1 "register_operand" "rk")]
2920                     UNSPEC_PRLG_STK))]
2921   ""
2922   ""
2923   [(set_attr "length" "0")]
2926 ;; Named pattern for expanding thread pointer reference.
2927 (define_expand "get_thread_pointerdi"
2928   [(match_operand:DI 0 "register_operand" "=r")]
2929   ""
2931   rtx tmp = aarch64_load_tp (operands[0]);
2932   if (tmp != operands[0])
2933     emit_move_insn (operands[0], tmp);
2934   DONE;
2937 ;; AdvSIMD Stuff
2938 (include "aarch64-simd.md")
2940 ;; Synchronization Builtins
2941 (include "sync.md")