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" [
104 (define_c_enum "unspecv" [
105 UNSPECV_EH_RETURN ; Represent EH_RETURN
109 ;; If further include files are added the defintion of MD_INCLUDES
112 (include "constraints.md")
113 (include "predicates.md")
114 (include "iterators.md")
116 ;; -------------------------------------------------------------------
117 ;; Instruction types and attributes
118 ;; -------------------------------------------------------------------
120 ;; Main data types used by the insntructions
122 (define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
123 (const_string "unknown"))
125 (define_attr "mode2" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
126 (const_string "unknown"))
128 ; The "v8type" attribute is used to for fine grained classification of
129 ; AArch64 instructions. This table briefly explains the meaning of each type.
131 ; adc add/subtract with carry.
132 ; adcs add/subtract with carry (setting condition flags).
133 ; adr calculate address.
134 ; alu simple alu instruction (no memory or fp regs access).
135 ; alu_ext simple alu instruction (sign/zero-extended register).
136 ; alu_shift simple alu instruction, with a source operand shifted by a constant.
137 ; alus simple alu instruction (setting condition flags).
138 ; alus_ext simple alu instruction (sign/zero-extended register, setting condition flags).
139 ; alus_shift simple alu instruction, with a source operand shifted by a constant (setting condition flags).
140 ; bfm bitfield move operation.
142 ; call subroutine call.
143 ; ccmp conditional compare.
144 ; clz count leading zeros/sign bits.
145 ; csel conditional select.
146 ; dmb data memory barrier.
147 ; extend sign/zero-extend (specialised bitfield move).
148 ; extr extract register-sized bitfield encoding.
149 ; fpsimd_load load single floating point / simd scalar register from memory.
150 ; fpsimd_load2 load pair of floating point / simd scalar registers from memory.
151 ; fpsimd_store store single floating point / simd scalar register to memory.
152 ; fpsimd_store2 store pair floating point / simd scalar registers to memory.
153 ; fadd floating point add/sub.
154 ; fccmp floating point conditional compare.
155 ; fcmp floating point comparison.
156 ; fconst floating point load immediate.
157 ; fcsel floating point conditional select.
158 ; fcvt floating point convert (float to float).
159 ; fcvtf2i floating point convert (float to integer).
160 ; fcvti2f floating point convert (integer to float).
161 ; fdiv floating point division operation.
162 ; ffarith floating point abs, neg or cpy.
163 ; fmadd floating point multiply-add/sub.
164 ; fminmax floating point min/max.
165 ; fmov floating point move (float to float).
166 ; fmovf2i floating point move (float to integer).
167 ; fmovi2f floating point move (integer to float).
168 ; fmul floating point multiply.
169 ; frint floating point round to integral.
170 ; fsqrt floating point square root.
171 ; load_acq load-acquire.
172 ; load load single general register from memory
173 ; load2 load pair of general registers from memory
174 ; logic logical operation (register).
175 ; logic_imm and/or/xor operation (immediate).
176 ; logic_shift logical operation with shift.
177 ; logics logical operation (register, setting condition flags).
178 ; logics_imm and/or/xor operation (immediate, setting condition flags).
179 ; logics_shift logical operation with shift (setting condition flags).
180 ; madd integer multiply-add/sub.
181 ; maddl widening integer multiply-add/sub.
182 ; misc miscellaneous - any type that doesn't fit into the rest.
183 ; move integer move operation.
184 ; move2 double integer move operation.
185 ; movk move 16-bit immediate with keep.
186 ; movz move 16-bit immmediate with zero/one.
187 ; mrs system/special register move.
188 ; mulh 64x64 to 128-bit multiply (high part).
189 ; mull widening multiply.
190 ; mult integer multiply instruction.
191 ; prefetch memory prefetch.
194 ; sdiv integer division operation (signed).
195 ; shift variable shift operation.
196 ; shift_imm immediate shift operation (specialised bitfield move).
197 ; store_rel store-release.
198 ; store store single general register to memory.
199 ; store2 store pair of general registers to memory.
200 ; udiv integer division operation (unsigned).
202 (define_attr "v8type"
275 (const_string "alu"))
277 ; The "type" attribute is is included here from AArch32 backend to be able
278 ; to share pipeline descriptions.
279 (include "../arm/types.md")
281 ;; Attribute that specifies whether or not the instruction touches fp
283 (define_attr "fp" "no,yes" (const_string "no"))
285 ;; Attribute that specifies whether or not the instruction touches simd
287 (define_attr "simd" "no,yes" (const_string "no"))
289 (define_attr "length" ""
292 ;; Attribute that controls whether an alternative is enabled or not.
293 ;; Currently it is only used to disable alternatives which touch fp or simd
294 ;; registers when -mgeneral-regs-only is specified.
295 (define_attr "enabled" "no,yes"
297 (and (eq_attr "fp" "yes")
298 (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
299 (and (eq_attr "simd" "yes")
300 (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
302 ] (const_string "yes")))
304 ;; -------------------------------------------------------------------
305 ;; Pipeline descriptions and scheduling
306 ;; -------------------------------------------------------------------
309 (include "aarch64-tune.md")
311 ;; True if the generic scheduling description should be used.
313 (define_attr "generic_sched" "yes,no"
315 (eq_attr "tune" "cortexa53,cortexa15")
317 (const_string "yes"))))
320 (include "../arm/cortex-a53.md")
321 (include "../arm/cortex-a15.md")
323 ;; -------------------------------------------------------------------
324 ;; Jumps and other miscellaneous insns
325 ;; -------------------------------------------------------------------
327 (define_insn "indirect_jump"
328 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
331 [(set_attr "v8type" "branch")
332 (set_attr "type" "branch")]
336 [(set (pc) (label_ref (match_operand 0 "" "")))]
339 [(set_attr "v8type" "branch")
340 (set_attr "type" "branch")]
343 (define_expand "cbranch<mode>4"
344 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
345 [(match_operand:GPI 1 "register_operand" "")
346 (match_operand:GPI 2 "aarch64_plus_operand" "")])
347 (label_ref (match_operand 3 "" ""))
351 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
353 operands[2] = const0_rtx;
357 (define_expand "cbranch<mode>4"
358 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
359 [(match_operand:GPF 1 "register_operand" "")
360 (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
361 (label_ref (match_operand 3 "" ""))
365 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
367 operands[2] = const0_rtx;
371 (define_insn "*condjump"
372 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
373 [(match_operand 1 "cc_register" "") (const_int 0)])
374 (label_ref (match_operand 2 "" ""))
378 [(set_attr "v8type" "branch")
379 (set_attr "type" "branch")]
382 (define_expand "casesi"
383 [(match_operand:SI 0 "register_operand" "") ; Index
384 (match_operand:SI 1 "const_int_operand" "") ; Lower bound
385 (match_operand:SI 2 "const_int_operand" "") ; Total range
386 (match_operand:DI 3 "" "") ; Table label
387 (match_operand:DI 4 "" "")] ; Out of range label
390 if (operands[1] != const0_rtx)
392 rtx reg = gen_reg_rtx (SImode);
394 /* Canonical RTL says that if you have:
398 then this should be emitted as:
402 The use of trunc_int_for_mode ensures that the resulting
403 constant can be represented in SImode, this is important
404 for the corner case where operand[1] is INT_MIN. */
406 operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
408 if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
409 (operands[1], SImode))
410 operands[1] = force_reg (SImode, operands[1]);
411 emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
415 if (!aarch64_plus_operand (operands[2], SImode))
416 operands[2] = force_reg (SImode, operands[2]);
417 emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
419 operands[0], operands[2], operands[4]));
421 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
422 emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
428 (define_insn "casesi_dispatch"
431 (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
432 (match_operand:SI 1 "register_operand" "r")]
434 (clobber (reg:CC CC_REGNUM))
435 (clobber (match_scratch:DI 3 "=r"))
436 (clobber (match_scratch:DI 4 "=r"))
437 (use (label_ref (match_operand 2 "" "")))])]
440 return aarch64_output_casesi (operands);
442 [(set_attr "length" "16")
443 (set_attr "v8type" "branch")
444 (set_attr "type" "branch")]
448 [(unspec[(const_int 0)] UNSPEC_NOP)]
451 [(set_attr "v8type" "misc")]
454 (define_expand "prologue"
455 [(clobber (const_int 0))]
458 aarch64_expand_prologue ();
463 (define_expand "epilogue"
464 [(clobber (const_int 0))]
467 aarch64_expand_epilogue (false);
472 (define_expand "sibcall_epilogue"
473 [(clobber (const_int 0))]
476 aarch64_expand_epilogue (true);
481 (define_insn "*do_return"
485 [(set_attr "v8type" "branch")
486 (set_attr "type" "branch")]
489 (define_insn "eh_return"
490 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
494 [(set_attr "v8type" "branch")
495 (set_attr "type" "branch")]
500 [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
503 [(set (match_dup 1) (match_dup 0))]
505 operands[1] = aarch64_final_eh_return_addr ();
509 (define_insn "*cb<optab><mode>1"
510 [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
512 (label_ref (match_operand 1 "" ""))
516 [(set_attr "v8type" "branch")
517 (set_attr "type" "branch")]
521 (define_insn "*tb<optab><mode>1"
522 [(set (pc) (if_then_else
523 (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
525 (match_operand 1 "const_int_operand" "n"))
527 (label_ref (match_operand 2 "" ""))
529 (clobber (match_scratch:DI 3 "=r"))]
532 if (get_attr_length (insn) == 8)
533 return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
534 return \"<tbz>\\t%<w>0, %1, %l2\";
536 [(set_attr "v8type" "branch")
537 (set_attr "type" "branch")
538 (set_attr "mode" "<MODE>")
540 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
541 (lt (minus (match_dup 2) (pc)) (const_int 32764)))
546 (define_insn "*cb<optab><mode>1"
547 [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
549 (label_ref (match_operand 1 "" ""))
551 (clobber (match_scratch:DI 2 "=r"))]
554 if (get_attr_length (insn) == 8)
555 return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
556 return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
558 [(set_attr "v8type" "branch")
559 (set_attr "type" "branch")
560 (set_attr "mode" "<MODE>")
562 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
563 (lt (minus (match_dup 1) (pc)) (const_int 32764)))
568 ;; -------------------------------------------------------------------
569 ;; Subroutine calls and sibcalls
570 ;; -------------------------------------------------------------------
572 (define_expand "call"
573 [(parallel [(call (match_operand 0 "memory_operand" "")
574 (match_operand 1 "general_operand" ""))
575 (use (match_operand 2 "" ""))
576 (clobber (reg:DI LR_REGNUM))])]
582 /* In an untyped call, we can get NULL for operand 2. */
583 if (operands[2] == NULL)
584 operands[2] = const0_rtx;
586 /* Decide if we should generate indirect calls by loading the
587 64-bit address of the callee into a register before performing
588 the branch-and-link. */
589 callee = XEXP (operands[0], 0);
590 if (GET_CODE (callee) == SYMBOL_REF
591 ? aarch64_is_long_call_p (callee)
593 XEXP (operands[0], 0) = force_reg (Pmode, callee);
597 (define_insn "*call_reg"
598 [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
599 (match_operand 1 "" ""))
600 (use (match_operand 2 "" ""))
601 (clobber (reg:DI LR_REGNUM))]
604 [(set_attr "v8type" "call")
605 (set_attr "type" "call")]
608 (define_insn "*call_symbol"
609 [(call (mem:DI (match_operand:DI 0 "" ""))
610 (match_operand 1 "" ""))
611 (use (match_operand 2 "" ""))
612 (clobber (reg:DI LR_REGNUM))]
613 "GET_CODE (operands[0]) == SYMBOL_REF
614 && !aarch64_is_long_call_p (operands[0])"
616 [(set_attr "v8type" "call")
617 (set_attr "type" "call")]
620 (define_expand "call_value"
621 [(parallel [(set (match_operand 0 "" "")
622 (call (match_operand 1 "memory_operand" "")
623 (match_operand 2 "general_operand" "")))
624 (use (match_operand 3 "" ""))
625 (clobber (reg:DI LR_REGNUM))])]
631 /* In an untyped call, we can get NULL for operand 3. */
632 if (operands[3] == NULL)
633 operands[3] = const0_rtx;
635 /* Decide if we should generate indirect calls by loading the
636 64-bit address of the callee into a register before performing
637 the branch-and-link. */
638 callee = XEXP (operands[1], 0);
639 if (GET_CODE (callee) == SYMBOL_REF
640 ? aarch64_is_long_call_p (callee)
642 XEXP (operands[1], 0) = force_reg (Pmode, callee);
646 (define_insn "*call_value_reg"
647 [(set (match_operand 0 "" "")
648 (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
649 (match_operand 2 "" "")))
650 (use (match_operand 3 "" ""))
651 (clobber (reg:DI LR_REGNUM))]
654 [(set_attr "v8type" "call")
655 (set_attr "type" "call")]
659 (define_insn "*call_value_symbol"
660 [(set (match_operand 0 "" "")
661 (call (mem:DI (match_operand:DI 1 "" ""))
662 (match_operand 2 "" "")))
663 (use (match_operand 3 "" ""))
664 (clobber (reg:DI LR_REGNUM))]
665 "GET_CODE (operands[1]) == SYMBOL_REF
666 && !aarch64_is_long_call_p (operands[1])"
668 [(set_attr "v8type" "call")
669 (set_attr "type" "call")]
672 (define_expand "sibcall"
673 [(parallel [(call (match_operand 0 "memory_operand" "")
674 (match_operand 1 "general_operand" ""))
676 (use (match_operand 2 "" ""))])]
679 if (operands[2] == NULL_RTX)
680 operands[2] = const0_rtx;
684 (define_expand "sibcall_value"
685 [(parallel [(set (match_operand 0 "" "")
686 (call (match_operand 1 "memory_operand" "")
687 (match_operand 2 "general_operand" "")))
689 (use (match_operand 3 "" ""))])]
692 if (operands[3] == NULL_RTX)
693 operands[3] = const0_rtx;
697 (define_insn "*sibcall_insn"
698 [(call (mem:DI (match_operand:DI 0 "" "X"))
699 (match_operand 1 "" ""))
701 (use (match_operand 2 "" ""))]
702 "GET_CODE (operands[0]) == SYMBOL_REF"
704 [(set_attr "v8type" "branch")
705 (set_attr "type" "branch")]
709 (define_insn "*sibcall_value_insn"
710 [(set (match_operand 0 "" "")
711 (call (mem:DI (match_operand 1 "" "X"))
712 (match_operand 2 "" "")))
714 (use (match_operand 3 "" ""))]
715 "GET_CODE (operands[1]) == SYMBOL_REF"
717 [(set_attr "v8type" "branch")
718 (set_attr "type" "branch")]
721 ;; Call subroutine returning any type.
723 (define_expand "untyped_call"
724 [(parallel [(call (match_operand 0 "")
727 (match_operand 2 "")])]
732 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
734 for (i = 0; i < XVECLEN (operands[2], 0); i++)
736 rtx set = XVECEXP (operands[2], 0, i);
737 emit_move_insn (SET_DEST (set), SET_SRC (set));
740 /* The optimizer does not know that the call sets the function value
741 registers we stored in the result block. We avoid problems by
742 claiming that all hard registers are used and clobbered at this
744 emit_insn (gen_blockage ());
748 ;; -------------------------------------------------------------------
750 ;; -------------------------------------------------------------------
752 (define_expand "mov<mode>"
753 [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
754 (match_operand:SHORT 1 "general_operand" ""))]
757 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
758 operands[1] = force_reg (<MODE>mode, operands[1]);
762 (define_insn "*mov<mode>_aarch64"
763 [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r, *w,r,*w, m, m, r,*w,*w")
764 (match_operand:SHORT 1 "general_operand" " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
765 "(register_operand (operands[0], <MODE>mode)
766 || aarch64_reg_or_zero (operands[1], <MODE>mode))"
768 switch (which_alternative)
771 return "mov\t%w0, %w1";
773 return "mov\t%w0, %1";
775 return aarch64_output_scalar_simd_mov_immediate (operands[1],
778 return "ldr<size>\t%w0, %1";
780 return "ldr\t%<size>0, %1";
782 return "str<size>\t%w1, %0";
784 return "str\t%<size>1, %0";
786 return "umov\t%w0, %1.<v>[0]";
788 return "dup\t%0.<Vallxd>, %w1";
790 return "dup\t%<Vetype>0, %1.<v>[0]";
795 [(set_attr "v8type" "move,alu,alu,load1,load1,store1,store1,*,*,*")
796 (set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
797 neon_from_gp<q>,neon_from_gp<q>, neon_dup")
798 (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")
799 (set_attr "mode" "<MODE>")]
802 (define_expand "mov<mode>"
803 [(set (match_operand:GPI 0 "nonimmediate_operand" "")
804 (match_operand:GPI 1 "general_operand" ""))]
807 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
808 operands[1] = force_reg (<MODE>mode, operands[1]);
810 if (CONSTANT_P (operands[1]))
812 aarch64_expand_mov_immediate (operands[0], operands[1]);
818 (define_insn "*movsi_aarch64"
819 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m, m,r,r ,*w, r,*w")
820 (match_operand:SI 1 "aarch64_mov_operand" " r,r,k,M,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
821 "(register_operand (operands[0], SImode)
822 || aarch64_reg_or_zero (operands[1], SImode))"
837 [(set_attr "v8type" "move,move,move,alu,load1,load1,store1,store1,adr,adr,fmov,fmov,fmov")
838 (set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
839 adr,adr,fmov,fmov,fmov")
840 (set_attr "mode" "SI")
841 (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
844 (define_insn "*movdi_aarch64"
845 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m, m,r,r, *w, r,*w,w")
846 (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))]
847 "(register_operand (operands[0], DImode)
848 || aarch64_reg_or_zero (operands[1], DImode))"
864 [(set_attr "v8type" "move,move,move,alu,load1,load1,store1,store1,adr,adr,fmov,fmov,fmov,fmov")
865 (set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
866 adr,adr,fmov,fmov,fmov,fmov")
867 (set_attr "mode" "DI")
868 (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
869 (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
872 (define_insn "insv_imm<mode>"
873 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
875 (match_operand:GPI 1 "const_int_operand" "n"))
876 (match_operand:GPI 2 "const_int_operand" "n"))]
877 "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
878 && UINTVAL (operands[1]) % 16 == 0"
879 "movk\\t%<w>0, %X2, lsl %1"
880 [(set_attr "v8type" "movk")
881 (set_attr "type" "mov_imm")
882 (set_attr "mode" "<MODE>")]
885 (define_expand "movti"
886 [(set (match_operand:TI 0 "nonimmediate_operand" "")
887 (match_operand:TI 1 "general_operand" ""))]
890 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
891 operands[1] = force_reg (TImode, operands[1]);
895 (define_insn "*movti_aarch64"
896 [(set (match_operand:TI 0
897 "nonimmediate_operand" "=r, *w,r ,*w,r ,Ump,Ump,*w,m")
899 "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r ,Z , m,*w"))]
900 "(register_operand (operands[0], TImode)
901 || aarch64_reg_or_zero (operands[1], TImode))"
906 orr\\t%0.16b, %1.16b, %1.16b
912 [(set_attr "v8type" "move2,fmovi2f,fmovf2i,*, \
913 load2,store2,store2,fpsimd_load,fpsimd_store")
914 (set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \
915 load2,store2,store2,f_loadd,f_stored")
916 (set_attr "mode" "DI,DI,DI,TI,DI,DI,DI,TI,TI")
917 (set_attr "length" "8,8,8,4,4,4,4,4,4")
918 (set_attr "simd" "*,*,*,yes,*,*,*,*,*")
919 (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
922 ;; Split a TImode register-register or register-immediate move into
923 ;; its component DImode pieces, taking care to handle overlapping
924 ;; source and dest registers.
926 [(set (match_operand:TI 0 "register_operand" "")
927 (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
928 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
931 aarch64_split_128bit_move (operands[0], operands[1]);
935 (define_expand "mov<mode>"
936 [(set (match_operand:GPF 0 "nonimmediate_operand" "")
937 (match_operand:GPF 1 "general_operand" ""))]
942 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
946 if (GET_CODE (operands[0]) == MEM)
947 operands[1] = force_reg (<MODE>mode, operands[1]);
951 (define_insn "*movsf_aarch64"
952 [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
953 (match_operand:SF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
954 "TARGET_FLOAT && (register_operand (operands[0], SFmode)
955 || register_operand (operands[1], SFmode))"
966 [(set_attr "v8type" "fmovi2f,fmovf2i,\
967 fmov,fconst,fpsimd_load,\
968 fpsimd_store,fpsimd_load,fpsimd_store,fmov")
969 (set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
970 f_loads,f_stores,f_loads,f_stores,fmov")
971 (set_attr "mode" "SF")]
974 (define_insn "*movdf_aarch64"
975 [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
976 (match_operand:DF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
977 "TARGET_FLOAT && (register_operand (operands[0], DFmode)
978 || register_operand (operands[1], DFmode))"
989 [(set_attr "v8type" "fmovi2f,fmovf2i,\
990 fmov,fconst,fpsimd_load,\
991 fpsimd_store,fpsimd_load,fpsimd_store,move")
992 (set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
993 f_loadd,f_stored,f_loadd,f_stored,mov_reg")
994 (set_attr "mode" "DF")]
997 (define_expand "movtf"
998 [(set (match_operand:TF 0 "nonimmediate_operand" "")
999 (match_operand:TF 1 "general_operand" ""))]
1004 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
1008 if (GET_CODE (operands[0]) == MEM)
1009 operands[1] = force_reg (TFmode, operands[1]);
1013 (define_insn "*movtf_aarch64"
1014 [(set (match_operand:TF 0
1015 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
1017 "general_operand" " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
1018 "TARGET_FLOAT && (register_operand (operands[0], TFmode)
1019 || register_operand (operands[1], TFmode))"
1021 orr\\t%0.16b, %1.16b, %1.16b
1031 [(set_attr "v8type" "logic,move2,fmovi2f,fmovf2i,fconst,fconst,fpsimd_load,fpsimd_store,fpsimd_load2,fpsimd_store2")
1032 (set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,fconstd,fconstd,\
1033 f_loadd,f_stored,neon_load1_2reg,neon_store1_2reg")
1034 (set_attr "mode" "DF,DF,DF,DF,DF,DF,TF,TF,DF,DF")
1035 (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
1036 (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
1037 (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
1041 [(set (match_operand:TF 0 "register_operand" "")
1042 (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
1043 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
1046 aarch64_split_128bit_move (operands[0], operands[1]);
1051 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1052 ;; fairly lax checking on the second memory operation.
1053 (define_insn "load_pair<mode>"
1054 [(set (match_operand:GPI 0 "register_operand" "=r")
1055 (match_operand:GPI 1 "aarch64_mem_pair_operand" "Ump"))
1056 (set (match_operand:GPI 2 "register_operand" "=r")
1057 (match_operand:GPI 3 "memory_operand" "m"))]
1058 "rtx_equal_p (XEXP (operands[3], 0),
1059 plus_constant (Pmode,
1060 XEXP (operands[1], 0),
1061 GET_MODE_SIZE (<MODE>mode)))"
1062 "ldp\\t%<w>0, %<w>2, %1"
1063 [(set_attr "v8type" "load2")
1064 (set_attr "type" "load2")
1065 (set_attr "mode" "<MODE>")]
1068 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1069 ;; fairly lax checking on the second memory operation.
1070 (define_insn "store_pair<mode>"
1071 [(set (match_operand:GPI 0 "aarch64_mem_pair_operand" "=Ump")
1072 (match_operand:GPI 1 "register_operand" "r"))
1073 (set (match_operand:GPI 2 "memory_operand" "=m")
1074 (match_operand:GPI 3 "register_operand" "r"))]
1075 "rtx_equal_p (XEXP (operands[2], 0),
1076 plus_constant (Pmode,
1077 XEXP (operands[0], 0),
1078 GET_MODE_SIZE (<MODE>mode)))"
1079 "stp\\t%<w>1, %<w>3, %0"
1080 [(set_attr "v8type" "store2")
1081 (set_attr "type" "store2")
1082 (set_attr "mode" "<MODE>")]
1085 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1086 ;; fairly lax checking on the second memory operation.
1087 (define_insn "load_pair<mode>"
1088 [(set (match_operand:GPF 0 "register_operand" "=w")
1089 (match_operand:GPF 1 "aarch64_mem_pair_operand" "Ump"))
1090 (set (match_operand:GPF 2 "register_operand" "=w")
1091 (match_operand:GPF 3 "memory_operand" "m"))]
1092 "rtx_equal_p (XEXP (operands[3], 0),
1093 plus_constant (Pmode,
1094 XEXP (operands[1], 0),
1095 GET_MODE_SIZE (<MODE>mode)))"
1096 "ldp\\t%<w>0, %<w>2, %1"
1097 [(set_attr "v8type" "fpsimd_load2")
1098 (set_attr "type" "neon_load1_2reg<q>")
1099 (set_attr "mode" "<MODE>")]
1102 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1103 ;; fairly lax checking on the second memory operation.
1104 (define_insn "store_pair<mode>"
1105 [(set (match_operand:GPF 0 "aarch64_mem_pair_operand" "=Ump")
1106 (match_operand:GPF 1 "register_operand" "w"))
1107 (set (match_operand:GPF 2 "memory_operand" "=m")
1108 (match_operand:GPF 3 "register_operand" "w"))]
1109 "rtx_equal_p (XEXP (operands[2], 0),
1110 plus_constant (Pmode,
1111 XEXP (operands[0], 0),
1112 GET_MODE_SIZE (<MODE>mode)))"
1113 "stp\\t%<w>1, %<w>3, %0"
1114 [(set_attr "v8type" "fpsimd_store2")
1115 (set_attr "type" "neon_store1_2reg<q>")
1116 (set_attr "mode" "<MODE>")]
1119 ;; Load pair with writeback. This is primarily used in function epilogues
1120 ;; when restoring [fp,lr]
1121 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
1123 [(set (match_operand:P 0 "register_operand" "=k")
1124 (plus:P (match_operand:P 1 "register_operand" "0")
1125 (match_operand:P 4 "const_int_operand" "n")))
1126 (set (match_operand:GPI 2 "register_operand" "=r")
1127 (mem:GPI (plus:P (match_dup 1)
1129 (set (match_operand:GPI 3 "register_operand" "=r")
1130 (mem:GPI (plus:P (match_dup 1)
1131 (match_operand:P 5 "const_int_operand" "n"))))])]
1132 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1133 "ldp\\t%<w>2, %<w>3, [%1], %4"
1134 [(set_attr "v8type" "load2")
1135 (set_attr "type" "load2")
1136 (set_attr "mode" "<GPI:MODE>")]
1139 ;; Store pair with writeback. This is primarily used in function prologues
1140 ;; when saving [fp,lr]
1141 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
1143 [(set (match_operand:P 0 "register_operand" "=&k")
1144 (plus:P (match_operand:P 1 "register_operand" "0")
1145 (match_operand:P 4 "const_int_operand" "n")))
1146 (set (mem:GPI (plus:P (match_dup 0)
1148 (match_operand:GPI 2 "register_operand" "r"))
1149 (set (mem:GPI (plus:P (match_dup 0)
1150 (match_operand:P 5 "const_int_operand" "n")))
1151 (match_operand:GPI 3 "register_operand" "r"))])]
1152 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1153 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1154 [(set_attr "v8type" "store2")
1155 (set_attr "type" "store2")
1156 (set_attr "mode" "<GPI:MODE>")]
1159 ;; -------------------------------------------------------------------
1160 ;; Sign/Zero extension
1161 ;; -------------------------------------------------------------------
1163 (define_expand "<optab>sidi2"
1164 [(set (match_operand:DI 0 "register_operand")
1165 (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1169 (define_insn "*extendsidi2_aarch64"
1170 [(set (match_operand:DI 0 "register_operand" "=r,r")
1171 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1176 [(set_attr "v8type" "extend,load1")
1177 (set_attr "type" "extend,load1")
1178 (set_attr "mode" "DI")]
1181 (define_insn "*zero_extendsidi2_aarch64"
1182 [(set (match_operand:DI 0 "register_operand" "=r,r")
1183 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1188 [(set_attr "v8type" "extend,load1")
1189 (set_attr "type" "extend,load1")
1190 (set_attr "mode" "DI")]
1193 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1194 [(set (match_operand:GPI 0 "register_operand")
1195 (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1199 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1200 [(set (match_operand:GPI 0 "register_operand" "=r,r")
1201 (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1204 sxt<SHORT:size>\t%<GPI:w>0, %w1
1205 ldrs<SHORT:size>\t%<GPI:w>0, %1"
1206 [(set_attr "v8type" "extend,load1")
1207 (set_attr "type" "extend,load1")
1208 (set_attr "mode" "<GPI:MODE>")]
1211 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1212 [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1213 (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1216 uxt<SHORT:size>\t%<GPI:w>0, %w1
1217 ldr<SHORT:size>\t%w0, %1
1218 ldr\t%<SHORT:size>0, %1"
1219 [(set_attr "v8type" "extend,load1,load1")
1220 (set_attr "type" "extend,load1,load1")
1221 (set_attr "mode" "<GPI:MODE>")]
1224 (define_expand "<optab>qihi2"
1225 [(set (match_operand:HI 0 "register_operand")
1226 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1230 (define_insn "*<optab>qihi2_aarch64"
1231 [(set (match_operand:HI 0 "register_operand" "=r,r")
1232 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1237 [(set_attr "v8type" "extend,load1")
1238 (set_attr "type" "extend,load1")
1239 (set_attr "mode" "HI")]
1242 ;; -------------------------------------------------------------------
1243 ;; Simple arithmetic
1244 ;; -------------------------------------------------------------------
1246 (define_expand "add<mode>3"
1248 (match_operand:GPI 0 "register_operand" "")
1249 (plus:GPI (match_operand:GPI 1 "register_operand" "")
1250 (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1253 if (! aarch64_plus_operand (operands[2], VOIDmode))
1255 rtx subtarget = ((optimize && can_create_pseudo_p ())
1256 ? gen_reg_rtx (<MODE>mode) : operands[0]);
1257 HOST_WIDE_INT imm = INTVAL (operands[2]);
1260 imm = -(-imm & ~0xfff);
1264 emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1265 operands[1] = subtarget;
1266 operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1271 (define_insn "*addsi3_aarch64"
1273 (match_operand:SI 0 "register_operand" "=rk,rk,rk")
1275 (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1276 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J")))]
1281 sub\\t%w0, %w1, #%n2"
1282 [(set_attr "v8type" "alu")
1283 (set_attr "type" "alu_imm,alu_reg,alu_imm")
1284 (set_attr "mode" "SI")]
1287 ;; zero_extend version of above
1288 (define_insn "*addsi3_aarch64_uxtw"
1290 (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1292 (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1293 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1298 sub\\t%w0, %w1, #%n2"
1299 [(set_attr "v8type" "alu")
1300 (set_attr "type" "alu_imm,alu_reg,alu_imm")
1301 (set_attr "mode" "SI")]
1304 (define_insn "*adddi3_aarch64"
1306 (match_operand:DI 0 "register_operand" "=rk,rk,rk,!w")
1308 (match_operand:DI 1 "register_operand" "%rk,rk,rk,!w")
1309 (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,!w")))]
1314 sub\\t%x0, %x1, #%n2
1315 add\\t%d0, %d1, %d2"
1316 [(set_attr "v8type" "alu")
1317 (set_attr "type" "alu_imm,alu_reg,alu_imm,alu_reg")
1318 (set_attr "mode" "DI")
1319 (set_attr "simd" "*,*,*,yes")]
1322 (define_insn "*add<mode>3_compare0"
1323 [(set (reg:CC_NZ CC_REGNUM)
1325 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1326 (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1328 (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1329 (plus:GPI (match_dup 1) (match_dup 2)))]
1332 adds\\t%<w>0, %<w>1, %<w>2
1333 adds\\t%<w>0, %<w>1, %<w>2
1334 subs\\t%<w>0, %<w>1, #%n2"
1335 [(set_attr "v8type" "alus")
1336 (set_attr "type" "alus_reg,alus_imm,alus_imm")
1337 (set_attr "mode" "<MODE>")]
1340 ;; zero_extend version of above
1341 (define_insn "*addsi3_compare0_uxtw"
1342 [(set (reg:CC_NZ CC_REGNUM)
1344 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1345 (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1347 (set (match_operand:DI 0 "register_operand" "=r,r,r")
1348 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1351 adds\\t%w0, %w1, %w2
1352 adds\\t%w0, %w1, %w2
1353 subs\\t%w0, %w1, #%n2"
1354 [(set_attr "v8type" "alus")
1355 (set_attr "type" "alus_reg,alus_imm,alus_imm")
1356 (set_attr "mode" "SI")]
1359 (define_insn "*adds_mul_imm_<mode>"
1360 [(set (reg:CC_NZ CC_REGNUM)
1363 (match_operand:GPI 1 "register_operand" "r")
1364 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1365 (match_operand:GPI 3 "register_operand" "r"))
1367 (set (match_operand:GPI 0 "register_operand" "=r")
1368 (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1371 "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1372 [(set_attr "v8type" "alus_shift")
1373 (set_attr "type" "alus_shift_imm")
1374 (set_attr "mode" "<MODE>")]
1377 (define_insn "*subs_mul_imm_<mode>"
1378 [(set (reg:CC_NZ CC_REGNUM)
1380 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1382 (match_operand:GPI 2 "register_operand" "r")
1383 (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1385 (set (match_operand:GPI 0 "register_operand" "=r")
1386 (minus:GPI (match_dup 1)
1387 (mult:GPI (match_dup 2) (match_dup 3))))]
1389 "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1390 [(set_attr "v8type" "alus_shift")
1391 (set_attr "type" "alus_shift_imm")
1392 (set_attr "mode" "<MODE>")]
1395 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1396 [(set (reg:CC_NZ CC_REGNUM)
1399 (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1400 (match_operand:GPI 2 "register_operand" "r"))
1402 (set (match_operand:GPI 0 "register_operand" "=r")
1403 (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1405 "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1406 [(set_attr "v8type" "alus_ext")
1407 (set_attr "type" "alus_ext")
1408 (set_attr "mode" "<GPI:MODE>")]
1411 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1412 [(set (reg:CC_NZ CC_REGNUM)
1414 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1416 (match_operand:ALLX 2 "register_operand" "r")))
1418 (set (match_operand:GPI 0 "register_operand" "=r")
1419 (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1421 "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1422 [(set_attr "v8type" "alus_ext")
1423 (set_attr "type" "alus_ext")
1424 (set_attr "mode" "<GPI:MODE>")]
1427 (define_insn "*adds_<optab><mode>_multp2"
1428 [(set (reg:CC_NZ CC_REGNUM)
1430 (plus:GPI (ANY_EXTRACT:GPI
1431 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1432 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1433 (match_operand 3 "const_int_operand" "n")
1435 (match_operand:GPI 4 "register_operand" "r"))
1437 (set (match_operand:GPI 0 "register_operand" "=r")
1438 (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1442 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1443 "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1444 [(set_attr "v8type" "alus_ext")
1445 (set_attr "type" "alus_ext")
1446 (set_attr "mode" "<MODE>")]
1449 (define_insn "*subs_<optab><mode>_multp2"
1450 [(set (reg:CC_NZ CC_REGNUM)
1452 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1454 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1455 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1456 (match_operand 3 "const_int_operand" "n")
1459 (set (match_operand:GPI 0 "register_operand" "=r")
1460 (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1461 (mult:GPI (match_dup 1) (match_dup 2))
1464 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1465 "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1466 [(set_attr "v8type" "alus_ext")
1467 (set_attr "type" "alus_ext")
1468 (set_attr "mode" "<MODE>")]
1471 (define_insn "*add<mode>3nr_compare0"
1472 [(set (reg:CC_NZ CC_REGNUM)
1474 (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1475 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1482 [(set_attr "v8type" "alus")
1483 (set_attr "type" "alus_reg,alus_imm,alus_imm")
1484 (set_attr "mode" "<MODE>")]
1487 (define_insn "*compare_neg<mode>"
1488 [(set (reg:CC_SWP CC_REGNUM)
1490 (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1491 (match_operand:GPI 1 "register_operand" "r")))]
1493 "cmn\\t%<w>1, %<w>0"
1494 [(set_attr "v8type" "alus")
1495 (set_attr "type" "alus_reg")
1496 (set_attr "mode" "<MODE>")]
1499 (define_insn "*add_<shift>_<mode>"
1500 [(set (match_operand:GPI 0 "register_operand" "=r")
1501 (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1502 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1503 (match_operand:GPI 3 "register_operand" "r")))]
1505 "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1506 [(set_attr "v8type" "alu_shift")
1507 (set_attr "type" "alu_shift_imm")
1508 (set_attr "mode" "<MODE>")]
1511 ;; zero_extend version of above
1512 (define_insn "*add_<shift>_si_uxtw"
1513 [(set (match_operand:DI 0 "register_operand" "=r")
1515 (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1516 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1517 (match_operand:SI 3 "register_operand" "r"))))]
1519 "add\\t%w0, %w3, %w1, <shift> %2"
1520 [(set_attr "v8type" "alu_shift")
1521 (set_attr "type" "alu_shift_imm")
1522 (set_attr "mode" "SI")]
1525 (define_insn "*add_mul_imm_<mode>"
1526 [(set (match_operand:GPI 0 "register_operand" "=r")
1527 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1528 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1529 (match_operand:GPI 3 "register_operand" "r")))]
1531 "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1532 [(set_attr "v8type" "alu_shift")
1533 (set_attr "type" "alu_shift_imm")
1534 (set_attr "mode" "<MODE>")]
1537 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1538 [(set (match_operand:GPI 0 "register_operand" "=rk")
1539 (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1540 (match_operand:GPI 2 "register_operand" "r")))]
1542 "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1543 [(set_attr "v8type" "alu_ext")
1544 (set_attr "type" "alu_ext")
1545 (set_attr "mode" "<GPI:MODE>")]
1548 ;; zero_extend version of above
1549 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1550 [(set (match_operand:DI 0 "register_operand" "=rk")
1552 (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1553 (match_operand:GPI 2 "register_operand" "r"))))]
1555 "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1556 [(set_attr "v8type" "alu_ext")
1557 (set_attr "type" "alu_ext")
1558 (set_attr "mode" "SI")]
1561 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1562 [(set (match_operand:GPI 0 "register_operand" "=rk")
1563 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1564 (match_operand:ALLX 1 "register_operand" "r"))
1565 (match_operand 2 "aarch64_imm3" "Ui3"))
1566 (match_operand:GPI 3 "register_operand" "r")))]
1568 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1569 [(set_attr "v8type" "alu_ext")
1570 (set_attr "type" "alu_ext")
1571 (set_attr "mode" "<GPI:MODE>")]
1574 ;; zero_extend version of above
1575 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1576 [(set (match_operand:DI 0 "register_operand" "=rk")
1578 (plus:SI (ashift:SI (ANY_EXTEND:SI
1579 (match_operand:SHORT 1 "register_operand" "r"))
1580 (match_operand 2 "aarch64_imm3" "Ui3"))
1581 (match_operand:SI 3 "register_operand" "r"))))]
1583 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1584 [(set_attr "v8type" "alu_ext")
1585 (set_attr "type" "alu_ext")
1586 (set_attr "mode" "SI")]
1589 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1590 [(set (match_operand:GPI 0 "register_operand" "=rk")
1591 (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1592 (match_operand:ALLX 1 "register_operand" "r"))
1593 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1594 (match_operand:GPI 3 "register_operand" "r")))]
1596 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1597 [(set_attr "v8type" "alu_ext")
1598 (set_attr "type" "alu_ext")
1599 (set_attr "mode" "<GPI:MODE>")]
1602 ;; zero_extend version of above
1603 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1604 [(set (match_operand:DI 0 "register_operand" "=rk")
1605 (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1606 (match_operand:SHORT 1 "register_operand" "r"))
1607 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1608 (match_operand:SI 3 "register_operand" "r"))))]
1610 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1611 [(set_attr "v8type" "alu_ext")
1612 (set_attr "type" "alu_ext")
1613 (set_attr "mode" "SI")]
1616 (define_insn "*add_<optab><mode>_multp2"
1617 [(set (match_operand:GPI 0 "register_operand" "=rk")
1618 (plus:GPI (ANY_EXTRACT:GPI
1619 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1620 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1621 (match_operand 3 "const_int_operand" "n")
1623 (match_operand:GPI 4 "register_operand" "r")))]
1624 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1625 "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1626 [(set_attr "v8type" "alu_ext")
1627 (set_attr "type" "alu_ext")
1628 (set_attr "mode" "<MODE>")]
1631 ;; zero_extend version of above
1632 (define_insn "*add_<optab>si_multp2_uxtw"
1633 [(set (match_operand:DI 0 "register_operand" "=rk")
1635 (plus:SI (ANY_EXTRACT:SI
1636 (mult:SI (match_operand:SI 1 "register_operand" "r")
1637 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1638 (match_operand 3 "const_int_operand" "n")
1640 (match_operand:SI 4 "register_operand" "r"))))]
1641 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1642 "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1643 [(set_attr "v8type" "alu_ext")
1644 (set_attr "type" "alu_ext")
1645 (set_attr "mode" "SI")]
1648 (define_insn "*add<mode>3_carryin"
1650 (match_operand:GPI 0 "register_operand" "=r")
1651 (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1653 (match_operand:GPI 1 "register_operand" "r")
1654 (match_operand:GPI 2 "register_operand" "r"))))]
1656 "adc\\t%<w>0, %<w>1, %<w>2"
1657 [(set_attr "v8type" "adc")
1658 (set_attr "type" "adc_reg")
1659 (set_attr "mode" "<MODE>")]
1662 ;; zero_extend version of above
1663 (define_insn "*addsi3_carryin_uxtw"
1665 (match_operand:DI 0 "register_operand" "=r")
1667 (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1669 (match_operand:SI 1 "register_operand" "r")
1670 (match_operand:SI 2 "register_operand" "r")))))]
1672 "adc\\t%w0, %w1, %w2"
1673 [(set_attr "v8type" "adc")
1674 (set_attr "type" "adc_reg")
1675 (set_attr "mode" "SI")]
1678 (define_insn "*add<mode>3_carryin_alt1"
1680 (match_operand:GPI 0 "register_operand" "=r")
1682 (match_operand:GPI 1 "register_operand" "r")
1683 (match_operand:GPI 2 "register_operand" "r"))
1684 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1686 "adc\\t%<w>0, %<w>1, %<w>2"
1687 [(set_attr "v8type" "adc")
1688 (set_attr "type" "adc_reg")
1689 (set_attr "mode" "<MODE>")]
1692 ;; zero_extend version of above
1693 (define_insn "*addsi3_carryin_alt1_uxtw"
1695 (match_operand:DI 0 "register_operand" "=r")
1698 (match_operand:SI 1 "register_operand" "r")
1699 (match_operand:SI 2 "register_operand" "r"))
1700 (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1702 "adc\\t%w0, %w1, %w2"
1703 [(set_attr "v8type" "adc")
1704 (set_attr "type" "adc_reg")
1705 (set_attr "mode" "SI")]
1708 (define_insn "*add<mode>3_carryin_alt2"
1710 (match_operand:GPI 0 "register_operand" "=r")
1712 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1713 (match_operand:GPI 1 "register_operand" "r"))
1714 (match_operand:GPI 2 "register_operand" "r")))]
1716 "adc\\t%<w>0, %<w>1, %<w>2"
1717 [(set_attr "v8type" "adc")
1718 (set_attr "type" "adc_reg")
1719 (set_attr "mode" "<MODE>")]
1722 ;; zero_extend version of above
1723 (define_insn "*addsi3_carryin_alt2_uxtw"
1725 (match_operand:DI 0 "register_operand" "=r")
1728 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1729 (match_operand:SI 1 "register_operand" "r"))
1730 (match_operand:SI 2 "register_operand" "r"))))]
1732 "adc\\t%w0, %w1, %w2"
1733 [(set_attr "v8type" "adc")
1734 (set_attr "type" "adc_reg")
1735 (set_attr "mode" "SI")]
1738 (define_insn "*add<mode>3_carryin_alt3"
1740 (match_operand:GPI 0 "register_operand" "=r")
1742 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1743 (match_operand:GPI 2 "register_operand" "r"))
1744 (match_operand:GPI 1 "register_operand" "r")))]
1746 "adc\\t%<w>0, %<w>1, %<w>2"
1747 [(set_attr "v8type" "adc")
1748 (set_attr "type" "adc_reg")
1749 (set_attr "mode" "<MODE>")]
1752 ;; zero_extend version of above
1753 (define_insn "*addsi3_carryin_alt3_uxtw"
1755 (match_operand:DI 0 "register_operand" "=r")
1758 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1759 (match_operand:SI 2 "register_operand" "r"))
1760 (match_operand:SI 1 "register_operand" "r"))))]
1762 "adc\\t%w0, %w1, %w2"
1763 [(set_attr "v8type" "adc")
1764 (set_attr "type" "adc_reg")
1765 (set_attr "mode" "SI")]
1768 (define_insn "*add_uxt<mode>_multp2"
1769 [(set (match_operand:GPI 0 "register_operand" "=rk")
1771 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1772 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1773 (match_operand 3 "const_int_operand" "n"))
1774 (match_operand:GPI 4 "register_operand" "r")))]
1775 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1777 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1778 INTVAL (operands[3])));
1779 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1780 [(set_attr "v8type" "alu_ext")
1781 (set_attr "type" "alu_ext")
1782 (set_attr "mode" "<MODE>")]
1785 ;; zero_extend version of above
1786 (define_insn "*add_uxtsi_multp2_uxtw"
1787 [(set (match_operand:DI 0 "register_operand" "=rk")
1790 (mult:SI (match_operand:SI 1 "register_operand" "r")
1791 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1792 (match_operand 3 "const_int_operand" "n"))
1793 (match_operand:SI 4 "register_operand" "r"))))]
1794 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1796 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1797 INTVAL (operands[3])));
1798 return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1799 [(set_attr "v8type" "alu_ext")
1800 (set_attr "type" "alu_ext")
1801 (set_attr "mode" "SI")]
1804 (define_insn "subsi3"
1805 [(set (match_operand:SI 0 "register_operand" "=rk")
1806 (minus:SI (match_operand:SI 1 "register_operand" "r")
1807 (match_operand:SI 2 "register_operand" "r")))]
1809 "sub\\t%w0, %w1, %w2"
1810 [(set_attr "v8type" "alu")
1811 (set_attr "type" "alu_reg")
1812 (set_attr "mode" "SI")]
1815 ;; zero_extend version of above
1816 (define_insn "*subsi3_uxtw"
1817 [(set (match_operand:DI 0 "register_operand" "=rk")
1819 (minus:SI (match_operand:SI 1 "register_operand" "r")
1820 (match_operand:SI 2 "register_operand" "r"))))]
1822 "sub\\t%w0, %w1, %w2"
1823 [(set_attr "v8type" "alu")
1824 (set_attr "type" "alu_reg")
1825 (set_attr "mode" "SI")]
1828 (define_insn "subdi3"
1829 [(set (match_operand:DI 0 "register_operand" "=rk,!w")
1830 (minus:DI (match_operand:DI 1 "register_operand" "r,!w")
1831 (match_operand:DI 2 "register_operand" "r,!w")))]
1835 sub\\t%d0, %d1, %d2"
1836 [(set_attr "v8type" "alu")
1837 (set_attr "type" "alu_reg")
1838 (set_attr "mode" "DI")
1839 (set_attr "simd" "*,yes")]
1843 (define_insn "*sub<mode>3_compare0"
1844 [(set (reg:CC_NZ CC_REGNUM)
1845 (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1846 (match_operand:GPI 2 "register_operand" "r"))
1848 (set (match_operand:GPI 0 "register_operand" "=r")
1849 (minus:GPI (match_dup 1) (match_dup 2)))]
1851 "subs\\t%<w>0, %<w>1, %<w>2"
1852 [(set_attr "v8type" "alus")
1853 (set_attr "type" "alus_reg")
1854 (set_attr "mode" "<MODE>")]
1857 ;; zero_extend version of above
1858 (define_insn "*subsi3_compare0_uxtw"
1859 [(set (reg:CC_NZ CC_REGNUM)
1860 (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1861 (match_operand:SI 2 "register_operand" "r"))
1863 (set (match_operand:DI 0 "register_operand" "=r")
1864 (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1866 "subs\\t%w0, %w1, %w2"
1867 [(set_attr "v8type" "alus")
1868 (set_attr "type" "alus_reg")
1869 (set_attr "mode" "SI")]
1872 (define_insn "*sub_<shift>_<mode>"
1873 [(set (match_operand:GPI 0 "register_operand" "=r")
1874 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1876 (match_operand:GPI 1 "register_operand" "r")
1877 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1879 "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1880 [(set_attr "v8type" "alu_shift")
1881 (set_attr "type" "alu_shift_imm")
1882 (set_attr "mode" "<MODE>")]
1885 ;; zero_extend version of above
1886 (define_insn "*sub_<shift>_si_uxtw"
1887 [(set (match_operand:DI 0 "register_operand" "=r")
1889 (minus:SI (match_operand:SI 3 "register_operand" "r")
1891 (match_operand:SI 1 "register_operand" "r")
1892 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1894 "sub\\t%w0, %w3, %w1, <shift> %2"
1895 [(set_attr "v8type" "alu_shift")
1896 (set_attr "type" "alu_shift_imm")
1897 (set_attr "mode" "SI")]
1900 (define_insn "*sub_mul_imm_<mode>"
1901 [(set (match_operand:GPI 0 "register_operand" "=r")
1902 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1904 (match_operand:GPI 1 "register_operand" "r")
1905 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1907 "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1908 [(set_attr "v8type" "alu_shift")
1909 (set_attr "type" "alu_shift_imm")
1910 (set_attr "mode" "<MODE>")]
1913 ;; zero_extend version of above
1914 (define_insn "*sub_mul_imm_si_uxtw"
1915 [(set (match_operand:DI 0 "register_operand" "=r")
1917 (minus:SI (match_operand:SI 3 "register_operand" "r")
1919 (match_operand:SI 1 "register_operand" "r")
1920 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
1922 "sub\\t%w0, %w3, %w1, lsl %p2"
1923 [(set_attr "v8type" "alu_shift")
1924 (set_attr "type" "alu_shift_imm")
1925 (set_attr "mode" "SI")]
1928 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
1929 [(set (match_operand:GPI 0 "register_operand" "=rk")
1930 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1932 (match_operand:ALLX 2 "register_operand" "r"))))]
1934 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1935 [(set_attr "v8type" "alu_ext")
1936 (set_attr "type" "alu_ext")
1937 (set_attr "mode" "<GPI:MODE>")]
1940 ;; zero_extend version of above
1941 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
1942 [(set (match_operand:DI 0 "register_operand" "=rk")
1944 (minus:SI (match_operand:SI 1 "register_operand" "r")
1946 (match_operand:SHORT 2 "register_operand" "r")))))]
1948 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
1949 [(set_attr "v8type" "alu_ext")
1950 (set_attr "type" "alu_ext")
1951 (set_attr "mode" "SI")]
1954 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
1955 [(set (match_operand:GPI 0 "register_operand" "=rk")
1956 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1957 (ashift:GPI (ANY_EXTEND:GPI
1958 (match_operand:ALLX 2 "register_operand" "r"))
1959 (match_operand 3 "aarch64_imm3" "Ui3"))))]
1961 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1962 [(set_attr "v8type" "alu_ext")
1963 (set_attr "type" "alu_ext")
1964 (set_attr "mode" "<GPI:MODE>")]
1967 ;; zero_extend version of above
1968 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
1969 [(set (match_operand:DI 0 "register_operand" "=rk")
1971 (minus:SI (match_operand:SI 1 "register_operand" "r")
1972 (ashift:SI (ANY_EXTEND:SI
1973 (match_operand:SHORT 2 "register_operand" "r"))
1974 (match_operand 3 "aarch64_imm3" "Ui3")))))]
1976 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
1977 [(set_attr "v8type" "alu_ext")
1978 (set_attr "type" "alu_ext")
1979 (set_attr "mode" "SI")]
1982 (define_insn "*sub_<optab><mode>_multp2"
1983 [(set (match_operand:GPI 0 "register_operand" "=rk")
1984 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1986 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1987 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1988 (match_operand 3 "const_int_operand" "n")
1990 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1991 "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1992 [(set_attr "v8type" "alu_ext")
1993 (set_attr "type" "alu_ext")
1994 (set_attr "mode" "<MODE>")]
1997 ;; zero_extend version of above
1998 (define_insn "*sub_<optab>si_multp2_uxtw"
1999 [(set (match_operand:DI 0 "register_operand" "=rk")
2001 (minus:SI (match_operand:SI 4 "register_operand" "r")
2003 (mult:SI (match_operand:SI 1 "register_operand" "r")
2004 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2005 (match_operand 3 "const_int_operand" "n")
2007 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
2008 "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
2009 [(set_attr "v8type" "alu_ext")
2010 (set_attr "type" "alu_ext")
2011 (set_attr "mode" "SI")]
2014 (define_insn "*sub<mode>3_carryin"
2016 (match_operand:GPI 0 "register_operand" "=r")
2017 (minus:GPI (minus:GPI
2018 (match_operand:GPI 1 "register_operand" "r")
2019 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2020 (match_operand:GPI 2 "register_operand" "r")))]
2022 "sbc\\t%<w>0, %<w>1, %<w>2"
2023 [(set_attr "v8type" "adc")
2024 (set_attr "type" "adc_reg")
2025 (set_attr "mode" "<MODE>")]
2028 ;; zero_extend version of the above
2029 (define_insn "*subsi3_carryin_uxtw"
2031 (match_operand:DI 0 "register_operand" "=r")
2034 (match_operand:SI 1 "register_operand" "r")
2035 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2036 (match_operand:SI 2 "register_operand" "r"))))]
2038 "sbc\\t%w0, %w1, %w2"
2039 [(set_attr "v8type" "adc")
2040 (set_attr "type" "adc_reg")
2041 (set_attr "mode" "SI")]
2044 (define_insn "*sub_uxt<mode>_multp2"
2045 [(set (match_operand:GPI 0 "register_operand" "=rk")
2046 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
2048 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2049 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2050 (match_operand 3 "const_int_operand" "n"))))]
2051 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2053 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2054 INTVAL (operands[3])));
2055 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
2056 [(set_attr "v8type" "alu_ext")
2057 (set_attr "type" "alu_ext")
2058 (set_attr "mode" "<MODE>")]
2061 ;; zero_extend version of above
2062 (define_insn "*sub_uxtsi_multp2_uxtw"
2063 [(set (match_operand:DI 0 "register_operand" "=rk")
2065 (minus:SI (match_operand:SI 4 "register_operand" "r")
2067 (mult:SI (match_operand:SI 1 "register_operand" "r")
2068 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2069 (match_operand 3 "const_int_operand" "n")))))]
2070 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2072 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2073 INTVAL (operands[3])));
2074 return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
2075 [(set_attr "v8type" "alu_ext")
2076 (set_attr "type" "alu_ext")
2077 (set_attr "mode" "SI")]
2080 (define_insn_and_split "absdi2"
2081 [(set (match_operand:DI 0 "register_operand" "=r,w")
2082 (abs:DI (match_operand:DI 1 "register_operand" "r,w")))
2083 (clobber (match_scratch:DI 2 "=&r,X"))]
2089 && GP_REGNUM_P (REGNO (operands[0]))
2090 && GP_REGNUM_P (REGNO (operands[1]))"
2093 emit_insn (gen_rtx_SET (VOIDmode, operands[2],
2094 gen_rtx_XOR (DImode,
2095 gen_rtx_ASHIFTRT (DImode,
2099 emit_insn (gen_rtx_SET (VOIDmode,
2101 gen_rtx_MINUS (DImode,
2103 gen_rtx_ASHIFTRT (DImode,
2108 [(set_attr "v8type" "alu")
2109 (set_attr "type" "alu_reg")
2110 (set_attr "mode" "DI")]
2113 (define_insn "neg<mode>2"
2114 [(set (match_operand:GPI 0 "register_operand" "=r,w")
2115 (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
2119 neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
2120 [(set_attr "v8type" "alu")
2121 (set_attr "type" "alu_reg, neon_neg<q>")
2122 (set_attr "simd" "*,yes")
2123 (set_attr "mode" "<MODE>")]
2126 ;; zero_extend version of above
2127 (define_insn "*negsi2_uxtw"
2128 [(set (match_operand:DI 0 "register_operand" "=r")
2129 (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
2132 [(set_attr "v8type" "alu")
2133 (set_attr "type" "alu_reg")
2134 (set_attr "mode" "SI")]
2137 (define_insn "*ngc<mode>"
2138 [(set (match_operand:GPI 0 "register_operand" "=r")
2139 (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2140 (match_operand:GPI 1 "register_operand" "r")))]
2142 "ngc\\t%<w>0, %<w>1"
2143 [(set_attr "v8type" "adc")
2144 (set_attr "type" "adc_reg")
2145 (set_attr "mode" "<MODE>")]
2148 (define_insn "*ngcsi_uxtw"
2149 [(set (match_operand:DI 0 "register_operand" "=r")
2151 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2152 (match_operand:SI 1 "register_operand" "r"))))]
2155 [(set_attr "v8type" "adc")
2156 (set_attr "type" "adc_reg")
2157 (set_attr "mode" "SI")]
2160 (define_insn "*neg<mode>2_compare0"
2161 [(set (reg:CC_NZ CC_REGNUM)
2162 (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2164 (set (match_operand:GPI 0 "register_operand" "=r")
2165 (neg:GPI (match_dup 1)))]
2167 "negs\\t%<w>0, %<w>1"
2168 [(set_attr "v8type" "alus")
2169 (set_attr "type" "alus_reg")
2170 (set_attr "mode" "<MODE>")]
2173 ;; zero_extend version of above
2174 (define_insn "*negsi2_compare0_uxtw"
2175 [(set (reg:CC_NZ CC_REGNUM)
2176 (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
2178 (set (match_operand:DI 0 "register_operand" "=r")
2179 (zero_extend:DI (neg:SI (match_dup 1))))]
2182 [(set_attr "v8type" "alus")
2183 (set_attr "type" "alus_reg")
2184 (set_attr "mode" "SI")]
2187 (define_insn "*neg_<shift><mode>3_compare0"
2188 [(set (reg:CC_NZ CC_REGNUM)
2190 (neg:GPI (ASHIFT:GPI
2191 (match_operand:GPI 1 "register_operand" "r")
2192 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2194 (set (match_operand:GPI 0 "register_operand" "=r")
2195 (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2197 "negs\\t%<w>0, %<w>1, <shift> %2"
2198 [(set_attr "v8type" "alus_shift")
2199 (set_attr "type" "alus_shift_imm")
2200 (set_attr "mode" "<MODE>")]
2203 (define_insn "*neg_<shift>_<mode>2"
2204 [(set (match_operand:GPI 0 "register_operand" "=r")
2205 (neg:GPI (ASHIFT:GPI
2206 (match_operand:GPI 1 "register_operand" "r")
2207 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2209 "neg\\t%<w>0, %<w>1, <shift> %2"
2210 [(set_attr "v8type" "alu_shift")
2211 (set_attr "type" "alu_shift_imm")
2212 (set_attr "mode" "<MODE>")]
2215 ;; zero_extend version of above
2216 (define_insn "*neg_<shift>_si2_uxtw"
2217 [(set (match_operand:DI 0 "register_operand" "=r")
2220 (match_operand:SI 1 "register_operand" "r")
2221 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2223 "neg\\t%w0, %w1, <shift> %2"
2224 [(set_attr "v8type" "alu_shift")
2225 (set_attr "type" "alu_shift_imm")
2226 (set_attr "mode" "SI")]
2229 (define_insn "*neg_mul_imm_<mode>2"
2230 [(set (match_operand:GPI 0 "register_operand" "=r")
2232 (match_operand:GPI 1 "register_operand" "r")
2233 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2235 "neg\\t%<w>0, %<w>1, lsl %p2"
2236 [(set_attr "v8type" "alu_shift")
2237 (set_attr "type" "alu_shift_imm")
2238 (set_attr "mode" "<MODE>")]
2241 ;; zero_extend version of above
2242 (define_insn "*neg_mul_imm_si2_uxtw"
2243 [(set (match_operand:DI 0 "register_operand" "=r")
2246 (match_operand:SI 1 "register_operand" "r")
2247 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2249 "neg\\t%w0, %w1, lsl %p2"
2250 [(set_attr "v8type" "alu_shift")
2251 (set_attr "type" "alu_shift_imm")
2252 (set_attr "mode" "SI")]
2255 (define_insn "mul<mode>3"
2256 [(set (match_operand:GPI 0 "register_operand" "=r")
2257 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2258 (match_operand:GPI 2 "register_operand" "r")))]
2260 "mul\\t%<w>0, %<w>1, %<w>2"
2261 [(set_attr "v8type" "mult")
2262 (set_attr "type" "mul")
2263 (set_attr "mode" "<MODE>")]
2266 ;; zero_extend version of above
2267 (define_insn "*mulsi3_uxtw"
2268 [(set (match_operand:DI 0 "register_operand" "=r")
2270 (mult:SI (match_operand:SI 1 "register_operand" "r")
2271 (match_operand:SI 2 "register_operand" "r"))))]
2273 "mul\\t%w0, %w1, %w2"
2274 [(set_attr "v8type" "mult")
2275 (set_attr "type" "mul")
2276 (set_attr "mode" "SI")]
2279 (define_insn "*madd<mode>"
2280 [(set (match_operand:GPI 0 "register_operand" "=r")
2281 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2282 (match_operand:GPI 2 "register_operand" "r"))
2283 (match_operand:GPI 3 "register_operand" "r")))]
2285 "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2286 [(set_attr "v8type" "madd")
2287 (set_attr "type" "mla")
2288 (set_attr "mode" "<MODE>")]
2291 ;; zero_extend version of above
2292 (define_insn "*maddsi_uxtw"
2293 [(set (match_operand:DI 0 "register_operand" "=r")
2295 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2296 (match_operand:SI 2 "register_operand" "r"))
2297 (match_operand:SI 3 "register_operand" "r"))))]
2299 "madd\\t%w0, %w1, %w2, %w3"
2300 [(set_attr "v8type" "madd")
2301 (set_attr "type" "mla")
2302 (set_attr "mode" "SI")]
2305 (define_insn "*msub<mode>"
2306 [(set (match_operand:GPI 0 "register_operand" "=r")
2307 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2308 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2309 (match_operand:GPI 2 "register_operand" "r"))))]
2312 "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2313 [(set_attr "v8type" "madd")
2314 (set_attr "type" "mla")
2315 (set_attr "mode" "<MODE>")]
2318 ;; zero_extend version of above
2319 (define_insn "*msubsi_uxtw"
2320 [(set (match_operand:DI 0 "register_operand" "=r")
2322 (minus:SI (match_operand:SI 3 "register_operand" "r")
2323 (mult:SI (match_operand:SI 1 "register_operand" "r")
2324 (match_operand:SI 2 "register_operand" "r")))))]
2327 "msub\\t%w0, %w1, %w2, %w3"
2328 [(set_attr "v8type" "madd")
2329 (set_attr "type" "mla")
2330 (set_attr "mode" "SI")]
2333 (define_insn "*mul<mode>_neg"
2334 [(set (match_operand:GPI 0 "register_operand" "=r")
2335 (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2336 (match_operand:GPI 2 "register_operand" "r")))]
2339 "mneg\\t%<w>0, %<w>1, %<w>2"
2340 [(set_attr "v8type" "mult")
2341 (set_attr "type" "mul")
2342 (set_attr "mode" "<MODE>")]
2345 ;; zero_extend version of above
2346 (define_insn "*mulsi_neg_uxtw"
2347 [(set (match_operand:DI 0 "register_operand" "=r")
2349 (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2350 (match_operand:SI 2 "register_operand" "r"))))]
2353 "mneg\\t%w0, %w1, %w2"
2354 [(set_attr "v8type" "mult")
2355 (set_attr "type" "mul")
2356 (set_attr "mode" "SI")]
2359 (define_insn "<su_optab>mulsidi3"
2360 [(set (match_operand:DI 0 "register_operand" "=r")
2361 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2362 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2364 "<su>mull\\t%0, %w1, %w2"
2365 [(set_attr "v8type" "mull")
2366 (set_attr "type" "<su>mull")
2367 (set_attr "mode" "DI")]
2370 (define_insn "<su_optab>maddsidi4"
2371 [(set (match_operand:DI 0 "register_operand" "=r")
2373 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2374 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2375 (match_operand:DI 3 "register_operand" "r")))]
2377 "<su>maddl\\t%0, %w1, %w2, %3"
2378 [(set_attr "v8type" "maddl")
2379 (set_attr "type" "<su>mlal")
2380 (set_attr "mode" "DI")]
2383 (define_insn "<su_optab>msubsidi4"
2384 [(set (match_operand:DI 0 "register_operand" "=r")
2386 (match_operand:DI 3 "register_operand" "r")
2387 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2389 (match_operand:SI 2 "register_operand" "r")))))]
2391 "<su>msubl\\t%0, %w1, %w2, %3"
2392 [(set_attr "v8type" "maddl")
2393 (set_attr "type" "<su>mlal")
2394 (set_attr "mode" "DI")]
2397 (define_insn "*<su_optab>mulsidi_neg"
2398 [(set (match_operand:DI 0 "register_operand" "=r")
2400 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2401 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2403 "<su>mnegl\\t%0, %w1, %w2"
2404 [(set_attr "v8type" "mull")
2405 (set_attr "type" "<su>mull")
2406 (set_attr "mode" "DI")]
2409 (define_insn "<su>muldi3_highpart"
2410 [(set (match_operand:DI 0 "register_operand" "=r")
2414 (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2415 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2418 "<su>mulh\\t%0, %1, %2"
2419 [(set_attr "v8type" "mulh")
2420 (set_attr "type" "<su>mull")
2421 (set_attr "mode" "DI")]
2424 (define_insn "<su_optab>div<mode>3"
2425 [(set (match_operand:GPI 0 "register_operand" "=r")
2426 (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2427 (match_operand:GPI 2 "register_operand" "r")))]
2429 "<su>div\\t%<w>0, %<w>1, %<w>2"
2430 [(set_attr "v8type" "<su>div")
2431 (set_attr "type" "<su>div")
2432 (set_attr "mode" "<MODE>")]
2435 ;; zero_extend version of above
2436 (define_insn "*<su_optab>divsi3_uxtw"
2437 [(set (match_operand:DI 0 "register_operand" "=r")
2439 (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2440 (match_operand:SI 2 "register_operand" "r"))))]
2442 "<su>div\\t%w0, %w1, %w2"
2443 [(set_attr "v8type" "<su>div")
2444 (set_attr "type" "<su>div")
2445 (set_attr "mode" "SI")]
2448 ;; -------------------------------------------------------------------
2450 ;; -------------------------------------------------------------------
2452 (define_insn "*cmp<mode>"
2453 [(set (reg:CC CC_REGNUM)
2454 (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2455 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2461 [(set_attr "v8type" "alus")
2462 (set_attr "type" "alus_reg,alus_imm,alus_imm")
2463 (set_attr "mode" "<MODE>")]
2466 (define_insn "*cmp<mode>"
2467 [(set (reg:CCFP CC_REGNUM)
2468 (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2469 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2473 fcmp\\t%<s>0, %<s>1"
2474 [(set_attr "v8type" "fcmp")
2475 (set_attr "type" "fcmp<s>")
2476 (set_attr "mode" "<MODE>")]
2479 (define_insn "*cmpe<mode>"
2480 [(set (reg:CCFPE CC_REGNUM)
2481 (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2482 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2486 fcmpe\\t%<s>0, %<s>1"
2487 [(set_attr "v8type" "fcmp")
2488 (set_attr "type" "fcmp<s>")
2489 (set_attr "mode" "<MODE>")]
2492 (define_insn "*cmp_swp_<shift>_reg<mode>"
2493 [(set (reg:CC_SWP CC_REGNUM)
2494 (compare:CC_SWP (ASHIFT:GPI
2495 (match_operand:GPI 0 "register_operand" "r")
2496 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2497 (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2499 "cmp\\t%<w>2, %<w>0, <shift> %1"
2500 [(set_attr "v8type" "alus_shift")
2501 (set_attr "type" "alus_shift_imm")
2502 (set_attr "mode" "<MODE>")]
2505 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2506 [(set (reg:CC_SWP CC_REGNUM)
2507 (compare:CC_SWP (ANY_EXTEND:GPI
2508 (match_operand:ALLX 0 "register_operand" "r"))
2509 (match_operand:GPI 1 "register_operand" "r")))]
2511 "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2512 [(set_attr "v8type" "alus_ext")
2513 (set_attr "type" "alus_ext")
2514 (set_attr "mode" "<GPI:MODE>")]
2517 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2518 [(set (reg:CC_SWP CC_REGNUM)
2519 (compare:CC_SWP (ashift:GPI
2521 (match_operand:ALLX 0 "register_operand" "r"))
2522 (match_operand 1 "aarch64_imm3" "Ui3"))
2523 (match_operand:GPI 2 "register_operand" "r")))]
2525 "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2526 [(set_attr "v8type" "alus_ext")
2527 (set_attr "type" "alus_ext")
2528 (set_attr "mode" "<GPI:MODE>")]
2531 ;; -------------------------------------------------------------------
2532 ;; Store-flag and conditional select insns
2533 ;; -------------------------------------------------------------------
2535 (define_expand "cstore<mode>4"
2536 [(set (match_operand:SI 0 "register_operand" "")
2537 (match_operator:SI 1 "aarch64_comparison_operator"
2538 [(match_operand:GPI 2 "register_operand" "")
2539 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2542 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2544 operands[3] = const0_rtx;
2548 (define_expand "cstore<mode>4"
2549 [(set (match_operand:SI 0 "register_operand" "")
2550 (match_operator:SI 1 "aarch64_comparison_operator"
2551 [(match_operand:GPF 2 "register_operand" "")
2552 (match_operand:GPF 3 "register_operand" "")]))]
2555 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2557 operands[3] = const0_rtx;
2561 (define_insn "*cstore<mode>_insn"
2562 [(set (match_operand:ALLI 0 "register_operand" "=r")
2563 (match_operator:ALLI 1 "aarch64_comparison_operator"
2564 [(match_operand 2 "cc_register" "") (const_int 0)]))]
2567 [(set_attr "v8type" "csel")
2568 (set_attr "type" "csel")
2569 (set_attr "mode" "<MODE>")]
2572 ;; zero_extend version of the above
2573 (define_insn "*cstoresi_insn_uxtw"
2574 [(set (match_operand:DI 0 "register_operand" "=r")
2576 (match_operator:SI 1 "aarch64_comparison_operator"
2577 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2580 [(set_attr "v8type" "csel")
2581 (set_attr "type" "csel")
2582 (set_attr "mode" "SI")]
2585 (define_insn "cstore<mode>_neg"
2586 [(set (match_operand:ALLI 0 "register_operand" "=r")
2587 (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2588 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2590 "csetm\\t%<w>0, %m1"
2591 [(set_attr "v8type" "csel")
2592 (set_attr "type" "csel")
2593 (set_attr "mode" "<MODE>")]
2596 ;; zero_extend version of the above
2597 (define_insn "*cstoresi_neg_uxtw"
2598 [(set (match_operand:DI 0 "register_operand" "=r")
2600 (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2601 [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2604 [(set_attr "v8type" "csel")
2605 (set_attr "type" "csel")
2606 (set_attr "mode" "SI")]
2609 (define_expand "cmov<mode>6"
2610 [(set (match_operand:GPI 0 "register_operand" "")
2612 (match_operator 1 "aarch64_comparison_operator"
2613 [(match_operand:GPI 2 "register_operand" "")
2614 (match_operand:GPI 3 "aarch64_plus_operand" "")])
2615 (match_operand:GPI 4 "register_operand" "")
2616 (match_operand:GPI 5 "register_operand" "")))]
2619 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2621 operands[3] = const0_rtx;
2625 (define_expand "cmov<mode>6"
2626 [(set (match_operand:GPF 0 "register_operand" "")
2628 (match_operator 1 "aarch64_comparison_operator"
2629 [(match_operand:GPF 2 "register_operand" "")
2630 (match_operand:GPF 3 "register_operand" "")])
2631 (match_operand:GPF 4 "register_operand" "")
2632 (match_operand:GPF 5 "register_operand" "")))]
2635 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2637 operands[3] = const0_rtx;
2641 (define_insn "*cmov<mode>_insn"
2642 [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2644 (match_operator 1 "aarch64_comparison_operator"
2645 [(match_operand 2 "cc_register" "") (const_int 0)])
2646 (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2647 (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2648 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2649 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2650 ;; Final two alternatives should be unreachable, but included for completeness
2652 csel\\t%<w>0, %<w>3, %<w>4, %m1
2653 csinv\\t%<w>0, %<w>3, <w>zr, %m1
2654 csinv\\t%<w>0, %<w>4, <w>zr, %M1
2655 csinc\\t%<w>0, %<w>3, <w>zr, %m1
2656 csinc\\t%<w>0, %<w>4, <w>zr, %M1
2659 [(set_attr "v8type" "csel")
2660 (set_attr "type" "csel")
2661 (set_attr "mode" "<MODE>")]
2664 ;; zero_extend version of above
2665 (define_insn "*cmovsi_insn_uxtw"
2666 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2669 (match_operator 1 "aarch64_comparison_operator"
2670 [(match_operand 2 "cc_register" "") (const_int 0)])
2671 (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2672 (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2673 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2674 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2675 ;; Final two alternatives should be unreachable, but included for completeness
2677 csel\\t%w0, %w3, %w4, %m1
2678 csinv\\t%w0, %w3, wzr, %m1
2679 csinv\\t%w0, %w4, wzr, %M1
2680 csinc\\t%w0, %w3, wzr, %m1
2681 csinc\\t%w0, %w4, wzr, %M1
2684 [(set_attr "v8type" "csel")
2685 (set_attr "type" "csel")
2686 (set_attr "mode" "SI")]
2689 (define_insn "*cmov<mode>_insn"
2690 [(set (match_operand:GPF 0 "register_operand" "=w")
2692 (match_operator 1 "aarch64_comparison_operator"
2693 [(match_operand 2 "cc_register" "") (const_int 0)])
2694 (match_operand:GPF 3 "register_operand" "w")
2695 (match_operand:GPF 4 "register_operand" "w")))]
2697 "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2698 [(set_attr "v8type" "fcsel")
2699 (set_attr "type" "fcsel")
2700 (set_attr "mode" "<MODE>")]
2703 (define_expand "mov<mode>cc"
2704 [(set (match_operand:ALLI 0 "register_operand" "")
2705 (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2706 (match_operand:ALLI 2 "register_operand" "")
2707 (match_operand:ALLI 3 "register_operand" "")))]
2711 enum rtx_code code = GET_CODE (operands[1]);
2713 if (code == UNEQ || code == LTGT)
2716 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2717 XEXP (operands[1], 1));
2718 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2722 (define_expand "mov<GPF:mode><GPI:mode>cc"
2723 [(set (match_operand:GPI 0 "register_operand" "")
2724 (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2725 (match_operand:GPF 2 "register_operand" "")
2726 (match_operand:GPF 3 "register_operand" "")))]
2730 enum rtx_code code = GET_CODE (operands[1]);
2732 if (code == UNEQ || code == LTGT)
2735 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2736 XEXP (operands[1], 1));
2737 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2741 (define_insn "*csinc2<mode>_insn"
2742 [(set (match_operand:GPI 0 "register_operand" "=r")
2743 (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator"
2744 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
2745 (match_operand:GPI 1 "register_operand" "r")))]
2747 "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2748 [(set_attr "v8type" "csel")
2749 (set_attr "type" "csel")
2750 (set_attr "mode" "<MODE>")])
2752 (define_insn "csinc3<mode>_insn"
2753 [(set (match_operand:GPI 0 "register_operand" "=r")
2755 (match_operator:GPI 1 "aarch64_comparison_operator"
2756 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2757 (plus:GPI (match_operand:GPI 3 "register_operand" "r")
2759 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2761 "csinc\\t%<w>0, %<w>4, %<w>3, %M1"
2762 [(set_attr "v8type" "csel")
2763 (set_attr "type" "csel")
2764 (set_attr "mode" "<MODE>")]
2767 (define_insn "*csinv3<mode>_insn"
2768 [(set (match_operand:GPI 0 "register_operand" "=r")
2770 (match_operator:GPI 1 "aarch64_comparison_operator"
2771 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2772 (not:GPI (match_operand:GPI 3 "register_operand" "r"))
2773 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2775 "csinv\\t%<w>0, %<w>4, %<w>3, %M1"
2776 [(set_attr "v8type" "csel")
2777 (set_attr "type" "csel")
2778 (set_attr "mode" "<MODE>")])
2780 (define_insn "*csneg3<mode>_insn"
2781 [(set (match_operand:GPI 0 "register_operand" "=r")
2783 (match_operator:GPI 1 "aarch64_comparison_operator"
2784 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2785 (neg:GPI (match_operand:GPI 3 "register_operand" "r"))
2786 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2788 "csneg\\t%<w>0, %<w>4, %<w>3, %M1"
2789 [(set_attr "v8type" "csel")
2790 (set_attr "type" "csel")
2791 (set_attr "mode" "<MODE>")])
2793 ;; -------------------------------------------------------------------
2794 ;; Logical operations
2795 ;; -------------------------------------------------------------------
2797 (define_insn "<optab><mode>3"
2798 [(set (match_operand:GPI 0 "register_operand" "=r,rk")
2799 (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2800 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
2802 "<logical>\\t%<w>0, %<w>1, %<w>2"
2803 [(set_attr "v8type" "logic,logic_imm")
2804 (set_attr "type" "logic_reg,logic_imm")
2805 (set_attr "mode" "<MODE>")])
2807 ;; zero_extend version of above
2808 (define_insn "*<optab>si3_uxtw"
2809 [(set (match_operand:DI 0 "register_operand" "=r,rk")
2811 (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2812 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2814 "<logical>\\t%w0, %w1, %w2"
2815 [(set_attr "v8type" "logic,logic_imm")
2816 (set_attr "type" "logic_reg,logic_imm")
2817 (set_attr "mode" "SI")])
2819 (define_insn "*and<mode>3_compare0"
2820 [(set (reg:CC_NZ CC_REGNUM)
2822 (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2823 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2825 (set (match_operand:GPI 0 "register_operand" "=r,r")
2826 (and:GPI (match_dup 1) (match_dup 2)))]
2828 "ands\\t%<w>0, %<w>1, %<w>2"
2829 [(set_attr "v8type" "logics,logics_imm")
2830 (set_attr "type" "logics_reg,logics_imm")
2831 (set_attr "mode" "<MODE>")]
2834 ;; zero_extend version of above
2835 (define_insn "*andsi3_compare0_uxtw"
2836 [(set (reg:CC_NZ CC_REGNUM)
2838 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2839 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2841 (set (match_operand:DI 0 "register_operand" "=r,r")
2842 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2844 "ands\\t%w0, %w1, %w2"
2845 [(set_attr "v8type" "logics,logics_imm")
2846 (set_attr "type" "logics_reg,logics_imm")
2847 (set_attr "mode" "SI")]
2850 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2851 [(set (reg:CC_NZ CC_REGNUM)
2854 (match_operand:GPI 1 "register_operand" "r")
2855 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2856 (match_operand:GPI 3 "register_operand" "r"))
2858 (set (match_operand:GPI 0 "register_operand" "=r")
2859 (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2861 "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2862 [(set_attr "v8type" "logics_shift")
2863 (set_attr "type" "logics_shift_imm")
2864 (set_attr "mode" "<MODE>")]
2867 ;; zero_extend version of above
2868 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2869 [(set (reg:CC_NZ CC_REGNUM)
2872 (match_operand:SI 1 "register_operand" "r")
2873 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2874 (match_operand:SI 3 "register_operand" "r"))
2876 (set (match_operand:DI 0 "register_operand" "=r")
2877 (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2880 "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2881 [(set_attr "v8type" "logics_shift")
2882 (set_attr "type" "logics_shift_imm")
2883 (set_attr "mode" "SI")]
2886 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2887 [(set (match_operand:GPI 0 "register_operand" "=r")
2888 (LOGICAL:GPI (SHIFT:GPI
2889 (match_operand:GPI 1 "register_operand" "r")
2890 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2891 (match_operand:GPI 3 "register_operand" "r")))]
2893 "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2894 [(set_attr "v8type" "logic_shift")
2895 (set_attr "type" "logic_shift_imm")
2896 (set_attr "mode" "<MODE>")])
2898 ;; zero_extend version of above
2899 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
2900 [(set (match_operand:DI 0 "register_operand" "=r")
2902 (LOGICAL:SI (SHIFT:SI
2903 (match_operand:SI 1 "register_operand" "r")
2904 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2905 (match_operand:SI 3 "register_operand" "r"))))]
2907 "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2908 [(set_attr "v8type" "logic_shift")
2909 (set_attr "type" "logic_shift_imm")
2910 (set_attr "mode" "SI")])
2912 (define_insn "one_cmpl<mode>2"
2913 [(set (match_operand:GPI 0 "register_operand" "=r")
2914 (not:GPI (match_operand:GPI 1 "register_operand" "r")))]
2916 "mvn\\t%<w>0, %<w>1"
2917 [(set_attr "v8type" "logic")
2918 (set_attr "type" "logic_reg")
2919 (set_attr "mode" "<MODE>")])
2921 (define_insn "*one_cmpl_<optab><mode>2"
2922 [(set (match_operand:GPI 0 "register_operand" "=r")
2923 (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
2924 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2926 "mvn\\t%<w>0, %<w>1, <shift> %2"
2927 [(set_attr "v8type" "logic_shift")
2928 (set_attr "type" "logic_shift_imm")
2929 (set_attr "mode" "<MODE>")])
2931 (define_insn "*<LOGICAL:optab>_one_cmpl<mode>3"
2932 [(set (match_operand:GPI 0 "register_operand" "=r")
2933 (LOGICAL:GPI (not:GPI
2934 (match_operand:GPI 1 "register_operand" "r"))
2935 (match_operand:GPI 2 "register_operand" "r")))]
2937 "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1"
2938 [(set_attr "v8type" "logic")
2939 (set_attr "type" "logic_reg")
2940 (set_attr "mode" "<MODE>")])
2942 (define_insn "*and_one_cmpl<mode>3_compare0"
2943 [(set (reg:CC_NZ CC_REGNUM)
2946 (match_operand:GPI 1 "register_operand" "r"))
2947 (match_operand:GPI 2 "register_operand" "r"))
2949 (set (match_operand:GPI 0 "register_operand" "=r")
2950 (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
2952 "bics\\t%<w>0, %<w>2, %<w>1"
2953 [(set_attr "v8type" "logics")
2954 (set_attr "type" "logics_reg")
2955 (set_attr "mode" "<MODE>")])
2957 ;; zero_extend version of above
2958 (define_insn "*and_one_cmplsi3_compare0_uxtw"
2959 [(set (reg:CC_NZ CC_REGNUM)
2962 (match_operand:SI 1 "register_operand" "r"))
2963 (match_operand:SI 2 "register_operand" "r"))
2965 (set (match_operand:DI 0 "register_operand" "=r")
2966 (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
2968 "bics\\t%w0, %w2, %w1"
2969 [(set_attr "v8type" "logics")
2970 (set_attr "type" "logics_reg")
2971 (set_attr "mode" "SI")])
2973 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
2974 [(set (match_operand:GPI 0 "register_operand" "=r")
2975 (LOGICAL:GPI (not:GPI
2977 (match_operand:GPI 1 "register_operand" "r")
2978 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2979 (match_operand:GPI 3 "register_operand" "r")))]
2981 "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2982 [(set_attr "v8type" "logic_shift")
2983 (set_attr "type" "logics_shift_imm")
2984 (set_attr "mode" "<MODE>")])
2986 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
2987 [(set (reg:CC_NZ CC_REGNUM)
2991 (match_operand:GPI 1 "register_operand" "r")
2992 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2993 (match_operand:GPI 3 "register_operand" "r"))
2995 (set (match_operand:GPI 0 "register_operand" "=r")
2998 (match_dup 1) (match_dup 2))) (match_dup 3)))]
3000 "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3001 [(set_attr "v8type" "logics_shift")
3002 (set_attr "type" "logics_shift_imm")
3003 (set_attr "mode" "<MODE>")])
3005 ;; zero_extend version of above
3006 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
3007 [(set (reg:CC_NZ CC_REGNUM)
3011 (match_operand:SI 1 "register_operand" "r")
3012 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
3013 (match_operand:SI 3 "register_operand" "r"))
3015 (set (match_operand:DI 0 "register_operand" "=r")
3016 (zero_extend:DI (and:SI
3018 (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
3020 "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3021 [(set_attr "v8type" "logics_shift")
3022 (set_attr "type" "logics_shift_imm")
3023 (set_attr "mode" "SI")])
3025 (define_insn "clz<mode>2"
3026 [(set (match_operand:GPI 0 "register_operand" "=r")
3027 (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
3029 "clz\\t%<w>0, %<w>1"
3030 [(set_attr "v8type" "clz")
3031 (set_attr "type" "clz")
3032 (set_attr "mode" "<MODE>")])
3034 (define_expand "ffs<mode>2"
3035 [(match_operand:GPI 0 "register_operand")
3036 (match_operand:GPI 1 "register_operand")]
3039 rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
3040 rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
3042 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3043 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3044 emit_insn (gen_csinc3<mode>_insn (operands[0], x, ccreg, operands[0], const0_rtx));
3049 (define_insn "clrsb<mode>2"
3050 [(set (match_operand:GPI 0 "register_operand" "=r")
3051 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_CLS))]
3053 "cls\\t%<w>0, %<w>1"
3054 [(set_attr "v8type" "clz")
3055 (set_attr "type" "clz")
3056 (set_attr "mode" "<MODE>")])
3058 (define_insn "rbit<mode>2"
3059 [(set (match_operand:GPI 0 "register_operand" "=r")
3060 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
3062 "rbit\\t%<w>0, %<w>1"
3063 [(set_attr "v8type" "rbit")
3064 (set_attr "type" "rbit")
3065 (set_attr "mode" "<MODE>")])
3067 (define_expand "ctz<mode>2"
3068 [(match_operand:GPI 0 "register_operand")
3069 (match_operand:GPI 1 "register_operand")]
3072 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3073 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3078 (define_insn "*and<mode>3nr_compare0"
3079 [(set (reg:CC_NZ CC_REGNUM)
3081 (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
3082 (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
3085 "tst\\t%<w>0, %<w>1"
3086 [(set_attr "v8type" "logics")
3087 (set_attr "type" "logics_reg")
3088 (set_attr "mode" "<MODE>")])
3090 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
3091 [(set (reg:CC_NZ CC_REGNUM)
3094 (match_operand:GPI 0 "register_operand" "r")
3095 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
3096 (match_operand:GPI 2 "register_operand" "r"))
3099 "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
3100 [(set_attr "v8type" "logics_shift")
3101 (set_attr "type" "logics_shift_imm")
3102 (set_attr "mode" "<MODE>")])
3104 ;; -------------------------------------------------------------------
3106 ;; -------------------------------------------------------------------
3108 (define_expand "<optab><mode>3"
3109 [(set (match_operand:GPI 0 "register_operand")
3110 (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
3111 (match_operand:QI 2 "nonmemory_operand")))]
3114 if (CONST_INT_P (operands[2]))
3116 operands[2] = GEN_INT (INTVAL (operands[2])
3117 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3119 if (operands[2] == const0_rtx)
3121 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3128 (define_expand "ashl<mode>3"
3129 [(set (match_operand:SHORT 0 "register_operand")
3130 (ashift:SHORT (match_operand:SHORT 1 "register_operand")
3131 (match_operand:QI 2 "nonmemory_operand")))]
3134 if (CONST_INT_P (operands[2]))
3136 operands[2] = GEN_INT (INTVAL (operands[2])
3137 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3139 if (operands[2] == const0_rtx)
3141 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3148 (define_expand "rotr<mode>3"
3149 [(set (match_operand:GPI 0 "register_operand")
3150 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3151 (match_operand:QI 2 "nonmemory_operand")))]
3154 if (CONST_INT_P (operands[2]))
3156 operands[2] = GEN_INT (INTVAL (operands[2])
3157 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3159 if (operands[2] == const0_rtx)
3161 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3168 (define_expand "rotl<mode>3"
3169 [(set (match_operand:GPI 0 "register_operand")
3170 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3171 (match_operand:QI 2 "nonmemory_operand")))]
3174 /* (SZ - cnt) % SZ == -cnt % SZ */
3175 if (CONST_INT_P (operands[2]))
3177 operands[2] = GEN_INT ((-INTVAL (operands[2]))
3178 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3179 if (operands[2] == const0_rtx)
3181 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3186 operands[2] = expand_simple_unop (QImode, NEG, operands[2],
3191 ;; Logical left shift using SISD or Integer instruction
3192 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
3193 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3195 (match_operand:GPI 1 "register_operand" "w,w,r")
3196 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3199 shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3200 ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
3201 lsl\t%<w>0, %<w>1, %<w>2"
3202 [(set_attr "simd" "yes,yes,no")
3203 (set_attr "v8type" "*,*,shift")
3204 (set_attr "type" "neon_shift_imm<q>, neon_shift_reg<q>,shift_reg")
3205 (set_attr "mode" "*,*,<MODE>")]
3208 ;; Logical right shift using SISD or Integer instruction
3209 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3210 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3212 (match_operand:GPI 1 "register_operand" "w,w,r")
3213 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3216 ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3218 lsr\t%<w>0, %<w>1, %<w>2"
3219 [(set_attr "simd" "yes,yes,no")
3220 (set_attr "v8type" "*,*,shift")
3221 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")
3222 (set_attr "mode" "*,*,<MODE>")]
3226 [(set (match_operand:DI 0 "aarch64_simd_register")
3228 (match_operand:DI 1 "aarch64_simd_register")
3229 (match_operand:QI 2 "aarch64_simd_register")))]
3230 "TARGET_SIMD && reload_completed"
3232 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3234 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_USHL))]
3239 [(set (match_operand:SI 0 "aarch64_simd_register")
3241 (match_operand:SI 1 "aarch64_simd_register")
3242 (match_operand:QI 2 "aarch64_simd_register")))]
3243 "TARGET_SIMD && reload_completed"
3245 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3247 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_USHL_2S))]
3251 ;; Arithmetic right shift using SISD or Integer instruction
3252 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3253 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3255 (match_operand:GPI 1 "register_operand" "w,w,r")
3256 (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,rUs<cmode>")))]
3259 sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3261 asr\t%<w>0, %<w>1, %<w>2"
3262 [(set_attr "simd" "yes,yes,no")
3263 (set_attr "v8type" "*,*,shift")
3264 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")
3265 (set_attr "mode" "*,*,<MODE>")]
3269 [(set (match_operand:DI 0 "aarch64_simd_register")
3271 (match_operand:DI 1 "aarch64_simd_register")
3272 (match_operand:QI 2 "aarch64_simd_register")))]
3273 "TARGET_SIMD && reload_completed"
3275 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3277 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_SSHL))]
3282 [(set (match_operand:SI 0 "aarch64_simd_register")
3284 (match_operand:SI 1 "aarch64_simd_register")
3285 (match_operand:QI 2 "aarch64_simd_register")))]
3286 "TARGET_SIMD && reload_completed"
3288 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3290 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_SSHL_2S))]
3294 (define_insn "*aarch64_sisd_ushl"
3295 [(set (match_operand:DI 0 "register_operand" "=w")
3296 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3297 (match_operand:QI 2 "register_operand" "w")]
3300 "ushl\t%d0, %d1, %d2"
3301 [(set_attr "simd" "yes")
3302 (set_attr "type" "neon_shift_reg")]
3305 (define_insn "*aarch64_ushl_2s"
3306 [(set (match_operand:SI 0 "register_operand" "=w")
3307 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3308 (match_operand:QI 2 "register_operand" "w")]
3311 "ushl\t%0.2s, %1.2s, %2.2s"
3312 [(set_attr "simd" "yes")
3313 (set_attr "type" "neon_shift_reg")]
3316 (define_insn "*aarch64_sisd_sshl"
3317 [(set (match_operand:DI 0 "register_operand" "=w")
3318 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3319 (match_operand:QI 2 "register_operand" "w")]
3322 "sshl\t%d0, %d1, %d2"
3323 [(set_attr "simd" "yes")
3324 (set_attr "type" "neon_shift_reg")]
3327 (define_insn "*aarch64_sshl_2s"
3328 [(set (match_operand:SI 0 "register_operand" "=w")
3329 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3330 (match_operand:QI 2 "register_operand" "w")]
3333 "sshl\t%0.2s, %1.2s, %2.2s"
3334 [(set_attr "simd" "yes")
3335 (set_attr "type" "neon_shift_reg")]
3338 (define_insn "*aarch64_sisd_neg_qi"
3339 [(set (match_operand:QI 0 "register_operand" "=w")
3340 (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3344 [(set_attr "simd" "yes")
3345 (set_attr "type" "neon_neg")]
3349 (define_insn "*ror<mode>3_insn"
3350 [(set (match_operand:GPI 0 "register_operand" "=r")
3352 (match_operand:GPI 1 "register_operand" "r")
3353 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3355 "ror\\t%<w>0, %<w>1, %<w>2"
3356 [(set_attr "v8type" "shift")
3357 (set_attr "type" "shift_reg")
3358 (set_attr "mode" "<MODE>")]
3361 ;; zero_extend version of above
3362 (define_insn "*<optab>si3_insn_uxtw"
3363 [(set (match_operand:DI 0 "register_operand" "=r")
3364 (zero_extend:DI (SHIFT:SI
3365 (match_operand:SI 1 "register_operand" "r")
3366 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3368 "<shift>\\t%w0, %w1, %w2"
3369 [(set_attr "v8type" "shift")
3370 (set_attr "type" "shift_reg")
3371 (set_attr "mode" "SI")]
3374 (define_insn "*ashl<mode>3_insn"
3375 [(set (match_operand:SHORT 0 "register_operand" "=r")
3376 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3377 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
3379 "lsl\\t%<w>0, %<w>1, %<w>2"
3380 [(set_attr "v8type" "shift")
3381 (set_attr "type" "shift_reg")
3382 (set_attr "mode" "<MODE>")]
3385 (define_insn "*<optab><mode>3_insn"
3386 [(set (match_operand:SHORT 0 "register_operand" "=r")
3387 (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3388 (match_operand 2 "const_int_operand" "n")))]
3389 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3391 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3392 return "<bfshift>\t%w0, %w1, %2, %3";
3394 [(set_attr "v8type" "bfm")
3395 (set_attr "type" "bfm")
3396 (set_attr "mode" "<MODE>")]
3399 (define_insn "*extr<mode>5_insn"
3400 [(set (match_operand:GPI 0 "register_operand" "=r")
3401 (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3402 (match_operand 3 "const_int_operand" "n"))
3403 (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3404 (match_operand 4 "const_int_operand" "n"))))]
3405 "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3406 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3407 "extr\\t%<w>0, %<w>1, %<w>2, %4"
3408 [(set_attr "v8type" "shift")
3409 (set_attr "type" "shift_imm")
3410 (set_attr "mode" "<MODE>")]
3413 ;; zero_extend version of the above
3414 (define_insn "*extrsi5_insn_uxtw"
3415 [(set (match_operand:DI 0 "register_operand" "=r")
3417 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3418 (match_operand 3 "const_int_operand" "n"))
3419 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3420 (match_operand 4 "const_int_operand" "n")))))]
3421 "UINTVAL (operands[3]) < 32 &&
3422 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3423 "extr\\t%w0, %w1, %w2, %4"
3424 [(set_attr "v8type" "shift")
3425 (set_attr "type" "shift_imm")
3426 (set_attr "mode" "SI")]
3429 (define_insn "*ror<mode>3_insn"
3430 [(set (match_operand:GPI 0 "register_operand" "=r")
3431 (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3432 (match_operand 2 "const_int_operand" "n")))]
3433 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3435 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3436 return "ror\\t%<w>0, %<w>1, %3";
3438 [(set_attr "v8type" "shift")
3439 (set_attr "type" "shift_imm")
3440 (set_attr "mode" "<MODE>")]
3443 ;; zero_extend version of the above
3444 (define_insn "*rorsi3_insn_uxtw"
3445 [(set (match_operand:DI 0 "register_operand" "=r")
3447 (rotate:SI (match_operand:SI 1 "register_operand" "r")
3448 (match_operand 2 "const_int_operand" "n"))))]
3449 "UINTVAL (operands[2]) < 32"
3451 operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3452 return "ror\\t%w0, %w1, %3";
3454 [(set_attr "v8type" "shift")
3455 (set_attr "type" "shift_imm")
3456 (set_attr "mode" "SI")]
3459 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3460 [(set (match_operand:GPI 0 "register_operand" "=r")
3462 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3463 (match_operand 2 "const_int_operand" "n"))))]
3464 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3466 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3467 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3469 [(set_attr "v8type" "bfm")
3470 (set_attr "type" "bfm")
3471 (set_attr "mode" "<GPI:MODE>")]
3474 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3475 [(set (match_operand:GPI 0 "register_operand" "=r")
3477 (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3478 (match_operand 2 "const_int_operand" "n"))))]
3479 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3481 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3482 return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3484 [(set_attr "v8type" "bfm")
3485 (set_attr "type" "bfm")
3486 (set_attr "mode" "<GPI:MODE>")]
3489 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3490 [(set (match_operand:GPI 0 "register_operand" "=r")
3492 (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3493 (match_operand 2 "const_int_operand" "n"))))]
3494 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3496 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3497 return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3499 [(set_attr "v8type" "bfm")
3500 (set_attr "type" "bfm")
3501 (set_attr "mode" "<GPI:MODE>")]
3504 ;; -------------------------------------------------------------------
3506 ;; -------------------------------------------------------------------
3508 (define_expand "<optab>"
3509 [(set (match_operand:DI 0 "register_operand" "=r")
3510 (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3511 (match_operand 2 "const_int_operand" "n")
3512 (match_operand 3 "const_int_operand" "n")))]
3517 (define_insn "*<optab><mode>"
3518 [(set (match_operand:GPI 0 "register_operand" "=r")
3519 (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3520 (match_operand 2 "const_int_operand" "n")
3521 (match_operand 3 "const_int_operand" "n")))]
3523 "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3524 [(set_attr "v8type" "bfm")
3525 (set_attr "type" "bfm")
3526 (set_attr "mode" "<MODE>")]
3529 ;; Bitfield Insert (insv)
3530 (define_expand "insv<mode>"
3531 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3532 (match_operand 1 "const_int_operand")
3533 (match_operand 2 "const_int_operand"))
3534 (match_operand:GPI 3 "general_operand"))]
3537 unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3538 unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3539 rtx value = operands[3];
3541 if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3544 if (CONST_INT_P (value))
3546 unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3548 /* Prefer AND/OR for inserting all zeros or all ones. */
3549 if ((UINTVAL (value) & mask) == 0
3550 || (UINTVAL (value) & mask) == mask)
3553 /* 16-bit aligned 16-bit wide insert is handled by insv_imm. */
3554 if (width == 16 && (pos % 16) == 0)
3557 operands[3] = force_reg (<MODE>mode, value);
3560 (define_insn "*insv_reg<mode>"
3561 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3562 (match_operand 1 "const_int_operand" "n")
3563 (match_operand 2 "const_int_operand" "n"))
3564 (match_operand:GPI 3 "register_operand" "r"))]
3565 "!(UINTVAL (operands[1]) == 0
3566 || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3567 > GET_MODE_BITSIZE (<MODE>mode)))"
3568 "bfi\\t%<w>0, %<w>3, %2, %1"
3569 [(set_attr "v8type" "bfm")
3570 (set_attr "type" "bfm")
3571 (set_attr "mode" "<MODE>")]
3574 (define_insn "*extr_insv_lower_reg<mode>"
3575 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3576 (match_operand 1 "const_int_operand" "n")
3578 (zero_extract:GPI (match_operand:GPI 2 "register_operand" "+r")
3580 (match_operand 3 "const_int_operand" "n")))]
3581 "!(UINTVAL (operands[1]) == 0
3582 || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3583 > GET_MODE_BITSIZE (<MODE>mode)))"
3584 "bfxil\\t%<w>0, %<w>2, %3, %1"
3585 [(set_attr "v8type" "bfm")
3586 (set_attr "type" "bfm")
3587 (set_attr "mode" "<MODE>")]
3590 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3591 [(set (match_operand:GPI 0 "register_operand" "=r")
3592 (ashift:GPI (ANY_EXTEND:GPI
3593 (match_operand:ALLX 1 "register_operand" "r"))
3594 (match_operand 2 "const_int_operand" "n")))]
3595 "UINTVAL (operands[2]) < <GPI:sizen>"
3597 operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3598 ? GEN_INT (<ALLX:sizen>)
3599 : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3600 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3602 [(set_attr "v8type" "bfm")
3603 (set_attr "type" "bfm")
3604 (set_attr "mode" "<GPI:MODE>")]
3607 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3609 (define_insn "*andim_ashift<mode>_bfiz"
3610 [(set (match_operand:GPI 0 "register_operand" "=r")
3611 (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3612 (match_operand 2 "const_int_operand" "n"))
3613 (match_operand 3 "const_int_operand" "n")))]
3614 "exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3615 && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3616 "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3617 [(set_attr "v8type" "bfm")
3618 (set_attr "type" "bfm")
3619 (set_attr "mode" "<MODE>")]
3622 (define_insn "bswap<mode>2"
3623 [(set (match_operand:GPI 0 "register_operand" "=r")
3624 (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3626 "rev\\t%<w>0, %<w>1"
3627 [(set_attr "v8type" "rev")
3628 (set_attr "type" "rev")
3629 (set_attr "mode" "<MODE>")]
3632 (define_insn "bswaphi2"
3633 [(set (match_operand:HI 0 "register_operand" "=r")
3634 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3637 [(set_attr "v8type" "rev")
3638 (set_attr "type" "rev")
3639 (set_attr "mode" "HI")]
3642 ;; zero_extend version of above
3643 (define_insn "*bswapsi2_uxtw"
3644 [(set (match_operand:DI 0 "register_operand" "=r")
3645 (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3648 [(set_attr "v8type" "rev")
3649 (set_attr "type" "rev")
3650 (set_attr "mode" "SI")]
3653 ;; -------------------------------------------------------------------
3654 ;; Floating-point intrinsics
3655 ;; -------------------------------------------------------------------
3657 ;; frint floating-point round to integral standard patterns.
3658 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round.
3660 (define_insn "<frint_pattern><mode>2"
3661 [(set (match_operand:GPF 0 "register_operand" "=w")
3662 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3665 "frint<frint_suffix>\\t%<s>0, %<s>1"
3666 [(set_attr "v8type" "frint")
3667 (set_attr "type" "f_rint<s>")
3668 (set_attr "mode" "<MODE>")]
3671 ;; frcvt floating-point round to integer and convert standard patterns.
3672 ;; Expands to lbtrunc, lceil, lfloor, lround.
3673 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3674 [(set (match_operand:GPI 0 "register_operand" "=r")
3675 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3678 "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3679 [(set_attr "v8type" "fcvtf2i")
3680 (set_attr "type" "f_cvtf2i")
3681 (set_attr "mode" "<GPF:MODE>")
3682 (set_attr "mode2" "<GPI:MODE>")]
3687 (define_insn "fma<mode>4"
3688 [(set (match_operand:GPF 0 "register_operand" "=w")
3689 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3690 (match_operand:GPF 2 "register_operand" "w")
3691 (match_operand:GPF 3 "register_operand" "w")))]
3693 "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3694 [(set_attr "v8type" "fmadd")
3695 (set_attr "type" "fmac<s>")
3696 (set_attr "mode" "<MODE>")]
3699 (define_insn "fnma<mode>4"
3700 [(set (match_operand:GPF 0 "register_operand" "=w")
3701 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3702 (match_operand:GPF 2 "register_operand" "w")
3703 (match_operand:GPF 3 "register_operand" "w")))]
3705 "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3706 [(set_attr "v8type" "fmadd")
3707 (set_attr "type" "fmac<s>")
3708 (set_attr "mode" "<MODE>")]
3711 (define_insn "fms<mode>4"
3712 [(set (match_operand:GPF 0 "register_operand" "=w")
3713 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3714 (match_operand:GPF 2 "register_operand" "w")
3715 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3717 "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3718 [(set_attr "v8type" "fmadd")
3719 (set_attr "type" "fmac<s>")
3720 (set_attr "mode" "<MODE>")]
3723 (define_insn "fnms<mode>4"
3724 [(set (match_operand:GPF 0 "register_operand" "=w")
3725 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3726 (match_operand:GPF 2 "register_operand" "w")
3727 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3729 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3730 [(set_attr "v8type" "fmadd")
3731 (set_attr "type" "fmac<s>")
3732 (set_attr "mode" "<MODE>")]
3735 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3736 (define_insn "*fnmadd<mode>4"
3737 [(set (match_operand:GPF 0 "register_operand" "=w")
3738 (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3739 (match_operand:GPF 2 "register_operand" "w")
3740 (match_operand:GPF 3 "register_operand" "w"))))]
3741 "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3742 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3743 [(set_attr "v8type" "fmadd")
3744 (set_attr "type" "fmac<s>")
3745 (set_attr "mode" "<MODE>")]
3748 ;; -------------------------------------------------------------------
3749 ;; Floating-point conversions
3750 ;; -------------------------------------------------------------------
3752 (define_insn "extendsfdf2"
3753 [(set (match_operand:DF 0 "register_operand" "=w")
3754 (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3757 [(set_attr "v8type" "fcvt")
3758 (set_attr "type" "f_cvt")
3759 (set_attr "mode" "DF")
3760 (set_attr "mode2" "SF")]
3763 (define_insn "truncdfsf2"
3764 [(set (match_operand:SF 0 "register_operand" "=w")
3765 (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3768 [(set_attr "v8type" "fcvt")
3769 (set_attr "type" "f_cvt")
3770 (set_attr "mode" "SF")
3771 (set_attr "mode2" "DF")]
3774 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3775 [(set (match_operand:GPI 0 "register_operand" "=r")
3776 (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3778 "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3779 [(set_attr "v8type" "fcvtf2i")
3780 (set_attr "type" "f_cvtf2i")
3781 (set_attr "mode" "<GPF:MODE>")
3782 (set_attr "mode2" "<GPI:MODE>")]
3785 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3786 [(set (match_operand:GPI 0 "register_operand" "=r")
3787 (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3789 "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3790 [(set_attr "v8type" "fcvtf2i")
3791 (set_attr "type" "f_cvtf2i")
3792 (set_attr "mode" "<GPF:MODE>")
3793 (set_attr "mode2" "<GPI:MODE>")]
3796 (define_insn "float<GPI:mode><GPF:mode>2"
3797 [(set (match_operand:GPF 0 "register_operand" "=w")
3798 (float:GPF (match_operand:GPI 1 "register_operand" "r")))]
3800 "scvtf\\t%<GPF:s>0, %<GPI:w>1"
3801 [(set_attr "v8type" "fcvti2f")
3802 (set_attr "type" "f_cvti2f")
3803 (set_attr "mode" "<GPF:MODE>")
3804 (set_attr "mode2" "<GPI:MODE>")]
3807 (define_insn "floatuns<GPI:mode><GPF:mode>2"
3808 [(set (match_operand:GPF 0 "register_operand" "=w")
3809 (unsigned_float:GPF (match_operand:GPI 1 "register_operand" "r")))]
3811 "ucvtf\\t%<GPF:s>0, %<GPI:w>1"
3812 [(set_attr "v8type" "fcvt")
3813 (set_attr "type" "f_cvt")
3814 (set_attr "mode" "<GPF:MODE>")
3815 (set_attr "mode2" "<GPI:MODE>")]
3818 ;; -------------------------------------------------------------------
3819 ;; Floating-point arithmetic
3820 ;; -------------------------------------------------------------------
3822 (define_insn "add<mode>3"
3823 [(set (match_operand:GPF 0 "register_operand" "=w")
3825 (match_operand:GPF 1 "register_operand" "w")
3826 (match_operand:GPF 2 "register_operand" "w")))]
3828 "fadd\\t%<s>0, %<s>1, %<s>2"
3829 [(set_attr "v8type" "fadd")
3830 (set_attr "type" "fadd<s>")
3831 (set_attr "mode" "<MODE>")]
3834 (define_insn "sub<mode>3"
3835 [(set (match_operand:GPF 0 "register_operand" "=w")
3837 (match_operand:GPF 1 "register_operand" "w")
3838 (match_operand:GPF 2 "register_operand" "w")))]
3840 "fsub\\t%<s>0, %<s>1, %<s>2"
3841 [(set_attr "v8type" "fadd")
3842 (set_attr "type" "fadd<s>")
3843 (set_attr "mode" "<MODE>")]
3846 (define_insn "mul<mode>3"
3847 [(set (match_operand:GPF 0 "register_operand" "=w")
3849 (match_operand:GPF 1 "register_operand" "w")
3850 (match_operand:GPF 2 "register_operand" "w")))]
3852 "fmul\\t%<s>0, %<s>1, %<s>2"
3853 [(set_attr "v8type" "fmul")
3854 (set_attr "type" "fmul<s>")
3855 (set_attr "mode" "<MODE>")]
3858 (define_insn "*fnmul<mode>3"
3859 [(set (match_operand:GPF 0 "register_operand" "=w")
3861 (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3862 (match_operand:GPF 2 "register_operand" "w")))]
3864 "fnmul\\t%<s>0, %<s>1, %<s>2"
3865 [(set_attr "v8type" "fmul")
3866 (set_attr "type" "fmul<s>")
3867 (set_attr "mode" "<MODE>")]
3870 (define_insn "div<mode>3"
3871 [(set (match_operand:GPF 0 "register_operand" "=w")
3873 (match_operand:GPF 1 "register_operand" "w")
3874 (match_operand:GPF 2 "register_operand" "w")))]
3876 "fdiv\\t%<s>0, %<s>1, %<s>2"
3877 [(set_attr "v8type" "fdiv")
3878 (set_attr "type" "fdiv<s>")
3879 (set_attr "mode" "<MODE>")]
3882 (define_insn "neg<mode>2"
3883 [(set (match_operand:GPF 0 "register_operand" "=w")
3884 (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
3886 "fneg\\t%<s>0, %<s>1"
3887 [(set_attr "v8type" "ffarith")
3888 (set_attr "type" "ffarith<s>")
3889 (set_attr "mode" "<MODE>")]
3892 (define_insn "sqrt<mode>2"
3893 [(set (match_operand:GPF 0 "register_operand" "=w")
3894 (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
3896 "fsqrt\\t%<s>0, %<s>1"
3897 [(set_attr "v8type" "fsqrt")
3898 (set_attr "type" "fsqrt<s>")
3899 (set_attr "mode" "<MODE>")]
3902 (define_insn "abs<mode>2"
3903 [(set (match_operand:GPF 0 "register_operand" "=w")
3904 (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
3906 "fabs\\t%<s>0, %<s>1"
3907 [(set_attr "v8type" "ffarith")
3908 (set_attr "type" "ffarith<s>")
3909 (set_attr "mode" "<MODE>")]
3912 ;; Given that smax/smin do not specify the result when either input is NaN,
3913 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
3916 (define_insn "smax<mode>3"
3917 [(set (match_operand:GPF 0 "register_operand" "=w")
3918 (smax:GPF (match_operand:GPF 1 "register_operand" "w")
3919 (match_operand:GPF 2 "register_operand" "w")))]
3921 "fmaxnm\\t%<s>0, %<s>1, %<s>2"
3922 [(set_attr "v8type" "fminmax")
3923 (set_attr "type" "f_minmax<s>")
3924 (set_attr "mode" "<MODE>")]
3927 (define_insn "smin<mode>3"
3928 [(set (match_operand:GPF 0 "register_operand" "=w")
3929 (smin:GPF (match_operand:GPF 1 "register_operand" "w")
3930 (match_operand:GPF 2 "register_operand" "w")))]
3932 "fminnm\\t%<s>0, %<s>1, %<s>2"
3933 [(set_attr "v8type" "fminmax")
3934 (set_attr "type" "f_minmax<s>")
3935 (set_attr "mode" "<MODE>")]
3938 ;; -------------------------------------------------------------------
3940 ;; -------------------------------------------------------------------
3942 (define_expand "aarch64_reload_mov<mode>"
3943 [(set (match_operand:TX 0 "register_operand" "=w")
3944 (match_operand:TX 1 "register_operand" "w"))
3945 (clobber (match_operand:DI 2 "register_operand" "=&r"))
3949 rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
3950 rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
3951 gen_aarch64_movtilow_tilow (op0, op1);
3952 gen_aarch64_movdi_tihigh (operands[2], op1);
3953 gen_aarch64_movtihigh_di (op0, operands[2]);
3958 ;; The following secondary reload helpers patterns are invoked
3959 ;; after or during reload as we don't want these patterns to start
3960 ;; kicking in during the combiner.
3962 (define_insn "aarch64_movdi_<mode>low"
3963 [(set (match_operand:DI 0 "register_operand" "=r")
3964 (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
3965 "reload_completed || reload_in_progress"
3967 [(set_attr "v8type" "fmovf2i")
3968 (set_attr "type" "f_mrc")
3969 (set_attr "mode" "DI")
3970 (set_attr "length" "4")
3973 (define_insn "aarch64_movdi_<mode>high"
3974 [(set (match_operand:DI 0 "register_operand" "=r")
3976 (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
3978 "reload_completed || reload_in_progress"
3979 "fmov\\t%x0, %1.d[1]"
3980 [(set_attr "v8type" "fmovf2i")
3981 (set_attr "type" "f_mrc")
3982 (set_attr "mode" "DI")
3983 (set_attr "length" "4")
3986 (define_insn "aarch64_mov<mode>high_di"
3987 [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
3988 (const_int 64) (const_int 64))
3989 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
3990 "reload_completed || reload_in_progress"
3991 "fmov\\t%0.d[1], %x1"
3992 [(set_attr "v8type" "fmovi2f")
3993 (set_attr "type" "f_mcr")
3994 (set_attr "mode" "DI")
3995 (set_attr "length" "4")
3998 (define_insn "aarch64_mov<mode>low_di"
3999 [(set (match_operand:TX 0 "register_operand" "=w")
4000 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4001 "reload_completed || reload_in_progress"
4003 [(set_attr "v8type" "fmovi2f")
4004 (set_attr "type" "f_mcr")
4005 (set_attr "mode" "DI")
4006 (set_attr "length" "4")
4009 (define_insn "aarch64_movtilow_tilow"
4010 [(set (match_operand:TI 0 "register_operand" "=w")
4012 (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
4013 "reload_completed || reload_in_progress"
4015 [(set_attr "v8type" "fmovi2f")
4016 (set_attr "type" "f_mcr")
4017 (set_attr "mode" "DI")
4018 (set_attr "length" "4")
4021 ;; There is a deliberate reason why the parameters of high and lo_sum's
4022 ;; don't have modes for ADRP and ADD instructions. This is to allow high
4023 ;; and lo_sum's to be used with the labels defining the jump tables in
4026 (define_expand "add_losym"
4027 [(set (match_operand 0 "register_operand" "=r")
4028 (lo_sum (match_operand 1 "register_operand" "r")
4029 (match_operand 2 "aarch64_valid_symref" "S")))]
4032 enum machine_mode mode = GET_MODE (operands[0]);
4034 emit_insn ((mode == DImode
4036 : gen_add_losym_si) (operands[0],
4042 (define_insn "add_losym_<mode>"
4043 [(set (match_operand:P 0 "register_operand" "=r")
4044 (lo_sum:P (match_operand:P 1 "register_operand" "r")
4045 (match_operand 2 "aarch64_valid_symref" "S")))]
4047 "add\\t%<w>0, %<w>1, :lo12:%a2"
4048 [(set_attr "v8type" "alu")
4049 (set_attr "type" "alu_reg")
4050 (set_attr "mode" "<MODE>")]
4053 (define_insn "ldr_got_small_<mode>"
4054 [(set (match_operand:PTR 0 "register_operand" "=r")
4055 (unspec:PTR [(mem:PTR (lo_sum:PTR
4056 (match_operand:PTR 1 "register_operand" "r")
4057 (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
4058 UNSPEC_GOTSMALLPIC))]
4060 "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
4061 [(set_attr "v8type" "load1")
4062 (set_attr "type" "load1")
4063 (set_attr "mode" "<MODE>")]
4066 (define_insn "ldr_got_small_sidi"
4067 [(set (match_operand:DI 0 "register_operand" "=r")
4069 (unspec:SI [(mem:SI (lo_sum:DI
4070 (match_operand:DI 1 "register_operand" "r")
4071 (match_operand:DI 2 "aarch64_valid_symref" "S")))]
4072 UNSPEC_GOTSMALLPIC)))]
4074 "ldr\\t%w0, [%1, #:got_lo12:%a2]"
4075 [(set_attr "v8type" "load1")
4076 (set_attr "type" "load1")
4077 (set_attr "mode" "DI")]
4080 (define_insn "ldr_got_tiny"
4081 [(set (match_operand:DI 0 "register_operand" "=r")
4082 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
4083 UNSPEC_GOTTINYPIC))]
4086 [(set_attr "v8type" "load1")
4087 (set_attr "type" "load1")
4088 (set_attr "mode" "DI")]
4091 (define_insn "aarch64_load_tp_hard"
4092 [(set (match_operand:DI 0 "register_operand" "=r")
4093 (unspec:DI [(const_int 0)] UNSPEC_TLS))]
4095 "mrs\\t%0, tpidr_el0"
4096 [(set_attr "v8type" "mrs")
4097 (set_attr "type" "mrs")
4098 (set_attr "mode" "DI")]
4101 ;; The TLS ABI specifically requires that the compiler does not schedule
4102 ;; instructions in the TLS stubs, in order to enable linker relaxation.
4103 ;; Therefore we treat the stubs as an atomic sequence.
4104 (define_expand "tlsgd_small"
4105 [(parallel [(set (match_operand 0 "register_operand" "")
4106 (call (mem:DI (match_dup 2)) (const_int 1)))
4107 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
4108 (clobber (reg:DI LR_REGNUM))])]
4111 operands[2] = aarch64_tls_get_addr ();
4114 (define_insn "*tlsgd_small"
4115 [(set (match_operand 0 "register_operand" "")
4116 (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
4117 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
4118 (clobber (reg:DI LR_REGNUM))
4121 "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
4122 [(set_attr "v8type" "call")
4123 (set_attr "type" "call")
4124 (set_attr "length" "16")])
4126 (define_insn "tlsie_small"
4127 [(set (match_operand:DI 0 "register_operand" "=r")
4128 (unspec:DI [(match_operand:DI 1 "aarch64_tls_ie_symref" "S")]
4129 UNSPEC_GOTSMALLTLS))]
4131 "adrp\\t%0, %A1\;ldr\\t%0, [%0, #%L1]"
4132 [(set_attr "v8type" "load1")
4133 (set_attr "type" "load1")
4134 (set_attr "mode" "DI")
4135 (set_attr "length" "8")]
4138 (define_insn "tlsle_small"
4139 [(set (match_operand:DI 0 "register_operand" "=r")
4140 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
4141 (match_operand:DI 2 "aarch64_tls_le_symref" "S")]
4142 UNSPEC_GOTSMALLTLS))]
4144 "add\\t%0, %1, #%G2\;add\\t%0, %0, #%L2"
4145 [(set_attr "v8type" "alu")
4146 (set_attr "type" "alu_reg")
4147 (set_attr "mode" "DI")
4148 (set_attr "length" "8")]
4151 (define_insn "tlsdesc_small"
4152 [(set (reg:DI R0_REGNUM)
4153 (unspec:DI [(match_operand:DI 0 "aarch64_valid_symref" "S")]
4155 (clobber (reg:DI LR_REGNUM))
4156 (clobber (match_scratch:DI 1 "=r"))]
4158 "adrp\\tx0, %A0\;ldr\\t%1, [x0, #%L0]\;add\\tx0, x0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
4159 [(set_attr "v8type" "call")
4160 (set_attr "type" "call")
4161 (set_attr "length" "16")])
4163 (define_insn "stack_tie"
4164 [(set (mem:BLK (scratch))
4165 (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
4166 (match_operand:DI 1 "register_operand" "rk")]
4170 [(set_attr "length" "0")]
4173 ;; Named pattern for expanding thread pointer reference.
4174 (define_expand "get_thread_pointerdi"
4175 [(match_operand:DI 0 "register_operand" "=r")]
4178 rtx tmp = aarch64_load_tp (operands[0]);
4179 if (tmp != operands[0])
4180 emit_move_insn (operands[0], tmp);
4185 (include "aarch64-simd.md")
4187 ;; Atomic Operations
4188 (include "atomics.md")