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, *w,r,*w, m, m, r,*w,*w")
767 (match_operand:SHORT 1 "general_operand" " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
768 "(register_operand (operands[0], <MODE>mode)
769 || aarch64_reg_or_zero (operands[1], <MODE>mode))"
773 movi\\t%0.<Vallxd>, %1
778 umov\\t%w0, %1.<v>[0]
779 dup\\t%0.<Vallxd>, %w1
781 [(set_attr "v8type" "move,alu,alu,load1,load1,store1,store1,*,*,*")
782 (set_attr "simd_type" "*,*,simd_move_imm,*,*,*,*,simd_movgp,simd_dupgp,simd_dup")
783 (set_attr "mode" "<MODE>")
784 (set_attr "simd_mode" "<MODE>")]
787 (define_expand "mov<mode>"
788 [(set (match_operand:GPI 0 "nonimmediate_operand" "")
789 (match_operand:GPI 1 "general_operand" ""))]
792 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
793 operands[1] = force_reg (<MODE>mode, operands[1]);
795 if (CONSTANT_P (operands[1]))
797 aarch64_expand_mov_immediate (operands[0], operands[1]);
803 (define_insn "*movsi_aarch64"
804 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m, *w, r,*w")
805 (match_operand:SI 1 "aarch64_mov_operand" " r,M,m,rZ,rZ,*w,*w"))]
806 "(register_operand (operands[0], SImode)
807 || aarch64_reg_or_zero (operands[1], SImode))"
816 [(set_attr "v8type" "move,alu,load1,store1,fmov,fmov,fmov")
817 (set_attr "mode" "SI")
818 (set_attr "fp" "*,*,*,*,yes,yes,yes")]
821 (define_insn "*movdi_aarch64"
822 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,m, r, r, *w, r,*w,w")
823 (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,m,rZ,Usa,Ush,rZ,*w,*w,Dd"))]
824 "(register_operand (operands[0], DImode)
825 || aarch64_reg_or_zero (operands[1], DImode))"
839 [(set_attr "v8type" "move,move,move,alu,load1,store1,adr,adr,fmov,fmov,fmov,fmov")
840 (set_attr "mode" "DI")
841 (set_attr "fp" "*,*,*,*,*,*,*,*,yes,yes,yes,yes")]
844 (define_insn "insv_imm<mode>"
845 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
847 (match_operand:GPI 1 "const_int_operand" "n"))
848 (match_operand:GPI 2 "const_int_operand" "n"))]
849 "INTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
850 && INTVAL (operands[1]) % 16 == 0
851 && UINTVAL (operands[2]) <= 0xffff"
852 "movk\\t%<w>0, %X2, lsl %1"
853 [(set_attr "v8type" "movk")
854 (set_attr "mode" "<MODE>")]
857 (define_expand "movti"
858 [(set (match_operand:TI 0 "nonimmediate_operand" "")
859 (match_operand:TI 1 "general_operand" ""))]
862 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
863 operands[1] = force_reg (TImode, operands[1]);
867 (define_insn "*movti_aarch64"
868 [(set (match_operand:TI 0
869 "nonimmediate_operand" "=r, *w,r ,*w,r ,Ump,Ump,*w,m")
871 "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r ,Z , m,*w"))]
872 "(register_operand (operands[0], TImode)
873 || aarch64_reg_or_zero (operands[1], TImode))"
878 orr\\t%0.16b, %1.16b, %1.16b
884 [(set_attr "v8type" "move2,fmovi2f,fmovf2i,*, \
885 load2,store2,store2,fpsimd_load,fpsimd_store")
886 (set_attr "simd_type" "*,*,*,simd_move,*,*,*,*,*")
887 (set_attr "mode" "DI,DI,DI,TI,DI,DI,DI,TI,TI")
888 (set_attr "length" "8,8,8,4,4,4,4,4,4")
889 (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")
890 (set_attr "simd" "*,*,*,yes,*,*,*,*,*")])
892 ;; Split a TImode register-register or register-immediate move into
893 ;; its component DImode pieces, taking care to handle overlapping
894 ;; source and dest registers.
896 [(set (match_operand:TI 0 "register_operand" "")
897 (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
898 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
901 aarch64_split_128bit_move (operands[0], operands[1]);
905 (define_expand "mov<mode>"
906 [(set (match_operand:GPF 0 "nonimmediate_operand" "")
907 (match_operand:GPF 1 "general_operand" ""))]
912 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
916 if (GET_CODE (operands[0]) == MEM)
917 operands[1] = force_reg (<MODE>mode, operands[1]);
921 (define_insn "*movsf_aarch64"
922 [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
923 (match_operand:SF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
924 "TARGET_FLOAT && (register_operand (operands[0], SFmode)
925 || register_operand (operands[1], SFmode))"
936 [(set_attr "v8type" "fmovi2f,fmovf2i,\
937 fmov,fconst,fpsimd_load,\
938 fpsimd_store,fpsimd_load,fpsimd_store,fmov")
939 (set_attr "mode" "SF")]
942 (define_insn "*movdf_aarch64"
943 [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
944 (match_operand:DF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
945 "TARGET_FLOAT && (register_operand (operands[0], DFmode)
946 || register_operand (operands[1], DFmode))"
957 [(set_attr "v8type" "fmovi2f,fmovf2i,\
958 fmov,fconst,fpsimd_load,\
959 fpsimd_store,fpsimd_load,fpsimd_store,move")
960 (set_attr "mode" "DF")]
963 (define_expand "movtf"
964 [(set (match_operand:TF 0 "nonimmediate_operand" "")
965 (match_operand:TF 1 "general_operand" ""))]
970 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
974 if (GET_CODE (operands[0]) == MEM)
975 operands[1] = force_reg (TFmode, operands[1]);
979 (define_insn "*movtf_aarch64"
980 [(set (match_operand:TF 0
981 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
983 "general_operand" " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
984 "TARGET_FLOAT && (register_operand (operands[0], TFmode)
985 || register_operand (operands[1], TFmode))"
987 orr\\t%0.16b, %1.16b, %1.16b
988 mov\\t%0, %1\;mov\\t%H0, %H1
989 fmov\\t%d0, %Q1\;fmov\\t%0.d[1], %R1
990 fmov\\t%Q0, %d1\;fmov\\t%R0, %1.d[1]
997 [(set_attr "v8type" "logic,move2,fmovi2f,fmovf2i,fconst,fconst,fpsimd_load,fpsimd_store,fpsimd_load2,fpsimd_store2")
998 (set_attr "mode" "DF,DF,DF,DF,DF,DF,TF,TF,DF,DF")
999 (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
1000 (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
1001 (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
1004 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1005 ;; fairly lax checking on the second memory operation.
1006 (define_insn "load_pair<mode>"
1007 [(set (match_operand:GPI 0 "register_operand" "=r")
1008 (match_operand:GPI 1 "aarch64_mem_pair_operand" "Ump"))
1009 (set (match_operand:GPI 2 "register_operand" "=r")
1010 (match_operand:GPI 3 "memory_operand" "m"))]
1011 "rtx_equal_p (XEXP (operands[3], 0),
1012 plus_constant (Pmode,
1013 XEXP (operands[1], 0),
1014 GET_MODE_SIZE (<MODE>mode)))"
1015 "ldp\\t%<w>0, %<w>2, %1"
1016 [(set_attr "v8type" "load2")
1017 (set_attr "mode" "<MODE>")]
1020 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1021 ;; fairly lax checking on the second memory operation.
1022 (define_insn "store_pair<mode>"
1023 [(set (match_operand:GPI 0 "aarch64_mem_pair_operand" "=Ump")
1024 (match_operand:GPI 1 "register_operand" "r"))
1025 (set (match_operand:GPI 2 "memory_operand" "=m")
1026 (match_operand:GPI 3 "register_operand" "r"))]
1027 "rtx_equal_p (XEXP (operands[2], 0),
1028 plus_constant (Pmode,
1029 XEXP (operands[0], 0),
1030 GET_MODE_SIZE (<MODE>mode)))"
1031 "stp\\t%<w>1, %<w>3, %0"
1032 [(set_attr "v8type" "store2")
1033 (set_attr "mode" "<MODE>")]
1036 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1037 ;; fairly lax checking on the second memory operation.
1038 (define_insn "load_pair<mode>"
1039 [(set (match_operand:GPF 0 "register_operand" "=w")
1040 (match_operand:GPF 1 "aarch64_mem_pair_operand" "Ump"))
1041 (set (match_operand:GPF 2 "register_operand" "=w")
1042 (match_operand:GPF 3 "memory_operand" "m"))]
1043 "rtx_equal_p (XEXP (operands[3], 0),
1044 plus_constant (Pmode,
1045 XEXP (operands[1], 0),
1046 GET_MODE_SIZE (<MODE>mode)))"
1047 "ldp\\t%<w>0, %<w>2, %1"
1048 [(set_attr "v8type" "fpsimd_load2")
1049 (set_attr "mode" "<MODE>")]
1052 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1053 ;; fairly lax checking on the second memory operation.
1054 (define_insn "store_pair<mode>"
1055 [(set (match_operand:GPF 0 "aarch64_mem_pair_operand" "=Ump")
1056 (match_operand:GPF 1 "register_operand" "w"))
1057 (set (match_operand:GPF 2 "memory_operand" "=m")
1058 (match_operand:GPF 3 "register_operand" "w"))]
1059 "rtx_equal_p (XEXP (operands[2], 0),
1060 plus_constant (Pmode,
1061 XEXP (operands[0], 0),
1062 GET_MODE_SIZE (<MODE>mode)))"
1063 "stp\\t%<w>1, %<w>3, %0"
1064 [(set_attr "v8type" "fpsimd_load2")
1065 (set_attr "mode" "<MODE>")]
1068 ;; Load pair with writeback. This is primarily used in function epilogues
1069 ;; when restoring [fp,lr]
1070 (define_insn "loadwb_pair<GPI:mode>_<PTR:mode>"
1072 [(set (match_operand:PTR 0 "register_operand" "=k")
1073 (plus:PTR (match_operand:PTR 1 "register_operand" "0")
1074 (match_operand:PTR 4 "const_int_operand" "n")))
1075 (set (match_operand:GPI 2 "register_operand" "=r")
1076 (mem:GPI (plus:PTR (match_dup 1)
1078 (set (match_operand:GPI 3 "register_operand" "=r")
1079 (mem:GPI (plus:PTR (match_dup 1)
1080 (match_operand:PTR 5 "const_int_operand" "n"))))])]
1081 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1082 "ldp\\t%<w>2, %<w>3, [%1], %4"
1083 [(set_attr "v8type" "load2")
1084 (set_attr "mode" "<GPI:MODE>")]
1087 ;; Store pair with writeback. This is primarily used in function prologues
1088 ;; when saving [fp,lr]
1089 (define_insn "storewb_pair<GPI:mode>_<PTR:mode>"
1091 [(set (match_operand:PTR 0 "register_operand" "=&k")
1092 (plus:PTR (match_operand:PTR 1 "register_operand" "0")
1093 (match_operand:PTR 4 "const_int_operand" "n")))
1094 (set (mem:GPI (plus:PTR (match_dup 0)
1096 (match_operand:GPI 2 "register_operand" "r"))
1097 (set (mem:GPI (plus:PTR (match_dup 0)
1098 (match_operand:PTR 5 "const_int_operand" "n")))
1099 (match_operand:GPI 3 "register_operand" "r"))])]
1100 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1101 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1102 [(set_attr "v8type" "store2")
1103 (set_attr "mode" "<GPI:MODE>")]
1106 ;; -------------------------------------------------------------------
1107 ;; Sign/Zero extension
1108 ;; -------------------------------------------------------------------
1110 (define_expand "<optab>sidi2"
1111 [(set (match_operand:DI 0 "register_operand")
1112 (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1116 (define_insn "*extendsidi2_aarch64"
1117 [(set (match_operand:DI 0 "register_operand" "=r,r")
1118 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1123 [(set_attr "v8type" "extend,load1")
1124 (set_attr "mode" "DI")]
1127 (define_insn "*zero_extendsidi2_aarch64"
1128 [(set (match_operand:DI 0 "register_operand" "=r,r")
1129 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1134 [(set_attr "v8type" "extend,load1")
1135 (set_attr "mode" "DI")]
1138 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1139 [(set (match_operand:GPI 0 "register_operand")
1140 (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1144 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1145 [(set (match_operand:GPI 0 "register_operand" "=r,r")
1146 (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1149 sxt<SHORT:size>\t%<GPI:w>0, %w1
1150 ldrs<SHORT:size>\t%<GPI:w>0, %1"
1151 [(set_attr "v8type" "extend,load1")
1152 (set_attr "mode" "<GPI:MODE>")]
1155 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1156 [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1157 (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1160 uxt<SHORT:size>\t%<GPI:w>0, %w1
1161 ldr<SHORT:size>\t%w0, %1
1162 ldr\t%<SHORT:size>0, %1"
1163 [(set_attr "v8type" "extend,load1,load1")
1164 (set_attr "mode" "<GPI:MODE>")]
1167 (define_expand "<optab>qihi2"
1168 [(set (match_operand:HI 0 "register_operand")
1169 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1173 (define_insn "*<optab>qihi2_aarch64"
1174 [(set (match_operand:HI 0 "register_operand" "=r,r")
1175 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1180 [(set_attr "v8type" "extend,load1")
1181 (set_attr "mode" "HI")]
1184 ;; -------------------------------------------------------------------
1185 ;; Simple arithmetic
1186 ;; -------------------------------------------------------------------
1188 (define_expand "add<mode>3"
1190 (match_operand:GPI 0 "register_operand" "")
1191 (plus:GPI (match_operand:GPI 1 "register_operand" "")
1192 (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1195 if (! aarch64_plus_operand (operands[2], VOIDmode))
1197 rtx subtarget = ((optimize && can_create_pseudo_p ())
1198 ? gen_reg_rtx (<MODE>mode) : operands[0]);
1199 HOST_WIDE_INT imm = INTVAL (operands[2]);
1202 imm = -(-imm & ~0xfff);
1206 emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1207 operands[1] = subtarget;
1208 operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1213 (define_insn "*addsi3_aarch64"
1215 (match_operand:SI 0 "register_operand" "=rk,rk,rk")
1217 (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1218 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J")))]
1223 sub\\t%w0, %w1, #%n2"
1224 [(set_attr "v8type" "alu")
1225 (set_attr "mode" "SI")]
1228 ;; zero_extend version of above
1229 (define_insn "*addsi3_aarch64_uxtw"
1231 (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1233 (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1234 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1239 sub\\t%w0, %w1, #%n2"
1240 [(set_attr "v8type" "alu")
1241 (set_attr "mode" "SI")]
1244 (define_insn "*adddi3_aarch64"
1246 (match_operand:DI 0 "register_operand" "=rk,rk,rk,!w")
1248 (match_operand:DI 1 "register_operand" "%rk,rk,rk,!w")
1249 (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,!w")))]
1254 sub\\t%x0, %x1, #%n2
1255 add\\t%d0, %d1, %d2"
1256 [(set_attr "v8type" "alu")
1257 (set_attr "mode" "DI")
1258 (set_attr "simd" "*,*,*,yes")]
1261 (define_insn "*add<mode>3_compare0"
1262 [(set (reg:CC_NZ CC_REGNUM)
1264 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r")
1265 (match_operand:GPI 2 "aarch64_plus_operand" "rI,J"))
1267 (set (match_operand:GPI 0 "register_operand" "=r,r")
1268 (plus:GPI (match_dup 1) (match_dup 2)))]
1271 adds\\t%<w>0, %<w>1, %<w>2
1272 subs\\t%<w>0, %<w>1, #%n2"
1273 [(set_attr "v8type" "alus")
1274 (set_attr "mode" "<MODE>")]
1277 ;; zero_extend version of above
1278 (define_insn "*addsi3_compare0_uxtw"
1279 [(set (reg:CC_NZ CC_REGNUM)
1281 (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
1282 (match_operand:SI 2 "aarch64_plus_operand" "rI,J"))
1284 (set (match_operand:DI 0 "register_operand" "=r,r")
1285 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1288 adds\\t%w0, %w1, %w2
1289 subs\\t%w0, %w1, #%n2"
1290 [(set_attr "v8type" "alus")
1291 (set_attr "mode" "SI")]
1294 (define_insn "*add<mode>3nr_compare0"
1295 [(set (reg:CC_NZ CC_REGNUM)
1297 (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r")
1298 (match_operand:GPI 1 "aarch64_plus_operand" "rI,J"))
1304 [(set_attr "v8type" "alus")
1305 (set_attr "mode" "<MODE>")]
1308 (define_insn "*compare_neg<mode>"
1309 [(set (reg:CC CC_REGNUM)
1311 (match_operand:GPI 0 "register_operand" "r")
1312 (neg:GPI (match_operand:GPI 1 "register_operand" "r"))))]
1314 "cmn\\t%<w>0, %<w>1"
1315 [(set_attr "v8type" "alus")
1316 (set_attr "mode" "<MODE>")]
1319 (define_insn "*add_<shift>_<mode>"
1320 [(set (match_operand:GPI 0 "register_operand" "=rk")
1321 (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1322 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1323 (match_operand:GPI 3 "register_operand" "r")))]
1325 "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1326 [(set_attr "v8type" "alu_shift")
1327 (set_attr "mode" "<MODE>")]
1330 ;; zero_extend version of above
1331 (define_insn "*add_<shift>_si_uxtw"
1332 [(set (match_operand:DI 0 "register_operand" "=rk")
1334 (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1335 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1336 (match_operand:SI 3 "register_operand" "r"))))]
1338 "add\\t%w0, %w3, %w1, <shift> %2"
1339 [(set_attr "v8type" "alu_shift")
1340 (set_attr "mode" "SI")]
1343 (define_insn "*add_mul_imm_<mode>"
1344 [(set (match_operand:GPI 0 "register_operand" "=rk")
1345 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1346 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1347 (match_operand:GPI 3 "register_operand" "r")))]
1349 "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1350 [(set_attr "v8type" "alu_shift")
1351 (set_attr "mode" "<MODE>")]
1354 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1355 [(set (match_operand:GPI 0 "register_operand" "=rk")
1356 (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1357 (match_operand:GPI 2 "register_operand" "r")))]
1359 "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1360 [(set_attr "v8type" "alu_ext")
1361 (set_attr "mode" "<GPI:MODE>")]
1364 ;; zero_extend version of above
1365 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1366 [(set (match_operand:DI 0 "register_operand" "=rk")
1368 (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1369 (match_operand:GPI 2 "register_operand" "r"))))]
1371 "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1372 [(set_attr "v8type" "alu_ext")
1373 (set_attr "mode" "SI")]
1376 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1377 [(set (match_operand:GPI 0 "register_operand" "=rk")
1378 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1379 (match_operand:ALLX 1 "register_operand" "r"))
1380 (match_operand 2 "aarch64_imm3" "Ui3"))
1381 (match_operand:GPI 3 "register_operand" "r")))]
1383 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1384 [(set_attr "v8type" "alu_ext")
1385 (set_attr "mode" "<GPI:MODE>")]
1388 ;; zero_extend version of above
1389 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1390 [(set (match_operand:DI 0 "register_operand" "=rk")
1392 (plus:SI (ashift:SI (ANY_EXTEND:SI
1393 (match_operand:SHORT 1 "register_operand" "r"))
1394 (match_operand 2 "aarch64_imm3" "Ui3"))
1395 (match_operand:SI 3 "register_operand" "r"))))]
1397 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1398 [(set_attr "v8type" "alu_ext")
1399 (set_attr "mode" "SI")]
1402 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1403 [(set (match_operand:GPI 0 "register_operand" "=rk")
1404 (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1405 (match_operand:ALLX 1 "register_operand" "r"))
1406 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1407 (match_operand:GPI 3 "register_operand" "r")))]
1409 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1410 [(set_attr "v8type" "alu_ext")
1411 (set_attr "mode" "<GPI:MODE>")]
1414 ;; zero_extend version of above
1415 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1416 [(set (match_operand:DI 0 "register_operand" "=rk")
1417 (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1418 (match_operand:SHORT 1 "register_operand" "r"))
1419 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1420 (match_operand:SI 3 "register_operand" "r"))))]
1422 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1423 [(set_attr "v8type" "alu_ext")
1424 (set_attr "mode" "SI")]
1427 (define_insn "*add_<optab><mode>_multp2"
1428 [(set (match_operand:GPI 0 "register_operand" "=rk")
1429 (plus:GPI (ANY_EXTRACT:GPI
1430 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1431 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1432 (match_operand 3 "const_int_operand" "n")
1434 (match_operand:GPI 4 "register_operand" "r")))]
1435 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1436 "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1437 [(set_attr "v8type" "alu_ext")
1438 (set_attr "mode" "<MODE>")]
1441 ;; zero_extend version of above
1442 (define_insn "*add_<optab>si_multp2_uxtw"
1443 [(set (match_operand:DI 0 "register_operand" "=rk")
1445 (plus:SI (ANY_EXTRACT:SI
1446 (mult:SI (match_operand:SI 1 "register_operand" "r")
1447 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1448 (match_operand 3 "const_int_operand" "n")
1450 (match_operand:SI 4 "register_operand" "r"))))]
1451 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1452 "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1453 [(set_attr "v8type" "alu_ext")
1454 (set_attr "mode" "SI")]
1457 (define_insn "*add<mode>3_carryin"
1459 (match_operand:GPI 0 "register_operand" "=r")
1460 (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1462 (match_operand:GPI 1 "register_operand" "r")
1463 (match_operand:GPI 2 "register_operand" "r"))))]
1465 "adc\\t%<w>0, %<w>1, %<w>2"
1466 [(set_attr "v8type" "adc")
1467 (set_attr "mode" "<MODE>")]
1470 ;; zero_extend version of above
1471 (define_insn "*addsi3_carryin_uxtw"
1473 (match_operand:DI 0 "register_operand" "=r")
1475 (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1477 (match_operand:SI 1 "register_operand" "r")
1478 (match_operand:SI 2 "register_operand" "r")))))]
1480 "adc\\t%w0, %w1, %w2"
1481 [(set_attr "v8type" "adc")
1482 (set_attr "mode" "SI")]
1485 (define_insn "*add<mode>3_carryin_alt1"
1487 (match_operand:GPI 0 "register_operand" "=r")
1489 (match_operand:GPI 1 "register_operand" "r")
1490 (match_operand:GPI 2 "register_operand" "r"))
1491 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1493 "adc\\t%<w>0, %<w>1, %<w>2"
1494 [(set_attr "v8type" "adc")
1495 (set_attr "mode" "<MODE>")]
1498 ;; zero_extend version of above
1499 (define_insn "*addsi3_carryin_alt1_uxtw"
1501 (match_operand:DI 0 "register_operand" "=r")
1504 (match_operand:SI 1 "register_operand" "r")
1505 (match_operand:SI 2 "register_operand" "r"))
1506 (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1508 "adc\\t%w0, %w1, %w2"
1509 [(set_attr "v8type" "adc")
1510 (set_attr "mode" "SI")]
1513 (define_insn "*add<mode>3_carryin_alt2"
1515 (match_operand:GPI 0 "register_operand" "=r")
1517 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1518 (match_operand:GPI 1 "register_operand" "r"))
1519 (match_operand:GPI 2 "register_operand" "r")))]
1521 "adc\\t%<w>0, %<w>1, %<w>2"
1522 [(set_attr "v8type" "adc")
1523 (set_attr "mode" "<MODE>")]
1526 ;; zero_extend version of above
1527 (define_insn "*addsi3_carryin_alt2_uxtw"
1529 (match_operand:DI 0 "register_operand" "=r")
1532 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1533 (match_operand:SI 1 "register_operand" "r"))
1534 (match_operand:SI 2 "register_operand" "r"))))]
1536 "adc\\t%w0, %w1, %w2"
1537 [(set_attr "v8type" "adc")
1538 (set_attr "mode" "SI")]
1541 (define_insn "*add<mode>3_carryin_alt3"
1543 (match_operand:GPI 0 "register_operand" "=r")
1545 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1546 (match_operand:GPI 2 "register_operand" "r"))
1547 (match_operand:GPI 1 "register_operand" "r")))]
1549 "adc\\t%<w>0, %<w>1, %<w>2"
1550 [(set_attr "v8type" "adc")
1551 (set_attr "mode" "<MODE>")]
1554 ;; zero_extend version of above
1555 (define_insn "*addsi3_carryin_alt3_uxtw"
1557 (match_operand:DI 0 "register_operand" "=r")
1560 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1561 (match_operand:SI 2 "register_operand" "r"))
1562 (match_operand:SI 1 "register_operand" "r"))))]
1564 "adc\\t%w0, %w1, %w2"
1565 [(set_attr "v8type" "adc")
1566 (set_attr "mode" "SI")]
1569 (define_insn "*add_uxt<mode>_multp2"
1570 [(set (match_operand:GPI 0 "register_operand" "=rk")
1572 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1573 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1574 (match_operand 3 "const_int_operand" "n"))
1575 (match_operand:GPI 4 "register_operand" "r")))]
1576 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1578 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1579 INTVAL (operands[3])));
1580 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1581 [(set_attr "v8type" "alu_ext")
1582 (set_attr "mode" "<MODE>")]
1585 ;; zero_extend version of above
1586 (define_insn "*add_uxtsi_multp2_uxtw"
1587 [(set (match_operand:DI 0 "register_operand" "=rk")
1590 (mult:SI (match_operand:SI 1 "register_operand" "r")
1591 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1592 (match_operand 3 "const_int_operand" "n"))
1593 (match_operand:SI 4 "register_operand" "r"))))]
1594 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1596 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1597 INTVAL (operands[3])));
1598 return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1599 [(set_attr "v8type" "alu_ext")
1600 (set_attr "mode" "SI")]
1603 (define_insn "subsi3"
1604 [(set (match_operand:SI 0 "register_operand" "=rk")
1605 (minus:SI (match_operand:SI 1 "register_operand" "r")
1606 (match_operand:SI 2 "register_operand" "r")))]
1608 "sub\\t%w0, %w1, %w2"
1609 [(set_attr "v8type" "alu")
1610 (set_attr "mode" "SI")]
1613 ;; zero_extend version of above
1614 (define_insn "*subsi3_uxtw"
1615 [(set (match_operand:DI 0 "register_operand" "=rk")
1617 (minus:SI (match_operand:SI 1 "register_operand" "r")
1618 (match_operand:SI 2 "register_operand" "r"))))]
1620 "sub\\t%w0, %w1, %w2"
1621 [(set_attr "v8type" "alu")
1622 (set_attr "mode" "SI")]
1625 (define_insn "subdi3"
1626 [(set (match_operand:DI 0 "register_operand" "=rk,!w")
1627 (minus:DI (match_operand:DI 1 "register_operand" "r,!w")
1628 (match_operand:DI 2 "register_operand" "r,!w")))]
1632 sub\\t%d0, %d1, %d2"
1633 [(set_attr "v8type" "alu")
1634 (set_attr "mode" "DI")
1635 (set_attr "simd" "*,yes")]
1639 (define_insn "*sub<mode>3_compare0"
1640 [(set (reg:CC_NZ CC_REGNUM)
1641 (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1642 (match_operand:GPI 2 "register_operand" "r"))
1644 (set (match_operand:GPI 0 "register_operand" "=r")
1645 (minus:GPI (match_dup 1) (match_dup 2)))]
1647 "subs\\t%<w>0, %<w>1, %<w>2"
1648 [(set_attr "v8type" "alus")
1649 (set_attr "mode" "<MODE>")]
1652 ;; zero_extend version of above
1653 (define_insn "*subsi3_compare0_uxtw"
1654 [(set (reg:CC_NZ CC_REGNUM)
1655 (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1656 (match_operand:SI 2 "register_operand" "r"))
1658 (set (match_operand:DI 0 "register_operand" "=r")
1659 (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1661 "subs\\t%w0, %w1, %w2"
1662 [(set_attr "v8type" "alus")
1663 (set_attr "mode" "SI")]
1666 (define_insn "*sub_<shift>_<mode>"
1667 [(set (match_operand:GPI 0 "register_operand" "=rk")
1668 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1670 (match_operand:GPI 1 "register_operand" "r")
1671 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1673 "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1674 [(set_attr "v8type" "alu_shift")
1675 (set_attr "mode" "<MODE>")]
1678 ;; zero_extend version of above
1679 (define_insn "*sub_<shift>_si_uxtw"
1680 [(set (match_operand:DI 0 "register_operand" "=rk")
1682 (minus:SI (match_operand:SI 3 "register_operand" "r")
1684 (match_operand:SI 1 "register_operand" "r")
1685 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1687 "sub\\t%w0, %w3, %w1, <shift> %2"
1688 [(set_attr "v8type" "alu_shift")
1689 (set_attr "mode" "SI")]
1692 (define_insn "*sub_mul_imm_<mode>"
1693 [(set (match_operand:GPI 0 "register_operand" "=rk")
1694 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1696 (match_operand:GPI 1 "register_operand" "r")
1697 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1699 "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1700 [(set_attr "v8type" "alu_shift")
1701 (set_attr "mode" "<MODE>")]
1704 ;; zero_extend version of above
1705 (define_insn "*sub_mul_imm_si_uxtw"
1706 [(set (match_operand:DI 0 "register_operand" "=rk")
1708 (minus:SI (match_operand:SI 3 "register_operand" "r")
1710 (match_operand:SI 1 "register_operand" "r")
1711 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
1713 "sub\\t%w0, %w3, %w1, lsl %p2"
1714 [(set_attr "v8type" "alu_shift")
1715 (set_attr "mode" "SI")]
1718 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
1719 [(set (match_operand:GPI 0 "register_operand" "=rk")
1720 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1722 (match_operand:ALLX 2 "register_operand" "r"))))]
1724 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1725 [(set_attr "v8type" "alu_ext")
1726 (set_attr "mode" "<GPI:MODE>")]
1729 ;; zero_extend version of above
1730 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
1731 [(set (match_operand:DI 0 "register_operand" "=rk")
1733 (minus:SI (match_operand:SI 1 "register_operand" "r")
1735 (match_operand:SHORT 2 "register_operand" "r")))))]
1737 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
1738 [(set_attr "v8type" "alu_ext")
1739 (set_attr "mode" "SI")]
1742 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
1743 [(set (match_operand:GPI 0 "register_operand" "=rk")
1744 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1745 (ashift:GPI (ANY_EXTEND:GPI
1746 (match_operand:ALLX 2 "register_operand" "r"))
1747 (match_operand 3 "aarch64_imm3" "Ui3"))))]
1749 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1750 [(set_attr "v8type" "alu_ext")
1751 (set_attr "mode" "<GPI:MODE>")]
1754 ;; zero_extend version of above
1755 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
1756 [(set (match_operand:DI 0 "register_operand" "=rk")
1758 (minus:SI (match_operand:SI 1 "register_operand" "r")
1759 (ashift:SI (ANY_EXTEND:SI
1760 (match_operand:SHORT 2 "register_operand" "r"))
1761 (match_operand 3 "aarch64_imm3" "Ui3")))))]
1763 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
1764 [(set_attr "v8type" "alu_ext")
1765 (set_attr "mode" "SI")]
1768 (define_insn "*sub_<optab><mode>_multp2"
1769 [(set (match_operand:GPI 0 "register_operand" "=rk")
1770 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1772 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1773 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1774 (match_operand 3 "const_int_operand" "n")
1776 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1777 "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1778 [(set_attr "v8type" "alu_ext")
1779 (set_attr "mode" "<MODE>")]
1782 ;; zero_extend version of above
1783 (define_insn "*sub_<optab>si_multp2_uxtw"
1784 [(set (match_operand:DI 0 "register_operand" "=rk")
1786 (minus:SI (match_operand:SI 4 "register_operand" "r")
1788 (mult:SI (match_operand:SI 1 "register_operand" "r")
1789 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1790 (match_operand 3 "const_int_operand" "n")
1792 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1793 "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1794 [(set_attr "v8type" "alu_ext")
1795 (set_attr "mode" "SI")]
1798 (define_insn "*sub<mode>3_carryin"
1800 (match_operand:GPI 0 "register_operand" "=r")
1801 (minus:GPI (minus:GPI
1802 (match_operand:GPI 1 "register_operand" "r")
1803 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
1804 (match_operand:GPI 2 "register_operand" "r")))]
1806 "sbc\\t%<w>0, %<w>1, %<w>2"
1807 [(set_attr "v8type" "adc")
1808 (set_attr "mode" "<MODE>")]
1811 ;; zero_extend version of the above
1812 (define_insn "*subsi3_carryin_uxtw"
1814 (match_operand:DI 0 "register_operand" "=r")
1817 (match_operand:SI 1 "register_operand" "r")
1818 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
1819 (match_operand:SI 2 "register_operand" "r"))))]
1821 "sbc\\t%w0, %w1, %w2"
1822 [(set_attr "v8type" "adc")
1823 (set_attr "mode" "SI")]
1826 (define_insn "*sub_uxt<mode>_multp2"
1827 [(set (match_operand:GPI 0 "register_operand" "=rk")
1828 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1830 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1831 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1832 (match_operand 3 "const_int_operand" "n"))))]
1833 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1835 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1836 INTVAL (operands[3])));
1837 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1838 [(set_attr "v8type" "alu_ext")
1839 (set_attr "mode" "<MODE>")]
1842 ;; zero_extend version of above
1843 (define_insn "*sub_uxtsi_multp2_uxtw"
1844 [(set (match_operand:DI 0 "register_operand" "=rk")
1846 (minus:SI (match_operand:SI 4 "register_operand" "r")
1848 (mult:SI (match_operand:SI 1 "register_operand" "r")
1849 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1850 (match_operand 3 "const_int_operand" "n")))))]
1851 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1853 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1854 INTVAL (operands[3])));
1855 return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
1856 [(set_attr "v8type" "alu_ext")
1857 (set_attr "mode" "SI")]
1860 (define_insn "neg<mode>2"
1861 [(set (match_operand:GPI 0 "register_operand" "=r")
1862 (neg:GPI (match_operand:GPI 1 "register_operand" "r")))]
1864 "neg\\t%<w>0, %<w>1"
1865 [(set_attr "v8type" "alu")
1866 (set_attr "mode" "<MODE>")]
1869 ;; zero_extend version of above
1870 (define_insn "*negsi2_uxtw"
1871 [(set (match_operand:DI 0 "register_operand" "=r")
1872 (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
1875 [(set_attr "v8type" "alu")
1876 (set_attr "mode" "SI")]
1879 (define_insn "*neg<mode>2_compare0"
1880 [(set (reg:CC_NZ CC_REGNUM)
1881 (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
1883 (set (match_operand:GPI 0 "register_operand" "=r")
1884 (neg:GPI (match_dup 1)))]
1886 "negs\\t%<w>0, %<w>1"
1887 [(set_attr "v8type" "alus")
1888 (set_attr "mode" "<MODE>")]
1891 ;; zero_extend version of above
1892 (define_insn "*negsi2_compare0_uxtw"
1893 [(set (reg:CC_NZ CC_REGNUM)
1894 (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
1896 (set (match_operand:DI 0 "register_operand" "=r")
1897 (zero_extend:DI (neg:SI (match_dup 1))))]
1900 [(set_attr "v8type" "alus")
1901 (set_attr "mode" "SI")]
1904 (define_insn "*neg_<shift><mode>3_compare0"
1905 [(set (reg:CC_NZ CC_REGNUM)
1907 (neg:GPI (ASHIFT:GPI
1908 (match_operand:GPI 1 "register_operand" "r")
1909 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
1911 (set (match_operand:GPI 0 "register_operand" "=r")
1912 (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
1914 "negs\\t%<w>0, %<w>1, <shift> %2"
1915 [(set_attr "v8type" "alus_shift")
1916 (set_attr "mode" "<MODE>")]
1919 (define_insn "*neg_<shift>_<mode>2"
1920 [(set (match_operand:GPI 0 "register_operand" "=r")
1921 (neg:GPI (ASHIFT:GPI
1922 (match_operand:GPI 1 "register_operand" "r")
1923 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1925 "neg\\t%<w>0, %<w>1, <shift> %2"
1926 [(set_attr "v8type" "alu_shift")
1927 (set_attr "mode" "<MODE>")]
1930 ;; zero_extend version of above
1931 (define_insn "*neg_<shift>_si2_uxtw"
1932 [(set (match_operand:DI 0 "register_operand" "=r")
1935 (match_operand:SI 1 "register_operand" "r")
1936 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1938 "neg\\t%w0, %w1, <shift> %2"
1939 [(set_attr "v8type" "alu_shift")
1940 (set_attr "mode" "SI")]
1943 (define_insn "*neg_mul_imm_<mode>2"
1944 [(set (match_operand:GPI 0 "register_operand" "=r")
1946 (match_operand:GPI 1 "register_operand" "r")
1947 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1949 "neg\\t%<w>0, %<w>1, lsl %p2"
1950 [(set_attr "v8type" "alu_shift")
1951 (set_attr "mode" "<MODE>")]
1954 ;; zero_extend version of above
1955 (define_insn "*neg_mul_imm_si2_uxtw"
1956 [(set (match_operand:DI 0 "register_operand" "=r")
1959 (match_operand:SI 1 "register_operand" "r")
1960 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
1962 "neg\\t%w0, %w1, lsl %p2"
1963 [(set_attr "v8type" "alu_shift")
1964 (set_attr "mode" "SI")]
1967 (define_insn "mul<mode>3"
1968 [(set (match_operand:GPI 0 "register_operand" "=r")
1969 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1970 (match_operand:GPI 2 "register_operand" "r")))]
1972 "mul\\t%<w>0, %<w>1, %<w>2"
1973 [(set_attr "v8type" "mult")
1974 (set_attr "mode" "<MODE>")]
1977 ;; zero_extend version of above
1978 (define_insn "*mulsi3_uxtw"
1979 [(set (match_operand:DI 0 "register_operand" "=r")
1981 (mult:SI (match_operand:SI 1 "register_operand" "r")
1982 (match_operand:SI 2 "register_operand" "r"))))]
1984 "mul\\t%w0, %w1, %w2"
1985 [(set_attr "v8type" "mult")
1986 (set_attr "mode" "SI")]
1989 (define_insn "*madd<mode>"
1990 [(set (match_operand:GPI 0 "register_operand" "=r")
1991 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1992 (match_operand:GPI 2 "register_operand" "r"))
1993 (match_operand:GPI 3 "register_operand" "r")))]
1995 "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
1996 [(set_attr "v8type" "madd")
1997 (set_attr "mode" "<MODE>")]
2000 ;; zero_extend version of above
2001 (define_insn "*maddsi_uxtw"
2002 [(set (match_operand:DI 0 "register_operand" "=r")
2004 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2005 (match_operand:SI 2 "register_operand" "r"))
2006 (match_operand:SI 3 "register_operand" "r"))))]
2008 "madd\\t%w0, %w1, %w2, %w3"
2009 [(set_attr "v8type" "madd")
2010 (set_attr "mode" "SI")]
2013 (define_insn "*msub<mode>"
2014 [(set (match_operand:GPI 0 "register_operand" "=r")
2015 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2016 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2017 (match_operand:GPI 2 "register_operand" "r"))))]
2020 "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2021 [(set_attr "v8type" "madd")
2022 (set_attr "mode" "<MODE>")]
2025 ;; zero_extend version of above
2026 (define_insn "*msubsi_uxtw"
2027 [(set (match_operand:DI 0 "register_operand" "=r")
2029 (minus:SI (match_operand:SI 3 "register_operand" "r")
2030 (mult:SI (match_operand:SI 1 "register_operand" "r")
2031 (match_operand:SI 2 "register_operand" "r")))))]
2034 "msub\\t%w0, %w1, %w2, %w3"
2035 [(set_attr "v8type" "madd")
2036 (set_attr "mode" "SI")]
2039 (define_insn "*mul<mode>_neg"
2040 [(set (match_operand:GPI 0 "register_operand" "=r")
2041 (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2042 (match_operand:GPI 2 "register_operand" "r")))]
2045 "mneg\\t%<w>0, %<w>1, %<w>2"
2046 [(set_attr "v8type" "mult")
2047 (set_attr "mode" "<MODE>")]
2050 ;; zero_extend version of above
2051 (define_insn "*mulsi_neg_uxtw"
2052 [(set (match_operand:DI 0 "register_operand" "=r")
2054 (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2055 (match_operand:SI 2 "register_operand" "r"))))]
2058 "mneg\\t%w0, %w1, %w2"
2059 [(set_attr "v8type" "mult")
2060 (set_attr "mode" "SI")]
2063 (define_insn "<su_optab>mulsidi3"
2064 [(set (match_operand:DI 0 "register_operand" "=r")
2065 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2066 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2068 "<su>mull\\t%0, %w1, %w2"
2069 [(set_attr "v8type" "mull")
2070 (set_attr "mode" "DI")]
2073 (define_insn "<su_optab>maddsidi4"
2074 [(set (match_operand:DI 0 "register_operand" "=r")
2076 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2077 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2078 (match_operand:DI 3 "register_operand" "r")))]
2080 "<su>maddl\\t%0, %w1, %w2, %3"
2081 [(set_attr "v8type" "maddl")
2082 (set_attr "mode" "DI")]
2085 (define_insn "<su_optab>msubsidi4"
2086 [(set (match_operand:DI 0 "register_operand" "=r")
2088 (match_operand:DI 3 "register_operand" "r")
2089 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2091 (match_operand:SI 2 "register_operand" "r")))))]
2093 "<su>msubl\\t%0, %w1, %w2, %3"
2094 [(set_attr "v8type" "maddl")
2095 (set_attr "mode" "DI")]
2098 (define_insn "*<su_optab>mulsidi_neg"
2099 [(set (match_operand:DI 0 "register_operand" "=r")
2101 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2102 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2104 "<su>mnegl\\t%0, %w1, %w2"
2105 [(set_attr "v8type" "mull")
2106 (set_attr "mode" "DI")]
2109 (define_insn "<su>muldi3_highpart"
2110 [(set (match_operand:DI 0 "register_operand" "=r")
2114 (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2115 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2118 "<su>mulh\\t%0, %1, %2"
2119 [(set_attr "v8type" "mulh")
2120 (set_attr "mode" "DI")]
2123 (define_insn "<su_optab>div<mode>3"
2124 [(set (match_operand:GPI 0 "register_operand" "=r")
2125 (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2126 (match_operand:GPI 2 "register_operand" "r")))]
2128 "<su>div\\t%<w>0, %<w>1, %<w>2"
2129 [(set_attr "v8type" "<su>div")
2130 (set_attr "mode" "<MODE>")]
2133 ;; zero_extend version of above
2134 (define_insn "*<su_optab>divsi3_uxtw"
2135 [(set (match_operand:DI 0 "register_operand" "=r")
2137 (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2138 (match_operand:SI 2 "register_operand" "r"))))]
2140 "<su>div\\t%w0, %w1, %w2"
2141 [(set_attr "v8type" "<su>div")
2142 (set_attr "mode" "SI")]
2145 ;; -------------------------------------------------------------------
2147 ;; -------------------------------------------------------------------
2149 (define_insn "*cmp<mode>"
2150 [(set (reg:CC CC_REGNUM)
2151 (compare:CC (match_operand:GPI 0 "register_operand" "r,r")
2152 (match_operand:GPI 1 "aarch64_plus_operand" "rI,J")))]
2157 [(set_attr "v8type" "alus")
2158 (set_attr "mode" "<MODE>")]
2161 (define_insn "*cmp<mode>"
2162 [(set (reg:CCFP CC_REGNUM)
2163 (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2164 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2168 fcmp\\t%<s>0, %<s>1"
2169 [(set_attr "v8type" "fcmp")
2170 (set_attr "mode" "<MODE>")]
2173 (define_insn "*cmpe<mode>"
2174 [(set (reg:CCFPE CC_REGNUM)
2175 (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2176 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2180 fcmpe\\t%<s>0, %<s>1"
2181 [(set_attr "v8type" "fcmp")
2182 (set_attr "mode" "<MODE>")]
2185 (define_insn "*cmp_swp_<shift>_reg<mode>"
2186 [(set (reg:CC_SWP CC_REGNUM)
2187 (compare:CC_SWP (ASHIFT:GPI
2188 (match_operand:GPI 0 "register_operand" "r")
2189 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2190 (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2192 "cmp\\t%<w>2, %<w>0, <shift> %1"
2193 [(set_attr "v8type" "alus_shift")
2194 (set_attr "mode" "<MODE>")]
2197 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2198 [(set (reg:CC_SWP CC_REGNUM)
2199 (compare:CC_SWP (ANY_EXTEND:GPI
2200 (match_operand:ALLX 0 "register_operand" "r"))
2201 (match_operand:GPI 1 "register_operand" "r")))]
2203 "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2204 [(set_attr "v8type" "alus_ext")
2205 (set_attr "mode" "<GPI:MODE>")]
2209 ;; -------------------------------------------------------------------
2210 ;; Store-flag and conditional select insns
2211 ;; -------------------------------------------------------------------
2213 (define_expand "cstore<mode>4"
2214 [(set (match_operand:SI 0 "register_operand" "")
2215 (match_operator:SI 1 "aarch64_comparison_operator"
2216 [(match_operand:GPI 2 "register_operand" "")
2217 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2220 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2222 operands[3] = const0_rtx;
2226 (define_expand "cstore<mode>4"
2227 [(set (match_operand:SI 0 "register_operand" "")
2228 (match_operator:SI 1 "aarch64_comparison_operator"
2229 [(match_operand:GPF 2 "register_operand" "")
2230 (match_operand:GPF 3 "register_operand" "")]))]
2233 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2235 operands[3] = const0_rtx;
2239 (define_insn "*cstore<mode>_insn"
2240 [(set (match_operand:ALLI 0 "register_operand" "=r")
2241 (match_operator:ALLI 1 "aarch64_comparison_operator"
2242 [(match_operand 2 "cc_register" "") (const_int 0)]))]
2245 [(set_attr "v8type" "csel")
2246 (set_attr "mode" "<MODE>")]
2249 ;; zero_extend version of the above
2250 (define_insn "*cstoresi_insn_uxtw"
2251 [(set (match_operand:DI 0 "register_operand" "=r")
2253 (match_operator:SI 1 "aarch64_comparison_operator"
2254 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2257 [(set_attr "v8type" "csel")
2258 (set_attr "mode" "SI")]
2261 (define_insn "*cstore<mode>_neg"
2262 [(set (match_operand:ALLI 0 "register_operand" "=r")
2263 (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2264 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2266 "csetm\\t%<w>0, %m1"
2267 [(set_attr "v8type" "csel")
2268 (set_attr "mode" "<MODE>")]
2271 ;; zero_extend version of the above
2272 (define_insn "*cstoresi_neg_uxtw"
2273 [(set (match_operand:DI 0 "register_operand" "=r")
2275 (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2276 [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2279 [(set_attr "v8type" "csel")
2280 (set_attr "mode" "SI")]
2283 (define_expand "cmov<mode>6"
2284 [(set (match_operand:GPI 0 "register_operand" "")
2286 (match_operator 1 "aarch64_comparison_operator"
2287 [(match_operand:GPI 2 "register_operand" "")
2288 (match_operand:GPI 3 "aarch64_plus_operand" "")])
2289 (match_operand:GPI 4 "register_operand" "")
2290 (match_operand:GPI 5 "register_operand" "")))]
2293 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2295 operands[3] = const0_rtx;
2299 (define_expand "cmov<mode>6"
2300 [(set (match_operand:GPF 0 "register_operand" "")
2302 (match_operator 1 "aarch64_comparison_operator"
2303 [(match_operand:GPF 2 "register_operand" "")
2304 (match_operand:GPF 3 "register_operand" "")])
2305 (match_operand:GPF 4 "register_operand" "")
2306 (match_operand:GPF 5 "register_operand" "")))]
2309 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2311 operands[3] = const0_rtx;
2315 (define_insn "*cmov<mode>_insn"
2316 [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2318 (match_operator 1 "aarch64_comparison_operator"
2319 [(match_operand 2 "cc_register" "") (const_int 0)])
2320 (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2321 (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2322 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2323 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2324 ;; Final two alternatives should be unreachable, but included for completeness
2326 csel\\t%<w>0, %<w>3, %<w>4, %m1
2327 csinv\\t%<w>0, %<w>3, <w>zr, %m1
2328 csinv\\t%<w>0, %<w>4, <w>zr, %M1
2329 csinc\\t%<w>0, %<w>3, <w>zr, %m1
2330 csinc\\t%<w>0, %<w>4, <w>zr, %M1
2333 [(set_attr "v8type" "csel")
2334 (set_attr "mode" "<MODE>")]
2337 ;; zero_extend version of above
2338 (define_insn "*cmovsi_insn_uxtw"
2339 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2342 (match_operator 1 "aarch64_comparison_operator"
2343 [(match_operand 2 "cc_register" "") (const_int 0)])
2344 (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2345 (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2346 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2347 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2348 ;; Final two alternatives should be unreachable, but included for completeness
2350 csel\\t%w0, %w3, %w4, %m1
2351 csinv\\t%w0, %w3, wzr, %m1
2352 csinv\\t%w0, %w4, wzr, %M1
2353 csinc\\t%w0, %w3, wzr, %m1
2354 csinc\\t%w0, %w4, wzr, %M1
2357 [(set_attr "v8type" "csel")
2358 (set_attr "mode" "SI")]
2361 (define_insn "*cmov<mode>_insn"
2362 [(set (match_operand:GPF 0 "register_operand" "=w")
2364 (match_operator 1 "aarch64_comparison_operator"
2365 [(match_operand 2 "cc_register" "") (const_int 0)])
2366 (match_operand:GPF 3 "register_operand" "w")
2367 (match_operand:GPF 4 "register_operand" "w")))]
2369 "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2370 [(set_attr "v8type" "fcsel")
2371 (set_attr "mode" "<MODE>")]
2374 (define_expand "mov<mode>cc"
2375 [(set (match_operand:ALLI 0 "register_operand" "")
2376 (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2377 (match_operand:ALLI 2 "register_operand" "")
2378 (match_operand:ALLI 3 "register_operand" "")))]
2382 enum rtx_code code = GET_CODE (operands[1]);
2384 if (code == UNEQ || code == LTGT)
2387 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2388 XEXP (operands[1], 1));
2389 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2393 (define_expand "mov<GPF:mode><GPI:mode>cc"
2394 [(set (match_operand:GPI 0 "register_operand" "")
2395 (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2396 (match_operand:GPF 2 "register_operand" "")
2397 (match_operand:GPF 3 "register_operand" "")))]
2401 enum rtx_code code = GET_CODE (operands[1]);
2403 if (code == UNEQ || code == LTGT)
2406 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2407 XEXP (operands[1], 1));
2408 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2412 (define_insn "*csinc2<mode>_insn"
2413 [(set (match_operand:GPI 0 "register_operand" "=r")
2414 (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator"
2415 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
2416 (match_operand:GPI 1 "register_operand" "r")))]
2418 "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2419 [(set_attr "v8type" "csel")
2420 (set_attr "mode" "<MODE>")])
2422 (define_insn "csinc3<mode>_insn"
2423 [(set (match_operand:GPI 0 "register_operand" "=r")
2425 (match_operator:GPI 1 "aarch64_comparison_operator"
2426 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2427 (plus:GPI (match_operand:GPI 3 "register_operand" "r")
2429 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2431 "csinc\\t%<w>0, %<w>4, %<w>3, %M1"
2432 [(set_attr "v8type" "csel")
2433 (set_attr "mode" "<MODE>")]
2436 (define_insn "*csinv3<mode>_insn"
2437 [(set (match_operand:GPI 0 "register_operand" "=r")
2439 (match_operator:GPI 1 "aarch64_comparison_operator"
2440 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2441 (not:GPI (match_operand:GPI 3 "register_operand" "r"))
2442 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2444 "csinv\\t%<w>0, %<w>4, %<w>3, %M1"
2445 [(set_attr "v8type" "csel")
2446 (set_attr "mode" "<MODE>")])
2448 (define_insn "*csneg3<mode>_insn"
2449 [(set (match_operand:GPI 0 "register_operand" "=r")
2451 (match_operator:GPI 1 "aarch64_comparison_operator"
2452 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2453 (neg:GPI (match_operand:GPI 3 "register_operand" "r"))
2454 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2456 "csneg\\t%<w>0, %<w>4, %<w>3, %M1"
2457 [(set_attr "v8type" "csel")
2458 (set_attr "mode" "<MODE>")])
2460 ;; -------------------------------------------------------------------
2461 ;; Logical operations
2462 ;; -------------------------------------------------------------------
2464 (define_insn "<optab><mode>3"
2465 [(set (match_operand:GPI 0 "register_operand" "=r,rk")
2466 (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2467 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
2469 "<logical>\\t%<w>0, %<w>1, %<w>2"
2470 [(set_attr "v8type" "logic,logic_imm")
2471 (set_attr "mode" "<MODE>")])
2473 ;; zero_extend version of above
2474 (define_insn "*<optab>si3_uxtw"
2475 [(set (match_operand:DI 0 "register_operand" "=r,rk")
2477 (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2478 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2480 "<logical>\\t%w0, %w1, %w2"
2481 [(set_attr "v8type" "logic,logic_imm")
2482 (set_attr "mode" "SI")])
2484 (define_insn "*and<mode>3_compare0"
2485 [(set (reg:CC_NZ CC_REGNUM)
2487 (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2488 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2490 (set (match_operand:GPI 0 "register_operand" "=r,r")
2491 (and:GPI (match_dup 1) (match_dup 2)))]
2493 "ands\\t%<w>0, %<w>1, %<w>2"
2494 [(set_attr "v8type" "logics,logics_imm")
2495 (set_attr "mode" "<MODE>")]
2498 ;; zero_extend version of above
2499 (define_insn "*andsi3_compare0_uxtw"
2500 [(set (reg:CC_NZ CC_REGNUM)
2502 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2503 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2505 (set (match_operand:DI 0 "register_operand" "=r,r")
2506 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2508 "ands\\t%w0, %w1, %w2"
2509 [(set_attr "v8type" "logics,logics_imm")
2510 (set_attr "mode" "SI")]
2513 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2514 [(set (reg:CC_NZ CC_REGNUM)
2517 (match_operand:GPI 1 "register_operand" "r")
2518 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2519 (match_operand:GPI 3 "register_operand" "r"))
2521 (set (match_operand:GPI 0 "register_operand" "=r")
2522 (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2524 "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2525 [(set_attr "v8type" "logics_shift")
2526 (set_attr "mode" "<MODE>")]
2529 ;; zero_extend version of above
2530 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2531 [(set (reg:CC_NZ CC_REGNUM)
2534 (match_operand:SI 1 "register_operand" "r")
2535 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2536 (match_operand:SI 3 "register_operand" "r"))
2538 (set (match_operand:DI 0 "register_operand" "=r")
2539 (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2542 "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2543 [(set_attr "v8type" "logics_shift")
2544 (set_attr "mode" "SI")]
2547 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2548 [(set (match_operand:GPI 0 "register_operand" "=r")
2549 (LOGICAL:GPI (SHIFT:GPI
2550 (match_operand:GPI 1 "register_operand" "r")
2551 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2552 (match_operand:GPI 3 "register_operand" "r")))]
2554 "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2555 [(set_attr "v8type" "logic_shift")
2556 (set_attr "mode" "<MODE>")])
2558 ;; zero_extend version of above
2559 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
2560 [(set (match_operand:DI 0 "register_operand" "=r")
2562 (LOGICAL:SI (SHIFT:SI
2563 (match_operand:SI 1 "register_operand" "r")
2564 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2565 (match_operand:SI 3 "register_operand" "r"))))]
2567 "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2568 [(set_attr "v8type" "logic_shift")
2569 (set_attr "mode" "SI")])
2571 (define_insn "one_cmpl<mode>2"
2572 [(set (match_operand:GPI 0 "register_operand" "=r")
2573 (not:GPI (match_operand:GPI 1 "register_operand" "r")))]
2575 "mvn\\t%<w>0, %<w>1"
2576 [(set_attr "v8type" "logic")
2577 (set_attr "mode" "<MODE>")])
2579 (define_insn "*one_cmpl_<optab><mode>2"
2580 [(set (match_operand:GPI 0 "register_operand" "=r")
2581 (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
2582 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2584 "mvn\\t%<w>0, %<w>1, <shift> %2"
2585 [(set_attr "v8type" "logic_shift")
2586 (set_attr "mode" "<MODE>")])
2588 (define_insn "*<LOGICAL:optab>_one_cmpl<mode>3"
2589 [(set (match_operand:GPI 0 "register_operand" "=r")
2590 (LOGICAL:GPI (not:GPI
2591 (match_operand:GPI 1 "register_operand" "r"))
2592 (match_operand:GPI 2 "register_operand" "r")))]
2594 "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1"
2595 [(set_attr "v8type" "logic")
2596 (set_attr "mode" "<MODE>")])
2598 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
2599 [(set (match_operand:GPI 0 "register_operand" "=r")
2600 (LOGICAL:GPI (not:GPI
2602 (match_operand:GPI 1 "register_operand" "r")
2603 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2604 (match_operand:GPI 3 "register_operand" "r")))]
2606 "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2607 [(set_attr "v8type" "logic_shift")
2608 (set_attr "mode" "<MODE>")])
2610 (define_insn "clz<mode>2"
2611 [(set (match_operand:GPI 0 "register_operand" "=r")
2612 (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
2614 "clz\\t%<w>0, %<w>1"
2615 [(set_attr "v8type" "clz")
2616 (set_attr "mode" "<MODE>")])
2618 (define_expand "ffs<mode>2"
2619 [(match_operand:GPI 0 "register_operand")
2620 (match_operand:GPI 1 "register_operand")]
2623 rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
2624 rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
2626 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2627 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2628 emit_insn (gen_csinc3<mode>_insn (operands[0], x, ccreg, operands[0], const0_rtx));
2633 (define_insn "clrsb<mode>2"
2634 [(set (match_operand:GPI 0 "register_operand" "=r")
2635 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_CLS))]
2637 "cls\\t%<w>0, %<w>1"
2638 [(set_attr "v8type" "clz")
2639 (set_attr "mode" "<MODE>")])
2641 (define_insn "rbit<mode>2"
2642 [(set (match_operand:GPI 0 "register_operand" "=r")
2643 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
2645 "rbit\\t%<w>0, %<w>1"
2646 [(set_attr "v8type" "rbit")
2647 (set_attr "mode" "<MODE>")])
2649 (define_expand "ctz<mode>2"
2650 [(match_operand:GPI 0 "register_operand")
2651 (match_operand:GPI 1 "register_operand")]
2654 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2655 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2660 (define_insn "*and<mode>3nr_compare0"
2661 [(set (reg:CC_NZ CC_REGNUM)
2663 (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
2664 (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
2667 "tst\\t%<w>0, %<w>1"
2668 [(set_attr "v8type" "logics")
2669 (set_attr "mode" "<MODE>")])
2671 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
2672 [(set (reg:CC_NZ CC_REGNUM)
2675 (match_operand:GPI 0 "register_operand" "r")
2676 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2677 (match_operand:GPI 2 "register_operand" "r"))
2680 "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
2681 [(set_attr "v8type" "logics_shift")
2682 (set_attr "mode" "<MODE>")])
2684 ;; -------------------------------------------------------------------
2686 ;; -------------------------------------------------------------------
2688 (define_expand "<optab><mode>3"
2689 [(set (match_operand:GPI 0 "register_operand")
2690 (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
2691 (match_operand:QI 2 "nonmemory_operand")))]
2694 if (CONST_INT_P (operands[2]))
2696 operands[2] = GEN_INT (INTVAL (operands[2])
2697 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2699 if (operands[2] == const0_rtx)
2701 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2708 (define_expand "ashl<mode>3"
2709 [(set (match_operand:SHORT 0 "register_operand")
2710 (ashift:SHORT (match_operand:SHORT 1 "register_operand")
2711 (match_operand:QI 2 "nonmemory_operand")))]
2714 if (CONST_INT_P (operands[2]))
2716 operands[2] = GEN_INT (INTVAL (operands[2])
2717 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2719 if (operands[2] == const0_rtx)
2721 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2728 (define_expand "rotr<mode>3"
2729 [(set (match_operand:GPI 0 "register_operand")
2730 (rotatert:GPI (match_operand:GPI 1 "register_operand")
2731 (match_operand:QI 2 "nonmemory_operand")))]
2734 if (CONST_INT_P (operands[2]))
2736 operands[2] = GEN_INT (INTVAL (operands[2])
2737 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2739 if (operands[2] == const0_rtx)
2741 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2748 (define_expand "rotl<mode>3"
2749 [(set (match_operand:GPI 0 "register_operand")
2750 (rotatert:GPI (match_operand:GPI 1 "register_operand")
2751 (match_operand:QI 2 "nonmemory_operand")))]
2754 /* (SZ - cnt) % SZ == -cnt % SZ */
2755 if (CONST_INT_P (operands[2]))
2757 operands[2] = GEN_INT ((-INTVAL (operands[2]))
2758 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2759 if (operands[2] == const0_rtx)
2761 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2766 operands[2] = expand_simple_unop (QImode, NEG, operands[2],
2771 (define_insn "*<optab><mode>3_insn"
2772 [(set (match_operand:GPI 0 "register_operand" "=r")
2774 (match_operand:GPI 1 "register_operand" "r")
2775 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
2777 "<shift>\\t%<w>0, %<w>1, %<w>2"
2778 [(set_attr "v8type" "shift")
2779 (set_attr "mode" "<MODE>")]
2782 ;; zero_extend version of above
2783 (define_insn "*<optab>si3_insn_uxtw"
2784 [(set (match_operand:DI 0 "register_operand" "=r")
2785 (zero_extend:DI (SHIFT:SI
2786 (match_operand:SI 1 "register_operand" "r")
2787 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
2789 "<shift>\\t%w0, %w1, %w2"
2790 [(set_attr "v8type" "shift")
2791 (set_attr "mode" "SI")]
2794 (define_insn "*ashl<mode>3_insn"
2795 [(set (match_operand:SHORT 0 "register_operand" "=r")
2796 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
2797 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
2799 "lsl\\t%<w>0, %<w>1, %<w>2"
2800 [(set_attr "v8type" "shift")
2801 (set_attr "mode" "<MODE>")]
2804 (define_insn "*<optab><mode>3_insn"
2805 [(set (match_operand:SHORT 0 "register_operand" "=r")
2806 (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
2807 (match_operand 2 "const_int_operand" "n")))]
2808 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
2810 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
2811 return "<bfshift>\t%w0, %w1, %2, %3";
2813 [(set_attr "v8type" "bfm")
2814 (set_attr "mode" "<MODE>")]
2817 (define_insn "*extr<mode>5_insn"
2818 [(set (match_operand:GPI 0 "register_operand" "=r")
2819 (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
2820 (match_operand 3 "const_int_operand" "n"))
2821 (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
2822 (match_operand 4 "const_int_operand" "n"))))]
2823 "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
2824 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
2825 "extr\\t%<w>0, %<w>1, %<w>2, %4"
2826 [(set_attr "v8type" "shift")
2827 (set_attr "mode" "<MODE>")]
2830 ;; zero_extend version of the above
2831 (define_insn "*extrsi5_insn_uxtw"
2832 [(set (match_operand:DI 0 "register_operand" "=r")
2834 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
2835 (match_operand 3 "const_int_operand" "n"))
2836 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
2837 (match_operand 4 "const_int_operand" "n")))))]
2838 "UINTVAL (operands[3]) < 32 &&
2839 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
2840 "extr\\t%w0, %w1, %w2, %4"
2841 [(set_attr "v8type" "shift")
2842 (set_attr "mode" "SI")]
2845 (define_insn "*ror<mode>3_insn"
2846 [(set (match_operand:GPI 0 "register_operand" "=r")
2847 (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
2848 (match_operand 2 "const_int_operand" "n")))]
2849 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
2851 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
2852 return "ror\\t%<w>0, %<w>1, %3";
2854 [(set_attr "v8type" "shift")
2855 (set_attr "mode" "<MODE>")]
2858 ;; zero_extend version of the above
2859 (define_insn "*rorsi3_insn_uxtw"
2860 [(set (match_operand:DI 0 "register_operand" "=r")
2862 (rotate:SI (match_operand:SI 1 "register_operand" "r")
2863 (match_operand 2 "const_int_operand" "n"))))]
2864 "UINTVAL (operands[2]) < 32"
2866 operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
2867 return "ror\\t%w0, %w1, %3";
2869 [(set_attr "v8type" "shift")
2870 (set_attr "mode" "SI")]
2873 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
2874 [(set (match_operand:GPI 0 "register_operand" "=r")
2876 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
2877 (match_operand 2 "const_int_operand" "n"))))]
2878 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
2880 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
2881 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
2883 [(set_attr "v8type" "bfm")
2884 (set_attr "mode" "<GPI:MODE>")]
2887 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
2888 [(set (match_operand:GPI 0 "register_operand" "=r")
2890 (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
2891 (match_operand 2 "const_int_operand" "n"))))]
2892 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
2894 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
2895 return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
2897 [(set_attr "v8type" "bfm")
2898 (set_attr "mode" "<GPI:MODE>")]
2901 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
2902 [(set (match_operand:GPI 0 "register_operand" "=r")
2904 (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
2905 (match_operand 2 "const_int_operand" "n"))))]
2906 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
2908 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
2909 return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
2911 [(set_attr "v8type" "bfm")
2912 (set_attr "mode" "<GPI:MODE>")]
2915 ;; -------------------------------------------------------------------
2917 ;; -------------------------------------------------------------------
2919 (define_expand "<optab>"
2920 [(set (match_operand:DI 0 "register_operand" "=r")
2921 (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
2922 (match_operand 2 "const_int_operand" "n")
2923 (match_operand 3 "const_int_operand" "n")))]
2928 (define_insn "*<optab><mode>"
2929 [(set (match_operand:GPI 0 "register_operand" "=r")
2930 (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
2931 (match_operand 2 "const_int_operand" "n")
2932 (match_operand 3 "const_int_operand" "n")))]
2934 "<su>bfx\\t%<w>0, %<w>1, %3, %2"
2935 [(set_attr "v8type" "bfm")
2936 (set_attr "mode" "<MODE>")]
2939 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
2940 [(set (match_operand:GPI 0 "register_operand" "=r")
2941 (ashift:GPI (ANY_EXTEND:GPI
2942 (match_operand:ALLX 1 "register_operand" "r"))
2943 (match_operand 2 "const_int_operand" "n")))]
2944 "UINTVAL (operands[2]) < <GPI:sizen>"
2946 operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
2947 ? GEN_INT (<ALLX:sizen>)
2948 : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
2949 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
2951 [(set_attr "v8type" "bfm")
2952 (set_attr "mode" "<GPI:MODE>")]
2955 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
2957 (define_insn "*andim_ashift<mode>_bfiz"
2958 [(set (match_operand:GPI 0 "register_operand" "=r")
2959 (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
2960 (match_operand 2 "const_int_operand" "n"))
2961 (match_operand 3 "const_int_operand" "n")))]
2962 "exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
2963 && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
2964 "ubfiz\\t%<w>0, %<w>1, %2, %P3"
2965 [(set_attr "v8type" "bfm")
2966 (set_attr "mode" "<MODE>")]
2969 (define_insn "bswap<mode>2"
2970 [(set (match_operand:GPI 0 "register_operand" "=r")
2971 (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
2973 "rev\\t%<w>0, %<w>1"
2974 [(set_attr "v8type" "rev")
2975 (set_attr "mode" "<MODE>")]
2978 (define_insn "bswaphi2"
2979 [(set (match_operand:HI 0 "register_operand" "=r")
2980 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
2983 [(set_attr "v8type" "rev")
2984 (set_attr "mode" "HI")]
2987 ;; zero_extend version of above
2988 (define_insn "*bswapsi2_uxtw"
2989 [(set (match_operand:DI 0 "register_operand" "=r")
2990 (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
2993 [(set_attr "v8type" "rev")
2994 (set_attr "mode" "SI")]
2997 ;; -------------------------------------------------------------------
2998 ;; Floating-point intrinsics
2999 ;; -------------------------------------------------------------------
3001 ;; frint floating-point round to integral standard patterns.
3002 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round.
3004 (define_insn "<frint_pattern><mode>2"
3005 [(set (match_operand:GPF 0 "register_operand" "=w")
3006 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3009 "frint<frint_suffix>\\t%<s>0, %<s>1"
3010 [(set_attr "v8type" "frint")
3011 (set_attr "mode" "<MODE>")]
3014 ;; frcvt floating-point round to integer and convert standard patterns.
3015 ;; Expands to lbtrunc, lceil, lfloor, lround.
3016 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3017 [(set (match_operand:GPI 0 "register_operand" "=r")
3018 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3021 "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3022 [(set_attr "v8type" "fcvtf2i")
3023 (set_attr "mode" "<GPF:MODE>")
3024 (set_attr "mode2" "<GPI:MODE>")]
3029 (define_insn "fma<mode>4"
3030 [(set (match_operand:GPF 0 "register_operand" "=w")
3031 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3032 (match_operand:GPF 2 "register_operand" "w")
3033 (match_operand:GPF 3 "register_operand" "w")))]
3035 "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3036 [(set_attr "v8type" "fmadd")
3037 (set_attr "mode" "<MODE>")]
3040 (define_insn "fnma<mode>4"
3041 [(set (match_operand:GPF 0 "register_operand" "=w")
3042 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3043 (match_operand:GPF 2 "register_operand" "w")
3044 (match_operand:GPF 3 "register_operand" "w")))]
3046 "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3047 [(set_attr "v8type" "fmadd")
3048 (set_attr "mode" "<MODE>")]
3051 (define_insn "fms<mode>4"
3052 [(set (match_operand:GPF 0 "register_operand" "=w")
3053 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3054 (match_operand:GPF 2 "register_operand" "w")
3055 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3057 "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3058 [(set_attr "v8type" "fmadd")
3059 (set_attr "mode" "<MODE>")]
3062 (define_insn "fnms<mode>4"
3063 [(set (match_operand:GPF 0 "register_operand" "=w")
3064 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3065 (match_operand:GPF 2 "register_operand" "w")
3066 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3068 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3069 [(set_attr "v8type" "fmadd")
3070 (set_attr "mode" "<MODE>")]
3073 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3074 (define_insn "*fnmadd<mode>4"
3075 [(set (match_operand:GPF 0 "register_operand" "=w")
3076 (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3077 (match_operand:GPF 2 "register_operand" "w")
3078 (match_operand:GPF 3 "register_operand" "w"))))]
3079 "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3080 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3081 [(set_attr "v8type" "fmadd")
3082 (set_attr "mode" "<MODE>")]
3085 ;; -------------------------------------------------------------------
3086 ;; Floating-point conversions
3087 ;; -------------------------------------------------------------------
3089 (define_insn "extendsfdf2"
3090 [(set (match_operand:DF 0 "register_operand" "=w")
3091 (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3094 [(set_attr "v8type" "fcvt")
3095 (set_attr "mode" "DF")
3096 (set_attr "mode2" "SF")]
3099 (define_insn "truncdfsf2"
3100 [(set (match_operand:SF 0 "register_operand" "=w")
3101 (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3104 [(set_attr "v8type" "fcvt")
3105 (set_attr "mode" "SF")
3106 (set_attr "mode2" "DF")]
3109 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3110 [(set (match_operand:GPI 0 "register_operand" "=r")
3111 (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3113 "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3114 [(set_attr "v8type" "fcvtf2i")
3115 (set_attr "mode" "<GPF:MODE>")
3116 (set_attr "mode2" "<GPI:MODE>")]
3119 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3120 [(set (match_operand:GPI 0 "register_operand" "=r")
3121 (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3123 "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3124 [(set_attr "v8type" "fcvtf2i")
3125 (set_attr "mode" "<GPF:MODE>")
3126 (set_attr "mode2" "<GPI:MODE>")]
3129 (define_insn "float<GPI:mode><GPF:mode>2"
3130 [(set (match_operand:GPF 0 "register_operand" "=w")
3131 (float:GPF (match_operand:GPI 1 "register_operand" "r")))]
3133 "scvtf\\t%<GPF:s>0, %<GPI:w>1"
3134 [(set_attr "v8type" "fcvti2f")
3135 (set_attr "mode" "<GPF:MODE>")
3136 (set_attr "mode2" "<GPI:MODE>")]
3139 (define_insn "floatuns<GPI:mode><GPF:mode>2"
3140 [(set (match_operand:GPF 0 "register_operand" "=w")
3141 (unsigned_float:GPF (match_operand:GPI 1 "register_operand" "r")))]
3143 "ucvtf\\t%<GPF:s>0, %<GPI:w>1"
3144 [(set_attr "v8type" "fcvt")
3145 (set_attr "mode" "<GPF:MODE>")
3146 (set_attr "mode2" "<GPI:MODE>")]
3149 ;; -------------------------------------------------------------------
3150 ;; Floating-point arithmetic
3151 ;; -------------------------------------------------------------------
3153 (define_insn "add<mode>3"
3154 [(set (match_operand:GPF 0 "register_operand" "=w")
3156 (match_operand:GPF 1 "register_operand" "w")
3157 (match_operand:GPF 2 "register_operand" "w")))]
3159 "fadd\\t%<s>0, %<s>1, %<s>2"
3160 [(set_attr "v8type" "fadd")
3161 (set_attr "mode" "<MODE>")]
3164 (define_insn "sub<mode>3"
3165 [(set (match_operand:GPF 0 "register_operand" "=w")
3167 (match_operand:GPF 1 "register_operand" "w")
3168 (match_operand:GPF 2 "register_operand" "w")))]
3170 "fsub\\t%<s>0, %<s>1, %<s>2"
3171 [(set_attr "v8type" "fadd")
3172 (set_attr "mode" "<MODE>")]
3175 (define_insn "mul<mode>3"
3176 [(set (match_operand:GPF 0 "register_operand" "=w")
3178 (match_operand:GPF 1 "register_operand" "w")
3179 (match_operand:GPF 2 "register_operand" "w")))]
3181 "fmul\\t%<s>0, %<s>1, %<s>2"
3182 [(set_attr "v8type" "fmul")
3183 (set_attr "mode" "<MODE>")]
3186 (define_insn "*fnmul<mode>3"
3187 [(set (match_operand:GPF 0 "register_operand" "=w")
3189 (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3190 (match_operand:GPF 2 "register_operand" "w")))]
3192 "fnmul\\t%<s>0, %<s>1, %<s>2"
3193 [(set_attr "v8type" "fmul")
3194 (set_attr "mode" "<MODE>")]
3197 (define_insn "div<mode>3"
3198 [(set (match_operand:GPF 0 "register_operand" "=w")
3200 (match_operand:GPF 1 "register_operand" "w")
3201 (match_operand:GPF 2 "register_operand" "w")))]
3203 "fdiv\\t%<s>0, %<s>1, %<s>2"
3204 [(set_attr "v8type" "fdiv")
3205 (set_attr "mode" "<MODE>")]
3208 (define_insn "neg<mode>2"
3209 [(set (match_operand:GPF 0 "register_operand" "=w")
3210 (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
3212 "fneg\\t%<s>0, %<s>1"
3213 [(set_attr "v8type" "ffarith")
3214 (set_attr "mode" "<MODE>")]
3217 (define_insn "sqrt<mode>2"
3218 [(set (match_operand:GPF 0 "register_operand" "=w")
3219 (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
3221 "fsqrt\\t%<s>0, %<s>1"
3222 [(set_attr "v8type" "fsqrt")
3223 (set_attr "mode" "<MODE>")]
3226 (define_insn "abs<mode>2"
3227 [(set (match_operand:GPF 0 "register_operand" "=w")
3228 (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
3230 "fabs\\t%<s>0, %<s>1"
3231 [(set_attr "v8type" "ffarith")
3232 (set_attr "mode" "<MODE>")]
3235 ;; Given that smax/smin do not specify the result when either input is NaN,
3236 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
3239 (define_insn "smax<mode>3"
3240 [(set (match_operand:GPF 0 "register_operand" "=w")
3241 (smax:GPF (match_operand:GPF 1 "register_operand" "w")
3242 (match_operand:GPF 2 "register_operand" "w")))]
3244 "fmaxnm\\t%<s>0, %<s>1, %<s>2"
3245 [(set_attr "v8type" "fminmax")
3246 (set_attr "mode" "<MODE>")]
3249 (define_insn "smin<mode>3"
3250 [(set (match_operand:GPF 0 "register_operand" "=w")
3251 (smin:GPF (match_operand:GPF 1 "register_operand" "w")
3252 (match_operand:GPF 2 "register_operand" "w")))]
3254 "fminnm\\t%<s>0, %<s>1, %<s>2"
3255 [(set_attr "v8type" "fminmax")
3256 (set_attr "mode" "<MODE>")]
3259 ;; -------------------------------------------------------------------
3261 ;; -------------------------------------------------------------------
3263 ;; Reload SP+imm where imm cannot be handled by a single ADD instruction.
3264 ;; Must load imm into a scratch register and copy SP to the dest reg before
3265 ;; adding, since SP cannot be used as a source register in an ADD
3267 (define_expand "reload_sp_immediate"
3268 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
3269 (match_operand:DI 1 "" ""))
3270 (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
3273 rtx sp = XEXP (operands[1], 0);
3274 rtx val = XEXP (operands[1], 1);
3275 unsigned regno = REGNO (operands[2]);
3276 rtx scratch = operands[1];
3277 gcc_assert (GET_CODE (operands[1]) == PLUS);
3278 gcc_assert (sp == stack_pointer_rtx);
3279 gcc_assert (CONST_INT_P (val));
3281 /* It is possible that one of the registers we got for operands[2]
3282 might coincide with that of operands[0] (which is why we made
3283 it TImode). Pick the other one to use as our scratch. */
3284 if (regno == REGNO (operands[0]))
3286 scratch = gen_rtx_REG (DImode, regno);
3288 emit_move_insn (scratch, val);
3289 emit_move_insn (operands[0], sp);
3290 emit_insn (gen_adddi3 (operands[0], operands[0], scratch));
3295 (define_expand "aarch64_reload_mov<mode>"
3296 [(set (match_operand:TX 0 "register_operand" "=w")
3297 (match_operand:TX 1 "register_operand" "w"))
3298 (clobber (match_operand:DI 2 "register_operand" "=&r"))
3302 rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
3303 rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
3304 gen_aarch64_movtilow_tilow (op0, op1);
3305 gen_aarch64_movdi_tihigh (operands[2], op1);
3306 gen_aarch64_movtihigh_di (op0, operands[2]);
3311 ;; The following secondary reload helpers patterns are invoked
3312 ;; after or during reload as we don't want these patterns to start
3313 ;; kicking in during the combiner.
3315 (define_insn "aarch64_movdi_tilow"
3316 [(set (match_operand:DI 0 "register_operand" "=r")
3317 (truncate:DI (match_operand:TI 1 "register_operand" "w")))]
3318 "reload_completed || reload_in_progress"
3320 [(set_attr "v8type" "fmovf2i")
3321 (set_attr "mode" "DI")
3322 (set_attr "length" "4")
3325 (define_insn "aarch64_movdi_tihigh"
3326 [(set (match_operand:DI 0 "register_operand" "=r")
3328 (lshiftrt:TI (match_operand:TI 1 "register_operand" "w")
3330 "reload_completed || reload_in_progress"
3331 "fmov\\t%x0, %1.d[1]"
3332 [(set_attr "v8type" "fmovf2i")
3333 (set_attr "mode" "DI")
3334 (set_attr "length" "4")
3337 (define_insn "aarch64_movtihigh_di"
3338 [(set (zero_extract:TI (match_operand:TI 0 "register_operand" "+w")
3339 (const_int 64) (const_int 64))
3340 (zero_extend:TI (match_operand:DI 1 "register_operand" "r")))]
3341 "reload_completed || reload_in_progress"
3342 "fmov\\t%0.d[1], %x1"
3344 [(set_attr "v8type" "fmovi2f")
3345 (set_attr "mode" "DI")
3346 (set_attr "length" "4")
3349 (define_insn "aarch64_movtilow_di"
3350 [(set (match_operand:TI 0 "register_operand" "=w")
3351 (zero_extend:TI (match_operand:DI 1 "register_operand" "r")))]
3352 "reload_completed || reload_in_progress"
3355 [(set_attr "v8type" "fmovi2f")
3356 (set_attr "mode" "DI")
3357 (set_attr "length" "4")
3360 (define_insn "aarch64_movtilow_tilow"
3361 [(set (match_operand:TI 0 "register_operand" "=w")
3363 (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
3364 "reload_completed || reload_in_progress"
3367 [(set_attr "v8type" "fmovi2f")
3368 (set_attr "mode" "DI")
3369 (set_attr "length" "4")
3372 ;; There is a deliberate reason why the parameters of high and lo_sum's
3373 ;; don't have modes for ADRP and ADD instructions. This is to allow high
3374 ;; and lo_sum's to be used with the labels defining the jump tables in
3377 (define_insn "add_losym"
3378 [(set (match_operand:DI 0 "register_operand" "=r")
3379 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
3380 (match_operand 2 "aarch64_valid_symref" "S")))]
3382 "add\\t%0, %1, :lo12:%a2"
3383 [(set_attr "v8type" "alu")
3384 (set_attr "mode" "DI")]
3388 (define_insn "ldr_got_small"
3389 [(set (match_operand:DI 0 "register_operand" "=r")
3390 (unspec:DI [(mem:DI (lo_sum:DI
3391 (match_operand:DI 1 "register_operand" "r")
3392 (match_operand:DI 2 "aarch64_valid_symref" "S")))]
3393 UNSPEC_GOTSMALLPIC))]
3395 "ldr\\t%0, [%1, #:got_lo12:%a2]"
3396 [(set_attr "v8type" "load1")
3397 (set_attr "mode" "DI")]
3400 (define_insn "aarch64_load_tp_hard"
3401 [(set (match_operand:DI 0 "register_operand" "=r")
3402 (unspec:DI [(const_int 0)] UNSPEC_TLS))]
3404 "mrs\\t%0, tpidr_el0"
3405 [(set_attr "v8type" "mrs")
3406 (set_attr "mode" "DI")]
3409 ;; The TLS ABI specifically requires that the compiler does not schedule
3410 ;; instructions in the TLS stubs, in order to enable linker relaxation.
3411 ;; Therefore we treat the stubs as an atomic sequence.
3412 (define_expand "tlsgd_small"
3413 [(parallel [(set (match_operand 0 "register_operand" "")
3414 (call (mem:DI (match_dup 2)) (const_int 1)))
3415 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
3416 (clobber (reg:DI LR_REGNUM))])]
3419 operands[2] = aarch64_tls_get_addr ();
3422 (define_insn "*tlsgd_small"
3423 [(set (match_operand 0 "register_operand" "")
3424 (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
3425 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
3426 (clobber (reg:DI LR_REGNUM))
3429 "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
3430 [(set_attr "v8type" "call")
3431 (set_attr "length" "16")])
3433 (define_insn "tlsie_small"
3434 [(set (match_operand:DI 0 "register_operand" "=r")
3435 (unspec:DI [(match_operand:DI 1 "aarch64_tls_ie_symref" "S")]
3436 UNSPEC_GOTSMALLTLS))]
3438 "adrp\\t%0, %A1\;ldr\\t%0, [%0, #%L1]"
3439 [(set_attr "v8type" "load1")
3440 (set_attr "mode" "DI")
3441 (set_attr "length" "8")]
3444 (define_insn "tlsle_small"
3445 [(set (match_operand:DI 0 "register_operand" "=r")
3446 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
3447 (match_operand:DI 2 "aarch64_tls_le_symref" "S")]
3448 UNSPEC_GOTSMALLTLS))]
3450 "add\\t%0, %1, #%G2\;add\\t%0, %0, #%L2"
3451 [(set_attr "v8type" "alu")
3452 (set_attr "mode" "DI")
3453 (set_attr "length" "8")]
3456 (define_insn "tlsdesc_small"
3457 [(set (reg:DI R0_REGNUM)
3458 (unspec:DI [(match_operand:DI 0 "aarch64_valid_symref" "S")]
3460 (clobber (reg:DI LR_REGNUM))
3461 (clobber (match_scratch:DI 1 "=r"))]
3463 "adrp\\tx0, %A0\;ldr\\t%1, [x0, #%L0]\;add\\tx0, x0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
3464 [(set_attr "v8type" "call")
3465 (set_attr "length" "16")])
3467 (define_insn "stack_tie"
3468 [(set (mem:BLK (scratch))
3469 (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
3470 (match_operand:DI 1 "register_operand" "rk")]
3474 [(set_attr "length" "0")]
3477 ;; Named pattern for expanding thread pointer reference.
3478 (define_expand "get_thread_pointerdi"
3479 [(match_operand:DI 0 "register_operand" "=r")]
3482 rtx tmp = aarch64_load_tp (operands[0]);
3483 if (tmp != operands[0])
3484 emit_move_insn (operands[0], tmp);
3489 (include "aarch64-simd.md")
3491 ;; Atomic Operations
3492 (include "atomics.md")