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" [
97 (define_c_enum "unspecv" [
98 UNSPECV_EH_RETURN ; Represent EH_RETURN
102 ;; If further include files are added the defintion of MD_INCLUDES
105 (include "constraints.md")
106 (include "predicates.md")
107 (include "iterators.md")
109 ;; -------------------------------------------------------------------
110 ;; Instruction types and attributes
111 ;; -------------------------------------------------------------------
113 ;; Main data types used by the insntructions
115 (define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
116 (const_string "unknown"))
118 (define_attr "mode2" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
119 (const_string "unknown"))
121 ; The "v8type" attribute is used to for fine grained classification of
122 ; AArch64 instructions. This table briefly explains the meaning of each type.
124 ; adc add/subtract with carry.
125 ; adcs add/subtract with carry (setting condition flags).
126 ; adr calculate address.
127 ; alu simple alu instruction (no memory or fp regs access).
128 ; alu_ext simple alu instruction (sign/zero-extended register).
129 ; alu_shift simple alu instruction, with a source operand shifted by a constant.
130 ; alus simple alu instruction (setting condition flags).
131 ; alus_ext simple alu instruction (sign/zero-extended register, setting condition flags).
132 ; alus_shift simple alu instruction, with a source operand shifted by a constant (setting condition flags).
133 ; bfm bitfield move operation.
135 ; call subroutine call.
136 ; ccmp conditional compare.
137 ; clz count leading zeros/sign bits.
138 ; csel conditional select.
139 ; dmb data memory barrier.
140 ; extend sign/zero-extend (specialised bitfield move).
141 ; extr extract register-sized bitfield encoding.
142 ; fpsimd_load load single floating point / simd scalar register from memory.
143 ; fpsimd_load2 load pair of floating point / simd scalar registers from memory.
144 ; fpsimd_store store single floating point / simd scalar register to memory.
145 ; fpsimd_store2 store pair floating point / simd scalar registers to memory.
146 ; fadd floating point add/sub.
147 ; fccmp floating point conditional compare.
148 ; fcmp floating point comparison.
149 ; fconst floating point load immediate.
150 ; fcsel floating point conditional select.
151 ; fcvt floating point convert (float to float).
152 ; fcvtf2i floating point convert (float to integer).
153 ; fcvti2f floating point convert (integer to float).
154 ; fdiv floating point division operation.
155 ; ffarith floating point abs, neg or cpy.
156 ; fmadd floating point multiply-add/sub.
157 ; fminmax floating point min/max.
158 ; fmov floating point move (float to float).
159 ; fmovf2i floating point move (float to integer).
160 ; fmovi2f floating point move (integer to float).
161 ; fmul floating point multiply.
162 ; frint floating point round to integral.
163 ; fsqrt floating point square root.
164 ; load_acq load-acquire.
165 ; load load single general register from memory
166 ; load2 load pair of general registers from memory
167 ; logic logical operation (register).
168 ; logic_imm and/or/xor operation (immediate).
169 ; logic_shift logical operation with shift.
170 ; logics logical operation (register, setting condition flags).
171 ; logics_imm and/or/xor operation (immediate, setting condition flags).
172 ; logics_shift logical operation with shift (setting condition flags).
173 ; madd integer multiply-add/sub.
174 ; maddl widening integer multiply-add/sub.
175 ; misc miscellaneous - any type that doesn't fit into the rest.
176 ; move integer move operation.
177 ; move2 double integer move operation.
178 ; movk move 16-bit immediate with keep.
179 ; movz move 16-bit immmediate with zero/one.
180 ; mrs system/special register move.
181 ; mulh 64x64 to 128-bit multiply (high part).
182 ; mull widening multiply.
183 ; mult integer multiply instruction.
184 ; prefetch memory prefetch.
187 ; sdiv integer division operation (signed).
188 ; shift variable shift operation.
189 ; shift_imm immediate shift operation (specialised bitfield move).
190 ; store_rel store-release.
191 ; store store single general register to memory.
192 ; store2 store pair of general registers to memory.
193 ; udiv integer division operation (unsigned).
195 (define_attr "v8type"
271 (const_string "alu"))
274 ; The "type" attribute is used by the AArch32 backend. Below is a mapping
275 ; from "v8type" to "type".
278 "alu,alu_shift,block,branch,call,f_2_r,f_cvt,f_flag,f_loads,
279 f_loadd,f_stored,f_stores,faddd,fadds,fcmpd,fcmps,fconstd,fconsts,
280 fcpys,fdivd,fdivs,ffarithd,ffariths,fmacd,fmacs,fmuld,fmuls,load_byte,
281 load1,load2,mult,r_2_f,store1,store2"
283 (eq_attr "v8type" "alu_shift,alus_shift,logic_shift,logics_shift") (const_string "alu_shift")
284 (eq_attr "v8type" "branch") (const_string "branch")
285 (eq_attr "v8type" "call") (const_string "call")
286 (eq_attr "v8type" "fmovf2i") (const_string "f_2_r")
287 (eq_attr "v8type" "fcvt,fcvtf2i,fcvti2f") (const_string "f_cvt")
288 (and (eq_attr "v8type" "fpsimd_load") (eq_attr "mode" "SF")) (const_string "f_loads")
289 (and (eq_attr "v8type" "fpsimd_load") (eq_attr "mode" "DF")) (const_string "f_loadd")
290 (and (eq_attr "v8type" "fpsimd_store") (eq_attr "mode" "SF")) (const_string "f_stores")
291 (and (eq_attr "v8type" "fpsimd_store") (eq_attr "mode" "DF")) (const_string "f_stored")
292 (and (eq_attr "v8type" "fadd,fminmax") (eq_attr "mode" "DF")) (const_string "faddd")
293 (and (eq_attr "v8type" "fadd,fminmax") (eq_attr "mode" "SF")) (const_string "fadds")
294 (and (eq_attr "v8type" "fcmp,fccmp") (eq_attr "mode" "DF")) (const_string "fcmpd")
295 (and (eq_attr "v8type" "fcmp,fccmp") (eq_attr "mode" "SF")) (const_string "fcmps")
296 (and (eq_attr "v8type" "fconst") (eq_attr "mode" "DF")) (const_string "fconstd")
297 (and (eq_attr "v8type" "fconst") (eq_attr "mode" "SF")) (const_string "fconsts")
298 (and (eq_attr "v8type" "fdiv,fsqrt") (eq_attr "mode" "DF")) (const_string "fdivd")
299 (and (eq_attr "v8type" "fdiv,fsqrt") (eq_attr "mode" "SF")) (const_string "fdivs")
300 (and (eq_attr "v8type" "ffarith") (eq_attr "mode" "DF")) (const_string "ffarithd")
301 (and (eq_attr "v8type" "ffarith") (eq_attr "mode" "SF")) (const_string "ffariths")
302 (and (eq_attr "v8type" "fmadd") (eq_attr "mode" "DF")) (const_string "fmacd")
303 (and (eq_attr "v8type" "fmadd") (eq_attr "mode" "SF")) (const_string "fmacs")
304 (and (eq_attr "v8type" "fmul") (eq_attr "mode" "DF")) (const_string "fmuld")
305 (and (eq_attr "v8type" "fmul") (eq_attr "mode" "SF")) (const_string "fmuls")
306 (and (eq_attr "v8type" "load1") (eq_attr "mode" "QI,HI")) (const_string "load_byte")
307 (and (eq_attr "v8type" "load1") (eq_attr "mode" "SI,DI,TI")) (const_string "load1")
308 (eq_attr "v8type" "load2") (const_string "load2")
309 (and (eq_attr "v8type" "mulh,mult,mull,madd,sdiv,udiv") (eq_attr "mode" "SI")) (const_string "mult")
310 (eq_attr "v8type" "fmovi2f") (const_string "r_2_f")
311 (eq_attr "v8type" "store1") (const_string "store1")
312 (eq_attr "v8type" "store2") (const_string "store2")
314 (const_string "alu")))
316 ;; Attribute that specifies whether or not the instruction touches fp
318 (define_attr "fp" "no,yes" (const_string "no"))
320 ;; Attribute that specifies whether or not the instruction touches simd
322 (define_attr "simd" "no,yes" (const_string "no"))
324 (define_attr "length" ""
327 ;; Attribute that controls whether an alternative is enabled or not.
328 ;; Currently it is only used to disable alternatives which touch fp or simd
329 ;; registers when -mgeneral-regs-only is specified.
330 (define_attr "enabled" "no,yes"
332 (and (eq_attr "fp" "yes")
333 (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
334 (and (eq_attr "simd" "yes")
335 (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
337 ] (const_string "yes")))
339 ;; -------------------------------------------------------------------
340 ;; Pipeline descriptions and scheduling
341 ;; -------------------------------------------------------------------
344 (include "aarch64-tune.md")
347 (include "aarch64-generic.md")
351 ;; -------------------------------------------------------------------
352 ;; Jumps and other miscellaneous insns
353 ;; -------------------------------------------------------------------
355 (define_insn "indirect_jump"
356 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
359 [(set_attr "v8type" "branch")]
363 [(set (pc) (label_ref (match_operand 0 "" "")))]
366 [(set_attr "v8type" "branch")]
369 (define_expand "cbranch<mode>4"
370 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
371 [(match_operand:GPI 1 "register_operand" "")
372 (match_operand:GPI 2 "aarch64_plus_operand" "")])
373 (label_ref (match_operand 3 "" ""))
377 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
379 operands[2] = const0_rtx;
383 (define_expand "cbranch<mode>4"
384 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
385 [(match_operand:GPF 1 "register_operand" "")
386 (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
387 (label_ref (match_operand 3 "" ""))
391 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
393 operands[2] = const0_rtx;
397 (define_insn "*condjump"
398 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
399 [(match_operand 1 "cc_register" "") (const_int 0)])
400 (label_ref (match_operand 2 "" ""))
404 [(set_attr "v8type" "branch")]
407 (define_expand "casesi"
408 [(match_operand:SI 0 "register_operand" "") ; Index
409 (match_operand:SI 1 "const_int_operand" "") ; Lower bound
410 (match_operand:SI 2 "const_int_operand" "") ; Total range
411 (match_operand:DI 3 "" "") ; Table label
412 (match_operand:DI 4 "" "")] ; Out of range label
415 if (operands[1] != const0_rtx)
417 rtx reg = gen_reg_rtx (SImode);
419 /* Canonical RTL says that if you have:
423 then this should be emitted as:
427 The use of trunc_int_for_mode ensures that the resulting
428 constant can be represented in SImode, this is important
429 for the corner case where operand[1] is INT_MIN. */
431 operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
433 if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
434 (operands[1], SImode))
435 operands[1] = force_reg (SImode, operands[1]);
436 emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
440 if (!aarch64_plus_operand (operands[2], SImode))
441 operands[2] = force_reg (SImode, operands[2]);
442 emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
444 operands[0], operands[2], operands[4]));
446 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
447 emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
453 (define_insn "casesi_dispatch"
456 (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
457 (match_operand:SI 1 "register_operand" "r")]
459 (clobber (reg:CC CC_REGNUM))
460 (clobber (match_scratch:DI 3 "=r"))
461 (clobber (match_scratch:DI 4 "=r"))
462 (use (label_ref (match_operand 2 "" "")))])]
465 return aarch64_output_casesi (operands);
467 [(set_attr "length" "16")
468 (set_attr "v8type" "branch")]
472 [(unspec[(const_int 0)] UNSPEC_NOP)]
475 [(set_attr "v8type" "misc")]
478 (define_expand "prologue"
479 [(clobber (const_int 0))]
482 aarch64_expand_prologue ();
487 (define_expand "epilogue"
488 [(clobber (const_int 0))]
491 aarch64_expand_epilogue (false);
496 (define_expand "sibcall_epilogue"
497 [(clobber (const_int 0))]
500 aarch64_expand_epilogue (true);
505 (define_insn "*do_return"
509 [(set_attr "v8type" "branch")]
512 (define_insn "eh_return"
513 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
517 [(set_attr "v8type" "branch")]
521 [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
524 [(set (match_dup 1) (match_dup 0))]
526 operands[1] = aarch64_final_eh_return_addr ();
530 (define_insn "*cb<optab><mode>1"
531 [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
533 (label_ref (match_operand 1 "" ""))
537 [(set_attr "v8type" "branch")]
540 (define_insn "*tb<optab><mode>1"
541 [(set (pc) (if_then_else
542 (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
544 (match_operand 1 "const_int_operand" "n"))
546 (label_ref (match_operand 2 "" ""))
548 (clobber (match_scratch:DI 3 "=r"))]
551 if (get_attr_length (insn) == 8)
552 return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
553 return \"<tbz>\\t%<w>0, %1, %l2\";
555 [(set_attr "v8type" "branch")
556 (set_attr "mode" "<MODE>")
558 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
559 (lt (minus (match_dup 2) (pc)) (const_int 32764)))
564 (define_insn "*cb<optab><mode>1"
565 [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
567 (label_ref (match_operand 1 "" ""))
569 (clobber (match_scratch:DI 2 "=r"))]
572 if (get_attr_length (insn) == 8)
573 return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
574 return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
576 [(set_attr "v8type" "branch")
577 (set_attr "mode" "<MODE>")
579 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
580 (lt (minus (match_dup 1) (pc)) (const_int 32764)))
585 ;; -------------------------------------------------------------------
586 ;; Subroutine calls and sibcalls
587 ;; -------------------------------------------------------------------
589 (define_expand "call"
590 [(parallel [(call (match_operand 0 "memory_operand" "")
591 (match_operand 1 "general_operand" ""))
592 (use (match_operand 2 "" ""))
593 (clobber (reg:DI LR_REGNUM))])]
599 /* In an untyped call, we can get NULL for operand 2. */
600 if (operands[2] == NULL)
601 operands[2] = const0_rtx;
603 /* Decide if we should generate indirect calls by loading the
604 64-bit address of the callee into a register before performing
605 the branch-and-link. */
606 callee = XEXP (operands[0], 0);
607 if (GET_CODE (callee) == SYMBOL_REF
608 ? aarch64_is_long_call_p (callee)
610 XEXP (operands[0], 0) = force_reg (Pmode, callee);
614 (define_insn "*call_reg"
615 [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
616 (match_operand 1 "" ""))
617 (use (match_operand 2 "" ""))
618 (clobber (reg:DI LR_REGNUM))]
621 [(set_attr "v8type" "call")]
624 (define_insn "*call_symbol"
625 [(call (mem:DI (match_operand:DI 0 "" ""))
626 (match_operand 1 "" ""))
627 (use (match_operand 2 "" ""))
628 (clobber (reg:DI LR_REGNUM))]
629 "GET_CODE (operands[0]) == SYMBOL_REF
630 && !aarch64_is_long_call_p (operands[0])"
632 [(set_attr "v8type" "call")]
635 (define_expand "call_value"
636 [(parallel [(set (match_operand 0 "" "")
637 (call (match_operand 1 "memory_operand" "")
638 (match_operand 2 "general_operand" "")))
639 (use (match_operand 3 "" ""))
640 (clobber (reg:DI LR_REGNUM))])]
646 /* In an untyped call, we can get NULL for operand 3. */
647 if (operands[3] == NULL)
648 operands[3] = const0_rtx;
650 /* Decide if we should generate indirect calls by loading the
651 64-bit address of the callee into a register before performing
652 the branch-and-link. */
653 callee = XEXP (operands[1], 0);
654 if (GET_CODE (callee) == SYMBOL_REF
655 ? aarch64_is_long_call_p (callee)
657 XEXP (operands[1], 0) = force_reg (Pmode, callee);
661 (define_insn "*call_value_reg"
662 [(set (match_operand 0 "" "")
663 (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
664 (match_operand 2 "" "")))
665 (use (match_operand 3 "" ""))
666 (clobber (reg:DI LR_REGNUM))]
669 [(set_attr "v8type" "call")]
672 (define_insn "*call_value_symbol"
673 [(set (match_operand 0 "" "")
674 (call (mem:DI (match_operand:DI 1 "" ""))
675 (match_operand 2 "" "")))
676 (use (match_operand 3 "" ""))
677 (clobber (reg:DI LR_REGNUM))]
678 "GET_CODE (operands[1]) == SYMBOL_REF
679 && !aarch64_is_long_call_p (operands[1])"
681 [(set_attr "v8type" "call")]
684 (define_expand "sibcall"
685 [(parallel [(call (match_operand 0 "memory_operand" "")
686 (match_operand 1 "general_operand" ""))
688 (use (match_operand 2 "" ""))])]
691 if (operands[2] == NULL_RTX)
692 operands[2] = const0_rtx;
696 (define_expand "sibcall_value"
697 [(parallel [(set (match_operand 0 "" "")
698 (call (match_operand 1 "memory_operand" "")
699 (match_operand 2 "general_operand" "")))
701 (use (match_operand 3 "" ""))])]
704 if (operands[3] == NULL_RTX)
705 operands[3] = const0_rtx;
709 (define_insn "*sibcall_insn"
710 [(call (mem:DI (match_operand:DI 0 "" "X"))
711 (match_operand 1 "" ""))
713 (use (match_operand 2 "" ""))]
714 "GET_CODE (operands[0]) == SYMBOL_REF"
716 [(set_attr "v8type" "branch")]
719 (define_insn "*sibcall_value_insn"
720 [(set (match_operand 0 "" "")
721 (call (mem:DI (match_operand 1 "" "X"))
722 (match_operand 2 "" "")))
724 (use (match_operand 3 "" ""))]
725 "GET_CODE (operands[1]) == SYMBOL_REF"
727 [(set_attr "v8type" "branch")]
730 ;; Call subroutine returning any type.
732 (define_expand "untyped_call"
733 [(parallel [(call (match_operand 0 "")
736 (match_operand 2 "")])]
741 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
743 for (i = 0; i < XVECLEN (operands[2], 0); i++)
745 rtx set = XVECEXP (operands[2], 0, i);
746 emit_move_insn (SET_DEST (set), SET_SRC (set));
749 /* The optimizer does not know that the call sets the function value
750 registers we stored in the result block. We avoid problems by
751 claiming that all hard registers are used and clobbered at this
753 emit_insn (gen_blockage ());
757 ;; -------------------------------------------------------------------
759 ;; -------------------------------------------------------------------
761 (define_expand "mov<mode>"
762 [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
763 (match_operand:SHORT 1 "general_operand" ""))]
766 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
767 operands[1] = force_reg (<MODE>mode, operands[1]);
771 (define_insn "*mov<mode>_aarch64"
772 [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r, *w,r,*w, m, m, r,*w,*w")
773 (match_operand:SHORT 1 "general_operand" " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
774 "(register_operand (operands[0], <MODE>mode)
775 || aarch64_reg_or_zero (operands[1], <MODE>mode))"
779 movi\\t%0.<Vallxd>, %1
784 umov\\t%w0, %1.<v>[0]
785 dup\\t%0.<Vallxd>, %w1
787 [(set_attr "v8type" "move,alu,alu,load1,load1,store1,store1,*,*,*")
788 (set_attr "simd_type" "*,*,simd_move_imm,*,*,*,*,simd_movgp,simd_dupgp,simd_dup")
789 (set_attr "mode" "<MODE>")
790 (set_attr "simd_mode" "<MODE>")]
793 (define_expand "mov<mode>"
794 [(set (match_operand:GPI 0 "nonimmediate_operand" "")
795 (match_operand:GPI 1 "general_operand" ""))]
798 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
799 operands[1] = force_reg (<MODE>mode, operands[1]);
801 if (CONSTANT_P (operands[1]))
803 aarch64_expand_mov_immediate (operands[0], operands[1]);
809 (define_insn "*movsi_aarch64"
810 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m, *w, r,*w")
811 (match_operand:SI 1 "aarch64_mov_operand" " r,M,m,rZ,rZ,*w,*w"))]
812 "(register_operand (operands[0], SImode)
813 || aarch64_reg_or_zero (operands[1], SImode))"
822 [(set_attr "v8type" "move,alu,load1,store1,fmov,fmov,fmov")
823 (set_attr "mode" "SI")
824 (set_attr "fp" "*,*,*,*,yes,yes,yes")]
827 (define_insn "*movdi_aarch64"
828 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,m, r, r, *w, r,*w,w")
829 (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,m,rZ,Usa,Ush,rZ,*w,*w,Dd"))]
830 "(register_operand (operands[0], DImode)
831 || aarch64_reg_or_zero (operands[1], DImode))"
845 [(set_attr "v8type" "move,move,move,alu,load1,store1,adr,adr,fmov,fmov,fmov,fmov")
846 (set_attr "mode" "DI")
847 (set_attr "fp" "*,*,*,*,*,*,*,*,yes,yes,yes,yes")]
850 (define_insn "insv_imm<mode>"
851 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
853 (match_operand:GPI 1 "const_int_operand" "n"))
854 (match_operand:GPI 2 "const_int_operand" "n"))]
855 "INTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
856 && INTVAL (operands[1]) % 16 == 0
857 && UINTVAL (operands[2]) <= 0xffff"
858 "movk\\t%<w>0, %X2, lsl %1"
859 [(set_attr "v8type" "movk")
860 (set_attr "mode" "<MODE>")]
863 (define_expand "movti"
864 [(set (match_operand:TI 0 "nonimmediate_operand" "")
865 (match_operand:TI 1 "general_operand" ""))]
868 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
869 operands[1] = force_reg (TImode, operands[1]);
873 (define_insn "*movti_aarch64"
874 [(set (match_operand:TI 0
875 "nonimmediate_operand" "=r, *w,r ,*w,r ,Ump,Ump,*w,m")
877 "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r ,Z , m,*w"))]
878 "(register_operand (operands[0], TImode)
879 || aarch64_reg_or_zero (operands[1], TImode))"
884 orr\\t%0.16b, %1.16b, %1.16b
890 [(set_attr "v8type" "move2,fmovi2f,fmovf2i,*, \
891 load2,store2,store2,fpsimd_load,fpsimd_store")
892 (set_attr "simd_type" "*,*,*,simd_move,*,*,*,*,*")
893 (set_attr "mode" "DI,DI,DI,TI,DI,DI,DI,TI,TI")
894 (set_attr "length" "8,8,8,4,4,4,4,4,4")
895 (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")
896 (set_attr "simd" "*,*,*,yes,*,*,*,*,*")])
898 ;; Split a TImode register-register or register-immediate move into
899 ;; its component DImode pieces, taking care to handle overlapping
900 ;; source and dest registers.
902 [(set (match_operand:TI 0 "register_operand" "")
903 (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
904 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
907 aarch64_split_128bit_move (operands[0], operands[1]);
911 (define_expand "mov<mode>"
912 [(set (match_operand:GPF 0 "nonimmediate_operand" "")
913 (match_operand:GPF 1 "general_operand" ""))]
918 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
922 if (GET_CODE (operands[0]) == MEM)
923 operands[1] = force_reg (<MODE>mode, operands[1]);
927 (define_insn "*movsf_aarch64"
928 [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
929 (match_operand:SF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
930 "TARGET_FLOAT && (register_operand (operands[0], SFmode)
931 || register_operand (operands[1], SFmode))"
942 [(set_attr "v8type" "fmovi2f,fmovf2i,\
943 fmov,fconst,fpsimd_load,\
944 fpsimd_store,fpsimd_load,fpsimd_store,fmov")
945 (set_attr "mode" "SF")]
948 (define_insn "*movdf_aarch64"
949 [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
950 (match_operand:DF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
951 "TARGET_FLOAT && (register_operand (operands[0], DFmode)
952 || register_operand (operands[1], DFmode))"
963 [(set_attr "v8type" "fmovi2f,fmovf2i,\
964 fmov,fconst,fpsimd_load,\
965 fpsimd_store,fpsimd_load,fpsimd_store,move")
966 (set_attr "mode" "DF")]
969 (define_expand "movtf"
970 [(set (match_operand:TF 0 "nonimmediate_operand" "")
971 (match_operand:TF 1 "general_operand" ""))]
976 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
980 if (GET_CODE (operands[0]) == MEM)
981 operands[1] = force_reg (TFmode, operands[1]);
985 (define_insn "*movtf_aarch64"
986 [(set (match_operand:TF 0
987 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
989 "general_operand" " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
990 "TARGET_FLOAT && (register_operand (operands[0], TFmode)
991 || register_operand (operands[1], TFmode))"
993 orr\\t%0.16b, %1.16b, %1.16b
994 mov\\t%0, %1\;mov\\t%H0, %H1
995 fmov\\t%d0, %Q1\;fmov\\t%0.d[1], %R1
996 fmov\\t%Q0, %d1\;fmov\\t%R0, %1.d[1]
1003 [(set_attr "v8type" "logic,move2,fmovi2f,fmovf2i,fconst,fconst,fpsimd_load,fpsimd_store,fpsimd_load2,fpsimd_store2")
1004 (set_attr "mode" "DF,DF,DF,DF,DF,DF,TF,TF,DF,DF")
1005 (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
1006 (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
1007 (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
1010 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1011 ;; fairly lax checking on the second memory operation.
1012 (define_insn "load_pair<mode>"
1013 [(set (match_operand:GPI 0 "register_operand" "=r")
1014 (match_operand:GPI 1 "aarch64_mem_pair_operand" "Ump"))
1015 (set (match_operand:GPI 2 "register_operand" "=r")
1016 (match_operand:GPI 3 "memory_operand" "m"))]
1017 "rtx_equal_p (XEXP (operands[3], 0),
1018 plus_constant (Pmode,
1019 XEXP (operands[1], 0),
1020 GET_MODE_SIZE (<MODE>mode)))"
1021 "ldp\\t%<w>0, %<w>2, %1"
1022 [(set_attr "v8type" "load2")
1023 (set_attr "mode" "<MODE>")]
1026 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1027 ;; fairly lax checking on the second memory operation.
1028 (define_insn "store_pair<mode>"
1029 [(set (match_operand:GPI 0 "aarch64_mem_pair_operand" "=Ump")
1030 (match_operand:GPI 1 "register_operand" "r"))
1031 (set (match_operand:GPI 2 "memory_operand" "=m")
1032 (match_operand:GPI 3 "register_operand" "r"))]
1033 "rtx_equal_p (XEXP (operands[2], 0),
1034 plus_constant (Pmode,
1035 XEXP (operands[0], 0),
1036 GET_MODE_SIZE (<MODE>mode)))"
1037 "stp\\t%<w>1, %<w>3, %0"
1038 [(set_attr "v8type" "store2")
1039 (set_attr "mode" "<MODE>")]
1042 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1043 ;; fairly lax checking on the second memory operation.
1044 (define_insn "load_pair<mode>"
1045 [(set (match_operand:GPF 0 "register_operand" "=w")
1046 (match_operand:GPF 1 "aarch64_mem_pair_operand" "Ump"))
1047 (set (match_operand:GPF 2 "register_operand" "=w")
1048 (match_operand:GPF 3 "memory_operand" "m"))]
1049 "rtx_equal_p (XEXP (operands[3], 0),
1050 plus_constant (Pmode,
1051 XEXP (operands[1], 0),
1052 GET_MODE_SIZE (<MODE>mode)))"
1053 "ldp\\t%<w>0, %<w>2, %1"
1054 [(set_attr "v8type" "fpsimd_load2")
1055 (set_attr "mode" "<MODE>")]
1058 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1059 ;; fairly lax checking on the second memory operation.
1060 (define_insn "store_pair<mode>"
1061 [(set (match_operand:GPF 0 "aarch64_mem_pair_operand" "=Ump")
1062 (match_operand:GPF 1 "register_operand" "w"))
1063 (set (match_operand:GPF 2 "memory_operand" "=m")
1064 (match_operand:GPF 3 "register_operand" "w"))]
1065 "rtx_equal_p (XEXP (operands[2], 0),
1066 plus_constant (Pmode,
1067 XEXP (operands[0], 0),
1068 GET_MODE_SIZE (<MODE>mode)))"
1069 "stp\\t%<w>1, %<w>3, %0"
1070 [(set_attr "v8type" "fpsimd_load2")
1071 (set_attr "mode" "<MODE>")]
1074 ;; Load pair with writeback. This is primarily used in function epilogues
1075 ;; when restoring [fp,lr]
1076 (define_insn "loadwb_pair<GPI:mode>_<PTR:mode>"
1078 [(set (match_operand:PTR 0 "register_operand" "=k")
1079 (plus:PTR (match_operand:PTR 1 "register_operand" "0")
1080 (match_operand:PTR 4 "const_int_operand" "n")))
1081 (set (match_operand:GPI 2 "register_operand" "=r")
1082 (mem:GPI (plus:PTR (match_dup 1)
1084 (set (match_operand:GPI 3 "register_operand" "=r")
1085 (mem:GPI (plus:PTR (match_dup 1)
1086 (match_operand:PTR 5 "const_int_operand" "n"))))])]
1087 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1088 "ldp\\t%<w>2, %<w>3, [%1], %4"
1089 [(set_attr "v8type" "load2")
1090 (set_attr "mode" "<GPI:MODE>")]
1093 ;; Store pair with writeback. This is primarily used in function prologues
1094 ;; when saving [fp,lr]
1095 (define_insn "storewb_pair<GPI:mode>_<PTR:mode>"
1097 [(set (match_operand:PTR 0 "register_operand" "=&k")
1098 (plus:PTR (match_operand:PTR 1 "register_operand" "0")
1099 (match_operand:PTR 4 "const_int_operand" "n")))
1100 (set (mem:GPI (plus:PTR (match_dup 0)
1102 (match_operand:GPI 2 "register_operand" "r"))
1103 (set (mem:GPI (plus:PTR (match_dup 0)
1104 (match_operand:PTR 5 "const_int_operand" "n")))
1105 (match_operand:GPI 3 "register_operand" "r"))])]
1106 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1107 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1108 [(set_attr "v8type" "store2")
1109 (set_attr "mode" "<GPI:MODE>")]
1112 ;; -------------------------------------------------------------------
1113 ;; Sign/Zero extension
1114 ;; -------------------------------------------------------------------
1116 (define_expand "<optab>sidi2"
1117 [(set (match_operand:DI 0 "register_operand")
1118 (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1122 (define_insn "*extendsidi2_aarch64"
1123 [(set (match_operand:DI 0 "register_operand" "=r,r")
1124 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1129 [(set_attr "v8type" "extend,load1")
1130 (set_attr "mode" "DI")]
1133 (define_insn "*zero_extendsidi2_aarch64"
1134 [(set (match_operand:DI 0 "register_operand" "=r,r")
1135 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1140 [(set_attr "v8type" "extend,load1")
1141 (set_attr "mode" "DI")]
1144 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1145 [(set (match_operand:GPI 0 "register_operand")
1146 (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1150 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1151 [(set (match_operand:GPI 0 "register_operand" "=r,r")
1152 (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1155 sxt<SHORT:size>\t%<GPI:w>0, %w1
1156 ldrs<SHORT:size>\t%<GPI:w>0, %1"
1157 [(set_attr "v8type" "extend,load1")
1158 (set_attr "mode" "<GPI:MODE>")]
1161 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1162 [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1163 (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1166 uxt<SHORT:size>\t%<GPI:w>0, %w1
1167 ldr<SHORT:size>\t%w0, %1
1168 ldr\t%<SHORT:size>0, %1"
1169 [(set_attr "v8type" "extend,load1,load1")
1170 (set_attr "mode" "<GPI:MODE>")]
1173 (define_expand "<optab>qihi2"
1174 [(set (match_operand:HI 0 "register_operand")
1175 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1179 (define_insn "*<optab>qihi2_aarch64"
1180 [(set (match_operand:HI 0 "register_operand" "=r,r")
1181 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1186 [(set_attr "v8type" "extend,load1")
1187 (set_attr "mode" "HI")]
1190 ;; -------------------------------------------------------------------
1191 ;; Simple arithmetic
1192 ;; -------------------------------------------------------------------
1194 (define_expand "add<mode>3"
1196 (match_operand:GPI 0 "register_operand" "")
1197 (plus:GPI (match_operand:GPI 1 "register_operand" "")
1198 (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1201 if (! aarch64_plus_operand (operands[2], VOIDmode))
1203 rtx subtarget = ((optimize && can_create_pseudo_p ())
1204 ? gen_reg_rtx (<MODE>mode) : operands[0]);
1205 HOST_WIDE_INT imm = INTVAL (operands[2]);
1208 imm = -(-imm & ~0xfff);
1212 emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1213 operands[1] = subtarget;
1214 operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1219 (define_insn "*addsi3_aarch64"
1221 (match_operand:SI 0 "register_operand" "=rk,rk,rk")
1223 (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1224 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J")))]
1229 sub\\t%w0, %w1, #%n2"
1230 [(set_attr "v8type" "alu")
1231 (set_attr "mode" "SI")]
1234 ;; zero_extend version of above
1235 (define_insn "*addsi3_aarch64_uxtw"
1237 (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1239 (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1240 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1245 sub\\t%w0, %w1, #%n2"
1246 [(set_attr "v8type" "alu")
1247 (set_attr "mode" "SI")]
1250 (define_insn "*adddi3_aarch64"
1252 (match_operand:DI 0 "register_operand" "=rk,rk,rk,!w")
1254 (match_operand:DI 1 "register_operand" "%rk,rk,rk,!w")
1255 (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,!w")))]
1260 sub\\t%x0, %x1, #%n2
1261 add\\t%d0, %d1, %d2"
1262 [(set_attr "v8type" "alu")
1263 (set_attr "mode" "DI")
1264 (set_attr "simd" "*,*,*,yes")]
1267 (define_insn "*add<mode>3_compare0"
1268 [(set (reg:CC_NZ CC_REGNUM)
1270 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r")
1271 (match_operand:GPI 2 "aarch64_plus_operand" "rI,J"))
1273 (set (match_operand:GPI 0 "register_operand" "=r,r")
1274 (plus:GPI (match_dup 1) (match_dup 2)))]
1277 adds\\t%<w>0, %<w>1, %<w>2
1278 subs\\t%<w>0, %<w>1, #%n2"
1279 [(set_attr "v8type" "alus")
1280 (set_attr "mode" "<MODE>")]
1283 ;; zero_extend version of above
1284 (define_insn "*addsi3_compare0_uxtw"
1285 [(set (reg:CC_NZ CC_REGNUM)
1287 (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
1288 (match_operand:SI 2 "aarch64_plus_operand" "rI,J"))
1290 (set (match_operand:DI 0 "register_operand" "=r,r")
1291 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1294 adds\\t%w0, %w1, %w2
1295 subs\\t%w0, %w1, #%n2"
1296 [(set_attr "v8type" "alus")
1297 (set_attr "mode" "SI")]
1300 (define_insn "*adds_mul_imm_<mode>"
1301 [(set (reg:CC_NZ CC_REGNUM)
1304 (match_operand:GPI 1 "register_operand" "r")
1305 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1306 (match_operand:GPI 3 "register_operand" "rk"))
1308 (set (match_operand:GPI 0 "register_operand" "=r")
1309 (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1312 "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1313 [(set_attr "v8type" "alus_shift")
1314 (set_attr "mode" "<MODE>")]
1317 (define_insn "*subs_mul_imm_<mode>"
1318 [(set (reg:CC_NZ CC_REGNUM)
1320 (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
1322 (match_operand:GPI 2 "register_operand" "r")
1323 (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1325 (set (match_operand:GPI 0 "register_operand" "=r")
1326 (minus:GPI (match_dup 1)
1327 (mult:GPI (match_dup 2) (match_dup 3))))]
1329 "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1330 [(set_attr "v8type" "alus_shift")
1331 (set_attr "mode" "<MODE>")]
1334 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1335 [(set (reg:CC_NZ CC_REGNUM)
1338 (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1339 (match_operand:GPI 2 "register_operand" "r"))
1341 (set (match_operand:GPI 0 "register_operand" "=r")
1342 (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1344 "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1345 [(set_attr "v8type" "alus_ext")
1346 (set_attr "mode" "<GPI:MODE>")]
1349 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1350 [(set (reg:CC_NZ CC_REGNUM)
1352 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1354 (match_operand:ALLX 2 "register_operand" "r")))
1356 (set (match_operand:GPI 0 "register_operand" "=r")
1357 (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1359 "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1360 [(set_attr "v8type" "alus_ext")
1361 (set_attr "mode" "<GPI:MODE>")]
1364 (define_insn "*adds_<optab><mode>_multp2"
1365 [(set (reg:CC_NZ CC_REGNUM)
1367 (plus:GPI (ANY_EXTRACT:GPI
1368 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1369 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1370 (match_operand 3 "const_int_operand" "n")
1372 (match_operand:GPI 4 "register_operand" "r"))
1374 (set (match_operand:GPI 0 "register_operand" "=r")
1375 (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1379 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1380 "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1381 [(set_attr "v8type" "alus_ext")
1382 (set_attr "mode" "<MODE>")]
1385 (define_insn "*subs_<optab><mode>_multp2"
1386 [(set (reg:CC_NZ CC_REGNUM)
1388 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1390 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1391 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1392 (match_operand 3 "const_int_operand" "n")
1395 (set (match_operand:GPI 0 "register_operand" "=r")
1396 (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1397 (mult:GPI (match_dup 1) (match_dup 2))
1400 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1401 "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1402 [(set_attr "v8type" "alus_ext")
1403 (set_attr "mode" "<MODE>")]
1406 (define_insn "*add<mode>3nr_compare0"
1407 [(set (reg:CC_NZ CC_REGNUM)
1409 (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r")
1410 (match_operand:GPI 1 "aarch64_plus_operand" "rI,J"))
1416 [(set_attr "v8type" "alus")
1417 (set_attr "mode" "<MODE>")]
1420 (define_insn "*compare_neg<mode>"
1421 [(set (reg:CC CC_REGNUM)
1423 (match_operand:GPI 0 "register_operand" "r")
1424 (neg:GPI (match_operand:GPI 1 "register_operand" "r"))))]
1426 "cmn\\t%<w>0, %<w>1"
1427 [(set_attr "v8type" "alus")
1428 (set_attr "mode" "<MODE>")]
1431 (define_insn "*add_<shift>_<mode>"
1432 [(set (match_operand:GPI 0 "register_operand" "=rk")
1433 (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1434 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1435 (match_operand:GPI 3 "register_operand" "r")))]
1437 "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1438 [(set_attr "v8type" "alu_shift")
1439 (set_attr "mode" "<MODE>")]
1442 ;; zero_extend version of above
1443 (define_insn "*add_<shift>_si_uxtw"
1444 [(set (match_operand:DI 0 "register_operand" "=rk")
1446 (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1447 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1448 (match_operand:SI 3 "register_operand" "r"))))]
1450 "add\\t%w0, %w3, %w1, <shift> %2"
1451 [(set_attr "v8type" "alu_shift")
1452 (set_attr "mode" "SI")]
1455 (define_insn "*add_mul_imm_<mode>"
1456 [(set (match_operand:GPI 0 "register_operand" "=rk")
1457 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1458 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1459 (match_operand:GPI 3 "register_operand" "r")))]
1461 "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1462 [(set_attr "v8type" "alu_shift")
1463 (set_attr "mode" "<MODE>")]
1466 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1467 [(set (match_operand:GPI 0 "register_operand" "=rk")
1468 (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1469 (match_operand:GPI 2 "register_operand" "r")))]
1471 "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1472 [(set_attr "v8type" "alu_ext")
1473 (set_attr "mode" "<GPI:MODE>")]
1476 ;; zero_extend version of above
1477 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1478 [(set (match_operand:DI 0 "register_operand" "=rk")
1480 (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1481 (match_operand:GPI 2 "register_operand" "r"))))]
1483 "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1484 [(set_attr "v8type" "alu_ext")
1485 (set_attr "mode" "SI")]
1488 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1489 [(set (match_operand:GPI 0 "register_operand" "=rk")
1490 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1491 (match_operand:ALLX 1 "register_operand" "r"))
1492 (match_operand 2 "aarch64_imm3" "Ui3"))
1493 (match_operand:GPI 3 "register_operand" "r")))]
1495 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1496 [(set_attr "v8type" "alu_ext")
1497 (set_attr "mode" "<GPI:MODE>")]
1500 ;; zero_extend version of above
1501 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1502 [(set (match_operand:DI 0 "register_operand" "=rk")
1504 (plus:SI (ashift:SI (ANY_EXTEND:SI
1505 (match_operand:SHORT 1 "register_operand" "r"))
1506 (match_operand 2 "aarch64_imm3" "Ui3"))
1507 (match_operand:SI 3 "register_operand" "r"))))]
1509 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1510 [(set_attr "v8type" "alu_ext")
1511 (set_attr "mode" "SI")]
1514 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1515 [(set (match_operand:GPI 0 "register_operand" "=rk")
1516 (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1517 (match_operand:ALLX 1 "register_operand" "r"))
1518 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1519 (match_operand:GPI 3 "register_operand" "r")))]
1521 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1522 [(set_attr "v8type" "alu_ext")
1523 (set_attr "mode" "<GPI:MODE>")]
1526 ;; zero_extend version of above
1527 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1528 [(set (match_operand:DI 0 "register_operand" "=rk")
1529 (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1530 (match_operand:SHORT 1 "register_operand" "r"))
1531 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1532 (match_operand:SI 3 "register_operand" "r"))))]
1534 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1535 [(set_attr "v8type" "alu_ext")
1536 (set_attr "mode" "SI")]
1539 (define_insn "*add_<optab><mode>_multp2"
1540 [(set (match_operand:GPI 0 "register_operand" "=rk")
1541 (plus:GPI (ANY_EXTRACT:GPI
1542 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1543 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1544 (match_operand 3 "const_int_operand" "n")
1546 (match_operand:GPI 4 "register_operand" "r")))]
1547 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1548 "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1549 [(set_attr "v8type" "alu_ext")
1550 (set_attr "mode" "<MODE>")]
1553 ;; zero_extend version of above
1554 (define_insn "*add_<optab>si_multp2_uxtw"
1555 [(set (match_operand:DI 0 "register_operand" "=rk")
1557 (plus:SI (ANY_EXTRACT:SI
1558 (mult:SI (match_operand:SI 1 "register_operand" "r")
1559 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1560 (match_operand 3 "const_int_operand" "n")
1562 (match_operand:SI 4 "register_operand" "r"))))]
1563 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1564 "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1565 [(set_attr "v8type" "alu_ext")
1566 (set_attr "mode" "SI")]
1569 (define_insn "*add<mode>3_carryin"
1571 (match_operand:GPI 0 "register_operand" "=r")
1572 (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1574 (match_operand:GPI 1 "register_operand" "r")
1575 (match_operand:GPI 2 "register_operand" "r"))))]
1577 "adc\\t%<w>0, %<w>1, %<w>2"
1578 [(set_attr "v8type" "adc")
1579 (set_attr "mode" "<MODE>")]
1582 ;; zero_extend version of above
1583 (define_insn "*addsi3_carryin_uxtw"
1585 (match_operand:DI 0 "register_operand" "=r")
1587 (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1589 (match_operand:SI 1 "register_operand" "r")
1590 (match_operand:SI 2 "register_operand" "r")))))]
1592 "adc\\t%w0, %w1, %w2"
1593 [(set_attr "v8type" "adc")
1594 (set_attr "mode" "SI")]
1597 (define_insn "*add<mode>3_carryin_alt1"
1599 (match_operand:GPI 0 "register_operand" "=r")
1601 (match_operand:GPI 1 "register_operand" "r")
1602 (match_operand:GPI 2 "register_operand" "r"))
1603 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1605 "adc\\t%<w>0, %<w>1, %<w>2"
1606 [(set_attr "v8type" "adc")
1607 (set_attr "mode" "<MODE>")]
1610 ;; zero_extend version of above
1611 (define_insn "*addsi3_carryin_alt1_uxtw"
1613 (match_operand:DI 0 "register_operand" "=r")
1616 (match_operand:SI 1 "register_operand" "r")
1617 (match_operand:SI 2 "register_operand" "r"))
1618 (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1620 "adc\\t%w0, %w1, %w2"
1621 [(set_attr "v8type" "adc")
1622 (set_attr "mode" "SI")]
1625 (define_insn "*add<mode>3_carryin_alt2"
1627 (match_operand:GPI 0 "register_operand" "=r")
1629 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1630 (match_operand:GPI 1 "register_operand" "r"))
1631 (match_operand:GPI 2 "register_operand" "r")))]
1633 "adc\\t%<w>0, %<w>1, %<w>2"
1634 [(set_attr "v8type" "adc")
1635 (set_attr "mode" "<MODE>")]
1638 ;; zero_extend version of above
1639 (define_insn "*addsi3_carryin_alt2_uxtw"
1641 (match_operand:DI 0 "register_operand" "=r")
1644 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1645 (match_operand:SI 1 "register_operand" "r"))
1646 (match_operand:SI 2 "register_operand" "r"))))]
1648 "adc\\t%w0, %w1, %w2"
1649 [(set_attr "v8type" "adc")
1650 (set_attr "mode" "SI")]
1653 (define_insn "*add<mode>3_carryin_alt3"
1655 (match_operand:GPI 0 "register_operand" "=r")
1657 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1658 (match_operand:GPI 2 "register_operand" "r"))
1659 (match_operand:GPI 1 "register_operand" "r")))]
1661 "adc\\t%<w>0, %<w>1, %<w>2"
1662 [(set_attr "v8type" "adc")
1663 (set_attr "mode" "<MODE>")]
1666 ;; zero_extend version of above
1667 (define_insn "*addsi3_carryin_alt3_uxtw"
1669 (match_operand:DI 0 "register_operand" "=r")
1672 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1673 (match_operand:SI 2 "register_operand" "r"))
1674 (match_operand:SI 1 "register_operand" "r"))))]
1676 "adc\\t%w0, %w1, %w2"
1677 [(set_attr "v8type" "adc")
1678 (set_attr "mode" "SI")]
1681 (define_insn "*add_uxt<mode>_multp2"
1682 [(set (match_operand:GPI 0 "register_operand" "=rk")
1684 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1685 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1686 (match_operand 3 "const_int_operand" "n"))
1687 (match_operand:GPI 4 "register_operand" "r")))]
1688 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1690 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1691 INTVAL (operands[3])));
1692 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1693 [(set_attr "v8type" "alu_ext")
1694 (set_attr "mode" "<MODE>")]
1697 ;; zero_extend version of above
1698 (define_insn "*add_uxtsi_multp2_uxtw"
1699 [(set (match_operand:DI 0 "register_operand" "=rk")
1702 (mult:SI (match_operand:SI 1 "register_operand" "r")
1703 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1704 (match_operand 3 "const_int_operand" "n"))
1705 (match_operand:SI 4 "register_operand" "r"))))]
1706 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1708 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1709 INTVAL (operands[3])));
1710 return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1711 [(set_attr "v8type" "alu_ext")
1712 (set_attr "mode" "SI")]
1715 (define_insn "subsi3"
1716 [(set (match_operand:SI 0 "register_operand" "=rk")
1717 (minus:SI (match_operand:SI 1 "register_operand" "r")
1718 (match_operand:SI 2 "register_operand" "r")))]
1720 "sub\\t%w0, %w1, %w2"
1721 [(set_attr "v8type" "alu")
1722 (set_attr "mode" "SI")]
1725 ;; zero_extend version of above
1726 (define_insn "*subsi3_uxtw"
1727 [(set (match_operand:DI 0 "register_operand" "=rk")
1729 (minus:SI (match_operand:SI 1 "register_operand" "r")
1730 (match_operand:SI 2 "register_operand" "r"))))]
1732 "sub\\t%w0, %w1, %w2"
1733 [(set_attr "v8type" "alu")
1734 (set_attr "mode" "SI")]
1737 (define_insn "subdi3"
1738 [(set (match_operand:DI 0 "register_operand" "=rk,!w")
1739 (minus:DI (match_operand:DI 1 "register_operand" "r,!w")
1740 (match_operand:DI 2 "register_operand" "r,!w")))]
1744 sub\\t%d0, %d1, %d2"
1745 [(set_attr "v8type" "alu")
1746 (set_attr "mode" "DI")
1747 (set_attr "simd" "*,yes")]
1751 (define_insn "*sub<mode>3_compare0"
1752 [(set (reg:CC_NZ CC_REGNUM)
1753 (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1754 (match_operand:GPI 2 "register_operand" "r"))
1756 (set (match_operand:GPI 0 "register_operand" "=r")
1757 (minus:GPI (match_dup 1) (match_dup 2)))]
1759 "subs\\t%<w>0, %<w>1, %<w>2"
1760 [(set_attr "v8type" "alus")
1761 (set_attr "mode" "<MODE>")]
1764 ;; zero_extend version of above
1765 (define_insn "*subsi3_compare0_uxtw"
1766 [(set (reg:CC_NZ CC_REGNUM)
1767 (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1768 (match_operand:SI 2 "register_operand" "r"))
1770 (set (match_operand:DI 0 "register_operand" "=r")
1771 (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1773 "subs\\t%w0, %w1, %w2"
1774 [(set_attr "v8type" "alus")
1775 (set_attr "mode" "SI")]
1778 (define_insn "*sub_<shift>_<mode>"
1779 [(set (match_operand:GPI 0 "register_operand" "=rk")
1780 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1782 (match_operand:GPI 1 "register_operand" "r")
1783 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1785 "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1786 [(set_attr "v8type" "alu_shift")
1787 (set_attr "mode" "<MODE>")]
1790 ;; zero_extend version of above
1791 (define_insn "*sub_<shift>_si_uxtw"
1792 [(set (match_operand:DI 0 "register_operand" "=rk")
1794 (minus:SI (match_operand:SI 3 "register_operand" "r")
1796 (match_operand:SI 1 "register_operand" "r")
1797 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1799 "sub\\t%w0, %w3, %w1, <shift> %2"
1800 [(set_attr "v8type" "alu_shift")
1801 (set_attr "mode" "SI")]
1804 (define_insn "*sub_mul_imm_<mode>"
1805 [(set (match_operand:GPI 0 "register_operand" "=rk")
1806 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1808 (match_operand:GPI 1 "register_operand" "r")
1809 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1811 "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1812 [(set_attr "v8type" "alu_shift")
1813 (set_attr "mode" "<MODE>")]
1816 ;; zero_extend version of above
1817 (define_insn "*sub_mul_imm_si_uxtw"
1818 [(set (match_operand:DI 0 "register_operand" "=rk")
1820 (minus:SI (match_operand:SI 3 "register_operand" "r")
1822 (match_operand:SI 1 "register_operand" "r")
1823 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
1825 "sub\\t%w0, %w3, %w1, lsl %p2"
1826 [(set_attr "v8type" "alu_shift")
1827 (set_attr "mode" "SI")]
1830 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
1831 [(set (match_operand:GPI 0 "register_operand" "=rk")
1832 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1834 (match_operand:ALLX 2 "register_operand" "r"))))]
1836 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1837 [(set_attr "v8type" "alu_ext")
1838 (set_attr "mode" "<GPI:MODE>")]
1841 ;; zero_extend version of above
1842 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
1843 [(set (match_operand:DI 0 "register_operand" "=rk")
1845 (minus:SI (match_operand:SI 1 "register_operand" "r")
1847 (match_operand:SHORT 2 "register_operand" "r")))))]
1849 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
1850 [(set_attr "v8type" "alu_ext")
1851 (set_attr "mode" "SI")]
1854 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
1855 [(set (match_operand:GPI 0 "register_operand" "=rk")
1856 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1857 (ashift:GPI (ANY_EXTEND:GPI
1858 (match_operand:ALLX 2 "register_operand" "r"))
1859 (match_operand 3 "aarch64_imm3" "Ui3"))))]
1861 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1862 [(set_attr "v8type" "alu_ext")
1863 (set_attr "mode" "<GPI:MODE>")]
1866 ;; zero_extend version of above
1867 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
1868 [(set (match_operand:DI 0 "register_operand" "=rk")
1870 (minus:SI (match_operand:SI 1 "register_operand" "r")
1871 (ashift:SI (ANY_EXTEND:SI
1872 (match_operand:SHORT 2 "register_operand" "r"))
1873 (match_operand 3 "aarch64_imm3" "Ui3")))))]
1875 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
1876 [(set_attr "v8type" "alu_ext")
1877 (set_attr "mode" "SI")]
1880 (define_insn "*sub_<optab><mode>_multp2"
1881 [(set (match_operand:GPI 0 "register_operand" "=rk")
1882 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1884 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1885 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1886 (match_operand 3 "const_int_operand" "n")
1888 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1889 "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1890 [(set_attr "v8type" "alu_ext")
1891 (set_attr "mode" "<MODE>")]
1894 ;; zero_extend version of above
1895 (define_insn "*sub_<optab>si_multp2_uxtw"
1896 [(set (match_operand:DI 0 "register_operand" "=rk")
1898 (minus:SI (match_operand:SI 4 "register_operand" "r")
1900 (mult:SI (match_operand:SI 1 "register_operand" "r")
1901 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1902 (match_operand 3 "const_int_operand" "n")
1904 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1905 "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1906 [(set_attr "v8type" "alu_ext")
1907 (set_attr "mode" "SI")]
1910 (define_insn "*sub<mode>3_carryin"
1912 (match_operand:GPI 0 "register_operand" "=r")
1913 (minus:GPI (minus:GPI
1914 (match_operand:GPI 1 "register_operand" "r")
1915 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
1916 (match_operand:GPI 2 "register_operand" "r")))]
1918 "sbc\\t%<w>0, %<w>1, %<w>2"
1919 [(set_attr "v8type" "adc")
1920 (set_attr "mode" "<MODE>")]
1923 ;; zero_extend version of the above
1924 (define_insn "*subsi3_carryin_uxtw"
1926 (match_operand:DI 0 "register_operand" "=r")
1929 (match_operand:SI 1 "register_operand" "r")
1930 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
1931 (match_operand:SI 2 "register_operand" "r"))))]
1933 "sbc\\t%w0, %w1, %w2"
1934 [(set_attr "v8type" "adc")
1935 (set_attr "mode" "SI")]
1938 (define_insn "*sub_uxt<mode>_multp2"
1939 [(set (match_operand:GPI 0 "register_operand" "=rk")
1940 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1942 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1943 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1944 (match_operand 3 "const_int_operand" "n"))))]
1945 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1947 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1948 INTVAL (operands[3])));
1949 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1950 [(set_attr "v8type" "alu_ext")
1951 (set_attr "mode" "<MODE>")]
1954 ;; zero_extend version of above
1955 (define_insn "*sub_uxtsi_multp2_uxtw"
1956 [(set (match_operand:DI 0 "register_operand" "=rk")
1958 (minus:SI (match_operand:SI 4 "register_operand" "r")
1960 (mult:SI (match_operand:SI 1 "register_operand" "r")
1961 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1962 (match_operand 3 "const_int_operand" "n")))))]
1963 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1965 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1966 INTVAL (operands[3])));
1967 return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
1968 [(set_attr "v8type" "alu_ext")
1969 (set_attr "mode" "SI")]
1972 (define_insn "neg<mode>2"
1973 [(set (match_operand:GPI 0 "register_operand" "=r")
1974 (neg:GPI (match_operand:GPI 1 "register_operand" "r")))]
1976 "neg\\t%<w>0, %<w>1"
1977 [(set_attr "v8type" "alu")
1978 (set_attr "mode" "<MODE>")]
1981 ;; zero_extend version of above
1982 (define_insn "*negsi2_uxtw"
1983 [(set (match_operand:DI 0 "register_operand" "=r")
1984 (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
1987 [(set_attr "v8type" "alu")
1988 (set_attr "mode" "SI")]
1991 (define_insn "*neg<mode>2_compare0"
1992 [(set (reg:CC_NZ CC_REGNUM)
1993 (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
1995 (set (match_operand:GPI 0 "register_operand" "=r")
1996 (neg:GPI (match_dup 1)))]
1998 "negs\\t%<w>0, %<w>1"
1999 [(set_attr "v8type" "alus")
2000 (set_attr "mode" "<MODE>")]
2003 ;; zero_extend version of above
2004 (define_insn "*negsi2_compare0_uxtw"
2005 [(set (reg:CC_NZ CC_REGNUM)
2006 (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
2008 (set (match_operand:DI 0 "register_operand" "=r")
2009 (zero_extend:DI (neg:SI (match_dup 1))))]
2012 [(set_attr "v8type" "alus")
2013 (set_attr "mode" "SI")]
2016 (define_insn "*neg_<shift><mode>3_compare0"
2017 [(set (reg:CC_NZ CC_REGNUM)
2019 (neg:GPI (ASHIFT:GPI
2020 (match_operand:GPI 1 "register_operand" "r")
2021 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2023 (set (match_operand:GPI 0 "register_operand" "=r")
2024 (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2026 "negs\\t%<w>0, %<w>1, <shift> %2"
2027 [(set_attr "v8type" "alus_shift")
2028 (set_attr "mode" "<MODE>")]
2031 (define_insn "*neg_<shift>_<mode>2"
2032 [(set (match_operand:GPI 0 "register_operand" "=r")
2033 (neg:GPI (ASHIFT:GPI
2034 (match_operand:GPI 1 "register_operand" "r")
2035 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2037 "neg\\t%<w>0, %<w>1, <shift> %2"
2038 [(set_attr "v8type" "alu_shift")
2039 (set_attr "mode" "<MODE>")]
2042 ;; zero_extend version of above
2043 (define_insn "*neg_<shift>_si2_uxtw"
2044 [(set (match_operand:DI 0 "register_operand" "=r")
2047 (match_operand:SI 1 "register_operand" "r")
2048 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2050 "neg\\t%w0, %w1, <shift> %2"
2051 [(set_attr "v8type" "alu_shift")
2052 (set_attr "mode" "SI")]
2055 (define_insn "*neg_mul_imm_<mode>2"
2056 [(set (match_operand:GPI 0 "register_operand" "=r")
2058 (match_operand:GPI 1 "register_operand" "r")
2059 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2061 "neg\\t%<w>0, %<w>1, lsl %p2"
2062 [(set_attr "v8type" "alu_shift")
2063 (set_attr "mode" "<MODE>")]
2066 ;; zero_extend version of above
2067 (define_insn "*neg_mul_imm_si2_uxtw"
2068 [(set (match_operand:DI 0 "register_operand" "=r")
2071 (match_operand:SI 1 "register_operand" "r")
2072 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2074 "neg\\t%w0, %w1, lsl %p2"
2075 [(set_attr "v8type" "alu_shift")
2076 (set_attr "mode" "SI")]
2079 (define_insn "mul<mode>3"
2080 [(set (match_operand:GPI 0 "register_operand" "=r")
2081 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2082 (match_operand:GPI 2 "register_operand" "r")))]
2084 "mul\\t%<w>0, %<w>1, %<w>2"
2085 [(set_attr "v8type" "mult")
2086 (set_attr "mode" "<MODE>")]
2089 ;; zero_extend version of above
2090 (define_insn "*mulsi3_uxtw"
2091 [(set (match_operand:DI 0 "register_operand" "=r")
2093 (mult:SI (match_operand:SI 1 "register_operand" "r")
2094 (match_operand:SI 2 "register_operand" "r"))))]
2096 "mul\\t%w0, %w1, %w2"
2097 [(set_attr "v8type" "mult")
2098 (set_attr "mode" "SI")]
2101 (define_insn "*madd<mode>"
2102 [(set (match_operand:GPI 0 "register_operand" "=r")
2103 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2104 (match_operand:GPI 2 "register_operand" "r"))
2105 (match_operand:GPI 3 "register_operand" "r")))]
2107 "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2108 [(set_attr "v8type" "madd")
2109 (set_attr "mode" "<MODE>")]
2112 ;; zero_extend version of above
2113 (define_insn "*maddsi_uxtw"
2114 [(set (match_operand:DI 0 "register_operand" "=r")
2116 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2117 (match_operand:SI 2 "register_operand" "r"))
2118 (match_operand:SI 3 "register_operand" "r"))))]
2120 "madd\\t%w0, %w1, %w2, %w3"
2121 [(set_attr "v8type" "madd")
2122 (set_attr "mode" "SI")]
2125 (define_insn "*msub<mode>"
2126 [(set (match_operand:GPI 0 "register_operand" "=r")
2127 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2128 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2129 (match_operand:GPI 2 "register_operand" "r"))))]
2132 "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2133 [(set_attr "v8type" "madd")
2134 (set_attr "mode" "<MODE>")]
2137 ;; zero_extend version of above
2138 (define_insn "*msubsi_uxtw"
2139 [(set (match_operand:DI 0 "register_operand" "=r")
2141 (minus:SI (match_operand:SI 3 "register_operand" "r")
2142 (mult:SI (match_operand:SI 1 "register_operand" "r")
2143 (match_operand:SI 2 "register_operand" "r")))))]
2146 "msub\\t%w0, %w1, %w2, %w3"
2147 [(set_attr "v8type" "madd")
2148 (set_attr "mode" "SI")]
2151 (define_insn "*mul<mode>_neg"
2152 [(set (match_operand:GPI 0 "register_operand" "=r")
2153 (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2154 (match_operand:GPI 2 "register_operand" "r")))]
2157 "mneg\\t%<w>0, %<w>1, %<w>2"
2158 [(set_attr "v8type" "mult")
2159 (set_attr "mode" "<MODE>")]
2162 ;; zero_extend version of above
2163 (define_insn "*mulsi_neg_uxtw"
2164 [(set (match_operand:DI 0 "register_operand" "=r")
2166 (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2167 (match_operand:SI 2 "register_operand" "r"))))]
2170 "mneg\\t%w0, %w1, %w2"
2171 [(set_attr "v8type" "mult")
2172 (set_attr "mode" "SI")]
2175 (define_insn "<su_optab>mulsidi3"
2176 [(set (match_operand:DI 0 "register_operand" "=r")
2177 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2178 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2180 "<su>mull\\t%0, %w1, %w2"
2181 [(set_attr "v8type" "mull")
2182 (set_attr "mode" "DI")]
2185 (define_insn "<su_optab>maddsidi4"
2186 [(set (match_operand:DI 0 "register_operand" "=r")
2188 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2189 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2190 (match_operand:DI 3 "register_operand" "r")))]
2192 "<su>maddl\\t%0, %w1, %w2, %3"
2193 [(set_attr "v8type" "maddl")
2194 (set_attr "mode" "DI")]
2197 (define_insn "<su_optab>msubsidi4"
2198 [(set (match_operand:DI 0 "register_operand" "=r")
2200 (match_operand:DI 3 "register_operand" "r")
2201 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2203 (match_operand:SI 2 "register_operand" "r")))))]
2205 "<su>msubl\\t%0, %w1, %w2, %3"
2206 [(set_attr "v8type" "maddl")
2207 (set_attr "mode" "DI")]
2210 (define_insn "*<su_optab>mulsidi_neg"
2211 [(set (match_operand:DI 0 "register_operand" "=r")
2213 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2214 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2216 "<su>mnegl\\t%0, %w1, %w2"
2217 [(set_attr "v8type" "mull")
2218 (set_attr "mode" "DI")]
2221 (define_insn "<su>muldi3_highpart"
2222 [(set (match_operand:DI 0 "register_operand" "=r")
2226 (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2227 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2230 "<su>mulh\\t%0, %1, %2"
2231 [(set_attr "v8type" "mulh")
2232 (set_attr "mode" "DI")]
2235 (define_insn "<su_optab>div<mode>3"
2236 [(set (match_operand:GPI 0 "register_operand" "=r")
2237 (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2238 (match_operand:GPI 2 "register_operand" "r")))]
2240 "<su>div\\t%<w>0, %<w>1, %<w>2"
2241 [(set_attr "v8type" "<su>div")
2242 (set_attr "mode" "<MODE>")]
2245 ;; zero_extend version of above
2246 (define_insn "*<su_optab>divsi3_uxtw"
2247 [(set (match_operand:DI 0 "register_operand" "=r")
2249 (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2250 (match_operand:SI 2 "register_operand" "r"))))]
2252 "<su>div\\t%w0, %w1, %w2"
2253 [(set_attr "v8type" "<su>div")
2254 (set_attr "mode" "SI")]
2257 ;; -------------------------------------------------------------------
2259 ;; -------------------------------------------------------------------
2261 (define_insn "*cmp<mode>"
2262 [(set (reg:CC CC_REGNUM)
2263 (compare:CC (match_operand:GPI 0 "register_operand" "r,r")
2264 (match_operand:GPI 1 "aarch64_plus_operand" "rI,J")))]
2269 [(set_attr "v8type" "alus")
2270 (set_attr "mode" "<MODE>")]
2273 (define_insn "*cmp<mode>"
2274 [(set (reg:CCFP CC_REGNUM)
2275 (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2276 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2280 fcmp\\t%<s>0, %<s>1"
2281 [(set_attr "v8type" "fcmp")
2282 (set_attr "mode" "<MODE>")]
2285 (define_insn "*cmpe<mode>"
2286 [(set (reg:CCFPE CC_REGNUM)
2287 (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2288 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2292 fcmpe\\t%<s>0, %<s>1"
2293 [(set_attr "v8type" "fcmp")
2294 (set_attr "mode" "<MODE>")]
2297 (define_insn "*cmp_swp_<shift>_reg<mode>"
2298 [(set (reg:CC_SWP CC_REGNUM)
2299 (compare:CC_SWP (ASHIFT:GPI
2300 (match_operand:GPI 0 "register_operand" "r")
2301 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2302 (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2304 "cmp\\t%<w>2, %<w>0, <shift> %1"
2305 [(set_attr "v8type" "alus_shift")
2306 (set_attr "mode" "<MODE>")]
2309 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2310 [(set (reg:CC_SWP CC_REGNUM)
2311 (compare:CC_SWP (ANY_EXTEND:GPI
2312 (match_operand:ALLX 0 "register_operand" "r"))
2313 (match_operand:GPI 1 "register_operand" "r")))]
2315 "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2316 [(set_attr "v8type" "alus_ext")
2317 (set_attr "mode" "<GPI:MODE>")]
2321 ;; -------------------------------------------------------------------
2322 ;; Store-flag and conditional select insns
2323 ;; -------------------------------------------------------------------
2325 (define_expand "cstore<mode>4"
2326 [(set (match_operand:SI 0 "register_operand" "")
2327 (match_operator:SI 1 "aarch64_comparison_operator"
2328 [(match_operand:GPI 2 "register_operand" "")
2329 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2332 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2334 operands[3] = const0_rtx;
2338 (define_expand "cstore<mode>4"
2339 [(set (match_operand:SI 0 "register_operand" "")
2340 (match_operator:SI 1 "aarch64_comparison_operator"
2341 [(match_operand:GPF 2 "register_operand" "")
2342 (match_operand:GPF 3 "register_operand" "")]))]
2345 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2347 operands[3] = const0_rtx;
2351 (define_insn "*cstore<mode>_insn"
2352 [(set (match_operand:ALLI 0 "register_operand" "=r")
2353 (match_operator:ALLI 1 "aarch64_comparison_operator"
2354 [(match_operand 2 "cc_register" "") (const_int 0)]))]
2357 [(set_attr "v8type" "csel")
2358 (set_attr "mode" "<MODE>")]
2361 ;; zero_extend version of the above
2362 (define_insn "*cstoresi_insn_uxtw"
2363 [(set (match_operand:DI 0 "register_operand" "=r")
2365 (match_operator:SI 1 "aarch64_comparison_operator"
2366 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2369 [(set_attr "v8type" "csel")
2370 (set_attr "mode" "SI")]
2373 (define_insn "*cstore<mode>_neg"
2374 [(set (match_operand:ALLI 0 "register_operand" "=r")
2375 (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2376 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2378 "csetm\\t%<w>0, %m1"
2379 [(set_attr "v8type" "csel")
2380 (set_attr "mode" "<MODE>")]
2383 ;; zero_extend version of the above
2384 (define_insn "*cstoresi_neg_uxtw"
2385 [(set (match_operand:DI 0 "register_operand" "=r")
2387 (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2388 [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2391 [(set_attr "v8type" "csel")
2392 (set_attr "mode" "SI")]
2395 (define_expand "cmov<mode>6"
2396 [(set (match_operand:GPI 0 "register_operand" "")
2398 (match_operator 1 "aarch64_comparison_operator"
2399 [(match_operand:GPI 2 "register_operand" "")
2400 (match_operand:GPI 3 "aarch64_plus_operand" "")])
2401 (match_operand:GPI 4 "register_operand" "")
2402 (match_operand:GPI 5 "register_operand" "")))]
2405 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2407 operands[3] = const0_rtx;
2411 (define_expand "cmov<mode>6"
2412 [(set (match_operand:GPF 0 "register_operand" "")
2414 (match_operator 1 "aarch64_comparison_operator"
2415 [(match_operand:GPF 2 "register_operand" "")
2416 (match_operand:GPF 3 "register_operand" "")])
2417 (match_operand:GPF 4 "register_operand" "")
2418 (match_operand:GPF 5 "register_operand" "")))]
2421 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2423 operands[3] = const0_rtx;
2427 (define_insn "*cmov<mode>_insn"
2428 [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2430 (match_operator 1 "aarch64_comparison_operator"
2431 [(match_operand 2 "cc_register" "") (const_int 0)])
2432 (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2433 (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2434 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2435 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2436 ;; Final two alternatives should be unreachable, but included for completeness
2438 csel\\t%<w>0, %<w>3, %<w>4, %m1
2439 csinv\\t%<w>0, %<w>3, <w>zr, %m1
2440 csinv\\t%<w>0, %<w>4, <w>zr, %M1
2441 csinc\\t%<w>0, %<w>3, <w>zr, %m1
2442 csinc\\t%<w>0, %<w>4, <w>zr, %M1
2445 [(set_attr "v8type" "csel")
2446 (set_attr "mode" "<MODE>")]
2449 ;; zero_extend version of above
2450 (define_insn "*cmovsi_insn_uxtw"
2451 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2454 (match_operator 1 "aarch64_comparison_operator"
2455 [(match_operand 2 "cc_register" "") (const_int 0)])
2456 (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2457 (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2458 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2459 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2460 ;; Final two alternatives should be unreachable, but included for completeness
2462 csel\\t%w0, %w3, %w4, %m1
2463 csinv\\t%w0, %w3, wzr, %m1
2464 csinv\\t%w0, %w4, wzr, %M1
2465 csinc\\t%w0, %w3, wzr, %m1
2466 csinc\\t%w0, %w4, wzr, %M1
2469 [(set_attr "v8type" "csel")
2470 (set_attr "mode" "SI")]
2473 (define_insn "*cmov<mode>_insn"
2474 [(set (match_operand:GPF 0 "register_operand" "=w")
2476 (match_operator 1 "aarch64_comparison_operator"
2477 [(match_operand 2 "cc_register" "") (const_int 0)])
2478 (match_operand:GPF 3 "register_operand" "w")
2479 (match_operand:GPF 4 "register_operand" "w")))]
2481 "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2482 [(set_attr "v8type" "fcsel")
2483 (set_attr "mode" "<MODE>")]
2486 (define_expand "mov<mode>cc"
2487 [(set (match_operand:ALLI 0 "register_operand" "")
2488 (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2489 (match_operand:ALLI 2 "register_operand" "")
2490 (match_operand:ALLI 3 "register_operand" "")))]
2494 enum rtx_code code = GET_CODE (operands[1]);
2496 if (code == UNEQ || code == LTGT)
2499 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2500 XEXP (operands[1], 1));
2501 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2505 (define_expand "mov<GPF:mode><GPI:mode>cc"
2506 [(set (match_operand:GPI 0 "register_operand" "")
2507 (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2508 (match_operand:GPF 2 "register_operand" "")
2509 (match_operand:GPF 3 "register_operand" "")))]
2513 enum rtx_code code = GET_CODE (operands[1]);
2515 if (code == UNEQ || code == LTGT)
2518 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2519 XEXP (operands[1], 1));
2520 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2524 (define_insn "*csinc2<mode>_insn"
2525 [(set (match_operand:GPI 0 "register_operand" "=r")
2526 (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator"
2527 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
2528 (match_operand:GPI 1 "register_operand" "r")))]
2530 "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2531 [(set_attr "v8type" "csel")
2532 (set_attr "mode" "<MODE>")])
2534 (define_insn "csinc3<mode>_insn"
2535 [(set (match_operand:GPI 0 "register_operand" "=r")
2537 (match_operator:GPI 1 "aarch64_comparison_operator"
2538 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2539 (plus:GPI (match_operand:GPI 3 "register_operand" "r")
2541 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2543 "csinc\\t%<w>0, %<w>4, %<w>3, %M1"
2544 [(set_attr "v8type" "csel")
2545 (set_attr "mode" "<MODE>")]
2548 (define_insn "*csinv3<mode>_insn"
2549 [(set (match_operand:GPI 0 "register_operand" "=r")
2551 (match_operator:GPI 1 "aarch64_comparison_operator"
2552 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2553 (not:GPI (match_operand:GPI 3 "register_operand" "r"))
2554 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2556 "csinv\\t%<w>0, %<w>4, %<w>3, %M1"
2557 [(set_attr "v8type" "csel")
2558 (set_attr "mode" "<MODE>")])
2560 (define_insn "*csneg3<mode>_insn"
2561 [(set (match_operand:GPI 0 "register_operand" "=r")
2563 (match_operator:GPI 1 "aarch64_comparison_operator"
2564 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2565 (neg:GPI (match_operand:GPI 3 "register_operand" "r"))
2566 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2568 "csneg\\t%<w>0, %<w>4, %<w>3, %M1"
2569 [(set_attr "v8type" "csel")
2570 (set_attr "mode" "<MODE>")])
2572 ;; -------------------------------------------------------------------
2573 ;; Logical operations
2574 ;; -------------------------------------------------------------------
2576 (define_insn "<optab><mode>3"
2577 [(set (match_operand:GPI 0 "register_operand" "=r,rk")
2578 (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2579 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
2581 "<logical>\\t%<w>0, %<w>1, %<w>2"
2582 [(set_attr "v8type" "logic,logic_imm")
2583 (set_attr "mode" "<MODE>")])
2585 ;; zero_extend version of above
2586 (define_insn "*<optab>si3_uxtw"
2587 [(set (match_operand:DI 0 "register_operand" "=r,rk")
2589 (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2590 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2592 "<logical>\\t%w0, %w1, %w2"
2593 [(set_attr "v8type" "logic,logic_imm")
2594 (set_attr "mode" "SI")])
2596 (define_insn "*and<mode>3_compare0"
2597 [(set (reg:CC_NZ CC_REGNUM)
2599 (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2600 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2602 (set (match_operand:GPI 0 "register_operand" "=r,r")
2603 (and:GPI (match_dup 1) (match_dup 2)))]
2605 "ands\\t%<w>0, %<w>1, %<w>2"
2606 [(set_attr "v8type" "logics,logics_imm")
2607 (set_attr "mode" "<MODE>")]
2610 ;; zero_extend version of above
2611 (define_insn "*andsi3_compare0_uxtw"
2612 [(set (reg:CC_NZ CC_REGNUM)
2614 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2615 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2617 (set (match_operand:DI 0 "register_operand" "=r,r")
2618 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2620 "ands\\t%w0, %w1, %w2"
2621 [(set_attr "v8type" "logics,logics_imm")
2622 (set_attr "mode" "SI")]
2625 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2626 [(set (reg:CC_NZ CC_REGNUM)
2629 (match_operand:GPI 1 "register_operand" "r")
2630 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2631 (match_operand:GPI 3 "register_operand" "r"))
2633 (set (match_operand:GPI 0 "register_operand" "=r")
2634 (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2636 "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2637 [(set_attr "v8type" "logics_shift")
2638 (set_attr "mode" "<MODE>")]
2641 ;; zero_extend version of above
2642 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2643 [(set (reg:CC_NZ CC_REGNUM)
2646 (match_operand:SI 1 "register_operand" "r")
2647 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2648 (match_operand:SI 3 "register_operand" "r"))
2650 (set (match_operand:DI 0 "register_operand" "=r")
2651 (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2654 "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2655 [(set_attr "v8type" "logics_shift")
2656 (set_attr "mode" "SI")]
2659 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2660 [(set (match_operand:GPI 0 "register_operand" "=r")
2661 (LOGICAL:GPI (SHIFT:GPI
2662 (match_operand:GPI 1 "register_operand" "r")
2663 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2664 (match_operand:GPI 3 "register_operand" "r")))]
2666 "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2667 [(set_attr "v8type" "logic_shift")
2668 (set_attr "mode" "<MODE>")])
2670 ;; zero_extend version of above
2671 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
2672 [(set (match_operand:DI 0 "register_operand" "=r")
2674 (LOGICAL:SI (SHIFT:SI
2675 (match_operand:SI 1 "register_operand" "r")
2676 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2677 (match_operand:SI 3 "register_operand" "r"))))]
2679 "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2680 [(set_attr "v8type" "logic_shift")
2681 (set_attr "mode" "SI")])
2683 (define_insn "one_cmpl<mode>2"
2684 [(set (match_operand:GPI 0 "register_operand" "=r")
2685 (not:GPI (match_operand:GPI 1 "register_operand" "r")))]
2687 "mvn\\t%<w>0, %<w>1"
2688 [(set_attr "v8type" "logic")
2689 (set_attr "mode" "<MODE>")])
2691 (define_insn "*one_cmpl_<optab><mode>2"
2692 [(set (match_operand:GPI 0 "register_operand" "=r")
2693 (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
2694 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2696 "mvn\\t%<w>0, %<w>1, <shift> %2"
2697 [(set_attr "v8type" "logic_shift")
2698 (set_attr "mode" "<MODE>")])
2700 (define_insn "*<LOGICAL:optab>_one_cmpl<mode>3"
2701 [(set (match_operand:GPI 0 "register_operand" "=r")
2702 (LOGICAL:GPI (not:GPI
2703 (match_operand:GPI 1 "register_operand" "r"))
2704 (match_operand:GPI 2 "register_operand" "r")))]
2706 "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1"
2707 [(set_attr "v8type" "logic")
2708 (set_attr "mode" "<MODE>")])
2710 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
2711 [(set (match_operand:GPI 0 "register_operand" "=r")
2712 (LOGICAL:GPI (not:GPI
2714 (match_operand:GPI 1 "register_operand" "r")
2715 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2716 (match_operand:GPI 3 "register_operand" "r")))]
2718 "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2719 [(set_attr "v8type" "logic_shift")
2720 (set_attr "mode" "<MODE>")])
2722 (define_insn "clz<mode>2"
2723 [(set (match_operand:GPI 0 "register_operand" "=r")
2724 (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
2726 "clz\\t%<w>0, %<w>1"
2727 [(set_attr "v8type" "clz")
2728 (set_attr "mode" "<MODE>")])
2730 (define_expand "ffs<mode>2"
2731 [(match_operand:GPI 0 "register_operand")
2732 (match_operand:GPI 1 "register_operand")]
2735 rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
2736 rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
2738 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2739 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2740 emit_insn (gen_csinc3<mode>_insn (operands[0], x, ccreg, operands[0], const0_rtx));
2745 (define_insn "clrsb<mode>2"
2746 [(set (match_operand:GPI 0 "register_operand" "=r")
2747 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_CLS))]
2749 "cls\\t%<w>0, %<w>1"
2750 [(set_attr "v8type" "clz")
2751 (set_attr "mode" "<MODE>")])
2753 (define_insn "rbit<mode>2"
2754 [(set (match_operand:GPI 0 "register_operand" "=r")
2755 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
2757 "rbit\\t%<w>0, %<w>1"
2758 [(set_attr "v8type" "rbit")
2759 (set_attr "mode" "<MODE>")])
2761 (define_expand "ctz<mode>2"
2762 [(match_operand:GPI 0 "register_operand")
2763 (match_operand:GPI 1 "register_operand")]
2766 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2767 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2772 (define_insn "*and<mode>3nr_compare0"
2773 [(set (reg:CC_NZ CC_REGNUM)
2775 (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
2776 (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
2779 "tst\\t%<w>0, %<w>1"
2780 [(set_attr "v8type" "logics")
2781 (set_attr "mode" "<MODE>")])
2783 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
2784 [(set (reg:CC_NZ CC_REGNUM)
2787 (match_operand:GPI 0 "register_operand" "r")
2788 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2789 (match_operand:GPI 2 "register_operand" "r"))
2792 "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
2793 [(set_attr "v8type" "logics_shift")
2794 (set_attr "mode" "<MODE>")])
2796 ;; -------------------------------------------------------------------
2798 ;; -------------------------------------------------------------------
2800 (define_expand "<optab><mode>3"
2801 [(set (match_operand:GPI 0 "register_operand")
2802 (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
2803 (match_operand:QI 2 "nonmemory_operand")))]
2806 if (CONST_INT_P (operands[2]))
2808 operands[2] = GEN_INT (INTVAL (operands[2])
2809 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2811 if (operands[2] == const0_rtx)
2813 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2820 (define_expand "ashl<mode>3"
2821 [(set (match_operand:SHORT 0 "register_operand")
2822 (ashift:SHORT (match_operand:SHORT 1 "register_operand")
2823 (match_operand:QI 2 "nonmemory_operand")))]
2826 if (CONST_INT_P (operands[2]))
2828 operands[2] = GEN_INT (INTVAL (operands[2])
2829 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2831 if (operands[2] == const0_rtx)
2833 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2840 (define_expand "rotr<mode>3"
2841 [(set (match_operand:GPI 0 "register_operand")
2842 (rotatert:GPI (match_operand:GPI 1 "register_operand")
2843 (match_operand:QI 2 "nonmemory_operand")))]
2846 if (CONST_INT_P (operands[2]))
2848 operands[2] = GEN_INT (INTVAL (operands[2])
2849 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2851 if (operands[2] == const0_rtx)
2853 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2860 (define_expand "rotl<mode>3"
2861 [(set (match_operand:GPI 0 "register_operand")
2862 (rotatert:GPI (match_operand:GPI 1 "register_operand")
2863 (match_operand:QI 2 "nonmemory_operand")))]
2866 /* (SZ - cnt) % SZ == -cnt % SZ */
2867 if (CONST_INT_P (operands[2]))
2869 operands[2] = GEN_INT ((-INTVAL (operands[2]))
2870 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2871 if (operands[2] == const0_rtx)
2873 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2878 operands[2] = expand_simple_unop (QImode, NEG, operands[2],
2883 (define_insn "*<optab><mode>3_insn"
2884 [(set (match_operand:GPI 0 "register_operand" "=r")
2886 (match_operand:GPI 1 "register_operand" "r")
2887 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
2889 "<shift>\\t%<w>0, %<w>1, %<w>2"
2890 [(set_attr "v8type" "shift")
2891 (set_attr "mode" "<MODE>")]
2894 ;; zero_extend version of above
2895 (define_insn "*<optab>si3_insn_uxtw"
2896 [(set (match_operand:DI 0 "register_operand" "=r")
2897 (zero_extend:DI (SHIFT:SI
2898 (match_operand:SI 1 "register_operand" "r")
2899 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
2901 "<shift>\\t%w0, %w1, %w2"
2902 [(set_attr "v8type" "shift")
2903 (set_attr "mode" "SI")]
2906 (define_insn "*ashl<mode>3_insn"
2907 [(set (match_operand:SHORT 0 "register_operand" "=r")
2908 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
2909 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
2911 "lsl\\t%<w>0, %<w>1, %<w>2"
2912 [(set_attr "v8type" "shift")
2913 (set_attr "mode" "<MODE>")]
2916 (define_insn "*<optab><mode>3_insn"
2917 [(set (match_operand:SHORT 0 "register_operand" "=r")
2918 (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
2919 (match_operand 2 "const_int_operand" "n")))]
2920 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
2922 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
2923 return "<bfshift>\t%w0, %w1, %2, %3";
2925 [(set_attr "v8type" "bfm")
2926 (set_attr "mode" "<MODE>")]
2929 (define_insn "*extr<mode>5_insn"
2930 [(set (match_operand:GPI 0 "register_operand" "=r")
2931 (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
2932 (match_operand 3 "const_int_operand" "n"))
2933 (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
2934 (match_operand 4 "const_int_operand" "n"))))]
2935 "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
2936 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
2937 "extr\\t%<w>0, %<w>1, %<w>2, %4"
2938 [(set_attr "v8type" "shift")
2939 (set_attr "mode" "<MODE>")]
2942 ;; zero_extend version of the above
2943 (define_insn "*extrsi5_insn_uxtw"
2944 [(set (match_operand:DI 0 "register_operand" "=r")
2946 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
2947 (match_operand 3 "const_int_operand" "n"))
2948 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
2949 (match_operand 4 "const_int_operand" "n")))))]
2950 "UINTVAL (operands[3]) < 32 &&
2951 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
2952 "extr\\t%w0, %w1, %w2, %4"
2953 [(set_attr "v8type" "shift")
2954 (set_attr "mode" "SI")]
2957 (define_insn "*ror<mode>3_insn"
2958 [(set (match_operand:GPI 0 "register_operand" "=r")
2959 (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
2960 (match_operand 2 "const_int_operand" "n")))]
2961 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
2963 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
2964 return "ror\\t%<w>0, %<w>1, %3";
2966 [(set_attr "v8type" "shift")
2967 (set_attr "mode" "<MODE>")]
2970 ;; zero_extend version of the above
2971 (define_insn "*rorsi3_insn_uxtw"
2972 [(set (match_operand:DI 0 "register_operand" "=r")
2974 (rotate:SI (match_operand:SI 1 "register_operand" "r")
2975 (match_operand 2 "const_int_operand" "n"))))]
2976 "UINTVAL (operands[2]) < 32"
2978 operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
2979 return "ror\\t%w0, %w1, %3";
2981 [(set_attr "v8type" "shift")
2982 (set_attr "mode" "SI")]
2985 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
2986 [(set (match_operand:GPI 0 "register_operand" "=r")
2988 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
2989 (match_operand 2 "const_int_operand" "n"))))]
2990 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
2992 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
2993 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
2995 [(set_attr "v8type" "bfm")
2996 (set_attr "mode" "<GPI:MODE>")]
2999 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3000 [(set (match_operand:GPI 0 "register_operand" "=r")
3002 (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3003 (match_operand 2 "const_int_operand" "n"))))]
3004 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3006 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3007 return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3009 [(set_attr "v8type" "bfm")
3010 (set_attr "mode" "<GPI:MODE>")]
3013 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3014 [(set (match_operand:GPI 0 "register_operand" "=r")
3016 (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3017 (match_operand 2 "const_int_operand" "n"))))]
3018 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3020 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3021 return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3023 [(set_attr "v8type" "bfm")
3024 (set_attr "mode" "<GPI:MODE>")]
3027 ;; -------------------------------------------------------------------
3029 ;; -------------------------------------------------------------------
3031 (define_expand "<optab>"
3032 [(set (match_operand:DI 0 "register_operand" "=r")
3033 (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3034 (match_operand 2 "const_int_operand" "n")
3035 (match_operand 3 "const_int_operand" "n")))]
3040 (define_insn "*<optab><mode>"
3041 [(set (match_operand:GPI 0 "register_operand" "=r")
3042 (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3043 (match_operand 2 "const_int_operand" "n")
3044 (match_operand 3 "const_int_operand" "n")))]
3046 "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3047 [(set_attr "v8type" "bfm")
3048 (set_attr "mode" "<MODE>")]
3051 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3052 [(set (match_operand:GPI 0 "register_operand" "=r")
3053 (ashift:GPI (ANY_EXTEND:GPI
3054 (match_operand:ALLX 1 "register_operand" "r"))
3055 (match_operand 2 "const_int_operand" "n")))]
3056 "UINTVAL (operands[2]) < <GPI:sizen>"
3058 operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3059 ? GEN_INT (<ALLX:sizen>)
3060 : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3061 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3063 [(set_attr "v8type" "bfm")
3064 (set_attr "mode" "<GPI:MODE>")]
3067 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3069 (define_insn "*andim_ashift<mode>_bfiz"
3070 [(set (match_operand:GPI 0 "register_operand" "=r")
3071 (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3072 (match_operand 2 "const_int_operand" "n"))
3073 (match_operand 3 "const_int_operand" "n")))]
3074 "exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3075 && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3076 "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3077 [(set_attr "v8type" "bfm")
3078 (set_attr "mode" "<MODE>")]
3081 (define_insn "bswap<mode>2"
3082 [(set (match_operand:GPI 0 "register_operand" "=r")
3083 (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3085 "rev\\t%<w>0, %<w>1"
3086 [(set_attr "v8type" "rev")
3087 (set_attr "mode" "<MODE>")]
3090 (define_insn "bswaphi2"
3091 [(set (match_operand:HI 0 "register_operand" "=r")
3092 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3095 [(set_attr "v8type" "rev")
3096 (set_attr "mode" "HI")]
3099 ;; zero_extend version of above
3100 (define_insn "*bswapsi2_uxtw"
3101 [(set (match_operand:DI 0 "register_operand" "=r")
3102 (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3105 [(set_attr "v8type" "rev")
3106 (set_attr "mode" "SI")]
3109 ;; -------------------------------------------------------------------
3110 ;; Floating-point intrinsics
3111 ;; -------------------------------------------------------------------
3113 ;; frint floating-point round to integral standard patterns.
3114 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round.
3116 (define_insn "<frint_pattern><mode>2"
3117 [(set (match_operand:GPF 0 "register_operand" "=w")
3118 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3121 "frint<frint_suffix>\\t%<s>0, %<s>1"
3122 [(set_attr "v8type" "frint")
3123 (set_attr "mode" "<MODE>")]
3126 ;; frcvt floating-point round to integer and convert standard patterns.
3127 ;; Expands to lbtrunc, lceil, lfloor, lround.
3128 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3129 [(set (match_operand:GPI 0 "register_operand" "=r")
3130 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3133 "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3134 [(set_attr "v8type" "fcvtf2i")
3135 (set_attr "mode" "<GPF:MODE>")
3136 (set_attr "mode2" "<GPI:MODE>")]
3141 (define_insn "fma<mode>4"
3142 [(set (match_operand:GPF 0 "register_operand" "=w")
3143 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3144 (match_operand:GPF 2 "register_operand" "w")
3145 (match_operand:GPF 3 "register_operand" "w")))]
3147 "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3148 [(set_attr "v8type" "fmadd")
3149 (set_attr "mode" "<MODE>")]
3152 (define_insn "fnma<mode>4"
3153 [(set (match_operand:GPF 0 "register_operand" "=w")
3154 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3155 (match_operand:GPF 2 "register_operand" "w")
3156 (match_operand:GPF 3 "register_operand" "w")))]
3158 "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3159 [(set_attr "v8type" "fmadd")
3160 (set_attr "mode" "<MODE>")]
3163 (define_insn "fms<mode>4"
3164 [(set (match_operand:GPF 0 "register_operand" "=w")
3165 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3166 (match_operand:GPF 2 "register_operand" "w")
3167 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3169 "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3170 [(set_attr "v8type" "fmadd")
3171 (set_attr "mode" "<MODE>")]
3174 (define_insn "fnms<mode>4"
3175 [(set (match_operand:GPF 0 "register_operand" "=w")
3176 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3177 (match_operand:GPF 2 "register_operand" "w")
3178 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3180 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3181 [(set_attr "v8type" "fmadd")
3182 (set_attr "mode" "<MODE>")]
3185 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3186 (define_insn "*fnmadd<mode>4"
3187 [(set (match_operand:GPF 0 "register_operand" "=w")
3188 (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3189 (match_operand:GPF 2 "register_operand" "w")
3190 (match_operand:GPF 3 "register_operand" "w"))))]
3191 "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3192 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3193 [(set_attr "v8type" "fmadd")
3194 (set_attr "mode" "<MODE>")]
3197 ;; -------------------------------------------------------------------
3198 ;; Floating-point conversions
3199 ;; -------------------------------------------------------------------
3201 (define_insn "extendsfdf2"
3202 [(set (match_operand:DF 0 "register_operand" "=w")
3203 (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3206 [(set_attr "v8type" "fcvt")
3207 (set_attr "mode" "DF")
3208 (set_attr "mode2" "SF")]
3211 (define_insn "truncdfsf2"
3212 [(set (match_operand:SF 0 "register_operand" "=w")
3213 (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3216 [(set_attr "v8type" "fcvt")
3217 (set_attr "mode" "SF")
3218 (set_attr "mode2" "DF")]
3221 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3222 [(set (match_operand:GPI 0 "register_operand" "=r")
3223 (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3225 "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3226 [(set_attr "v8type" "fcvtf2i")
3227 (set_attr "mode" "<GPF:MODE>")
3228 (set_attr "mode2" "<GPI:MODE>")]
3231 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3232 [(set (match_operand:GPI 0 "register_operand" "=r")
3233 (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3235 "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3236 [(set_attr "v8type" "fcvtf2i")
3237 (set_attr "mode" "<GPF:MODE>")
3238 (set_attr "mode2" "<GPI:MODE>")]
3241 (define_insn "float<GPI:mode><GPF:mode>2"
3242 [(set (match_operand:GPF 0 "register_operand" "=w")
3243 (float:GPF (match_operand:GPI 1 "register_operand" "r")))]
3245 "scvtf\\t%<GPF:s>0, %<GPI:w>1"
3246 [(set_attr "v8type" "fcvti2f")
3247 (set_attr "mode" "<GPF:MODE>")
3248 (set_attr "mode2" "<GPI:MODE>")]
3251 (define_insn "floatuns<GPI:mode><GPF:mode>2"
3252 [(set (match_operand:GPF 0 "register_operand" "=w")
3253 (unsigned_float:GPF (match_operand:GPI 1 "register_operand" "r")))]
3255 "ucvtf\\t%<GPF:s>0, %<GPI:w>1"
3256 [(set_attr "v8type" "fcvt")
3257 (set_attr "mode" "<GPF:MODE>")
3258 (set_attr "mode2" "<GPI:MODE>")]
3261 ;; -------------------------------------------------------------------
3262 ;; Floating-point arithmetic
3263 ;; -------------------------------------------------------------------
3265 (define_insn "add<mode>3"
3266 [(set (match_operand:GPF 0 "register_operand" "=w")
3268 (match_operand:GPF 1 "register_operand" "w")
3269 (match_operand:GPF 2 "register_operand" "w")))]
3271 "fadd\\t%<s>0, %<s>1, %<s>2"
3272 [(set_attr "v8type" "fadd")
3273 (set_attr "mode" "<MODE>")]
3276 (define_insn "sub<mode>3"
3277 [(set (match_operand:GPF 0 "register_operand" "=w")
3279 (match_operand:GPF 1 "register_operand" "w")
3280 (match_operand:GPF 2 "register_operand" "w")))]
3282 "fsub\\t%<s>0, %<s>1, %<s>2"
3283 [(set_attr "v8type" "fadd")
3284 (set_attr "mode" "<MODE>")]
3287 (define_insn "mul<mode>3"
3288 [(set (match_operand:GPF 0 "register_operand" "=w")
3290 (match_operand:GPF 1 "register_operand" "w")
3291 (match_operand:GPF 2 "register_operand" "w")))]
3293 "fmul\\t%<s>0, %<s>1, %<s>2"
3294 [(set_attr "v8type" "fmul")
3295 (set_attr "mode" "<MODE>")]
3298 (define_insn "*fnmul<mode>3"
3299 [(set (match_operand:GPF 0 "register_operand" "=w")
3301 (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3302 (match_operand:GPF 2 "register_operand" "w")))]
3304 "fnmul\\t%<s>0, %<s>1, %<s>2"
3305 [(set_attr "v8type" "fmul")
3306 (set_attr "mode" "<MODE>")]
3309 (define_insn "div<mode>3"
3310 [(set (match_operand:GPF 0 "register_operand" "=w")
3312 (match_operand:GPF 1 "register_operand" "w")
3313 (match_operand:GPF 2 "register_operand" "w")))]
3315 "fdiv\\t%<s>0, %<s>1, %<s>2"
3316 [(set_attr "v8type" "fdiv")
3317 (set_attr "mode" "<MODE>")]
3320 (define_insn "neg<mode>2"
3321 [(set (match_operand:GPF 0 "register_operand" "=w")
3322 (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
3324 "fneg\\t%<s>0, %<s>1"
3325 [(set_attr "v8type" "ffarith")
3326 (set_attr "mode" "<MODE>")]
3329 (define_insn "sqrt<mode>2"
3330 [(set (match_operand:GPF 0 "register_operand" "=w")
3331 (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
3333 "fsqrt\\t%<s>0, %<s>1"
3334 [(set_attr "v8type" "fsqrt")
3335 (set_attr "mode" "<MODE>")]
3338 (define_insn "abs<mode>2"
3339 [(set (match_operand:GPF 0 "register_operand" "=w")
3340 (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
3342 "fabs\\t%<s>0, %<s>1"
3343 [(set_attr "v8type" "ffarith")
3344 (set_attr "mode" "<MODE>")]
3347 ;; Given that smax/smin do not specify the result when either input is NaN,
3348 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
3351 (define_insn "smax<mode>3"
3352 [(set (match_operand:GPF 0 "register_operand" "=w")
3353 (smax:GPF (match_operand:GPF 1 "register_operand" "w")
3354 (match_operand:GPF 2 "register_operand" "w")))]
3356 "fmaxnm\\t%<s>0, %<s>1, %<s>2"
3357 [(set_attr "v8type" "fminmax")
3358 (set_attr "mode" "<MODE>")]
3361 (define_insn "smin<mode>3"
3362 [(set (match_operand:GPF 0 "register_operand" "=w")
3363 (smin:GPF (match_operand:GPF 1 "register_operand" "w")
3364 (match_operand:GPF 2 "register_operand" "w")))]
3366 "fminnm\\t%<s>0, %<s>1, %<s>2"
3367 [(set_attr "v8type" "fminmax")
3368 (set_attr "mode" "<MODE>")]
3371 (define_insn "aarch64_frecp<FRECP:frecp_suffix><mode>"
3372 [(set (match_operand:GPF 0 "register_operand" "=w")
3373 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3376 "frecp<FRECP:frecp_suffix>\\t%<s>0, %<s>1"
3377 [(set_attr "v8type" "frecp<FRECP:frecp_suffix>")
3378 (set_attr "mode" "<MODE>")]
3381 (define_insn "aarch64_frecps<mode>"
3382 [(set (match_operand:GPF 0 "register_operand" "=w")
3383 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")
3384 (match_operand:GPF 2 "register_operand" "w")]
3387 "frecps\\t%<s>0, %<s>1, %<s>2"
3388 [(set_attr "v8type" "frecps")
3389 (set_attr "mode" "<MODE>")]
3392 ;; -------------------------------------------------------------------
3394 ;; -------------------------------------------------------------------
3396 ;; Reload SP+imm where imm cannot be handled by a single ADD instruction.
3397 ;; Must load imm into a scratch register and copy SP to the dest reg before
3398 ;; adding, since SP cannot be used as a source register in an ADD
3400 (define_expand "reload_sp_immediate"
3401 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
3402 (match_operand:DI 1 "" ""))
3403 (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
3406 rtx sp = XEXP (operands[1], 0);
3407 rtx val = XEXP (operands[1], 1);
3408 unsigned regno = REGNO (operands[2]);
3409 rtx scratch = operands[1];
3410 gcc_assert (GET_CODE (operands[1]) == PLUS);
3411 gcc_assert (sp == stack_pointer_rtx);
3412 gcc_assert (CONST_INT_P (val));
3414 /* It is possible that one of the registers we got for operands[2]
3415 might coincide with that of operands[0] (which is why we made
3416 it TImode). Pick the other one to use as our scratch. */
3417 if (regno == REGNO (operands[0]))
3419 scratch = gen_rtx_REG (DImode, regno);
3421 emit_move_insn (scratch, val);
3422 emit_move_insn (operands[0], sp);
3423 emit_insn (gen_adddi3 (operands[0], operands[0], scratch));
3428 (define_expand "aarch64_reload_mov<mode>"
3429 [(set (match_operand:TX 0 "register_operand" "=w")
3430 (match_operand:TX 1 "register_operand" "w"))
3431 (clobber (match_operand:DI 2 "register_operand" "=&r"))
3435 rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
3436 rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
3437 gen_aarch64_movtilow_tilow (op0, op1);
3438 gen_aarch64_movdi_tihigh (operands[2], op1);
3439 gen_aarch64_movtihigh_di (op0, operands[2]);
3444 ;; The following secondary reload helpers patterns are invoked
3445 ;; after or during reload as we don't want these patterns to start
3446 ;; kicking in during the combiner.
3448 (define_insn "aarch64_movdi_tilow"
3449 [(set (match_operand:DI 0 "register_operand" "=r")
3450 (truncate:DI (match_operand:TI 1 "register_operand" "w")))]
3451 "reload_completed || reload_in_progress"
3453 [(set_attr "v8type" "fmovf2i")
3454 (set_attr "mode" "DI")
3455 (set_attr "length" "4")
3458 (define_insn "aarch64_movdi_tihigh"
3459 [(set (match_operand:DI 0 "register_operand" "=r")
3461 (lshiftrt:TI (match_operand:TI 1 "register_operand" "w")
3463 "reload_completed || reload_in_progress"
3464 "fmov\\t%x0, %1.d[1]"
3465 [(set_attr "v8type" "fmovf2i")
3466 (set_attr "mode" "DI")
3467 (set_attr "length" "4")
3470 (define_insn "aarch64_movtihigh_di"
3471 [(set (zero_extract:TI (match_operand:TI 0 "register_operand" "+w")
3472 (const_int 64) (const_int 64))
3473 (zero_extend:TI (match_operand:DI 1 "register_operand" "r")))]
3474 "reload_completed || reload_in_progress"
3475 "fmov\\t%0.d[1], %x1"
3477 [(set_attr "v8type" "fmovi2f")
3478 (set_attr "mode" "DI")
3479 (set_attr "length" "4")
3482 (define_insn "aarch64_movtilow_di"
3483 [(set (match_operand:TI 0 "register_operand" "=w")
3484 (zero_extend:TI (match_operand:DI 1 "register_operand" "r")))]
3485 "reload_completed || reload_in_progress"
3488 [(set_attr "v8type" "fmovi2f")
3489 (set_attr "mode" "DI")
3490 (set_attr "length" "4")
3493 (define_insn "aarch64_movtilow_tilow"
3494 [(set (match_operand:TI 0 "register_operand" "=w")
3496 (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
3497 "reload_completed || reload_in_progress"
3500 [(set_attr "v8type" "fmovi2f")
3501 (set_attr "mode" "DI")
3502 (set_attr "length" "4")
3505 ;; There is a deliberate reason why the parameters of high and lo_sum's
3506 ;; don't have modes for ADRP and ADD instructions. This is to allow high
3507 ;; and lo_sum's to be used with the labels defining the jump tables in
3510 (define_insn "add_losym"
3511 [(set (match_operand:DI 0 "register_operand" "=r")
3512 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
3513 (match_operand 2 "aarch64_valid_symref" "S")))]
3515 "add\\t%0, %1, :lo12:%a2"
3516 [(set_attr "v8type" "alu")
3517 (set_attr "mode" "DI")]
3521 (define_insn "ldr_got_small"
3522 [(set (match_operand:DI 0 "register_operand" "=r")
3523 (unspec:DI [(mem:DI (lo_sum:DI
3524 (match_operand:DI 1 "register_operand" "r")
3525 (match_operand:DI 2 "aarch64_valid_symref" "S")))]
3526 UNSPEC_GOTSMALLPIC))]
3528 "ldr\\t%0, [%1, #:got_lo12:%a2]"
3529 [(set_attr "v8type" "load1")
3530 (set_attr "mode" "DI")]
3533 (define_insn "aarch64_load_tp_hard"
3534 [(set (match_operand:DI 0 "register_operand" "=r")
3535 (unspec:DI [(const_int 0)] UNSPEC_TLS))]
3537 "mrs\\t%0, tpidr_el0"
3538 [(set_attr "v8type" "mrs")
3539 (set_attr "mode" "DI")]
3542 ;; The TLS ABI specifically requires that the compiler does not schedule
3543 ;; instructions in the TLS stubs, in order to enable linker relaxation.
3544 ;; Therefore we treat the stubs as an atomic sequence.
3545 (define_expand "tlsgd_small"
3546 [(parallel [(set (match_operand 0 "register_operand" "")
3547 (call (mem:DI (match_dup 2)) (const_int 1)))
3548 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
3549 (clobber (reg:DI LR_REGNUM))])]
3552 operands[2] = aarch64_tls_get_addr ();
3555 (define_insn "*tlsgd_small"
3556 [(set (match_operand 0 "register_operand" "")
3557 (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
3558 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
3559 (clobber (reg:DI LR_REGNUM))
3562 "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
3563 [(set_attr "v8type" "call")
3564 (set_attr "length" "16")])
3566 (define_insn "tlsie_small"
3567 [(set (match_operand:DI 0 "register_operand" "=r")
3568 (unspec:DI [(match_operand:DI 1 "aarch64_tls_ie_symref" "S")]
3569 UNSPEC_GOTSMALLTLS))]
3571 "adrp\\t%0, %A1\;ldr\\t%0, [%0, #%L1]"
3572 [(set_attr "v8type" "load1")
3573 (set_attr "mode" "DI")
3574 (set_attr "length" "8")]
3577 (define_insn "tlsle_small"
3578 [(set (match_operand:DI 0 "register_operand" "=r")
3579 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
3580 (match_operand:DI 2 "aarch64_tls_le_symref" "S")]
3581 UNSPEC_GOTSMALLTLS))]
3583 "add\\t%0, %1, #%G2\;add\\t%0, %0, #%L2"
3584 [(set_attr "v8type" "alu")
3585 (set_attr "mode" "DI")
3586 (set_attr "length" "8")]
3589 (define_insn "tlsdesc_small"
3590 [(set (reg:DI R0_REGNUM)
3591 (unspec:DI [(match_operand:DI 0 "aarch64_valid_symref" "S")]
3593 (clobber (reg:DI LR_REGNUM))
3594 (clobber (match_scratch:DI 1 "=r"))]
3596 "adrp\\tx0, %A0\;ldr\\t%1, [x0, #%L0]\;add\\tx0, x0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
3597 [(set_attr "v8type" "call")
3598 (set_attr "length" "16")])
3600 (define_insn "stack_tie"
3601 [(set (mem:BLK (scratch))
3602 (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
3603 (match_operand:DI 1 "register_operand" "rk")]
3607 [(set_attr "length" "0")]
3610 ;; Named pattern for expanding thread pointer reference.
3611 (define_expand "get_thread_pointerdi"
3612 [(match_operand:DI 0 "register_operand" "=r")]
3615 rtx tmp = aarch64_load_tp (operands[0]);
3616 if (tmp != operands[0])
3617 emit_move_insn (operands[0], tmp);
3622 (include "aarch64-simd.md")
3624 ;; Atomic Operations
3625 (include "atomics.md")