1 ;; Machine description for AArch64 architecture.
2 ;; Copyright (C) 2009-2013 Free Software Foundation, Inc.
3 ;; Contributed by ARM Ltd.
5 ;; This file is part of GCC.
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)
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/>.
68 (define_c_enum "unspec" [
94 (define_c_enum "unspecv" [
95 UNSPECV_EH_RETURN ; Represent EH_RETURN
99 ;; If further include files are added the defintion of MD_INCLUDES
102 (include "constraints.md")
103 (include "predicates.md")
104 (include "iterators.md")
106 ;; -------------------------------------------------------------------
107 ;; Instruction types and attributes
108 ;; -------------------------------------------------------------------
110 ;; Main data types used by the insntructions
112 (define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
113 (const_string "unknown"))
115 (define_attr "mode2" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
116 (const_string "unknown"))
118 ; The "v8type" attribute is used to for fine grained classification of
119 ; AArch64 instructions. This table briefly explains the meaning of each type.
121 ; adc add/subtract with carry.
122 ; adcs add/subtract with carry (setting condition flags).
123 ; adr calculate address.
124 ; alu simple alu instruction (no memory or fp regs access).
125 ; alu_ext simple alu instruction (sign/zero-extended register).
126 ; alu_shift simple alu instruction, with a source operand shifted by a constant.
127 ; alus simple alu instruction (setting condition flags).
128 ; alus_ext simple alu instruction (sign/zero-extended register, setting condition flags).
129 ; alus_shift simple alu instruction, with a source operand shifted by a constant (setting condition flags).
130 ; bfm bitfield move operation.
132 ; call subroutine call.
133 ; ccmp conditional compare.
134 ; clz count leading zeros/sign bits.
135 ; csel conditional select.
136 ; dmb data memory barrier.
137 ; extend sign/zero-extend (specialised bitfield move).
138 ; extr extract register-sized bitfield encoding.
139 ; fpsimd_load load single floating point / simd scalar register from memory.
140 ; fpsimd_load2 load pair of floating point / simd scalar registers from memory.
141 ; fpsimd_store store single floating point / simd scalar register to memory.
142 ; fpsimd_store2 store pair floating point / simd scalar registers to memory.
143 ; fadd floating point add/sub.
144 ; fccmp floating point conditional compare.
145 ; fcmp floating point comparison.
146 ; fconst floating point load immediate.
147 ; fcsel floating point conditional select.
148 ; fcvt floating point convert (float to float).
149 ; fcvtf2i floating point convert (float to integer).
150 ; fcvti2f floating point convert (integer to float).
151 ; fdiv floating point division operation.
152 ; ffarith floating point abs, neg or cpy.
153 ; fmadd floating point multiply-add/sub.
154 ; fminmax floating point min/max.
155 ; fmov floating point move (float to float).
156 ; fmovf2i floating point move (float to integer).
157 ; fmovi2f floating point move (integer to float).
158 ; fmul floating point multiply.
159 ; frint floating point round to integral.
160 ; fsqrt floating point square root.
161 ; load_acq load-acquire.
162 ; load load single general register from memory
163 ; load2 load pair of general registers from memory
164 ; logic logical operation (register).
165 ; logic_imm and/or/xor operation (immediate).
166 ; logic_shift logical operation with shift.
167 ; logics logical operation (register, setting condition flags).
168 ; logics_imm and/or/xor operation (immediate, setting condition flags).
169 ; logics_shift logical operation with shift (setting condition flags).
170 ; madd integer multiply-add/sub.
171 ; maddl widening integer multiply-add/sub.
172 ; misc miscellaneous - any type that doesn't fit into the rest.
173 ; move integer move operation.
174 ; move2 double integer move operation.
175 ; movk move 16-bit immediate with keep.
176 ; movz move 16-bit immmediate with zero/one.
177 ; mrs system/special register move.
178 ; mulh 64x64 to 128-bit multiply (high part).
179 ; mull widening multiply.
180 ; mult integer multiply instruction.
181 ; prefetch memory prefetch.
184 ; sdiv integer division operation (signed).
185 ; shift variable shift operation.
186 ; shift_imm immediate shift operation (specialised bitfield move).
187 ; store_rel store-release.
188 ; store store single general register to memory.
189 ; store2 store pair of general registers to memory.
190 ; udiv integer division operation (unsigned).
192 (define_attr "v8type"
265 (const_string "alu"))
268 ; The "type" attribute is used by the AArch32 backend. Below is a mapping
269 ; from "v8type" to "type".
272 "alu,alu_shift,block,branch,call,f_2_r,f_cvt,f_flag,f_loads,
273 f_loadd,f_stored,f_stores,faddd,fadds,fcmpd,fcmps,fconstd,fconsts,
274 fcpys,fdivd,fdivs,ffarithd,ffariths,fmacd,fmacs,fmuld,fmuls,load_byte,
275 load1,load2,mult,r_2_f,store1,store2"
277 (eq_attr "v8type" "alu_shift,alus_shift,logic_shift,logics_shift") (const_string "alu_shift")
278 (eq_attr "v8type" "branch") (const_string "branch")
279 (eq_attr "v8type" "call") (const_string "call")
280 (eq_attr "v8type" "fmovf2i") (const_string "f_2_r")
281 (eq_attr "v8type" "fcvt,fcvtf2i,fcvti2f") (const_string "f_cvt")
282 (and (eq_attr "v8type" "fpsimd_load") (eq_attr "mode" "SF")) (const_string "f_loads")
283 (and (eq_attr "v8type" "fpsimd_load") (eq_attr "mode" "DF")) (const_string "f_loadd")
284 (and (eq_attr "v8type" "fpsimd_store") (eq_attr "mode" "SF")) (const_string "f_stores")
285 (and (eq_attr "v8type" "fpsimd_store") (eq_attr "mode" "DF")) (const_string "f_stored")
286 (and (eq_attr "v8type" "fadd,fminmax") (eq_attr "mode" "DF")) (const_string "faddd")
287 (and (eq_attr "v8type" "fadd,fminmax") (eq_attr "mode" "SF")) (const_string "fadds")
288 (and (eq_attr "v8type" "fcmp,fccmp") (eq_attr "mode" "DF")) (const_string "fcmpd")
289 (and (eq_attr "v8type" "fcmp,fccmp") (eq_attr "mode" "SF")) (const_string "fcmps")
290 (and (eq_attr "v8type" "fconst") (eq_attr "mode" "DF")) (const_string "fconstd")
291 (and (eq_attr "v8type" "fconst") (eq_attr "mode" "SF")) (const_string "fconsts")
292 (and (eq_attr "v8type" "fdiv,fsqrt") (eq_attr "mode" "DF")) (const_string "fdivd")
293 (and (eq_attr "v8type" "fdiv,fsqrt") (eq_attr "mode" "SF")) (const_string "fdivs")
294 (and (eq_attr "v8type" "ffarith") (eq_attr "mode" "DF")) (const_string "ffarithd")
295 (and (eq_attr "v8type" "ffarith") (eq_attr "mode" "SF")) (const_string "ffariths")
296 (and (eq_attr "v8type" "fmadd") (eq_attr "mode" "DF")) (const_string "fmacd")
297 (and (eq_attr "v8type" "fmadd") (eq_attr "mode" "SF")) (const_string "fmacs")
298 (and (eq_attr "v8type" "fmul") (eq_attr "mode" "DF")) (const_string "fmuld")
299 (and (eq_attr "v8type" "fmul") (eq_attr "mode" "SF")) (const_string "fmuls")
300 (and (eq_attr "v8type" "load1") (eq_attr "mode" "QI,HI")) (const_string "load_byte")
301 (and (eq_attr "v8type" "load1") (eq_attr "mode" "SI,DI,TI")) (const_string "load1")
302 (eq_attr "v8type" "load2") (const_string "load2")
303 (and (eq_attr "v8type" "mulh,mult,mull,madd,sdiv,udiv") (eq_attr "mode" "SI")) (const_string "mult")
304 (eq_attr "v8type" "fmovi2f") (const_string "r_2_f")
305 (eq_attr "v8type" "store1") (const_string "store1")
306 (eq_attr "v8type" "store2") (const_string "store2")
308 (const_string "alu")))
310 ;; Attribute that specifies whether or not the instruction touches fp
312 (define_attr "fp" "no,yes" (const_string "no"))
314 ;; Attribute that specifies whether or not the instruction touches simd
316 (define_attr "simd" "no,yes" (const_string "no"))
318 (define_attr "length" ""
321 ;; Attribute that controls whether an alternative is enabled or not.
322 ;; Currently it is only used to disable alternatives which touch fp or simd
323 ;; registers when -mgeneral-regs-only is specified.
324 (define_attr "enabled" "no,yes"
326 (and (eq_attr "fp" "yes")
327 (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
328 (and (eq_attr "simd" "yes")
329 (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
331 ] (const_string "yes")))
333 ;; -------------------------------------------------------------------
334 ;; Pipeline descriptions and scheduling
335 ;; -------------------------------------------------------------------
338 (include "aarch64-tune.md")
341 (include "aarch64-generic.md")
345 ;; -------------------------------------------------------------------
346 ;; Jumps and other miscellaneous insns
347 ;; -------------------------------------------------------------------
349 (define_insn "indirect_jump"
350 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
353 [(set_attr "v8type" "branch")]
357 [(set (pc) (label_ref (match_operand 0 "" "")))]
360 [(set_attr "v8type" "branch")]
363 (define_expand "cbranch<mode>4"
364 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
365 [(match_operand:GPI 1 "register_operand" "")
366 (match_operand:GPI 2 "aarch64_plus_operand" "")])
367 (label_ref (match_operand 3 "" ""))
371 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
373 operands[2] = const0_rtx;
377 (define_expand "cbranch<mode>4"
378 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
379 [(match_operand:GPF 1 "register_operand" "")
380 (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
381 (label_ref (match_operand 3 "" ""))
385 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
387 operands[2] = const0_rtx;
391 (define_insn "*condjump"
392 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
393 [(match_operand 1 "cc_register" "") (const_int 0)])
394 (label_ref (match_operand 2 "" ""))
398 [(set_attr "v8type" "branch")]
401 (define_expand "casesi"
402 [(match_operand:SI 0 "register_operand" "") ; Index
403 (match_operand:SI 1 "const_int_operand" "") ; Lower bound
404 (match_operand:SI 2 "const_int_operand" "") ; Total range
405 (match_operand:DI 3 "" "") ; Table label
406 (match_operand:DI 4 "" "")] ; Out of range label
409 if (operands[1] != const0_rtx)
411 rtx reg = gen_reg_rtx (SImode);
413 /* Canonical RTL says that if you have:
417 then this should be emitted as:
421 The use of trunc_int_for_mode ensures that the resulting
422 constant can be represented in SImode, this is important
423 for the corner case where operand[1] is INT_MIN. */
425 operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
427 if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
428 (operands[1], SImode))
429 operands[1] = force_reg (SImode, operands[1]);
430 emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
434 if (!aarch64_plus_operand (operands[2], SImode))
435 operands[2] = force_reg (SImode, operands[2]);
436 emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
438 operands[0], operands[2], operands[4]));
440 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
441 emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
447 (define_insn "casesi_dispatch"
450 (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
451 (match_operand:SI 1 "register_operand" "r")]
453 (clobber (reg:CC CC_REGNUM))
454 (clobber (match_scratch:DI 3 "=r"))
455 (clobber (match_scratch:DI 4 "=r"))
456 (use (label_ref (match_operand 2 "" "")))])]
459 return aarch64_output_casesi (operands);
461 [(set_attr "length" "16")
462 (set_attr "v8type" "branch")]
466 [(unspec[(const_int 0)] UNSPEC_NOP)]
469 [(set_attr "v8type" "misc")]
472 (define_expand "prologue"
473 [(clobber (const_int 0))]
476 aarch64_expand_prologue ();
481 (define_expand "epilogue"
482 [(clobber (const_int 0))]
485 aarch64_expand_epilogue (false);
490 (define_expand "sibcall_epilogue"
491 [(clobber (const_int 0))]
494 aarch64_expand_epilogue (true);
499 (define_insn "*do_return"
503 [(set_attr "v8type" "branch")]
506 (define_insn "eh_return"
507 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
511 [(set_attr "v8type" "branch")]
515 [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
518 [(set (match_dup 1) (match_dup 0))]
520 operands[1] = aarch64_final_eh_return_addr ();
524 (define_insn "*cb<optab><mode>1"
525 [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
527 (label_ref (match_operand 1 "" ""))
531 [(set_attr "v8type" "branch")]
534 (define_insn "*tb<optab><mode>1"
535 [(set (pc) (if_then_else
536 (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
538 (match_operand 1 "const_int_operand" "n"))
540 (label_ref (match_operand 2 "" ""))
542 (clobber (match_scratch:DI 3 "=r"))]
545 if (get_attr_length (insn) == 8)
546 return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
547 return \"<tbz>\\t%<w>0, %1, %l2\";
549 [(set_attr "v8type" "branch")
550 (set_attr "mode" "<MODE>")
552 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
553 (lt (minus (match_dup 2) (pc)) (const_int 32764)))
558 (define_insn "*cb<optab><mode>1"
559 [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
561 (label_ref (match_operand 1 "" ""))
563 (clobber (match_scratch:DI 2 "=r"))]
566 if (get_attr_length (insn) == 8)
567 return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
568 return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
570 [(set_attr "v8type" "branch")
571 (set_attr "mode" "<MODE>")
573 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
574 (lt (minus (match_dup 1) (pc)) (const_int 32764)))
579 ;; -------------------------------------------------------------------
580 ;; Subroutine calls and sibcalls
581 ;; -------------------------------------------------------------------
583 (define_expand "call"
584 [(parallel [(call (match_operand 0 "memory_operand" "")
585 (match_operand 1 "general_operand" ""))
586 (use (match_operand 2 "" ""))
587 (clobber (reg:DI LR_REGNUM))])]
593 /* In an untyped call, we can get NULL for operand 2. */
594 if (operands[2] == NULL)
595 operands[2] = const0_rtx;
597 /* Decide if we should generate indirect calls by loading the
598 64-bit address of the callee into a register before performing
599 the branch-and-link. */
600 callee = XEXP (operands[0], 0);
601 if (GET_CODE (callee) == SYMBOL_REF
602 ? aarch64_is_long_call_p (callee)
604 XEXP (operands[0], 0) = force_reg (Pmode, callee);
608 (define_insn "*call_reg"
609 [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
610 (match_operand 1 "" ""))
611 (use (match_operand 2 "" ""))
612 (clobber (reg:DI LR_REGNUM))]
615 [(set_attr "v8type" "call")]
618 (define_insn "*call_symbol"
619 [(call (mem:DI (match_operand:DI 0 "" ""))
620 (match_operand 1 "" ""))
621 (use (match_operand 2 "" ""))
622 (clobber (reg:DI LR_REGNUM))]
623 "GET_CODE (operands[0]) == SYMBOL_REF
624 && !aarch64_is_long_call_p (operands[0])"
626 [(set_attr "v8type" "call")]
629 (define_expand "call_value"
630 [(parallel [(set (match_operand 0 "" "")
631 (call (match_operand 1 "memory_operand" "")
632 (match_operand 2 "general_operand" "")))
633 (use (match_operand 3 "" ""))
634 (clobber (reg:DI LR_REGNUM))])]
640 /* In an untyped call, we can get NULL for operand 3. */
641 if (operands[3] == NULL)
642 operands[3] = const0_rtx;
644 /* Decide if we should generate indirect calls by loading the
645 64-bit address of the callee into a register before performing
646 the branch-and-link. */
647 callee = XEXP (operands[1], 0);
648 if (GET_CODE (callee) == SYMBOL_REF
649 ? aarch64_is_long_call_p (callee)
651 XEXP (operands[1], 0) = force_reg (Pmode, callee);
655 (define_insn "*call_value_reg"
656 [(set (match_operand 0 "" "")
657 (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
658 (match_operand 2 "" "")))
659 (use (match_operand 3 "" ""))
660 (clobber (reg:DI LR_REGNUM))]
663 [(set_attr "v8type" "call")]
666 (define_insn "*call_value_symbol"
667 [(set (match_operand 0 "" "")
668 (call (mem:DI (match_operand:DI 1 "" ""))
669 (match_operand 2 "" "")))
670 (use (match_operand 3 "" ""))
671 (clobber (reg:DI LR_REGNUM))]
672 "GET_CODE (operands[1]) == SYMBOL_REF
673 && !aarch64_is_long_call_p (operands[1])"
675 [(set_attr "v8type" "call")]
678 (define_expand "sibcall"
679 [(parallel [(call (match_operand 0 "memory_operand" "")
680 (match_operand 1 "general_operand" ""))
682 (use (match_operand 2 "" ""))])]
685 if (operands[2] == NULL_RTX)
686 operands[2] = const0_rtx;
690 (define_expand "sibcall_value"
691 [(parallel [(set (match_operand 0 "" "")
692 (call (match_operand 1 "memory_operand" "")
693 (match_operand 2 "general_operand" "")))
695 (use (match_operand 3 "" ""))])]
698 if (operands[3] == NULL_RTX)
699 operands[3] = const0_rtx;
703 (define_insn "*sibcall_insn"
704 [(call (mem:DI (match_operand:DI 0 "" "X"))
705 (match_operand 1 "" ""))
707 (use (match_operand 2 "" ""))]
708 "GET_CODE (operands[0]) == SYMBOL_REF"
710 [(set_attr "v8type" "branch")]
713 (define_insn "*sibcall_value_insn"
714 [(set (match_operand 0 "" "")
715 (call (mem:DI (match_operand 1 "" "X"))
716 (match_operand 2 "" "")))
718 (use (match_operand 3 "" ""))]
719 "GET_CODE (operands[1]) == SYMBOL_REF"
721 [(set_attr "v8type" "branch")]
724 ;; Call subroutine returning any type.
726 (define_expand "untyped_call"
727 [(parallel [(call (match_operand 0 "")
730 (match_operand 2 "")])]
735 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
737 for (i = 0; i < XVECLEN (operands[2], 0); i++)
739 rtx set = XVECEXP (operands[2], 0, i);
740 emit_move_insn (SET_DEST (set), SET_SRC (set));
743 /* The optimizer does not know that the call sets the function value
744 registers we stored in the result block. We avoid problems by
745 claiming that all hard registers are used and clobbered at this
747 emit_insn (gen_blockage ());
751 ;; -------------------------------------------------------------------
753 ;; -------------------------------------------------------------------
755 (define_expand "mov<mode>"
756 [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
757 (match_operand:SHORT 1 "general_operand" ""))]
760 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
761 operands[1] = force_reg (<MODE>mode, operands[1]);
765 (define_insn "*mov<mode>_aarch64"
766 [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r,r,m, r,*w")
767 (match_operand:SHORT 1 "general_operand" " r,M,m,rZ,*w,r"))]
768 "(register_operand (operands[0], <MODE>mode)
769 || aarch64_reg_or_zero (operands[1], <MODE>mode))"
775 umov\\t%w0, %1.<v>[0]
776 dup\\t%0.<Vallxd>, %w1"
777 [(set_attr "v8type" "move,alu,load1,store1,*,*")
778 (set_attr "simd_type" "*,*,*,*,simd_movgp,simd_dupgp")
779 (set_attr "mode" "<MODE>")
780 (set_attr "simd_mode" "<MODE>")]
783 (define_expand "mov<mode>"
784 [(set (match_operand:GPI 0 "nonimmediate_operand" "")
785 (match_operand:GPI 1 "general_operand" ""))]
788 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
789 operands[1] = force_reg (<MODE>mode, operands[1]);
791 if (CONSTANT_P (operands[1]))
793 aarch64_expand_mov_immediate (operands[0], operands[1]);
799 (define_insn "*movsi_aarch64"
800 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m, *w, r,*w")
801 (match_operand:SI 1 "aarch64_mov_operand" " r,M,m,rZ,rZ,*w,*w"))]
802 "(register_operand (operands[0], SImode)
803 || aarch64_reg_or_zero (operands[1], SImode))"
812 [(set_attr "v8type" "move,alu,load1,store1,fmov,fmov,fmov")
813 (set_attr "mode" "SI")
814 (set_attr "fp" "*,*,*,*,yes,yes,yes")]
817 (define_insn "*movdi_aarch64"
818 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,m, r, r, *w, r,*w,w")
819 (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,m,rZ,Usa,Ush,rZ,*w,*w,Dd"))]
820 "(register_operand (operands[0], DImode)
821 || aarch64_reg_or_zero (operands[1], DImode))"
835 [(set_attr "v8type" "move,move,move,alu,load1,store1,adr,adr,fmov,fmov,fmov,fmov")
836 (set_attr "mode" "DI")
837 (set_attr "fp" "*,*,*,*,*,*,*,*,yes,yes,yes,yes")]
840 (define_insn "insv_imm<mode>"
841 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
843 (match_operand:GPI 1 "const_int_operand" "n"))
844 (match_operand:GPI 2 "const_int_operand" "n"))]
845 "INTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
846 && INTVAL (operands[1]) % 16 == 0
847 && UINTVAL (operands[2]) <= 0xffff"
848 "movk\\t%<w>0, %X2, lsl %1"
849 [(set_attr "v8type" "movk")
850 (set_attr "mode" "<MODE>")]
853 (define_expand "movti"
854 [(set (match_operand:TI 0 "nonimmediate_operand" "")
855 (match_operand:TI 1 "general_operand" ""))]
858 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
859 operands[1] = force_reg (TImode, operands[1]);
863 (define_insn "*movti_aarch64"
864 [(set (match_operand:TI 0
865 "nonimmediate_operand" "=r, *w,r ,*w,r ,Ump,Ump,*w,m")
867 "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r ,Z , m,*w"))]
868 "(register_operand (operands[0], TImode)
869 || aarch64_reg_or_zero (operands[1], TImode))"
874 orr\\t%0.16b, %1.16b, %1.16b
880 [(set_attr "v8type" "move2,fmovi2f,fmovf2i,*, \
881 load2,store2,store2,fpsimd_load,fpsimd_store")
882 (set_attr "simd_type" "*,*,*,simd_move,*,*,*,*,*")
883 (set_attr "mode" "DI,DI,DI,TI,DI,DI,DI,TI,TI")
884 (set_attr "length" "8,8,8,4,4,4,4,4,4")
885 (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")
886 (set_attr "simd" "*,*,*,yes,*,*,*,*,*")])
888 ;; Split a TImode register-register or register-immediate move into
889 ;; its component DImode pieces, taking care to handle overlapping
890 ;; source and dest registers.
892 [(set (match_operand:TI 0 "register_operand" "")
893 (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
894 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
897 aarch64_split_128bit_move (operands[0], operands[1]);
901 (define_expand "mov<mode>"
902 [(set (match_operand:GPF 0 "nonimmediate_operand" "")
903 (match_operand:GPF 1 "general_operand" ""))]
908 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
912 if (GET_CODE (operands[0]) == MEM)
913 operands[1] = force_reg (<MODE>mode, operands[1]);
917 (define_insn "*movsf_aarch64"
918 [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
919 (match_operand:SF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
920 "TARGET_FLOAT && (register_operand (operands[0], SFmode)
921 || register_operand (operands[1], SFmode))"
932 [(set_attr "v8type" "fmovi2f,fmovf2i,\
933 fmov,fconst,fpsimd_load,\
934 fpsimd_store,fpsimd_load,fpsimd_store,fmov")
935 (set_attr "mode" "SF")]
938 (define_insn "*movdf_aarch64"
939 [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
940 (match_operand:DF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
941 "TARGET_FLOAT && (register_operand (operands[0], DFmode)
942 || register_operand (operands[1], DFmode))"
953 [(set_attr "v8type" "fmovi2f,fmovf2i,\
954 fmov,fconst,fpsimd_load,\
955 fpsimd_store,fpsimd_load,fpsimd_store,move")
956 (set_attr "mode" "DF")]
959 (define_expand "movtf"
960 [(set (match_operand:TF 0 "nonimmediate_operand" "")
961 (match_operand:TF 1 "general_operand" ""))]
966 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
970 if (GET_CODE (operands[0]) == MEM)
971 operands[1] = force_reg (TFmode, operands[1]);
975 (define_insn "*movtf_aarch64"
976 [(set (match_operand:TF 0
977 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
979 "general_operand" " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
980 "TARGET_FLOAT && (register_operand (operands[0], TFmode)
981 || register_operand (operands[1], TFmode))"
983 orr\\t%0.16b, %1.16b, %1.16b
984 mov\\t%0, %1\;mov\\t%H0, %H1
985 fmov\\t%d0, %Q1\;fmov\\t%0.d[1], %R1
986 fmov\\t%Q0, %d1\;fmov\\t%R0, %1.d[1]
993 [(set_attr "v8type" "logic,move2,fmovi2f,fmovf2i,fconst,fconst,fpsimd_load,fpsimd_store,fpsimd_load2,fpsimd_store2")
994 (set_attr "mode" "DF,DF,DF,DF,DF,DF,TF,TF,DF,DF")
995 (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
996 (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
997 (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
1000 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1001 ;; fairly lax checking on the second memory operation.
1002 (define_insn "load_pair<mode>"
1003 [(set (match_operand:GPI 0 "register_operand" "=r")
1004 (match_operand:GPI 1 "aarch64_mem_pair_operand" "Ump"))
1005 (set (match_operand:GPI 2 "register_operand" "=r")
1006 (match_operand:GPI 3 "memory_operand" "m"))]
1007 "rtx_equal_p (XEXP (operands[3], 0),
1008 plus_constant (Pmode,
1009 XEXP (operands[1], 0),
1010 GET_MODE_SIZE (<MODE>mode)))"
1011 "ldp\\t%<w>0, %<w>2, %1"
1012 [(set_attr "v8type" "load2")
1013 (set_attr "mode" "<MODE>")]
1016 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1017 ;; fairly lax checking on the second memory operation.
1018 (define_insn "store_pair<mode>"
1019 [(set (match_operand:GPI 0 "aarch64_mem_pair_operand" "=Ump")
1020 (match_operand:GPI 1 "register_operand" "r"))
1021 (set (match_operand:GPI 2 "memory_operand" "=m")
1022 (match_operand:GPI 3 "register_operand" "r"))]
1023 "rtx_equal_p (XEXP (operands[2], 0),
1024 plus_constant (Pmode,
1025 XEXP (operands[0], 0),
1026 GET_MODE_SIZE (<MODE>mode)))"
1027 "stp\\t%<w>1, %<w>3, %0"
1028 [(set_attr "v8type" "store2")
1029 (set_attr "mode" "<MODE>")]
1032 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1033 ;; fairly lax checking on the second memory operation.
1034 (define_insn "load_pair<mode>"
1035 [(set (match_operand:GPF 0 "register_operand" "=w")
1036 (match_operand:GPF 1 "aarch64_mem_pair_operand" "Ump"))
1037 (set (match_operand:GPF 2 "register_operand" "=w")
1038 (match_operand:GPF 3 "memory_operand" "m"))]
1039 "rtx_equal_p (XEXP (operands[3], 0),
1040 plus_constant (Pmode,
1041 XEXP (operands[1], 0),
1042 GET_MODE_SIZE (<MODE>mode)))"
1043 "ldp\\t%<w>0, %<w>2, %1"
1044 [(set_attr "v8type" "fpsimd_load2")
1045 (set_attr "mode" "<MODE>")]
1048 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1049 ;; fairly lax checking on the second memory operation.
1050 (define_insn "store_pair<mode>"
1051 [(set (match_operand:GPF 0 "aarch64_mem_pair_operand" "=Ump")
1052 (match_operand:GPF 1 "register_operand" "w"))
1053 (set (match_operand:GPF 2 "memory_operand" "=m")
1054 (match_operand:GPF 3 "register_operand" "w"))]
1055 "rtx_equal_p (XEXP (operands[2], 0),
1056 plus_constant (Pmode,
1057 XEXP (operands[0], 0),
1058 GET_MODE_SIZE (<MODE>mode)))"
1059 "stp\\t%<w>1, %<w>3, %0"
1060 [(set_attr "v8type" "fpsimd_load2")
1061 (set_attr "mode" "<MODE>")]
1064 ;; Load pair with writeback. This is primarily used in function epilogues
1065 ;; when restoring [fp,lr]
1066 (define_insn "loadwb_pair<GPI:mode>_<PTR:mode>"
1068 [(set (match_operand:PTR 0 "register_operand" "=k")
1069 (plus:PTR (match_operand:PTR 1 "register_operand" "0")
1070 (match_operand:PTR 4 "const_int_operand" "n")))
1071 (set (match_operand:GPI 2 "register_operand" "=r")
1072 (mem:GPI (plus:PTR (match_dup 1)
1074 (set (match_operand:GPI 3 "register_operand" "=r")
1075 (mem:GPI (plus:PTR (match_dup 1)
1076 (match_operand:PTR 5 "const_int_operand" "n"))))])]
1077 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1078 "ldp\\t%<w>2, %<w>3, [%1], %4"
1079 [(set_attr "v8type" "load2")
1080 (set_attr "mode" "<GPI:MODE>")]
1083 ;; Store pair with writeback. This is primarily used in function prologues
1084 ;; when saving [fp,lr]
1085 (define_insn "storewb_pair<GPI:mode>_<PTR:mode>"
1087 [(set (match_operand:PTR 0 "register_operand" "=&k")
1088 (plus:PTR (match_operand:PTR 1 "register_operand" "0")
1089 (match_operand:PTR 4 "const_int_operand" "n")))
1090 (set (mem:GPI (plus:PTR (match_dup 0)
1092 (match_operand:GPI 2 "register_operand" "r"))
1093 (set (mem:GPI (plus:PTR (match_dup 0)
1094 (match_operand:PTR 5 "const_int_operand" "n")))
1095 (match_operand:GPI 3 "register_operand" "r"))])]
1096 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1097 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1098 [(set_attr "v8type" "store2")
1099 (set_attr "mode" "<GPI:MODE>")]
1102 ;; -------------------------------------------------------------------
1103 ;; Sign/Zero extension
1104 ;; -------------------------------------------------------------------
1106 (define_expand "<optab>sidi2"
1107 [(set (match_operand:DI 0 "register_operand")
1108 (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1112 (define_insn "*extendsidi2_aarch64"
1113 [(set (match_operand:DI 0 "register_operand" "=r,r")
1114 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1119 [(set_attr "v8type" "extend,load1")
1120 (set_attr "mode" "DI")]
1123 (define_insn "*zero_extendsidi2_aarch64"
1124 [(set (match_operand:DI 0 "register_operand" "=r,r")
1125 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1130 [(set_attr "v8type" "extend,load1")
1131 (set_attr "mode" "DI")]
1134 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1135 [(set (match_operand:GPI 0 "register_operand")
1136 (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1140 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1141 [(set (match_operand:GPI 0 "register_operand" "=r,r")
1142 (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1145 sxt<SHORT:size>\t%<GPI:w>0, %w1
1146 ldrs<SHORT:size>\t%<GPI:w>0, %1"
1147 [(set_attr "v8type" "extend,load1")
1148 (set_attr "mode" "<GPI:MODE>")]
1151 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1152 [(set (match_operand:GPI 0 "register_operand" "=r,r")
1153 (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1156 uxt<SHORT:size>\t%<GPI:w>0, %w1
1157 ldr<SHORT:size>\t%w0, %1"
1158 [(set_attr "v8type" "extend,load1")
1159 (set_attr "mode" "<GPI:MODE>")]
1162 (define_expand "<optab>qihi2"
1163 [(set (match_operand:HI 0 "register_operand")
1164 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1168 (define_insn "*<optab>qihi2_aarch64"
1169 [(set (match_operand:HI 0 "register_operand" "=r,r")
1170 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1175 [(set_attr "v8type" "extend,load1")
1176 (set_attr "mode" "HI")]
1179 ;; -------------------------------------------------------------------
1180 ;; Simple arithmetic
1181 ;; -------------------------------------------------------------------
1183 (define_expand "add<mode>3"
1185 (match_operand:GPI 0 "register_operand" "")
1186 (plus:GPI (match_operand:GPI 1 "register_operand" "")
1187 (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1190 if (! aarch64_plus_operand (operands[2], VOIDmode))
1192 rtx subtarget = ((optimize && can_create_pseudo_p ())
1193 ? gen_reg_rtx (<MODE>mode) : operands[0]);
1194 HOST_WIDE_INT imm = INTVAL (operands[2]);
1197 imm = -(-imm & ~0xfff);
1201 emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1202 operands[1] = subtarget;
1203 operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1208 (define_insn "*addsi3_aarch64"
1210 (match_operand:SI 0 "register_operand" "=rk,rk,rk")
1212 (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1213 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J")))]
1218 sub\\t%w0, %w1, #%n2"
1219 [(set_attr "v8type" "alu")
1220 (set_attr "mode" "SI")]
1223 ;; zero_extend version of above
1224 (define_insn "*addsi3_aarch64_uxtw"
1226 (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1228 (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1229 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1234 sub\\t%w0, %w1, #%n2"
1235 [(set_attr "v8type" "alu")
1236 (set_attr "mode" "SI")]
1239 (define_insn "*adddi3_aarch64"
1241 (match_operand:DI 0 "register_operand" "=rk,rk,rk,!w")
1243 (match_operand:DI 1 "register_operand" "%rk,rk,rk,!w")
1244 (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,!w")))]
1249 sub\\t%x0, %x1, #%n2
1250 add\\t%d0, %d1, %d2"
1251 [(set_attr "v8type" "alu")
1252 (set_attr "mode" "DI")
1253 (set_attr "simd" "*,*,*,yes")]
1256 (define_insn "*add<mode>3_compare0"
1257 [(set (reg:CC_NZ CC_REGNUM)
1259 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r")
1260 (match_operand:GPI 2 "aarch64_plus_operand" "rI,J"))
1262 (set (match_operand:GPI 0 "register_operand" "=r,r")
1263 (plus:GPI (match_dup 1) (match_dup 2)))]
1266 adds\\t%<w>0, %<w>1, %<w>2
1267 subs\\t%<w>0, %<w>1, #%n2"
1268 [(set_attr "v8type" "alus")
1269 (set_attr "mode" "<MODE>")]
1272 ;; zero_extend version of above
1273 (define_insn "*addsi3_compare0_uxtw"
1274 [(set (reg:CC_NZ CC_REGNUM)
1276 (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
1277 (match_operand:SI 2 "aarch64_plus_operand" "rI,J"))
1279 (set (match_operand:DI 0 "register_operand" "=r,r")
1280 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1283 adds\\t%w0, %w1, %w2
1284 subs\\t%w0, %w1, #%n2"
1285 [(set_attr "v8type" "alus")
1286 (set_attr "mode" "SI")]
1289 (define_insn "*add<mode>3nr_compare0"
1290 [(set (reg:CC_NZ CC_REGNUM)
1292 (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r")
1293 (match_operand:GPI 1 "aarch64_plus_operand" "rI,J"))
1299 [(set_attr "v8type" "alus")
1300 (set_attr "mode" "<MODE>")]
1303 (define_insn "*compare_neg<mode>"
1304 [(set (reg:CC CC_REGNUM)
1306 (match_operand:GPI 0 "register_operand" "r")
1307 (neg:GPI (match_operand:GPI 1 "register_operand" "r"))))]
1309 "cmn\\t%<w>0, %<w>1"
1310 [(set_attr "v8type" "alus")
1311 (set_attr "mode" "<MODE>")]
1314 (define_insn "*add_<shift>_<mode>"
1315 [(set (match_operand:GPI 0 "register_operand" "=rk")
1316 (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1317 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1318 (match_operand:GPI 3 "register_operand" "r")))]
1320 "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1321 [(set_attr "v8type" "alu_shift")
1322 (set_attr "mode" "<MODE>")]
1325 ;; zero_extend version of above
1326 (define_insn "*add_<shift>_si_uxtw"
1327 [(set (match_operand:DI 0 "register_operand" "=rk")
1329 (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1330 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1331 (match_operand:SI 3 "register_operand" "r"))))]
1333 "add\\t%w0, %w3, %w1, <shift> %2"
1334 [(set_attr "v8type" "alu_shift")
1335 (set_attr "mode" "SI")]
1338 (define_insn "*add_mul_imm_<mode>"
1339 [(set (match_operand:GPI 0 "register_operand" "=rk")
1340 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1341 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1342 (match_operand:GPI 3 "register_operand" "r")))]
1344 "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1345 [(set_attr "v8type" "alu_shift")
1346 (set_attr "mode" "<MODE>")]
1349 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1350 [(set (match_operand:GPI 0 "register_operand" "=rk")
1351 (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1352 (match_operand:GPI 2 "register_operand" "r")))]
1354 "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1355 [(set_attr "v8type" "alu_ext")
1356 (set_attr "mode" "<GPI:MODE>")]
1359 ;; zero_extend version of above
1360 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1361 [(set (match_operand:DI 0 "register_operand" "=rk")
1363 (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1364 (match_operand:GPI 2 "register_operand" "r"))))]
1366 "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1367 [(set_attr "v8type" "alu_ext")
1368 (set_attr "mode" "SI")]
1371 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1372 [(set (match_operand:GPI 0 "register_operand" "=rk")
1373 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1374 (match_operand:ALLX 1 "register_operand" "r"))
1375 (match_operand 2 "aarch64_imm3" "Ui3"))
1376 (match_operand:GPI 3 "register_operand" "r")))]
1378 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1379 [(set_attr "v8type" "alu_ext")
1380 (set_attr "mode" "<GPI:MODE>")]
1383 ;; zero_extend version of above
1384 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1385 [(set (match_operand:DI 0 "register_operand" "=rk")
1387 (plus:SI (ashift:SI (ANY_EXTEND:SI
1388 (match_operand:SHORT 1 "register_operand" "r"))
1389 (match_operand 2 "aarch64_imm3" "Ui3"))
1390 (match_operand:SI 3 "register_operand" "r"))))]
1392 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1393 [(set_attr "v8type" "alu_ext")
1394 (set_attr "mode" "SI")]
1397 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1398 [(set (match_operand:GPI 0 "register_operand" "=rk")
1399 (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1400 (match_operand:ALLX 1 "register_operand" "r"))
1401 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1402 (match_operand:GPI 3 "register_operand" "r")))]
1404 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1405 [(set_attr "v8type" "alu_ext")
1406 (set_attr "mode" "<GPI:MODE>")]
1409 ;; zero_extend version of above
1410 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1411 [(set (match_operand:DI 0 "register_operand" "=rk")
1412 (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1413 (match_operand:SHORT 1 "register_operand" "r"))
1414 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1415 (match_operand:SI 3 "register_operand" "r"))))]
1417 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1418 [(set_attr "v8type" "alu_ext")
1419 (set_attr "mode" "SI")]
1422 (define_insn "*add_<optab><mode>_multp2"
1423 [(set (match_operand:GPI 0 "register_operand" "=rk")
1424 (plus:GPI (ANY_EXTRACT:GPI
1425 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1426 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1427 (match_operand 3 "const_int_operand" "n")
1429 (match_operand:GPI 4 "register_operand" "r")))]
1430 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1431 "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1432 [(set_attr "v8type" "alu_ext")
1433 (set_attr "mode" "<MODE>")]
1436 ;; zero_extend version of above
1437 (define_insn "*add_<optab>si_multp2_uxtw"
1438 [(set (match_operand:DI 0 "register_operand" "=rk")
1440 (plus:SI (ANY_EXTRACT:SI
1441 (mult:SI (match_operand:SI 1 "register_operand" "r")
1442 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1443 (match_operand 3 "const_int_operand" "n")
1445 (match_operand:SI 4 "register_operand" "r"))))]
1446 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1447 "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1448 [(set_attr "v8type" "alu_ext")
1449 (set_attr "mode" "SI")]
1452 (define_insn "*add<mode>3_carryin"
1454 (match_operand:GPI 0 "register_operand" "=r")
1455 (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1457 (match_operand:GPI 1 "register_operand" "r")
1458 (match_operand:GPI 2 "register_operand" "r"))))]
1460 "adc\\t%<w>0, %<w>1, %<w>2"
1461 [(set_attr "v8type" "adc")
1462 (set_attr "mode" "<MODE>")]
1465 ;; zero_extend version of above
1466 (define_insn "*addsi3_carryin_uxtw"
1468 (match_operand:DI 0 "register_operand" "=r")
1470 (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1472 (match_operand:SI 1 "register_operand" "r")
1473 (match_operand:SI 2 "register_operand" "r")))))]
1475 "adc\\t%w0, %w1, %w2"
1476 [(set_attr "v8type" "adc")
1477 (set_attr "mode" "SI")]
1480 (define_insn "*add<mode>3_carryin_alt1"
1482 (match_operand:GPI 0 "register_operand" "=r")
1484 (match_operand:GPI 1 "register_operand" "r")
1485 (match_operand:GPI 2 "register_operand" "r"))
1486 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1488 "adc\\t%<w>0, %<w>1, %<w>2"
1489 [(set_attr "v8type" "adc")
1490 (set_attr "mode" "<MODE>")]
1493 ;; zero_extend version of above
1494 (define_insn "*addsi3_carryin_alt1_uxtw"
1496 (match_operand:DI 0 "register_operand" "=r")
1499 (match_operand:SI 1 "register_operand" "r")
1500 (match_operand:SI 2 "register_operand" "r"))
1501 (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1503 "adc\\t%w0, %w1, %w2"
1504 [(set_attr "v8type" "adc")
1505 (set_attr "mode" "SI")]
1508 (define_insn "*add<mode>3_carryin_alt2"
1510 (match_operand:GPI 0 "register_operand" "=r")
1512 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1513 (match_operand:GPI 1 "register_operand" "r"))
1514 (match_operand:GPI 2 "register_operand" "r")))]
1516 "adc\\t%<w>0, %<w>1, %<w>2"
1517 [(set_attr "v8type" "adc")
1518 (set_attr "mode" "<MODE>")]
1521 ;; zero_extend version of above
1522 (define_insn "*addsi3_carryin_alt2_uxtw"
1524 (match_operand:DI 0 "register_operand" "=r")
1527 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1528 (match_operand:SI 1 "register_operand" "r"))
1529 (match_operand:SI 2 "register_operand" "r"))))]
1531 "adc\\t%w0, %w1, %w2"
1532 [(set_attr "v8type" "adc")
1533 (set_attr "mode" "SI")]
1536 (define_insn "*add<mode>3_carryin_alt3"
1538 (match_operand:GPI 0 "register_operand" "=r")
1540 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1541 (match_operand:GPI 2 "register_operand" "r"))
1542 (match_operand:GPI 1 "register_operand" "r")))]
1544 "adc\\t%<w>0, %<w>1, %<w>2"
1545 [(set_attr "v8type" "adc")
1546 (set_attr "mode" "<MODE>")]
1549 ;; zero_extend version of above
1550 (define_insn "*addsi3_carryin_alt3_uxtw"
1552 (match_operand:DI 0 "register_operand" "=r")
1555 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1556 (match_operand:SI 2 "register_operand" "r"))
1557 (match_operand:SI 1 "register_operand" "r"))))]
1559 "adc\\t%w0, %w1, %w2"
1560 [(set_attr "v8type" "adc")
1561 (set_attr "mode" "SI")]
1564 (define_insn "*add_uxt<mode>_multp2"
1565 [(set (match_operand:GPI 0 "register_operand" "=rk")
1567 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1568 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1569 (match_operand 3 "const_int_operand" "n"))
1570 (match_operand:GPI 4 "register_operand" "r")))]
1571 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1573 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1574 INTVAL (operands[3])));
1575 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1576 [(set_attr "v8type" "alu_ext")
1577 (set_attr "mode" "<MODE>")]
1580 ;; zero_extend version of above
1581 (define_insn "*add_uxtsi_multp2_uxtw"
1582 [(set (match_operand:DI 0 "register_operand" "=rk")
1585 (mult:SI (match_operand:SI 1 "register_operand" "r")
1586 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1587 (match_operand 3 "const_int_operand" "n"))
1588 (match_operand:SI 4 "register_operand" "r"))))]
1589 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1591 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1592 INTVAL (operands[3])));
1593 return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1594 [(set_attr "v8type" "alu_ext")
1595 (set_attr "mode" "SI")]
1598 (define_insn "subsi3"
1599 [(set (match_operand:SI 0 "register_operand" "=rk")
1600 (minus:SI (match_operand:SI 1 "register_operand" "r")
1601 (match_operand:SI 2 "register_operand" "r")))]
1603 "sub\\t%w0, %w1, %w2"
1604 [(set_attr "v8type" "alu")
1605 (set_attr "mode" "SI")]
1608 ;; zero_extend version of above
1609 (define_insn "*subsi3_uxtw"
1610 [(set (match_operand:DI 0 "register_operand" "=rk")
1612 (minus:SI (match_operand:SI 1 "register_operand" "r")
1613 (match_operand:SI 2 "register_operand" "r"))))]
1615 "sub\\t%w0, %w1, %w2"
1616 [(set_attr "v8type" "alu")
1617 (set_attr "mode" "SI")]
1620 (define_insn "subdi3"
1621 [(set (match_operand:DI 0 "register_operand" "=rk,!w")
1622 (minus:DI (match_operand:DI 1 "register_operand" "r,!w")
1623 (match_operand:DI 2 "register_operand" "r,!w")))]
1627 sub\\t%d0, %d1, %d2"
1628 [(set_attr "v8type" "alu")
1629 (set_attr "mode" "DI")
1630 (set_attr "simd" "*,yes")]
1634 (define_insn "*sub<mode>3_compare0"
1635 [(set (reg:CC_NZ CC_REGNUM)
1636 (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1637 (match_operand:GPI 2 "register_operand" "r"))
1639 (set (match_operand:GPI 0 "register_operand" "=r")
1640 (minus:GPI (match_dup 1) (match_dup 2)))]
1642 "subs\\t%<w>0, %<w>1, %<w>2"
1643 [(set_attr "v8type" "alus")
1644 (set_attr "mode" "<MODE>")]
1647 ;; zero_extend version of above
1648 (define_insn "*subsi3_compare0_uxtw"
1649 [(set (reg:CC_NZ CC_REGNUM)
1650 (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1651 (match_operand:SI 2 "register_operand" "r"))
1653 (set (match_operand:DI 0 "register_operand" "=r")
1654 (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1656 "subs\\t%w0, %w1, %w2"
1657 [(set_attr "v8type" "alus")
1658 (set_attr "mode" "SI")]
1661 (define_insn "*sub_<shift>_<mode>"
1662 [(set (match_operand:GPI 0 "register_operand" "=rk")
1663 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1665 (match_operand:GPI 1 "register_operand" "r")
1666 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1668 "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1669 [(set_attr "v8type" "alu_shift")
1670 (set_attr "mode" "<MODE>")]
1673 ;; zero_extend version of above
1674 (define_insn "*sub_<shift>_si_uxtw"
1675 [(set (match_operand:DI 0 "register_operand" "=rk")
1677 (minus:SI (match_operand:SI 3 "register_operand" "r")
1679 (match_operand:SI 1 "register_operand" "r")
1680 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1682 "sub\\t%w0, %w3, %w1, <shift> %2"
1683 [(set_attr "v8type" "alu_shift")
1684 (set_attr "mode" "SI")]
1687 (define_insn "*sub_mul_imm_<mode>"
1688 [(set (match_operand:GPI 0 "register_operand" "=rk")
1689 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1691 (match_operand:GPI 1 "register_operand" "r")
1692 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1694 "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1695 [(set_attr "v8type" "alu_shift")
1696 (set_attr "mode" "<MODE>")]
1699 ;; zero_extend version of above
1700 (define_insn "*sub_mul_imm_si_uxtw"
1701 [(set (match_operand:DI 0 "register_operand" "=rk")
1703 (minus:SI (match_operand:SI 3 "register_operand" "r")
1705 (match_operand:SI 1 "register_operand" "r")
1706 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
1708 "sub\\t%w0, %w3, %w1, lsl %p2"
1709 [(set_attr "v8type" "alu_shift")
1710 (set_attr "mode" "SI")]
1713 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
1714 [(set (match_operand:GPI 0 "register_operand" "=rk")
1715 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1717 (match_operand:ALLX 2 "register_operand" "r"))))]
1719 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1720 [(set_attr "v8type" "alu_ext")
1721 (set_attr "mode" "<GPI:MODE>")]
1724 ;; zero_extend version of above
1725 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
1726 [(set (match_operand:DI 0 "register_operand" "=rk")
1728 (minus:SI (match_operand:SI 1 "register_operand" "r")
1730 (match_operand:SHORT 2 "register_operand" "r")))))]
1732 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
1733 [(set_attr "v8type" "alu_ext")
1734 (set_attr "mode" "SI")]
1737 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
1738 [(set (match_operand:GPI 0 "register_operand" "=rk")
1739 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1740 (ashift:GPI (ANY_EXTEND:GPI
1741 (match_operand:ALLX 2 "register_operand" "r"))
1742 (match_operand 3 "aarch64_imm3" "Ui3"))))]
1744 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1745 [(set_attr "v8type" "alu_ext")
1746 (set_attr "mode" "<GPI:MODE>")]
1749 ;; zero_extend version of above
1750 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
1751 [(set (match_operand:DI 0 "register_operand" "=rk")
1753 (minus:SI (match_operand:SI 1 "register_operand" "r")
1754 (ashift:SI (ANY_EXTEND:SI
1755 (match_operand:SHORT 2 "register_operand" "r"))
1756 (match_operand 3 "aarch64_imm3" "Ui3")))))]
1758 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
1759 [(set_attr "v8type" "alu_ext")
1760 (set_attr "mode" "SI")]
1763 (define_insn "*sub_<optab><mode>_multp2"
1764 [(set (match_operand:GPI 0 "register_operand" "=rk")
1765 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1767 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1768 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1769 (match_operand 3 "const_int_operand" "n")
1771 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1772 "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1773 [(set_attr "v8type" "alu_ext")
1774 (set_attr "mode" "<MODE>")]
1777 ;; zero_extend version of above
1778 (define_insn "*sub_<optab>si_multp2_uxtw"
1779 [(set (match_operand:DI 0 "register_operand" "=rk")
1781 (minus:SI (match_operand:SI 4 "register_operand" "r")
1783 (mult:SI (match_operand:SI 1 "register_operand" "r")
1784 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1785 (match_operand 3 "const_int_operand" "n")
1787 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1788 "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1789 [(set_attr "v8type" "alu_ext")
1790 (set_attr "mode" "SI")]
1793 (define_insn "*sub_uxt<mode>_multp2"
1794 [(set (match_operand:GPI 0 "register_operand" "=rk")
1795 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1797 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1798 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1799 (match_operand 3 "const_int_operand" "n"))))]
1800 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1802 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1803 INTVAL (operands[3])));
1804 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1805 [(set_attr "v8type" "alu_ext")
1806 (set_attr "mode" "<MODE>")]
1809 ;; zero_extend version of above
1810 (define_insn "*sub_uxtsi_multp2_uxtw"
1811 [(set (match_operand:DI 0 "register_operand" "=rk")
1813 (minus:SI (match_operand:SI 4 "register_operand" "r")
1815 (mult:SI (match_operand:SI 1 "register_operand" "r")
1816 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1817 (match_operand 3 "const_int_operand" "n")))))]
1818 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1820 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1821 INTVAL (operands[3])));
1822 return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
1823 [(set_attr "v8type" "alu_ext")
1824 (set_attr "mode" "SI")]
1827 (define_insn "neg<mode>2"
1828 [(set (match_operand:GPI 0 "register_operand" "=r")
1829 (neg:GPI (match_operand:GPI 1 "register_operand" "r")))]
1831 "neg\\t%<w>0, %<w>1"
1832 [(set_attr "v8type" "alu")
1833 (set_attr "mode" "<MODE>")]
1836 ;; zero_extend version of above
1837 (define_insn "*negsi2_uxtw"
1838 [(set (match_operand:DI 0 "register_operand" "=r")
1839 (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
1842 [(set_attr "v8type" "alu")
1843 (set_attr "mode" "SI")]
1846 (define_insn "*neg<mode>2_compare0"
1847 [(set (reg:CC_NZ CC_REGNUM)
1848 (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
1850 (set (match_operand:GPI 0 "register_operand" "=r")
1851 (neg:GPI (match_dup 1)))]
1853 "negs\\t%<w>0, %<w>1"
1854 [(set_attr "v8type" "alus")
1855 (set_attr "mode" "<MODE>")]
1858 ;; zero_extend version of above
1859 (define_insn "*negsi2_compare0_uxtw"
1860 [(set (reg:CC_NZ CC_REGNUM)
1861 (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
1863 (set (match_operand:DI 0 "register_operand" "=r")
1864 (zero_extend:DI (neg:SI (match_dup 1))))]
1867 [(set_attr "v8type" "alus")
1868 (set_attr "mode" "SI")]
1871 (define_insn "*neg_<shift>_<mode>2"
1872 [(set (match_operand:GPI 0 "register_operand" "=r")
1873 (neg:GPI (ASHIFT:GPI
1874 (match_operand:GPI 1 "register_operand" "r")
1875 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1877 "neg\\t%<w>0, %<w>1, <shift> %2"
1878 [(set_attr "v8type" "alu_shift")
1879 (set_attr "mode" "<MODE>")]
1882 ;; zero_extend version of above
1883 (define_insn "*neg_<shift>_si2_uxtw"
1884 [(set (match_operand:DI 0 "register_operand" "=r")
1887 (match_operand:SI 1 "register_operand" "r")
1888 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1890 "neg\\t%w0, %w1, <shift> %2"
1891 [(set_attr "v8type" "alu_shift")
1892 (set_attr "mode" "SI")]
1895 (define_insn "*neg_mul_imm_<mode>2"
1896 [(set (match_operand:GPI 0 "register_operand" "=r")
1898 (match_operand:GPI 1 "register_operand" "r")
1899 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1901 "neg\\t%<w>0, %<w>1, lsl %p2"
1902 [(set_attr "v8type" "alu_shift")
1903 (set_attr "mode" "<MODE>")]
1906 ;; zero_extend version of above
1907 (define_insn "*neg_mul_imm_si2_uxtw"
1908 [(set (match_operand:DI 0 "register_operand" "=r")
1911 (match_operand:SI 1 "register_operand" "r")
1912 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
1914 "neg\\t%w0, %w1, lsl %p2"
1915 [(set_attr "v8type" "alu_shift")
1916 (set_attr "mode" "SI")]
1919 (define_insn "mul<mode>3"
1920 [(set (match_operand:GPI 0 "register_operand" "=r")
1921 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1922 (match_operand:GPI 2 "register_operand" "r")))]
1924 "mul\\t%<w>0, %<w>1, %<w>2"
1925 [(set_attr "v8type" "mult")
1926 (set_attr "mode" "<MODE>")]
1929 ;; zero_extend version of above
1930 (define_insn "*mulsi3_uxtw"
1931 [(set (match_operand:DI 0 "register_operand" "=r")
1933 (mult:SI (match_operand:SI 1 "register_operand" "r")
1934 (match_operand:SI 2 "register_operand" "r"))))]
1936 "mul\\t%w0, %w1, %w2"
1937 [(set_attr "v8type" "mult")
1938 (set_attr "mode" "SI")]
1941 (define_insn "*madd<mode>"
1942 [(set (match_operand:GPI 0 "register_operand" "=r")
1943 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1944 (match_operand:GPI 2 "register_operand" "r"))
1945 (match_operand:GPI 3 "register_operand" "r")))]
1947 "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
1948 [(set_attr "v8type" "madd")
1949 (set_attr "mode" "<MODE>")]
1952 ;; zero_extend version of above
1953 (define_insn "*maddsi_uxtw"
1954 [(set (match_operand:DI 0 "register_operand" "=r")
1956 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
1957 (match_operand:SI 2 "register_operand" "r"))
1958 (match_operand:SI 3 "register_operand" "r"))))]
1960 "madd\\t%w0, %w1, %w2, %w3"
1961 [(set_attr "v8type" "madd")
1962 (set_attr "mode" "SI")]
1965 (define_insn "*msub<mode>"
1966 [(set (match_operand:GPI 0 "register_operand" "=r")
1967 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1968 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1969 (match_operand:GPI 2 "register_operand" "r"))))]
1972 "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
1973 [(set_attr "v8type" "madd")
1974 (set_attr "mode" "<MODE>")]
1977 ;; zero_extend version of above
1978 (define_insn "*msubsi_uxtw"
1979 [(set (match_operand:DI 0 "register_operand" "=r")
1981 (minus:SI (match_operand:SI 3 "register_operand" "r")
1982 (mult:SI (match_operand:SI 1 "register_operand" "r")
1983 (match_operand:SI 2 "register_operand" "r")))))]
1986 "msub\\t%w0, %w1, %w2, %w3"
1987 [(set_attr "v8type" "madd")
1988 (set_attr "mode" "SI")]
1991 (define_insn "*mul<mode>_neg"
1992 [(set (match_operand:GPI 0 "register_operand" "=r")
1993 (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
1994 (match_operand:GPI 2 "register_operand" "r")))]
1997 "mneg\\t%<w>0, %<w>1, %<w>2"
1998 [(set_attr "v8type" "mult")
1999 (set_attr "mode" "<MODE>")]
2002 ;; zero_extend version of above
2003 (define_insn "*mulsi_neg_uxtw"
2004 [(set (match_operand:DI 0 "register_operand" "=r")
2006 (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2007 (match_operand:SI 2 "register_operand" "r"))))]
2010 "mneg\\t%w0, %w1, %w2"
2011 [(set_attr "v8type" "mult")
2012 (set_attr "mode" "SI")]
2015 (define_insn "<su_optab>mulsidi3"
2016 [(set (match_operand:DI 0 "register_operand" "=r")
2017 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2018 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2020 "<su>mull\\t%0, %w1, %w2"
2021 [(set_attr "v8type" "mull")
2022 (set_attr "mode" "DI")]
2025 (define_insn "<su_optab>maddsidi4"
2026 [(set (match_operand:DI 0 "register_operand" "=r")
2028 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2029 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2030 (match_operand:DI 3 "register_operand" "r")))]
2032 "<su>maddl\\t%0, %w1, %w2, %3"
2033 [(set_attr "v8type" "maddl")
2034 (set_attr "mode" "DI")]
2037 (define_insn "<su_optab>msubsidi4"
2038 [(set (match_operand:DI 0 "register_operand" "=r")
2040 (match_operand:DI 3 "register_operand" "r")
2041 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2043 (match_operand:SI 2 "register_operand" "r")))))]
2045 "<su>msubl\\t%0, %w1, %w2, %3"
2046 [(set_attr "v8type" "maddl")
2047 (set_attr "mode" "DI")]
2050 (define_insn "*<su_optab>mulsidi_neg"
2051 [(set (match_operand:DI 0 "register_operand" "=r")
2053 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2054 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2056 "<su>mnegl\\t%0, %w1, %w2"
2057 [(set_attr "v8type" "mull")
2058 (set_attr "mode" "DI")]
2061 (define_insn "<su>muldi3_highpart"
2062 [(set (match_operand:DI 0 "register_operand" "=r")
2066 (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2067 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2070 "<su>mulh\\t%0, %1, %2"
2071 [(set_attr "v8type" "mulh")
2072 (set_attr "mode" "DI")]
2075 (define_insn "<su_optab>div<mode>3"
2076 [(set (match_operand:GPI 0 "register_operand" "=r")
2077 (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2078 (match_operand:GPI 2 "register_operand" "r")))]
2080 "<su>div\\t%<w>0, %<w>1, %<w>2"
2081 [(set_attr "v8type" "<su>div")
2082 (set_attr "mode" "<MODE>")]
2085 ;; zero_extend version of above
2086 (define_insn "*<su_optab>divsi3_uxtw"
2087 [(set (match_operand:DI 0 "register_operand" "=r")
2089 (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2090 (match_operand:SI 2 "register_operand" "r"))))]
2092 "<su>div\\t%w0, %w1, %w2"
2093 [(set_attr "v8type" "<su>div")
2094 (set_attr "mode" "SI")]
2097 ;; -------------------------------------------------------------------
2099 ;; -------------------------------------------------------------------
2101 (define_insn "*cmp<mode>"
2102 [(set (reg:CC CC_REGNUM)
2103 (compare:CC (match_operand:GPI 0 "register_operand" "r,r")
2104 (match_operand:GPI 1 "aarch64_plus_operand" "rI,J")))]
2109 [(set_attr "v8type" "alus")
2110 (set_attr "mode" "<MODE>")]
2113 (define_insn "*cmp<mode>"
2114 [(set (reg:CCFP CC_REGNUM)
2115 (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2116 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2120 fcmp\\t%<s>0, %<s>1"
2121 [(set_attr "v8type" "fcmp")
2122 (set_attr "mode" "<MODE>")]
2125 (define_insn "*cmpe<mode>"
2126 [(set (reg:CCFPE CC_REGNUM)
2127 (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2128 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2132 fcmpe\\t%<s>0, %<s>1"
2133 [(set_attr "v8type" "fcmp")
2134 (set_attr "mode" "<MODE>")]
2137 (define_insn "*cmp_swp_<shift>_reg<mode>"
2138 [(set (reg:CC_SWP CC_REGNUM)
2139 (compare:CC_SWP (ASHIFT:GPI
2140 (match_operand:GPI 0 "register_operand" "r")
2141 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2142 (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2144 "cmp\\t%<w>2, %<w>0, <shift> %1"
2145 [(set_attr "v8type" "alus_shift")
2146 (set_attr "mode" "<MODE>")]
2149 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2150 [(set (reg:CC_SWP CC_REGNUM)
2151 (compare:CC_SWP (ANY_EXTEND:GPI
2152 (match_operand:ALLX 0 "register_operand" "r"))
2153 (match_operand:GPI 1 "register_operand" "r")))]
2155 "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2156 [(set_attr "v8type" "alus_ext")
2157 (set_attr "mode" "<GPI:MODE>")]
2161 ;; -------------------------------------------------------------------
2162 ;; Store-flag and conditional select insns
2163 ;; -------------------------------------------------------------------
2165 (define_expand "cstore<mode>4"
2166 [(set (match_operand:SI 0 "register_operand" "")
2167 (match_operator:SI 1 "aarch64_comparison_operator"
2168 [(match_operand:GPI 2 "register_operand" "")
2169 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2172 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2174 operands[3] = const0_rtx;
2178 (define_expand "cstore<mode>4"
2179 [(set (match_operand:SI 0 "register_operand" "")
2180 (match_operator:SI 1 "aarch64_comparison_operator"
2181 [(match_operand:GPF 2 "register_operand" "")
2182 (match_operand:GPF 3 "register_operand" "")]))]
2185 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2187 operands[3] = const0_rtx;
2191 (define_insn "*cstore<mode>_insn"
2192 [(set (match_operand:ALLI 0 "register_operand" "=r")
2193 (match_operator:ALLI 1 "aarch64_comparison_operator"
2194 [(match_operand 2 "cc_register" "") (const_int 0)]))]
2197 [(set_attr "v8type" "csel")
2198 (set_attr "mode" "<MODE>")]
2201 ;; zero_extend version of the above
2202 (define_insn "*cstoresi_insn_uxtw"
2203 [(set (match_operand:DI 0 "register_operand" "=r")
2205 (match_operator:SI 1 "aarch64_comparison_operator"
2206 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2209 [(set_attr "v8type" "csel")
2210 (set_attr "mode" "SI")]
2213 (define_insn "*cstore<mode>_neg"
2214 [(set (match_operand:ALLI 0 "register_operand" "=r")
2215 (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2216 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2218 "csetm\\t%<w>0, %m1"
2219 [(set_attr "v8type" "csel")
2220 (set_attr "mode" "<MODE>")]
2223 ;; zero_extend version of the above
2224 (define_insn "*cstoresi_neg_uxtw"
2225 [(set (match_operand:DI 0 "register_operand" "=r")
2227 (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2228 [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2231 [(set_attr "v8type" "csel")
2232 (set_attr "mode" "SI")]
2235 (define_expand "cmov<mode>6"
2236 [(set (match_operand:GPI 0 "register_operand" "")
2238 (match_operator 1 "aarch64_comparison_operator"
2239 [(match_operand:GPI 2 "register_operand" "")
2240 (match_operand:GPI 3 "aarch64_plus_operand" "")])
2241 (match_operand:GPI 4 "register_operand" "")
2242 (match_operand:GPI 5 "register_operand" "")))]
2245 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2247 operands[3] = const0_rtx;
2251 (define_expand "cmov<mode>6"
2252 [(set (match_operand:GPF 0 "register_operand" "")
2254 (match_operator 1 "aarch64_comparison_operator"
2255 [(match_operand:GPF 2 "register_operand" "")
2256 (match_operand:GPF 3 "register_operand" "")])
2257 (match_operand:GPF 4 "register_operand" "")
2258 (match_operand:GPF 5 "register_operand" "")))]
2261 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2263 operands[3] = const0_rtx;
2267 (define_insn "*cmov<mode>_insn"
2268 [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2270 (match_operator 1 "aarch64_comparison_operator"
2271 [(match_operand 2 "cc_register" "") (const_int 0)])
2272 (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2273 (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2274 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2275 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2276 ;; Final two alternatives should be unreachable, but included for completeness
2278 csel\\t%<w>0, %<w>3, %<w>4, %m1
2279 csinv\\t%<w>0, %<w>3, <w>zr, %m1
2280 csinv\\t%<w>0, %<w>4, <w>zr, %M1
2281 csinc\\t%<w>0, %<w>3, <w>zr, %m1
2282 csinc\\t%<w>0, %<w>4, <w>zr, %M1
2285 [(set_attr "v8type" "csel")
2286 (set_attr "mode" "<MODE>")]
2289 ;; zero_extend version of above
2290 (define_insn "*cmovsi_insn_uxtw"
2291 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2294 (match_operator 1 "aarch64_comparison_operator"
2295 [(match_operand 2 "cc_register" "") (const_int 0)])
2296 (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2297 (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2298 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2299 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2300 ;; Final two alternatives should be unreachable, but included for completeness
2302 csel\\t%w0, %w3, %w4, %m1
2303 csinv\\t%w0, %w3, wzr, %m1
2304 csinv\\t%w0, %w4, wzr, %M1
2305 csinc\\t%w0, %w3, wzr, %m1
2306 csinc\\t%w0, %w4, wzr, %M1
2309 [(set_attr "v8type" "csel")
2310 (set_attr "mode" "SI")]
2313 (define_insn "*cmov<mode>_insn"
2314 [(set (match_operand:GPF 0 "register_operand" "=w")
2316 (match_operator 1 "aarch64_comparison_operator"
2317 [(match_operand 2 "cc_register" "") (const_int 0)])
2318 (match_operand:GPF 3 "register_operand" "w")
2319 (match_operand:GPF 4 "register_operand" "w")))]
2321 "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2322 [(set_attr "v8type" "fcsel")
2323 (set_attr "mode" "<MODE>")]
2326 (define_expand "mov<mode>cc"
2327 [(set (match_operand:ALLI 0 "register_operand" "")
2328 (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2329 (match_operand:ALLI 2 "register_operand" "")
2330 (match_operand:ALLI 3 "register_operand" "")))]
2334 enum rtx_code code = GET_CODE (operands[1]);
2336 if (code == UNEQ || code == LTGT)
2339 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2340 XEXP (operands[1], 1));
2341 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2345 (define_expand "mov<GPF:mode><GPI:mode>cc"
2346 [(set (match_operand:GPI 0 "register_operand" "")
2347 (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2348 (match_operand:GPF 2 "register_operand" "")
2349 (match_operand:GPF 3 "register_operand" "")))]
2353 enum rtx_code code = GET_CODE (operands[1]);
2355 if (code == UNEQ || code == LTGT)
2358 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2359 XEXP (operands[1], 1));
2360 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2364 (define_insn "*csinc2<mode>_insn"
2365 [(set (match_operand:GPI 0 "register_operand" "=r")
2366 (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator"
2367 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
2368 (match_operand:GPI 1 "register_operand" "r")))]
2370 "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2371 [(set_attr "v8type" "csel")
2372 (set_attr "mode" "<MODE>")])
2374 (define_insn "csinc3<mode>_insn"
2375 [(set (match_operand:GPI 0 "register_operand" "=r")
2377 (match_operator:GPI 1 "aarch64_comparison_operator"
2378 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2379 (plus:GPI (match_operand:GPI 3 "register_operand" "r")
2381 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2383 "csinc\\t%<w>0, %<w>4, %<w>3, %M1"
2384 [(set_attr "v8type" "csel")
2385 (set_attr "mode" "<MODE>")]
2388 (define_insn "*csinv3<mode>_insn"
2389 [(set (match_operand:GPI 0 "register_operand" "=r")
2391 (match_operator:GPI 1 "aarch64_comparison_operator"
2392 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2393 (not:GPI (match_operand:GPI 3 "register_operand" "r"))
2394 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2396 "csinv\\t%<w>0, %<w>4, %<w>3, %M1"
2397 [(set_attr "v8type" "csel")
2398 (set_attr "mode" "<MODE>")])
2400 (define_insn "*csneg3<mode>_insn"
2401 [(set (match_operand:GPI 0 "register_operand" "=r")
2403 (match_operator:GPI 1 "aarch64_comparison_operator"
2404 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2405 (neg:GPI (match_operand:GPI 3 "register_operand" "r"))
2406 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2408 "csneg\\t%<w>0, %<w>4, %<w>3, %M1"
2409 [(set_attr "v8type" "csel")
2410 (set_attr "mode" "<MODE>")])
2412 ;; -------------------------------------------------------------------
2413 ;; Logical operations
2414 ;; -------------------------------------------------------------------
2416 (define_insn "<optab><mode>3"
2417 [(set (match_operand:GPI 0 "register_operand" "=r,rk")
2418 (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2419 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
2421 "<logical>\\t%<w>0, %<w>1, %<w>2"
2422 [(set_attr "v8type" "logic,logic_imm")
2423 (set_attr "mode" "<MODE>")])
2425 ;; zero_extend version of above
2426 (define_insn "*<optab>si3_uxtw"
2427 [(set (match_operand:DI 0 "register_operand" "=r,rk")
2429 (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2430 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2432 "<logical>\\t%w0, %w1, %w2"
2433 [(set_attr "v8type" "logic,logic_imm")
2434 (set_attr "mode" "SI")])
2436 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2437 [(set (match_operand:GPI 0 "register_operand" "=r")
2438 (LOGICAL:GPI (SHIFT:GPI
2439 (match_operand:GPI 1 "register_operand" "r")
2440 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2441 (match_operand:GPI 3 "register_operand" "r")))]
2443 "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2444 [(set_attr "v8type" "logic_shift")
2445 (set_attr "mode" "<MODE>")])
2447 ;; zero_extend version of above
2448 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
2449 [(set (match_operand:DI 0 "register_operand" "=r")
2451 (LOGICAL:SI (SHIFT:SI
2452 (match_operand:SI 1 "register_operand" "r")
2453 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2454 (match_operand:SI 3 "register_operand" "r"))))]
2456 "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2457 [(set_attr "v8type" "logic_shift")
2458 (set_attr "mode" "SI")])
2460 (define_insn "one_cmpl<mode>2"
2461 [(set (match_operand:GPI 0 "register_operand" "=r")
2462 (not:GPI (match_operand:GPI 1 "register_operand" "r")))]
2464 "mvn\\t%<w>0, %<w>1"
2465 [(set_attr "v8type" "logic")
2466 (set_attr "mode" "<MODE>")])
2468 (define_insn "*one_cmpl_<optab><mode>2"
2469 [(set (match_operand:GPI 0 "register_operand" "=r")
2470 (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
2471 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2473 "mvn\\t%<w>0, %<w>1, <shift> %2"
2474 [(set_attr "v8type" "logic_shift")
2475 (set_attr "mode" "<MODE>")])
2477 (define_insn "*<LOGICAL:optab>_one_cmpl<mode>3"
2478 [(set (match_operand:GPI 0 "register_operand" "=r")
2479 (LOGICAL:GPI (not:GPI
2480 (match_operand:GPI 1 "register_operand" "r"))
2481 (match_operand:GPI 2 "register_operand" "r")))]
2483 "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1"
2484 [(set_attr "v8type" "logic")
2485 (set_attr "mode" "<MODE>")])
2487 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
2488 [(set (match_operand:GPI 0 "register_operand" "=r")
2489 (LOGICAL:GPI (not:GPI
2491 (match_operand:GPI 1 "register_operand" "r")
2492 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2493 (match_operand:GPI 3 "register_operand" "r")))]
2495 "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2496 [(set_attr "v8type" "logic_shift")
2497 (set_attr "mode" "<MODE>")])
2499 (define_insn "clz<mode>2"
2500 [(set (match_operand:GPI 0 "register_operand" "=r")
2501 (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
2503 "clz\\t%<w>0, %<w>1"
2504 [(set_attr "v8type" "clz")
2505 (set_attr "mode" "<MODE>")])
2507 (define_expand "ffs<mode>2"
2508 [(match_operand:GPI 0 "register_operand")
2509 (match_operand:GPI 1 "register_operand")]
2512 rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
2513 rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
2515 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2516 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2517 emit_insn (gen_csinc3<mode>_insn (operands[0], x, ccreg, operands[0], const0_rtx));
2522 (define_insn "clrsb<mode>2"
2523 [(set (match_operand:GPI 0 "register_operand" "=r")
2524 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_CLS))]
2526 "cls\\t%<w>0, %<w>1"
2527 [(set_attr "v8type" "clz")
2528 (set_attr "mode" "<MODE>")])
2530 (define_insn "rbit<mode>2"
2531 [(set (match_operand:GPI 0 "register_operand" "=r")
2532 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
2534 "rbit\\t%<w>0, %<w>1"
2535 [(set_attr "v8type" "rbit")
2536 (set_attr "mode" "<MODE>")])
2538 (define_expand "ctz<mode>2"
2539 [(match_operand:GPI 0 "register_operand")
2540 (match_operand:GPI 1 "register_operand")]
2543 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2544 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2549 (define_insn "*and<mode>3nr_compare0"
2550 [(set (reg:CC_NZ CC_REGNUM)
2552 (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
2553 (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
2556 "tst\\t%<w>0, %<w>1"
2557 [(set_attr "v8type" "logics")
2558 (set_attr "mode" "<MODE>")])
2560 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
2561 [(set (reg:CC_NZ CC_REGNUM)
2564 (match_operand:GPI 0 "register_operand" "r")
2565 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2566 (match_operand:GPI 2 "register_operand" "r"))
2569 "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
2570 [(set_attr "v8type" "logics_shift")
2571 (set_attr "mode" "<MODE>")])
2573 ;; -------------------------------------------------------------------
2575 ;; -------------------------------------------------------------------
2577 (define_expand "<optab><mode>3"
2578 [(set (match_operand:GPI 0 "register_operand")
2579 (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
2580 (match_operand:QI 2 "nonmemory_operand")))]
2583 if (CONST_INT_P (operands[2]))
2585 operands[2] = GEN_INT (INTVAL (operands[2])
2586 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2588 if (operands[2] == const0_rtx)
2590 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2597 (define_expand "ashl<mode>3"
2598 [(set (match_operand:SHORT 0 "register_operand")
2599 (ashift:SHORT (match_operand:SHORT 1 "register_operand")
2600 (match_operand:QI 2 "nonmemory_operand")))]
2603 if (CONST_INT_P (operands[2]))
2605 operands[2] = GEN_INT (INTVAL (operands[2])
2606 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2608 if (operands[2] == const0_rtx)
2610 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2617 (define_expand "rotr<mode>3"
2618 [(set (match_operand:GPI 0 "register_operand")
2619 (rotatert:GPI (match_operand:GPI 1 "register_operand")
2620 (match_operand:QI 2 "nonmemory_operand")))]
2623 if (CONST_INT_P (operands[2]))
2625 operands[2] = GEN_INT (INTVAL (operands[2])
2626 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2628 if (operands[2] == const0_rtx)
2630 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2637 (define_expand "rotl<mode>3"
2638 [(set (match_operand:GPI 0 "register_operand")
2639 (rotatert:GPI (match_operand:GPI 1 "register_operand")
2640 (match_operand:QI 2 "nonmemory_operand")))]
2643 /* (SZ - cnt) % SZ == -cnt % SZ */
2644 if (CONST_INT_P (operands[2]))
2646 operands[2] = GEN_INT ((-INTVAL (operands[2]))
2647 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2648 if (operands[2] == const0_rtx)
2650 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2655 operands[2] = expand_simple_unop (QImode, NEG, operands[2],
2660 (define_insn "*<optab><mode>3_insn"
2661 [(set (match_operand:GPI 0 "register_operand" "=r")
2663 (match_operand:GPI 1 "register_operand" "r")
2664 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
2666 "<shift>\\t%<w>0, %<w>1, %<w>2"
2667 [(set_attr "v8type" "shift")
2668 (set_attr "mode" "<MODE>")]
2671 ;; zero_extend version of above
2672 (define_insn "*<optab>si3_insn_uxtw"
2673 [(set (match_operand:DI 0 "register_operand" "=r")
2674 (zero_extend:DI (SHIFT:SI
2675 (match_operand:SI 1 "register_operand" "r")
2676 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
2678 "<shift>\\t%w0, %w1, %w2"
2679 [(set_attr "v8type" "shift")
2680 (set_attr "mode" "SI")]
2683 (define_insn "*ashl<mode>3_insn"
2684 [(set (match_operand:SHORT 0 "register_operand" "=r")
2685 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
2686 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
2688 "lsl\\t%<w>0, %<w>1, %<w>2"
2689 [(set_attr "v8type" "shift")
2690 (set_attr "mode" "<MODE>")]
2693 (define_insn "*<optab><mode>3_insn"
2694 [(set (match_operand:SHORT 0 "register_operand" "=r")
2695 (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
2696 (match_operand 2 "const_int_operand" "n")))]
2697 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
2699 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
2700 return "<bfshift>\t%w0, %w1, %2, %3";
2702 [(set_attr "v8type" "bfm")
2703 (set_attr "mode" "<MODE>")]
2706 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
2707 [(set (match_operand:GPI 0 "register_operand" "=r")
2709 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
2710 (match_operand 2 "const_int_operand" "n"))))]
2711 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
2713 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
2714 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
2716 [(set_attr "v8type" "bfm")
2717 (set_attr "mode" "<GPI:MODE>")]
2720 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
2721 [(set (match_operand:GPI 0 "register_operand" "=r")
2723 (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
2724 (match_operand 2 "const_int_operand" "n"))))]
2725 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
2727 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
2728 return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
2730 [(set_attr "v8type" "bfm")
2731 (set_attr "mode" "<GPI:MODE>")]
2734 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
2735 [(set (match_operand:GPI 0 "register_operand" "=r")
2737 (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
2738 (match_operand 2 "const_int_operand" "n"))))]
2739 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
2741 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
2742 return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
2744 [(set_attr "v8type" "bfm")
2745 (set_attr "mode" "<GPI:MODE>")]
2748 ;; -------------------------------------------------------------------
2750 ;; -------------------------------------------------------------------
2752 (define_expand "<optab>"
2753 [(set (match_operand:DI 0 "register_operand" "=r")
2754 (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
2755 (match_operand 2 "const_int_operand" "n")
2756 (match_operand 3 "const_int_operand" "n")))]
2761 (define_insn "*<optab><mode>"
2762 [(set (match_operand:GPI 0 "register_operand" "=r")
2763 (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
2764 (match_operand 2 "const_int_operand" "n")
2765 (match_operand 3 "const_int_operand" "n")))]
2767 "<su>bfx\\t%<w>0, %<w>1, %3, %2"
2768 [(set_attr "v8type" "bfm")
2769 (set_attr "mode" "<MODE>")]
2772 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
2773 [(set (match_operand:GPI 0 "register_operand" "=r")
2774 (ashift:GPI (ANY_EXTEND:GPI
2775 (match_operand:ALLX 1 "register_operand" "r"))
2776 (match_operand 2 "const_int_operand" "n")))]
2777 "UINTVAL (operands[2]) < <GPI:sizen>"
2779 operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
2780 ? GEN_INT (<ALLX:sizen>)
2781 : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
2782 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
2784 [(set_attr "v8type" "bfm")
2785 (set_attr "mode" "<GPI:MODE>")]
2788 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
2790 (define_insn "*andim_ashift<mode>_bfiz"
2791 [(set (match_operand:GPI 0 "register_operand" "=r")
2792 (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
2793 (match_operand 2 "const_int_operand" "n"))
2794 (match_operand 3 "const_int_operand" "n")))]
2795 "exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
2796 && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
2797 "ubfiz\\t%<w>0, %<w>1, %2, %P3"
2798 [(set_attr "v8type" "bfm")
2799 (set_attr "mode" "<MODE>")]
2802 (define_insn "bswap<mode>2"
2803 [(set (match_operand:GPI 0 "register_operand" "=r")
2804 (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
2806 "rev\\t%<w>0, %<w>1"
2807 [(set_attr "v8type" "rev")
2808 (set_attr "mode" "<MODE>")]
2811 (define_insn "bswaphi2"
2812 [(set (match_operand:HI 0 "register_operand" "=r")
2813 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
2816 [(set_attr "v8type" "rev")
2817 (set_attr "mode" "HI")]
2820 ;; zero_extend version of above
2821 (define_insn "*bswapsi2_uxtw"
2822 [(set (match_operand:DI 0 "register_operand" "=r")
2823 (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
2826 [(set_attr "v8type" "rev")
2827 (set_attr "mode" "SI")]
2830 ;; -------------------------------------------------------------------
2831 ;; Floating-point intrinsics
2832 ;; -------------------------------------------------------------------
2834 ;; frint floating-point round to integral standard patterns.
2835 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round.
2837 (define_insn "<frint_pattern><mode>2"
2838 [(set (match_operand:GPF 0 "register_operand" "=w")
2839 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2842 "frint<frint_suffix>\\t%<s>0, %<s>1"
2843 [(set_attr "v8type" "frint")
2844 (set_attr "mode" "<MODE>")]
2847 ;; frcvt floating-point round to integer and convert standard patterns.
2848 ;; Expands to lbtrunc, lceil, lfloor, lround.
2849 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
2850 [(set (match_operand:GPI 0 "register_operand" "=r")
2851 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2854 "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
2855 [(set_attr "v8type" "fcvtf2i")
2856 (set_attr "mode" "<GPF:MODE>")
2857 (set_attr "mode2" "<GPI:MODE>")]
2862 (define_insn "fma<mode>4"
2863 [(set (match_operand:GPF 0 "register_operand" "=w")
2864 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
2865 (match_operand:GPF 2 "register_operand" "w")
2866 (match_operand:GPF 3 "register_operand" "w")))]
2868 "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
2869 [(set_attr "v8type" "fmadd")
2870 (set_attr "mode" "<MODE>")]
2873 (define_insn "fnma<mode>4"
2874 [(set (match_operand:GPF 0 "register_operand" "=w")
2875 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
2876 (match_operand:GPF 2 "register_operand" "w")
2877 (match_operand:GPF 3 "register_operand" "w")))]
2879 "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
2880 [(set_attr "v8type" "fmadd")
2881 (set_attr "mode" "<MODE>")]
2884 (define_insn "fms<mode>4"
2885 [(set (match_operand:GPF 0 "register_operand" "=w")
2886 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
2887 (match_operand:GPF 2 "register_operand" "w")
2888 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
2890 "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
2891 [(set_attr "v8type" "fmadd")
2892 (set_attr "mode" "<MODE>")]
2895 (define_insn "fnms<mode>4"
2896 [(set (match_operand:GPF 0 "register_operand" "=w")
2897 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
2898 (match_operand:GPF 2 "register_operand" "w")
2899 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
2901 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
2902 [(set_attr "v8type" "fmadd")
2903 (set_attr "mode" "<MODE>")]
2906 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
2907 (define_insn "*fnmadd<mode>4"
2908 [(set (match_operand:GPF 0 "register_operand" "=w")
2909 (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
2910 (match_operand:GPF 2 "register_operand" "w")
2911 (match_operand:GPF 3 "register_operand" "w"))))]
2912 "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
2913 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
2914 [(set_attr "v8type" "fmadd")
2915 (set_attr "mode" "<MODE>")]
2918 ;; -------------------------------------------------------------------
2919 ;; Floating-point conversions
2920 ;; -------------------------------------------------------------------
2922 (define_insn "extendsfdf2"
2923 [(set (match_operand:DF 0 "register_operand" "=w")
2924 (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
2927 [(set_attr "v8type" "fcvt")
2928 (set_attr "mode" "DF")
2929 (set_attr "mode2" "SF")]
2932 (define_insn "truncdfsf2"
2933 [(set (match_operand:SF 0 "register_operand" "=w")
2934 (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
2937 [(set_attr "v8type" "fcvt")
2938 (set_attr "mode" "SF")
2939 (set_attr "mode2" "DF")]
2942 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
2943 [(set (match_operand:GPI 0 "register_operand" "=r")
2944 (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
2946 "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
2947 [(set_attr "v8type" "fcvtf2i")
2948 (set_attr "mode" "<GPF:MODE>")
2949 (set_attr "mode2" "<GPI:MODE>")]
2952 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
2953 [(set (match_operand:GPI 0 "register_operand" "=r")
2954 (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
2956 "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
2957 [(set_attr "v8type" "fcvtf2i")
2958 (set_attr "mode" "<GPF:MODE>")
2959 (set_attr "mode2" "<GPI:MODE>")]
2962 (define_insn "float<GPI:mode><GPF:mode>2"
2963 [(set (match_operand:GPF 0 "register_operand" "=w")
2964 (float:GPF (match_operand:GPI 1 "register_operand" "r")))]
2966 "scvtf\\t%<GPF:s>0, %<GPI:w>1"
2967 [(set_attr "v8type" "fcvti2f")
2968 (set_attr "mode" "<GPF:MODE>")
2969 (set_attr "mode2" "<GPI:MODE>")]
2972 (define_insn "floatuns<GPI:mode><GPF:mode>2"
2973 [(set (match_operand:GPF 0 "register_operand" "=w")
2974 (unsigned_float:GPF (match_operand:GPI 1 "register_operand" "r")))]
2976 "ucvtf\\t%<GPF:s>0, %<GPI:w>1"
2977 [(set_attr "v8type" "fcvt")
2978 (set_attr "mode" "<GPF:MODE>")
2979 (set_attr "mode2" "<GPI:MODE>")]
2982 ;; -------------------------------------------------------------------
2983 ;; Floating-point arithmetic
2984 ;; -------------------------------------------------------------------
2986 (define_insn "add<mode>3"
2987 [(set (match_operand:GPF 0 "register_operand" "=w")
2989 (match_operand:GPF 1 "register_operand" "w")
2990 (match_operand:GPF 2 "register_operand" "w")))]
2992 "fadd\\t%<s>0, %<s>1, %<s>2"
2993 [(set_attr "v8type" "fadd")
2994 (set_attr "mode" "<MODE>")]
2997 (define_insn "sub<mode>3"
2998 [(set (match_operand:GPF 0 "register_operand" "=w")
3000 (match_operand:GPF 1 "register_operand" "w")
3001 (match_operand:GPF 2 "register_operand" "w")))]
3003 "fsub\\t%<s>0, %<s>1, %<s>2"
3004 [(set_attr "v8type" "fadd")
3005 (set_attr "mode" "<MODE>")]
3008 (define_insn "mul<mode>3"
3009 [(set (match_operand:GPF 0 "register_operand" "=w")
3011 (match_operand:GPF 1 "register_operand" "w")
3012 (match_operand:GPF 2 "register_operand" "w")))]
3014 "fmul\\t%<s>0, %<s>1, %<s>2"
3015 [(set_attr "v8type" "fmul")
3016 (set_attr "mode" "<MODE>")]
3019 (define_insn "*fnmul<mode>3"
3020 [(set (match_operand:GPF 0 "register_operand" "=w")
3022 (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3023 (match_operand:GPF 2 "register_operand" "w")))]
3025 "fnmul\\t%<s>0, %<s>1, %<s>2"
3026 [(set_attr "v8type" "fmul")
3027 (set_attr "mode" "<MODE>")]
3030 (define_insn "div<mode>3"
3031 [(set (match_operand:GPF 0 "register_operand" "=w")
3033 (match_operand:GPF 1 "register_operand" "w")
3034 (match_operand:GPF 2 "register_operand" "w")))]
3036 "fdiv\\t%<s>0, %<s>1, %<s>2"
3037 [(set_attr "v8type" "fdiv")
3038 (set_attr "mode" "<MODE>")]
3041 (define_insn "neg<mode>2"
3042 [(set (match_operand:GPF 0 "register_operand" "=w")
3043 (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
3045 "fneg\\t%<s>0, %<s>1"
3046 [(set_attr "v8type" "ffarith")
3047 (set_attr "mode" "<MODE>")]
3050 (define_insn "sqrt<mode>2"
3051 [(set (match_operand:GPF 0 "register_operand" "=w")
3052 (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
3054 "fsqrt\\t%<s>0, %<s>1"
3055 [(set_attr "v8type" "fsqrt")
3056 (set_attr "mode" "<MODE>")]
3059 (define_insn "abs<mode>2"
3060 [(set (match_operand:GPF 0 "register_operand" "=w")
3061 (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
3063 "fabs\\t%<s>0, %<s>1"
3064 [(set_attr "v8type" "ffarith")
3065 (set_attr "mode" "<MODE>")]
3068 ;; Given that smax/smin do not specify the result when either input is NaN,
3069 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
3072 (define_insn "smax<mode>3"
3073 [(set (match_operand:GPF 0 "register_operand" "=w")
3074 (smax:GPF (match_operand:GPF 1 "register_operand" "w")
3075 (match_operand:GPF 2 "register_operand" "w")))]
3077 "fmaxnm\\t%<s>0, %<s>1, %<s>2"
3078 [(set_attr "v8type" "fminmax")
3079 (set_attr "mode" "<MODE>")]
3082 (define_insn "smin<mode>3"
3083 [(set (match_operand:GPF 0 "register_operand" "=w")
3084 (smin:GPF (match_operand:GPF 1 "register_operand" "w")
3085 (match_operand:GPF 2 "register_operand" "w")))]
3087 "fminnm\\t%<s>0, %<s>1, %<s>2"
3088 [(set_attr "v8type" "fminmax")
3089 (set_attr "mode" "<MODE>")]
3092 ;; -------------------------------------------------------------------
3094 ;; -------------------------------------------------------------------
3096 ;; Reload SP+imm where imm cannot be handled by a single ADD instruction.
3097 ;; Must load imm into a scratch register and copy SP to the dest reg before
3098 ;; adding, since SP cannot be used as a source register in an ADD
3100 (define_expand "reload_sp_immediate"
3101 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
3102 (match_operand:DI 1 "" ""))
3103 (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
3106 rtx sp = XEXP (operands[1], 0);
3107 rtx val = XEXP (operands[1], 1);
3108 unsigned regno = REGNO (operands[2]);
3109 rtx scratch = operands[1];
3110 gcc_assert (GET_CODE (operands[1]) == PLUS);
3111 gcc_assert (sp == stack_pointer_rtx);
3112 gcc_assert (CONST_INT_P (val));
3114 /* It is possible that one of the registers we got for operands[2]
3115 might coincide with that of operands[0] (which is why we made
3116 it TImode). Pick the other one to use as our scratch. */
3117 if (regno == REGNO (operands[0]))
3119 scratch = gen_rtx_REG (DImode, regno);
3121 emit_move_insn (scratch, val);
3122 emit_move_insn (operands[0], sp);
3123 emit_insn (gen_adddi3 (operands[0], operands[0], scratch));
3128 (define_expand "aarch64_reload_mov<mode>"
3129 [(set (match_operand:TX 0 "register_operand" "=w")
3130 (match_operand:TX 1 "register_operand" "w"))
3131 (clobber (match_operand:DI 2 "register_operand" "=&r"))
3135 rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
3136 rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
3137 gen_aarch64_movtilow_tilow (op0, op1);
3138 gen_aarch64_movdi_tihigh (operands[2], op1);
3139 gen_aarch64_movtihigh_di (op0, operands[2]);
3144 ;; The following secondary reload helpers patterns are invoked
3145 ;; after or during reload as we don't want these patterns to start
3146 ;; kicking in during the combiner.
3148 (define_insn "aarch64_movdi_tilow"
3149 [(set (match_operand:DI 0 "register_operand" "=r")
3150 (truncate:DI (match_operand:TI 1 "register_operand" "w")))]
3151 "reload_completed || reload_in_progress"
3153 [(set_attr "v8type" "fmovf2i")
3154 (set_attr "mode" "DI")
3155 (set_attr "length" "4")
3158 (define_insn "aarch64_movdi_tihigh"
3159 [(set (match_operand:DI 0 "register_operand" "=r")
3161 (lshiftrt:TI (match_operand:TI 1 "register_operand" "w")
3163 "reload_completed || reload_in_progress"
3164 "fmov\\t%x0, %1.d[1]"
3165 [(set_attr "v8type" "fmovf2i")
3166 (set_attr "mode" "DI")
3167 (set_attr "length" "4")
3170 (define_insn "aarch64_movtihigh_di"
3171 [(set (zero_extract:TI (match_operand:TI 0 "register_operand" "+w")
3172 (const_int 64) (const_int 64))
3173 (zero_extend:TI (match_operand:DI 1 "register_operand" "r")))]
3174 "reload_completed || reload_in_progress"
3175 "fmov\\t%0.d[1], %x1"
3177 [(set_attr "v8type" "fmovi2f")
3178 (set_attr "mode" "DI")
3179 (set_attr "length" "4")
3182 (define_insn "aarch64_movtilow_di"
3183 [(set (match_operand:TI 0 "register_operand" "=w")
3184 (zero_extend:TI (match_operand:DI 1 "register_operand" "r")))]
3185 "reload_completed || reload_in_progress"
3188 [(set_attr "v8type" "fmovi2f")
3189 (set_attr "mode" "DI")
3190 (set_attr "length" "4")
3193 (define_insn "aarch64_movtilow_tilow"
3194 [(set (match_operand:TI 0 "register_operand" "=w")
3196 (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
3197 "reload_completed || reload_in_progress"
3200 [(set_attr "v8type" "fmovi2f")
3201 (set_attr "mode" "DI")
3202 (set_attr "length" "4")
3205 ;; There is a deliberate reason why the parameters of high and lo_sum's
3206 ;; don't have modes for ADRP and ADD instructions. This is to allow high
3207 ;; and lo_sum's to be used with the labels defining the jump tables in
3210 (define_insn "add_losym"
3211 [(set (match_operand:DI 0 "register_operand" "=r")
3212 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
3213 (match_operand 2 "aarch64_valid_symref" "S")))]
3215 "add\\t%0, %1, :lo12:%a2"
3216 [(set_attr "v8type" "alu")
3217 (set_attr "mode" "DI")]
3221 (define_insn "ldr_got_small"
3222 [(set (match_operand:DI 0 "register_operand" "=r")
3223 (unspec:DI [(mem:DI (lo_sum:DI
3224 (match_operand:DI 1 "register_operand" "r")
3225 (match_operand:DI 2 "aarch64_valid_symref" "S")))]
3226 UNSPEC_GOTSMALLPIC))]
3228 "ldr\\t%0, [%1, #:got_lo12:%a2]"
3229 [(set_attr "v8type" "load1")
3230 (set_attr "mode" "DI")]
3233 (define_insn "aarch64_load_tp_hard"
3234 [(set (match_operand:DI 0 "register_operand" "=r")
3235 (unspec:DI [(const_int 0)] UNSPEC_TLS))]
3237 "mrs\\t%0, tpidr_el0"
3238 [(set_attr "v8type" "mrs")
3239 (set_attr "mode" "DI")]
3242 ;; The TLS ABI specifically requires that the compiler does not schedule
3243 ;; instructions in the TLS stubs, in order to enable linker relaxation.
3244 ;; Therefore we treat the stubs as an atomic sequence.
3245 (define_expand "tlsgd_small"
3246 [(parallel [(set (match_operand 0 "register_operand" "")
3247 (call (mem:DI (match_dup 2)) (const_int 1)))
3248 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
3249 (clobber (reg:DI LR_REGNUM))])]
3252 operands[2] = aarch64_tls_get_addr ();
3255 (define_insn "*tlsgd_small"
3256 [(set (match_operand 0 "register_operand" "")
3257 (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
3258 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
3259 (clobber (reg:DI LR_REGNUM))
3262 "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
3263 [(set_attr "v8type" "call")
3264 (set_attr "length" "16")])
3266 (define_insn "tlsie_small"
3267 [(set (match_operand:DI 0 "register_operand" "=r")
3268 (unspec:DI [(match_operand:DI 1 "aarch64_tls_ie_symref" "S")]
3269 UNSPEC_GOTSMALLTLS))]
3271 "adrp\\t%0, %A1\;ldr\\t%0, [%0, #%L1]"
3272 [(set_attr "v8type" "load1")
3273 (set_attr "mode" "DI")
3274 (set_attr "length" "8")]
3277 (define_insn "tlsle_small"
3278 [(set (match_operand:DI 0 "register_operand" "=r")
3279 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
3280 (match_operand:DI 2 "aarch64_tls_le_symref" "S")]
3281 UNSPEC_GOTSMALLTLS))]
3283 "add\\t%0, %1, #%G2\;add\\t%0, %0, #%L2"
3284 [(set_attr "v8type" "alu")
3285 (set_attr "mode" "DI")
3286 (set_attr "length" "8")]
3289 (define_insn "tlsdesc_small"
3290 [(set (reg:DI R0_REGNUM)
3291 (unspec:DI [(match_operand:DI 0 "aarch64_valid_symref" "S")]
3293 (clobber (reg:DI LR_REGNUM))
3294 (clobber (match_scratch:DI 1 "=r"))]
3296 "adrp\\tx0, %A0\;ldr\\t%1, [x0, #%L0]\;add\\tx0, x0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
3297 [(set_attr "v8type" "call")
3298 (set_attr "length" "16")])
3300 (define_insn "stack_tie"
3301 [(set (mem:BLK (scratch))
3302 (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
3303 (match_operand:DI 1 "register_operand" "rk")]
3307 [(set_attr "length" "0")]
3310 ;; Named pattern for expanding thread pointer reference.
3311 (define_expand "get_thread_pointerdi"
3312 [(match_operand:DI 0 "register_operand" "=r")]
3315 rtx tmp = aarch64_load_tp (operands[0]);
3316 if (tmp != operands[0])
3317 emit_move_insn (operands[0], tmp);
3322 (include "aarch64-simd.md")
3324 ;; Atomic Operations
3325 (include "atomics.md")