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")
312 (include "aarch64-generic.md")
315 (include "../arm/cortex-a53.md")
317 ;; -------------------------------------------------------------------
318 ;; Jumps and other miscellaneous insns
319 ;; -------------------------------------------------------------------
321 (define_insn "indirect_jump"
322 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
325 [(set_attr "v8type" "branch")
326 (set_attr "type" "branch")]
330 [(set (pc) (label_ref (match_operand 0 "" "")))]
333 [(set_attr "v8type" "branch")
334 (set_attr "type" "branch")]
337 (define_expand "cbranch<mode>4"
338 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
339 [(match_operand:GPI 1 "register_operand" "")
340 (match_operand:GPI 2 "aarch64_plus_operand" "")])
341 (label_ref (match_operand 3 "" ""))
345 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
347 operands[2] = const0_rtx;
351 (define_expand "cbranch<mode>4"
352 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
353 [(match_operand:GPF 1 "register_operand" "")
354 (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
355 (label_ref (match_operand 3 "" ""))
359 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
361 operands[2] = const0_rtx;
365 (define_insn "*condjump"
366 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
367 [(match_operand 1 "cc_register" "") (const_int 0)])
368 (label_ref (match_operand 2 "" ""))
372 [(set_attr "v8type" "branch")
373 (set_attr "type" "branch")]
376 (define_expand "casesi"
377 [(match_operand:SI 0 "register_operand" "") ; Index
378 (match_operand:SI 1 "const_int_operand" "") ; Lower bound
379 (match_operand:SI 2 "const_int_operand" "") ; Total range
380 (match_operand:DI 3 "" "") ; Table label
381 (match_operand:DI 4 "" "")] ; Out of range label
384 if (operands[1] != const0_rtx)
386 rtx reg = gen_reg_rtx (SImode);
388 /* Canonical RTL says that if you have:
392 then this should be emitted as:
396 The use of trunc_int_for_mode ensures that the resulting
397 constant can be represented in SImode, this is important
398 for the corner case where operand[1] is INT_MIN. */
400 operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
402 if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
403 (operands[1], SImode))
404 operands[1] = force_reg (SImode, operands[1]);
405 emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
409 if (!aarch64_plus_operand (operands[2], SImode))
410 operands[2] = force_reg (SImode, operands[2]);
411 emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
413 operands[0], operands[2], operands[4]));
415 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
416 emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
422 (define_insn "casesi_dispatch"
425 (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
426 (match_operand:SI 1 "register_operand" "r")]
428 (clobber (reg:CC CC_REGNUM))
429 (clobber (match_scratch:DI 3 "=r"))
430 (clobber (match_scratch:DI 4 "=r"))
431 (use (label_ref (match_operand 2 "" "")))])]
434 return aarch64_output_casesi (operands);
436 [(set_attr "length" "16")
437 (set_attr "v8type" "branch")
438 (set_attr "type" "branch")]
442 [(unspec[(const_int 0)] UNSPEC_NOP)]
445 [(set_attr "v8type" "misc")]
448 (define_expand "prologue"
449 [(clobber (const_int 0))]
452 aarch64_expand_prologue ();
457 (define_expand "epilogue"
458 [(clobber (const_int 0))]
461 aarch64_expand_epilogue (false);
466 (define_expand "sibcall_epilogue"
467 [(clobber (const_int 0))]
470 aarch64_expand_epilogue (true);
475 (define_insn "*do_return"
479 [(set_attr "v8type" "branch")
480 (set_attr "type" "branch")]
483 (define_insn "eh_return"
484 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
488 [(set_attr "v8type" "branch")
489 (set_attr "type" "branch")]
494 [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
497 [(set (match_dup 1) (match_dup 0))]
499 operands[1] = aarch64_final_eh_return_addr ();
503 (define_insn "*cb<optab><mode>1"
504 [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
506 (label_ref (match_operand 1 "" ""))
510 [(set_attr "v8type" "branch")
511 (set_attr "type" "branch")]
515 (define_insn "*tb<optab><mode>1"
516 [(set (pc) (if_then_else
517 (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
519 (match_operand 1 "const_int_operand" "n"))
521 (label_ref (match_operand 2 "" ""))
523 (clobber (match_scratch:DI 3 "=r"))]
526 if (get_attr_length (insn) == 8)
527 return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
528 return \"<tbz>\\t%<w>0, %1, %l2\";
530 [(set_attr "v8type" "branch")
531 (set_attr "type" "branch")
532 (set_attr "mode" "<MODE>")
534 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
535 (lt (minus (match_dup 2) (pc)) (const_int 32764)))
540 (define_insn "*cb<optab><mode>1"
541 [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
543 (label_ref (match_operand 1 "" ""))
545 (clobber (match_scratch:DI 2 "=r"))]
548 if (get_attr_length (insn) == 8)
549 return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
550 return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
552 [(set_attr "v8type" "branch")
553 (set_attr "type" "branch")
554 (set_attr "mode" "<MODE>")
556 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
557 (lt (minus (match_dup 1) (pc)) (const_int 32764)))
562 ;; -------------------------------------------------------------------
563 ;; Subroutine calls and sibcalls
564 ;; -------------------------------------------------------------------
566 (define_expand "call"
567 [(parallel [(call (match_operand 0 "memory_operand" "")
568 (match_operand 1 "general_operand" ""))
569 (use (match_operand 2 "" ""))
570 (clobber (reg:DI LR_REGNUM))])]
576 /* In an untyped call, we can get NULL for operand 2. */
577 if (operands[2] == NULL)
578 operands[2] = const0_rtx;
580 /* Decide if we should generate indirect calls by loading the
581 64-bit address of the callee into a register before performing
582 the branch-and-link. */
583 callee = XEXP (operands[0], 0);
584 if (GET_CODE (callee) == SYMBOL_REF
585 ? aarch64_is_long_call_p (callee)
587 XEXP (operands[0], 0) = force_reg (Pmode, callee);
591 (define_insn "*call_reg"
592 [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
593 (match_operand 1 "" ""))
594 (use (match_operand 2 "" ""))
595 (clobber (reg:DI LR_REGNUM))]
598 [(set_attr "v8type" "call")
599 (set_attr "type" "call")]
602 (define_insn "*call_symbol"
603 [(call (mem:DI (match_operand:DI 0 "" ""))
604 (match_operand 1 "" ""))
605 (use (match_operand 2 "" ""))
606 (clobber (reg:DI LR_REGNUM))]
607 "GET_CODE (operands[0]) == SYMBOL_REF
608 && !aarch64_is_long_call_p (operands[0])"
610 [(set_attr "v8type" "call")
611 (set_attr "type" "call")]
614 (define_expand "call_value"
615 [(parallel [(set (match_operand 0 "" "")
616 (call (match_operand 1 "memory_operand" "")
617 (match_operand 2 "general_operand" "")))
618 (use (match_operand 3 "" ""))
619 (clobber (reg:DI LR_REGNUM))])]
625 /* In an untyped call, we can get NULL for operand 3. */
626 if (operands[3] == NULL)
627 operands[3] = const0_rtx;
629 /* Decide if we should generate indirect calls by loading the
630 64-bit address of the callee into a register before performing
631 the branch-and-link. */
632 callee = XEXP (operands[1], 0);
633 if (GET_CODE (callee) == SYMBOL_REF
634 ? aarch64_is_long_call_p (callee)
636 XEXP (operands[1], 0) = force_reg (Pmode, callee);
640 (define_insn "*call_value_reg"
641 [(set (match_operand 0 "" "")
642 (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
643 (match_operand 2 "" "")))
644 (use (match_operand 3 "" ""))
645 (clobber (reg:DI LR_REGNUM))]
648 [(set_attr "v8type" "call")
649 (set_attr "type" "call")]
653 (define_insn "*call_value_symbol"
654 [(set (match_operand 0 "" "")
655 (call (mem:DI (match_operand:DI 1 "" ""))
656 (match_operand 2 "" "")))
657 (use (match_operand 3 "" ""))
658 (clobber (reg:DI LR_REGNUM))]
659 "GET_CODE (operands[1]) == SYMBOL_REF
660 && !aarch64_is_long_call_p (operands[1])"
662 [(set_attr "v8type" "call")
663 (set_attr "type" "call")]
666 (define_expand "sibcall"
667 [(parallel [(call (match_operand 0 "memory_operand" "")
668 (match_operand 1 "general_operand" ""))
670 (use (match_operand 2 "" ""))])]
673 if (operands[2] == NULL_RTX)
674 operands[2] = const0_rtx;
678 (define_expand "sibcall_value"
679 [(parallel [(set (match_operand 0 "" "")
680 (call (match_operand 1 "memory_operand" "")
681 (match_operand 2 "general_operand" "")))
683 (use (match_operand 3 "" ""))])]
686 if (operands[3] == NULL_RTX)
687 operands[3] = const0_rtx;
691 (define_insn "*sibcall_insn"
692 [(call (mem:DI (match_operand:DI 0 "" "X"))
693 (match_operand 1 "" ""))
695 (use (match_operand 2 "" ""))]
696 "GET_CODE (operands[0]) == SYMBOL_REF"
698 [(set_attr "v8type" "branch")
699 (set_attr "type" "branch")]
703 (define_insn "*sibcall_value_insn"
704 [(set (match_operand 0 "" "")
705 (call (mem:DI (match_operand 1 "" "X"))
706 (match_operand 2 "" "")))
708 (use (match_operand 3 "" ""))]
709 "GET_CODE (operands[1]) == SYMBOL_REF"
711 [(set_attr "v8type" "branch")
712 (set_attr "type" "branch")]
715 ;; Call subroutine returning any type.
717 (define_expand "untyped_call"
718 [(parallel [(call (match_operand 0 "")
721 (match_operand 2 "")])]
726 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
728 for (i = 0; i < XVECLEN (operands[2], 0); i++)
730 rtx set = XVECEXP (operands[2], 0, i);
731 emit_move_insn (SET_DEST (set), SET_SRC (set));
734 /* The optimizer does not know that the call sets the function value
735 registers we stored in the result block. We avoid problems by
736 claiming that all hard registers are used and clobbered at this
738 emit_insn (gen_blockage ());
742 ;; -------------------------------------------------------------------
744 ;; -------------------------------------------------------------------
746 (define_expand "mov<mode>"
747 [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
748 (match_operand:SHORT 1 "general_operand" ""))]
751 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
752 operands[1] = force_reg (<MODE>mode, operands[1]);
756 (define_insn "*mov<mode>_aarch64"
757 [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r, *w,r,*w, m, m, r,*w,*w")
758 (match_operand:SHORT 1 "general_operand" " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
759 "(register_operand (operands[0], <MODE>mode)
760 || aarch64_reg_or_zero (operands[1], <MODE>mode))"
762 switch (which_alternative)
765 return "mov\t%w0, %w1";
767 return "mov\t%w0, %1";
769 return aarch64_output_scalar_simd_mov_immediate (operands[1],
772 return "ldr<size>\t%w0, %1";
774 return "ldr\t%<size>0, %1";
776 return "str<size>\t%w1, %0";
778 return "str\t%<size>1, %0";
780 return "umov\t%w0, %1.<v>[0]";
782 return "dup\t%0.<Vallxd>, %w1";
784 return "dup\t%0, %1.<v>[0]";
789 [(set_attr "v8type" "move,alu,alu,load1,load1,store1,store1,*,*,*")
790 (set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,*,*,*")
791 (set_attr "simd_type" "*,*,simd_move_imm,*,*,*,*,simd_movgp,simd_dupgp,simd_dup")
792 (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")
793 (set_attr "mode" "<MODE>")
794 (set_attr "simd_mode" "<MODE>")]
797 (define_expand "mov<mode>"
798 [(set (match_operand:GPI 0 "nonimmediate_operand" "")
799 (match_operand:GPI 1 "general_operand" ""))]
802 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
803 operands[1] = force_reg (<MODE>mode, operands[1]);
805 if (CONSTANT_P (operands[1]))
807 aarch64_expand_mov_immediate (operands[0], operands[1]);
813 (define_insn "*movsi_aarch64"
814 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m, m,r,r ,*w, r,*w")
815 (match_operand:SI 1 "aarch64_mov_operand" " r,r,k,M,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
816 "(register_operand (operands[0], SImode)
817 || aarch64_reg_or_zero (operands[1], SImode))"
832 [(set_attr "v8type" "move,move,move,alu,load1,load1,store1,store1,adr,adr,fmov,fmov,fmov")
833 (set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
834 adr,adr,mov_reg,mov_reg,mov_reg")
835 (set_attr "mode" "SI")
836 (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
839 (define_insn "*movdi_aarch64"
840 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m, m,r,r, *w, r,*w,w")
841 (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))]
842 "(register_operand (operands[0], DImode)
843 || aarch64_reg_or_zero (operands[1], DImode))"
859 [(set_attr "v8type" "move,move,move,alu,load1,load1,store1,store1,adr,adr,fmov,fmov,fmov,fmov")
860 (set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
861 adr,adr,mov_reg,mov_reg,mov_reg,mov_reg")
862 (set_attr "mode" "DI")
863 (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
864 (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
867 (define_insn "insv_imm<mode>"
868 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
870 (match_operand:GPI 1 "const_int_operand" "n"))
871 (match_operand:GPI 2 "const_int_operand" "n"))]
872 "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
873 && UINTVAL (operands[1]) % 16 == 0"
874 "movk\\t%<w>0, %X2, lsl %1"
875 [(set_attr "v8type" "movk")
876 (set_attr "type" "mov_imm")
877 (set_attr "mode" "<MODE>")]
880 (define_expand "movti"
881 [(set (match_operand:TI 0 "nonimmediate_operand" "")
882 (match_operand:TI 1 "general_operand" ""))]
885 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
886 operands[1] = force_reg (TImode, operands[1]);
890 (define_insn "*movti_aarch64"
891 [(set (match_operand:TI 0
892 "nonimmediate_operand" "=r, *w,r ,*w,r ,Ump,Ump,*w,m")
894 "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r ,Z , m,*w"))]
895 "(register_operand (operands[0], TImode)
896 || aarch64_reg_or_zero (operands[1], TImode))"
901 orr\\t%0.16b, %1.16b, %1.16b
907 [(set_attr "v8type" "move2,fmovi2f,fmovf2i,*, \
908 load2,store2,store2,fpsimd_load,fpsimd_store")
909 (set_attr "type" "mov_reg,f_mcr,f_mrc,*, \
910 load2,store2,store2,f_loadd,f_stored")
911 (set_attr "simd_type" "*,*,*,simd_move,*,*,*,*,*")
912 (set_attr "mode" "DI,DI,DI,TI,DI,DI,DI,TI,TI")
913 (set_attr "length" "8,8,8,4,4,4,4,4,4")
914 (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")
915 (set_attr "simd" "*,*,*,yes,*,*,*,*,*")])
917 ;; Split a TImode register-register or register-immediate move into
918 ;; its component DImode pieces, taking care to handle overlapping
919 ;; source and dest registers.
921 [(set (match_operand:TI 0 "register_operand" "")
922 (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
923 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
926 aarch64_split_128bit_move (operands[0], operands[1]);
930 (define_expand "mov<mode>"
931 [(set (match_operand:GPF 0 "nonimmediate_operand" "")
932 (match_operand:GPF 1 "general_operand" ""))]
937 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
941 if (GET_CODE (operands[0]) == MEM)
942 operands[1] = force_reg (<MODE>mode, operands[1]);
946 (define_insn "*movsf_aarch64"
947 [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
948 (match_operand:SF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
949 "TARGET_FLOAT && (register_operand (operands[0], SFmode)
950 || register_operand (operands[1], SFmode))"
961 [(set_attr "v8type" "fmovi2f,fmovf2i,\
962 fmov,fconst,fpsimd_load,\
963 fpsimd_store,fpsimd_load,fpsimd_store,fmov")
964 (set_attr "type" "f_mcr,f_mrc,mov_reg,fconsts,\
965 f_loads,f_stores,f_loads,f_stores,mov_reg")
966 (set_attr "mode" "SF")]
969 (define_insn "*movdf_aarch64"
970 [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
971 (match_operand:DF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
972 "TARGET_FLOAT && (register_operand (operands[0], DFmode)
973 || register_operand (operands[1], DFmode))"
984 [(set_attr "v8type" "fmovi2f,fmovf2i,\
985 fmov,fconst,fpsimd_load,\
986 fpsimd_store,fpsimd_load,fpsimd_store,move")
987 (set_attr "type" "f_mcr,f_mrc,mov_reg,fconstd,\
988 f_loadd,f_stored,f_loadd,f_stored,mov_reg")
989 (set_attr "mode" "DF")]
992 (define_expand "movtf"
993 [(set (match_operand:TF 0 "nonimmediate_operand" "")
994 (match_operand:TF 1 "general_operand" ""))]
999 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
1003 if (GET_CODE (operands[0]) == MEM)
1004 operands[1] = force_reg (TFmode, operands[1]);
1008 (define_insn "*movtf_aarch64"
1009 [(set (match_operand:TF 0
1010 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
1012 "general_operand" " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
1013 "TARGET_FLOAT && (register_operand (operands[0], TFmode)
1014 || register_operand (operands[1], TFmode))"
1016 orr\\t%0.16b, %1.16b, %1.16b
1026 [(set_attr "v8type" "logic,move2,fmovi2f,fmovf2i,fconst,fconst,fpsimd_load,fpsimd_store,fpsimd_load2,fpsimd_store2")
1027 (set_attr "type" "logic_reg,mov_reg,f_mcr,f_mrc,fconstd,fconstd,\
1028 f_loadd,f_stored,f_loadd,f_stored")
1029 (set_attr "mode" "DF,DF,DF,DF,DF,DF,TF,TF,DF,DF")
1030 (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
1031 (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
1032 (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
1036 [(set (match_operand:TF 0 "register_operand" "")
1037 (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
1038 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
1041 aarch64_split_128bit_move (operands[0], operands[1]);
1046 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1047 ;; fairly lax checking on the second memory operation.
1048 (define_insn "load_pair<mode>"
1049 [(set (match_operand:GPI 0 "register_operand" "=r")
1050 (match_operand:GPI 1 "aarch64_mem_pair_operand" "Ump"))
1051 (set (match_operand:GPI 2 "register_operand" "=r")
1052 (match_operand:GPI 3 "memory_operand" "m"))]
1053 "rtx_equal_p (XEXP (operands[3], 0),
1054 plus_constant (Pmode,
1055 XEXP (operands[1], 0),
1056 GET_MODE_SIZE (<MODE>mode)))"
1057 "ldp\\t%<w>0, %<w>2, %1"
1058 [(set_attr "v8type" "load2")
1059 (set_attr "type" "load2")
1060 (set_attr "mode" "<MODE>")]
1063 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1064 ;; fairly lax checking on the second memory operation.
1065 (define_insn "store_pair<mode>"
1066 [(set (match_operand:GPI 0 "aarch64_mem_pair_operand" "=Ump")
1067 (match_operand:GPI 1 "register_operand" "r"))
1068 (set (match_operand:GPI 2 "memory_operand" "=m")
1069 (match_operand:GPI 3 "register_operand" "r"))]
1070 "rtx_equal_p (XEXP (operands[2], 0),
1071 plus_constant (Pmode,
1072 XEXP (operands[0], 0),
1073 GET_MODE_SIZE (<MODE>mode)))"
1074 "stp\\t%<w>1, %<w>3, %0"
1075 [(set_attr "v8type" "store2")
1076 (set_attr "type" "store2")
1077 (set_attr "mode" "<MODE>")]
1080 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1081 ;; fairly lax checking on the second memory operation.
1082 (define_insn "load_pair<mode>"
1083 [(set (match_operand:GPF 0 "register_operand" "=w")
1084 (match_operand:GPF 1 "aarch64_mem_pair_operand" "Ump"))
1085 (set (match_operand:GPF 2 "register_operand" "=w")
1086 (match_operand:GPF 3 "memory_operand" "m"))]
1087 "rtx_equal_p (XEXP (operands[3], 0),
1088 plus_constant (Pmode,
1089 XEXP (operands[1], 0),
1090 GET_MODE_SIZE (<MODE>mode)))"
1091 "ldp\\t%<w>0, %<w>2, %1"
1092 [(set_attr "v8type" "fpsimd_load2")
1093 (set_attr "type" "f_load<s>")
1094 (set_attr "mode" "<MODE>")]
1097 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1098 ;; fairly lax checking on the second memory operation.
1099 (define_insn "store_pair<mode>"
1100 [(set (match_operand:GPF 0 "aarch64_mem_pair_operand" "=Ump")
1101 (match_operand:GPF 1 "register_operand" "w"))
1102 (set (match_operand:GPF 2 "memory_operand" "=m")
1103 (match_operand:GPF 3 "register_operand" "w"))]
1104 "rtx_equal_p (XEXP (operands[2], 0),
1105 plus_constant (Pmode,
1106 XEXP (operands[0], 0),
1107 GET_MODE_SIZE (<MODE>mode)))"
1108 "stp\\t%<w>1, %<w>3, %0"
1109 [(set_attr "v8type" "fpsimd_load2")
1110 (set_attr "type" "f_load<s>")
1111 (set_attr "mode" "<MODE>")]
1114 ;; Load pair with writeback. This is primarily used in function epilogues
1115 ;; when restoring [fp,lr]
1116 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
1118 [(set (match_operand:P 0 "register_operand" "=k")
1119 (plus:P (match_operand:P 1 "register_operand" "0")
1120 (match_operand:P 4 "const_int_operand" "n")))
1121 (set (match_operand:GPI 2 "register_operand" "=r")
1122 (mem:GPI (plus:P (match_dup 1)
1124 (set (match_operand:GPI 3 "register_operand" "=r")
1125 (mem:GPI (plus:P (match_dup 1)
1126 (match_operand:P 5 "const_int_operand" "n"))))])]
1127 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1128 "ldp\\t%<w>2, %<w>3, [%1], %4"
1129 [(set_attr "v8type" "load2")
1130 (set_attr "type" "load2")
1131 (set_attr "mode" "<GPI:MODE>")]
1134 ;; Store pair with writeback. This is primarily used in function prologues
1135 ;; when saving [fp,lr]
1136 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
1138 [(set (match_operand:P 0 "register_operand" "=&k")
1139 (plus:P (match_operand:P 1 "register_operand" "0")
1140 (match_operand:P 4 "const_int_operand" "n")))
1141 (set (mem:GPI (plus:P (match_dup 0)
1143 (match_operand:GPI 2 "register_operand" "r"))
1144 (set (mem:GPI (plus:P (match_dup 0)
1145 (match_operand:P 5 "const_int_operand" "n")))
1146 (match_operand:GPI 3 "register_operand" "r"))])]
1147 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1148 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1149 [(set_attr "v8type" "store2")
1150 (set_attr "type" "store2")
1151 (set_attr "mode" "<GPI:MODE>")]
1154 ;; -------------------------------------------------------------------
1155 ;; Sign/Zero extension
1156 ;; -------------------------------------------------------------------
1158 (define_expand "<optab>sidi2"
1159 [(set (match_operand:DI 0 "register_operand")
1160 (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1164 (define_insn "*extendsidi2_aarch64"
1165 [(set (match_operand:DI 0 "register_operand" "=r,r")
1166 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1171 [(set_attr "v8type" "extend,load1")
1172 (set_attr "type" "extend,load1")
1173 (set_attr "mode" "DI")]
1176 (define_insn "*zero_extendsidi2_aarch64"
1177 [(set (match_operand:DI 0 "register_operand" "=r,r")
1178 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1183 [(set_attr "v8type" "extend,load1")
1184 (set_attr "type" "extend,load1")
1185 (set_attr "mode" "DI")]
1188 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1189 [(set (match_operand:GPI 0 "register_operand")
1190 (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1194 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1195 [(set (match_operand:GPI 0 "register_operand" "=r,r")
1196 (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1199 sxt<SHORT:size>\t%<GPI:w>0, %w1
1200 ldrs<SHORT:size>\t%<GPI:w>0, %1"
1201 [(set_attr "v8type" "extend,load1")
1202 (set_attr "type" "extend,load1")
1203 (set_attr "mode" "<GPI:MODE>")]
1206 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1207 [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1208 (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1211 uxt<SHORT:size>\t%<GPI:w>0, %w1
1212 ldr<SHORT:size>\t%w0, %1
1213 ldr\t%<SHORT:size>0, %1"
1214 [(set_attr "v8type" "extend,load1,load1")
1215 (set_attr "type" "extend,load1,load1")
1216 (set_attr "mode" "<GPI:MODE>")]
1219 (define_expand "<optab>qihi2"
1220 [(set (match_operand:HI 0 "register_operand")
1221 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1225 (define_insn "*<optab>qihi2_aarch64"
1226 [(set (match_operand:HI 0 "register_operand" "=r,r")
1227 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1232 [(set_attr "v8type" "extend,load1")
1233 (set_attr "type" "extend,load1")
1234 (set_attr "mode" "HI")]
1237 ;; -------------------------------------------------------------------
1238 ;; Simple arithmetic
1239 ;; -------------------------------------------------------------------
1241 (define_expand "add<mode>3"
1243 (match_operand:GPI 0 "register_operand" "")
1244 (plus:GPI (match_operand:GPI 1 "register_operand" "")
1245 (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1248 if (! aarch64_plus_operand (operands[2], VOIDmode))
1250 rtx subtarget = ((optimize && can_create_pseudo_p ())
1251 ? gen_reg_rtx (<MODE>mode) : operands[0]);
1252 HOST_WIDE_INT imm = INTVAL (operands[2]);
1255 imm = -(-imm & ~0xfff);
1259 emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1260 operands[1] = subtarget;
1261 operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1266 (define_insn "*addsi3_aarch64"
1268 (match_operand:SI 0 "register_operand" "=rk,rk,rk")
1270 (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1271 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J")))]
1276 sub\\t%w0, %w1, #%n2"
1277 [(set_attr "v8type" "alu")
1278 (set_attr "type" "alu_imm,alu_reg,alu_imm")
1279 (set_attr "mode" "SI")]
1282 ;; zero_extend version of above
1283 (define_insn "*addsi3_aarch64_uxtw"
1285 (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1287 (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1288 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1293 sub\\t%w0, %w1, #%n2"
1294 [(set_attr "v8type" "alu")
1295 (set_attr "type" "alu_imm,alu_reg,alu_imm")
1296 (set_attr "mode" "SI")]
1299 (define_insn "*adddi3_aarch64"
1301 (match_operand:DI 0 "register_operand" "=rk,rk,rk,!w")
1303 (match_operand:DI 1 "register_operand" "%rk,rk,rk,!w")
1304 (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,!w")))]
1309 sub\\t%x0, %x1, #%n2
1310 add\\t%d0, %d1, %d2"
1311 [(set_attr "v8type" "alu")
1312 (set_attr "type" "alu_imm,alu_reg,alu_imm,alu_reg")
1313 (set_attr "mode" "DI")
1314 (set_attr "simd" "*,*,*,yes")]
1317 (define_insn "*add<mode>3_compare0"
1318 [(set (reg:CC_NZ CC_REGNUM)
1320 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1321 (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1323 (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1324 (plus:GPI (match_dup 1) (match_dup 2)))]
1327 adds\\t%<w>0, %<w>1, %<w>2
1328 adds\\t%<w>0, %<w>1, %<w>2
1329 subs\\t%<w>0, %<w>1, #%n2"
1330 [(set_attr "v8type" "alus")
1331 (set_attr "type" "alus_reg,alus_imm,alus_imm")
1332 (set_attr "mode" "<MODE>")]
1335 ;; zero_extend version of above
1336 (define_insn "*addsi3_compare0_uxtw"
1337 [(set (reg:CC_NZ CC_REGNUM)
1339 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1340 (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1342 (set (match_operand:DI 0 "register_operand" "=r,r,r")
1343 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1346 adds\\t%w0, %w1, %w2
1347 adds\\t%w0, %w1, %w2
1348 subs\\t%w0, %w1, #%n2"
1349 [(set_attr "v8type" "alus")
1350 (set_attr "type" "alus_reg,alus_imm,alus_imm")
1351 (set_attr "mode" "SI")]
1354 (define_insn "*adds_mul_imm_<mode>"
1355 [(set (reg:CC_NZ CC_REGNUM)
1358 (match_operand:GPI 1 "register_operand" "r")
1359 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1360 (match_operand:GPI 3 "register_operand" "rk"))
1362 (set (match_operand:GPI 0 "register_operand" "=r")
1363 (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1366 "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1367 [(set_attr "v8type" "alus_shift")
1368 (set_attr "type" "alus_shift_imm")
1369 (set_attr "mode" "<MODE>")]
1372 (define_insn "*subs_mul_imm_<mode>"
1373 [(set (reg:CC_NZ CC_REGNUM)
1375 (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
1377 (match_operand:GPI 2 "register_operand" "r")
1378 (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1380 (set (match_operand:GPI 0 "register_operand" "=r")
1381 (minus:GPI (match_dup 1)
1382 (mult:GPI (match_dup 2) (match_dup 3))))]
1384 "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1385 [(set_attr "v8type" "alus_shift")
1386 (set_attr "type" "alus_shift_imm")
1387 (set_attr "mode" "<MODE>")]
1390 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1391 [(set (reg:CC_NZ CC_REGNUM)
1394 (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1395 (match_operand:GPI 2 "register_operand" "r"))
1397 (set (match_operand:GPI 0 "register_operand" "=r")
1398 (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1400 "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1401 [(set_attr "v8type" "alus_ext")
1402 (set_attr "type" "alus_ext")
1403 (set_attr "mode" "<GPI:MODE>")]
1406 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1407 [(set (reg:CC_NZ CC_REGNUM)
1409 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1411 (match_operand:ALLX 2 "register_operand" "r")))
1413 (set (match_operand:GPI 0 "register_operand" "=r")
1414 (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1416 "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1417 [(set_attr "v8type" "alus_ext")
1418 (set_attr "type" "alus_ext")
1419 (set_attr "mode" "<GPI:MODE>")]
1422 (define_insn "*adds_<optab><mode>_multp2"
1423 [(set (reg:CC_NZ CC_REGNUM)
1425 (plus:GPI (ANY_EXTRACT:GPI
1426 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1427 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1428 (match_operand 3 "const_int_operand" "n")
1430 (match_operand:GPI 4 "register_operand" "r"))
1432 (set (match_operand:GPI 0 "register_operand" "=r")
1433 (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1437 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1438 "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1439 [(set_attr "v8type" "alus_ext")
1440 (set_attr "type" "alus_ext")
1441 (set_attr "mode" "<MODE>")]
1444 (define_insn "*subs_<optab><mode>_multp2"
1445 [(set (reg:CC_NZ CC_REGNUM)
1447 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1449 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1450 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1451 (match_operand 3 "const_int_operand" "n")
1454 (set (match_operand:GPI 0 "register_operand" "=r")
1455 (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1456 (mult:GPI (match_dup 1) (match_dup 2))
1459 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1460 "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1461 [(set_attr "v8type" "alus_ext")
1462 (set_attr "type" "alus_ext")
1463 (set_attr "mode" "<MODE>")]
1466 (define_insn "*add<mode>3nr_compare0"
1467 [(set (reg:CC_NZ CC_REGNUM)
1469 (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1470 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1477 [(set_attr "v8type" "alus")
1478 (set_attr "type" "alus_reg,alus_imm,alus_imm")
1479 (set_attr "mode" "<MODE>")]
1482 (define_insn "*compare_neg<mode>"
1483 [(set (reg:CC CC_REGNUM)
1485 (match_operand:GPI 0 "register_operand" "r")
1486 (neg:GPI (match_operand:GPI 1 "register_operand" "r"))))]
1488 "cmn\\t%<w>0, %<w>1"
1489 [(set_attr "v8type" "alus")
1490 (set_attr "type" "alus_reg")
1491 (set_attr "mode" "<MODE>")]
1494 (define_insn "*add_<shift>_<mode>"
1495 [(set (match_operand:GPI 0 "register_operand" "=rk")
1496 (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1497 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1498 (match_operand:GPI 3 "register_operand" "r")))]
1500 "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1501 [(set_attr "v8type" "alu_shift")
1502 (set_attr "type" "alu_shift_imm")
1503 (set_attr "mode" "<MODE>")]
1506 ;; zero_extend version of above
1507 (define_insn "*add_<shift>_si_uxtw"
1508 [(set (match_operand:DI 0 "register_operand" "=rk")
1510 (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1511 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1512 (match_operand:SI 3 "register_operand" "r"))))]
1514 "add\\t%w0, %w3, %w1, <shift> %2"
1515 [(set_attr "v8type" "alu_shift")
1516 (set_attr "type" "alu_shift_imm")
1517 (set_attr "mode" "SI")]
1520 (define_insn "*add_mul_imm_<mode>"
1521 [(set (match_operand:GPI 0 "register_operand" "=rk")
1522 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1523 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1524 (match_operand:GPI 3 "register_operand" "r")))]
1526 "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1527 [(set_attr "v8type" "alu_shift")
1528 (set_attr "type" "alu_shift_imm")
1529 (set_attr "mode" "<MODE>")]
1532 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1533 [(set (match_operand:GPI 0 "register_operand" "=rk")
1534 (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1535 (match_operand:GPI 2 "register_operand" "r")))]
1537 "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1538 [(set_attr "v8type" "alu_ext")
1539 (set_attr "type" "alu_ext")
1540 (set_attr "mode" "<GPI:MODE>")]
1543 ;; zero_extend version of above
1544 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1545 [(set (match_operand:DI 0 "register_operand" "=rk")
1547 (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1548 (match_operand:GPI 2 "register_operand" "r"))))]
1550 "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1551 [(set_attr "v8type" "alu_ext")
1552 (set_attr "type" "alu_ext")
1553 (set_attr "mode" "SI")]
1556 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1557 [(set (match_operand:GPI 0 "register_operand" "=rk")
1558 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1559 (match_operand:ALLX 1 "register_operand" "r"))
1560 (match_operand 2 "aarch64_imm3" "Ui3"))
1561 (match_operand:GPI 3 "register_operand" "r")))]
1563 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1564 [(set_attr "v8type" "alu_ext")
1565 (set_attr "type" "alu_ext")
1566 (set_attr "mode" "<GPI:MODE>")]
1569 ;; zero_extend version of above
1570 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1571 [(set (match_operand:DI 0 "register_operand" "=rk")
1573 (plus:SI (ashift:SI (ANY_EXTEND:SI
1574 (match_operand:SHORT 1 "register_operand" "r"))
1575 (match_operand 2 "aarch64_imm3" "Ui3"))
1576 (match_operand:SI 3 "register_operand" "r"))))]
1578 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1579 [(set_attr "v8type" "alu_ext")
1580 (set_attr "type" "alu_ext")
1581 (set_attr "mode" "SI")]
1584 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1585 [(set (match_operand:GPI 0 "register_operand" "=rk")
1586 (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1587 (match_operand:ALLX 1 "register_operand" "r"))
1588 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1589 (match_operand:GPI 3 "register_operand" "r")))]
1591 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1592 [(set_attr "v8type" "alu_ext")
1593 (set_attr "type" "alu_ext")
1594 (set_attr "mode" "<GPI:MODE>")]
1597 ;; zero_extend version of above
1598 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1599 [(set (match_operand:DI 0 "register_operand" "=rk")
1600 (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1601 (match_operand:SHORT 1 "register_operand" "r"))
1602 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1603 (match_operand:SI 3 "register_operand" "r"))))]
1605 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1606 [(set_attr "v8type" "alu_ext")
1607 (set_attr "type" "alu_ext")
1608 (set_attr "mode" "SI")]
1611 (define_insn "*add_<optab><mode>_multp2"
1612 [(set (match_operand:GPI 0 "register_operand" "=rk")
1613 (plus:GPI (ANY_EXTRACT:GPI
1614 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1615 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1616 (match_operand 3 "const_int_operand" "n")
1618 (match_operand:GPI 4 "register_operand" "r")))]
1619 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1620 "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1621 [(set_attr "v8type" "alu_ext")
1622 (set_attr "type" "alu_ext")
1623 (set_attr "mode" "<MODE>")]
1626 ;; zero_extend version of above
1627 (define_insn "*add_<optab>si_multp2_uxtw"
1628 [(set (match_operand:DI 0 "register_operand" "=rk")
1630 (plus:SI (ANY_EXTRACT:SI
1631 (mult:SI (match_operand:SI 1 "register_operand" "r")
1632 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1633 (match_operand 3 "const_int_operand" "n")
1635 (match_operand:SI 4 "register_operand" "r"))))]
1636 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1637 "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1638 [(set_attr "v8type" "alu_ext")
1639 (set_attr "type" "alu_ext")
1640 (set_attr "mode" "SI")]
1643 (define_insn "*add<mode>3_carryin"
1645 (match_operand:GPI 0 "register_operand" "=r")
1646 (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1648 (match_operand:GPI 1 "register_operand" "r")
1649 (match_operand:GPI 2 "register_operand" "r"))))]
1651 "adc\\t%<w>0, %<w>1, %<w>2"
1652 [(set_attr "v8type" "adc")
1653 (set_attr "type" "adc_reg")
1654 (set_attr "mode" "<MODE>")]
1657 ;; zero_extend version of above
1658 (define_insn "*addsi3_carryin_uxtw"
1660 (match_operand:DI 0 "register_operand" "=r")
1662 (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1664 (match_operand:SI 1 "register_operand" "r")
1665 (match_operand:SI 2 "register_operand" "r")))))]
1667 "adc\\t%w0, %w1, %w2"
1668 [(set_attr "v8type" "adc")
1669 (set_attr "type" "adc_reg")
1670 (set_attr "mode" "SI")]
1673 (define_insn "*add<mode>3_carryin_alt1"
1675 (match_operand:GPI 0 "register_operand" "=r")
1677 (match_operand:GPI 1 "register_operand" "r")
1678 (match_operand:GPI 2 "register_operand" "r"))
1679 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1681 "adc\\t%<w>0, %<w>1, %<w>2"
1682 [(set_attr "v8type" "adc")
1683 (set_attr "type" "adc_reg")
1684 (set_attr "mode" "<MODE>")]
1687 ;; zero_extend version of above
1688 (define_insn "*addsi3_carryin_alt1_uxtw"
1690 (match_operand:DI 0 "register_operand" "=r")
1693 (match_operand:SI 1 "register_operand" "r")
1694 (match_operand:SI 2 "register_operand" "r"))
1695 (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1697 "adc\\t%w0, %w1, %w2"
1698 [(set_attr "v8type" "adc")
1699 (set_attr "type" "adc_reg")
1700 (set_attr "mode" "SI")]
1703 (define_insn "*add<mode>3_carryin_alt2"
1705 (match_operand:GPI 0 "register_operand" "=r")
1707 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1708 (match_operand:GPI 1 "register_operand" "r"))
1709 (match_operand:GPI 2 "register_operand" "r")))]
1711 "adc\\t%<w>0, %<w>1, %<w>2"
1712 [(set_attr "v8type" "adc")
1713 (set_attr "type" "adc_reg")
1714 (set_attr "mode" "<MODE>")]
1717 ;; zero_extend version of above
1718 (define_insn "*addsi3_carryin_alt2_uxtw"
1720 (match_operand:DI 0 "register_operand" "=r")
1723 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1724 (match_operand:SI 1 "register_operand" "r"))
1725 (match_operand:SI 2 "register_operand" "r"))))]
1727 "adc\\t%w0, %w1, %w2"
1728 [(set_attr "v8type" "adc")
1729 (set_attr "type" "adc_reg")
1730 (set_attr "mode" "SI")]
1733 (define_insn "*add<mode>3_carryin_alt3"
1735 (match_operand:GPI 0 "register_operand" "=r")
1737 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1738 (match_operand:GPI 2 "register_operand" "r"))
1739 (match_operand:GPI 1 "register_operand" "r")))]
1741 "adc\\t%<w>0, %<w>1, %<w>2"
1742 [(set_attr "v8type" "adc")
1743 (set_attr "type" "adc_reg")
1744 (set_attr "mode" "<MODE>")]
1747 ;; zero_extend version of above
1748 (define_insn "*addsi3_carryin_alt3_uxtw"
1750 (match_operand:DI 0 "register_operand" "=r")
1753 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1754 (match_operand:SI 2 "register_operand" "r"))
1755 (match_operand:SI 1 "register_operand" "r"))))]
1757 "adc\\t%w0, %w1, %w2"
1758 [(set_attr "v8type" "adc")
1759 (set_attr "type" "adc_reg")
1760 (set_attr "mode" "SI")]
1763 (define_insn "*add_uxt<mode>_multp2"
1764 [(set (match_operand:GPI 0 "register_operand" "=rk")
1766 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1767 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1768 (match_operand 3 "const_int_operand" "n"))
1769 (match_operand:GPI 4 "register_operand" "r")))]
1770 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1772 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1773 INTVAL (operands[3])));
1774 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1775 [(set_attr "v8type" "alu_ext")
1776 (set_attr "type" "alu_ext")
1777 (set_attr "mode" "<MODE>")]
1780 ;; zero_extend version of above
1781 (define_insn "*add_uxtsi_multp2_uxtw"
1782 [(set (match_operand:DI 0 "register_operand" "=rk")
1785 (mult:SI (match_operand:SI 1 "register_operand" "r")
1786 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1787 (match_operand 3 "const_int_operand" "n"))
1788 (match_operand:SI 4 "register_operand" "r"))))]
1789 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1791 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1792 INTVAL (operands[3])));
1793 return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1794 [(set_attr "v8type" "alu_ext")
1795 (set_attr "type" "alu_ext")
1796 (set_attr "mode" "SI")]
1799 (define_insn "subsi3"
1800 [(set (match_operand:SI 0 "register_operand" "=rk")
1801 (minus:SI (match_operand:SI 1 "register_operand" "r")
1802 (match_operand:SI 2 "register_operand" "r")))]
1804 "sub\\t%w0, %w1, %w2"
1805 [(set_attr "v8type" "alu")
1806 (set_attr "type" "alu_reg")
1807 (set_attr "mode" "SI")]
1810 ;; zero_extend version of above
1811 (define_insn "*subsi3_uxtw"
1812 [(set (match_operand:DI 0 "register_operand" "=rk")
1814 (minus:SI (match_operand:SI 1 "register_operand" "r")
1815 (match_operand:SI 2 "register_operand" "r"))))]
1817 "sub\\t%w0, %w1, %w2"
1818 [(set_attr "v8type" "alu")
1819 (set_attr "type" "alu_reg")
1820 (set_attr "mode" "SI")]
1823 (define_insn "subdi3"
1824 [(set (match_operand:DI 0 "register_operand" "=rk,!w")
1825 (minus:DI (match_operand:DI 1 "register_operand" "r,!w")
1826 (match_operand:DI 2 "register_operand" "r,!w")))]
1830 sub\\t%d0, %d1, %d2"
1831 [(set_attr "v8type" "alu")
1832 (set_attr "type" "alu_reg")
1833 (set_attr "mode" "DI")
1834 (set_attr "simd" "*,yes")]
1838 (define_insn "*sub<mode>3_compare0"
1839 [(set (reg:CC_NZ CC_REGNUM)
1840 (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1841 (match_operand:GPI 2 "register_operand" "r"))
1843 (set (match_operand:GPI 0 "register_operand" "=r")
1844 (minus:GPI (match_dup 1) (match_dup 2)))]
1846 "subs\\t%<w>0, %<w>1, %<w>2"
1847 [(set_attr "v8type" "alus")
1848 (set_attr "type" "alus_reg")
1849 (set_attr "mode" "<MODE>")]
1852 ;; zero_extend version of above
1853 (define_insn "*subsi3_compare0_uxtw"
1854 [(set (reg:CC_NZ CC_REGNUM)
1855 (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1856 (match_operand:SI 2 "register_operand" "r"))
1858 (set (match_operand:DI 0 "register_operand" "=r")
1859 (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1861 "subs\\t%w0, %w1, %w2"
1862 [(set_attr "v8type" "alus")
1863 (set_attr "type" "alus_reg")
1864 (set_attr "mode" "SI")]
1867 (define_insn "*sub_<shift>_<mode>"
1868 [(set (match_operand:GPI 0 "register_operand" "=rk")
1869 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1871 (match_operand:GPI 1 "register_operand" "r")
1872 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1874 "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1875 [(set_attr "v8type" "alu_shift")
1876 (set_attr "type" "alu_shift_imm")
1877 (set_attr "mode" "<MODE>")]
1880 ;; zero_extend version of above
1881 (define_insn "*sub_<shift>_si_uxtw"
1882 [(set (match_operand:DI 0 "register_operand" "=rk")
1884 (minus:SI (match_operand:SI 3 "register_operand" "r")
1886 (match_operand:SI 1 "register_operand" "r")
1887 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1889 "sub\\t%w0, %w3, %w1, <shift> %2"
1890 [(set_attr "v8type" "alu_shift")
1891 (set_attr "type" "alu_shift_imm")
1892 (set_attr "mode" "SI")]
1895 (define_insn "*sub_mul_imm_<mode>"
1896 [(set (match_operand:GPI 0 "register_operand" "=rk")
1897 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1899 (match_operand:GPI 1 "register_operand" "r")
1900 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1902 "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1903 [(set_attr "v8type" "alu_shift")
1904 (set_attr "type" "alu_shift_imm")
1905 (set_attr "mode" "<MODE>")]
1908 ;; zero_extend version of above
1909 (define_insn "*sub_mul_imm_si_uxtw"
1910 [(set (match_operand:DI 0 "register_operand" "=rk")
1912 (minus:SI (match_operand:SI 3 "register_operand" "r")
1914 (match_operand:SI 1 "register_operand" "r")
1915 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
1917 "sub\\t%w0, %w3, %w1, lsl %p2"
1918 [(set_attr "v8type" "alu_shift")
1919 (set_attr "type" "alu_shift_imm")
1920 (set_attr "mode" "SI")]
1923 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
1924 [(set (match_operand:GPI 0 "register_operand" "=rk")
1925 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1927 (match_operand:ALLX 2 "register_operand" "r"))))]
1929 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1930 [(set_attr "v8type" "alu_ext")
1931 (set_attr "type" "alu_ext")
1932 (set_attr "mode" "<GPI:MODE>")]
1935 ;; zero_extend version of above
1936 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
1937 [(set (match_operand:DI 0 "register_operand" "=rk")
1939 (minus:SI (match_operand:SI 1 "register_operand" "r")
1941 (match_operand:SHORT 2 "register_operand" "r")))))]
1943 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
1944 [(set_attr "v8type" "alu_ext")
1945 (set_attr "type" "alu_ext")
1946 (set_attr "mode" "SI")]
1949 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
1950 [(set (match_operand:GPI 0 "register_operand" "=rk")
1951 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1952 (ashift:GPI (ANY_EXTEND:GPI
1953 (match_operand:ALLX 2 "register_operand" "r"))
1954 (match_operand 3 "aarch64_imm3" "Ui3"))))]
1956 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1957 [(set_attr "v8type" "alu_ext")
1958 (set_attr "type" "alu_ext")
1959 (set_attr "mode" "<GPI:MODE>")]
1962 ;; zero_extend version of above
1963 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
1964 [(set (match_operand:DI 0 "register_operand" "=rk")
1966 (minus:SI (match_operand:SI 1 "register_operand" "r")
1967 (ashift:SI (ANY_EXTEND:SI
1968 (match_operand:SHORT 2 "register_operand" "r"))
1969 (match_operand 3 "aarch64_imm3" "Ui3")))))]
1971 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
1972 [(set_attr "v8type" "alu_ext")
1973 (set_attr "type" "alu_ext")
1974 (set_attr "mode" "SI")]
1977 (define_insn "*sub_<optab><mode>_multp2"
1978 [(set (match_operand:GPI 0 "register_operand" "=rk")
1979 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1981 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1982 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1983 (match_operand 3 "const_int_operand" "n")
1985 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1986 "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1987 [(set_attr "v8type" "alu_ext")
1988 (set_attr "type" "alu_ext")
1989 (set_attr "mode" "<MODE>")]
1992 ;; zero_extend version of above
1993 (define_insn "*sub_<optab>si_multp2_uxtw"
1994 [(set (match_operand:DI 0 "register_operand" "=rk")
1996 (minus:SI (match_operand:SI 4 "register_operand" "r")
1998 (mult:SI (match_operand:SI 1 "register_operand" "r")
1999 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2000 (match_operand 3 "const_int_operand" "n")
2002 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
2003 "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
2004 [(set_attr "v8type" "alu_ext")
2005 (set_attr "type" "alu_ext")
2006 (set_attr "mode" "SI")]
2009 (define_insn "*sub<mode>3_carryin"
2011 (match_operand:GPI 0 "register_operand" "=r")
2012 (minus:GPI (minus:GPI
2013 (match_operand:GPI 1 "register_operand" "r")
2014 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2015 (match_operand:GPI 2 "register_operand" "r")))]
2017 "sbc\\t%<w>0, %<w>1, %<w>2"
2018 [(set_attr "v8type" "adc")
2019 (set_attr "type" "adc_reg")
2020 (set_attr "mode" "<MODE>")]
2023 ;; zero_extend version of the above
2024 (define_insn "*subsi3_carryin_uxtw"
2026 (match_operand:DI 0 "register_operand" "=r")
2029 (match_operand:SI 1 "register_operand" "r")
2030 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2031 (match_operand:SI 2 "register_operand" "r"))))]
2033 "sbc\\t%w0, %w1, %w2"
2034 [(set_attr "v8type" "adc")
2035 (set_attr "type" "adc_reg")
2036 (set_attr "mode" "SI")]
2039 (define_insn "*sub_uxt<mode>_multp2"
2040 [(set (match_operand:GPI 0 "register_operand" "=rk")
2041 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
2043 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2044 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2045 (match_operand 3 "const_int_operand" "n"))))]
2046 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2048 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2049 INTVAL (operands[3])));
2050 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
2051 [(set_attr "v8type" "alu_ext")
2052 (set_attr "type" "alu_ext")
2053 (set_attr "mode" "<MODE>")]
2056 ;; zero_extend version of above
2057 (define_insn "*sub_uxtsi_multp2_uxtw"
2058 [(set (match_operand:DI 0 "register_operand" "=rk")
2060 (minus:SI (match_operand:SI 4 "register_operand" "r")
2062 (mult:SI (match_operand:SI 1 "register_operand" "r")
2063 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2064 (match_operand 3 "const_int_operand" "n")))))]
2065 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2067 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2068 INTVAL (operands[3])));
2069 return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
2070 [(set_attr "v8type" "alu_ext")
2071 (set_attr "type" "alu_ext")
2072 (set_attr "mode" "SI")]
2075 (define_insn_and_split "absdi2"
2076 [(set (match_operand:DI 0 "register_operand" "=r,w")
2077 (abs:DI (match_operand:DI 1 "register_operand" "r,w")))
2078 (clobber (match_scratch:DI 2 "=&r,X"))]
2084 && GP_REGNUM_P (REGNO (operands[0]))
2085 && GP_REGNUM_P (REGNO (operands[1]))"
2088 emit_insn (gen_rtx_SET (VOIDmode, operands[2],
2089 gen_rtx_XOR (DImode,
2090 gen_rtx_ASHIFTRT (DImode,
2094 emit_insn (gen_rtx_SET (VOIDmode,
2096 gen_rtx_MINUS (DImode,
2098 gen_rtx_ASHIFTRT (DImode,
2103 [(set_attr "v8type" "alu")
2104 (set_attr "type" "alu_reg")
2105 (set_attr "mode" "DI")]
2108 (define_insn "neg<mode>2"
2109 [(set (match_operand:GPI 0 "register_operand" "=r,w")
2110 (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
2114 neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
2115 [(set_attr "v8type" "alu")
2116 (set_attr "type" "alu_reg")
2117 (set_attr "simd_type" "*,simd_negabs")
2118 (set_attr "simd" "*,yes")
2119 (set_attr "mode" "<MODE>")
2120 (set_attr "simd_mode" "<MODE>")]
2123 ;; zero_extend version of above
2124 (define_insn "*negsi2_uxtw"
2125 [(set (match_operand:DI 0 "register_operand" "=r")
2126 (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
2129 [(set_attr "v8type" "alu")
2130 (set_attr "type" "alu_reg")
2131 (set_attr "mode" "SI")]
2134 (define_insn "*ngc<mode>"
2135 [(set (match_operand:GPI 0 "register_operand" "=r")
2136 (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2137 (match_operand:GPI 1 "register_operand" "r")))]
2139 "ngc\\t%<w>0, %<w>1"
2140 [(set_attr "v8type" "adc")
2141 (set_attr "type" "adc_reg")
2142 (set_attr "mode" "<MODE>")]
2145 (define_insn "*ngcsi_uxtw"
2146 [(set (match_operand:DI 0 "register_operand" "=r")
2148 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2149 (match_operand:SI 1 "register_operand" "r"))))]
2152 [(set_attr "v8type" "adc")
2153 (set_attr "type" "adc_reg")
2154 (set_attr "mode" "SI")]
2157 (define_insn "*neg<mode>2_compare0"
2158 [(set (reg:CC_NZ CC_REGNUM)
2159 (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2161 (set (match_operand:GPI 0 "register_operand" "=r")
2162 (neg:GPI (match_dup 1)))]
2164 "negs\\t%<w>0, %<w>1"
2165 [(set_attr "v8type" "alus")
2166 (set_attr "type" "alus_reg")
2167 (set_attr "mode" "<MODE>")]
2170 ;; zero_extend version of above
2171 (define_insn "*negsi2_compare0_uxtw"
2172 [(set (reg:CC_NZ CC_REGNUM)
2173 (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
2175 (set (match_operand:DI 0 "register_operand" "=r")
2176 (zero_extend:DI (neg:SI (match_dup 1))))]
2179 [(set_attr "v8type" "alus")
2180 (set_attr "type" "alus_reg")
2181 (set_attr "mode" "SI")]
2184 (define_insn "*neg_<shift><mode>3_compare0"
2185 [(set (reg:CC_NZ CC_REGNUM)
2187 (neg:GPI (ASHIFT:GPI
2188 (match_operand:GPI 1 "register_operand" "r")
2189 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2191 (set (match_operand:GPI 0 "register_operand" "=r")
2192 (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2194 "negs\\t%<w>0, %<w>1, <shift> %2"
2195 [(set_attr "v8type" "alus_shift")
2196 (set_attr "type" "alus_shift_imm")
2197 (set_attr "mode" "<MODE>")]
2200 (define_insn "*neg_<shift>_<mode>2"
2201 [(set (match_operand:GPI 0 "register_operand" "=r")
2202 (neg:GPI (ASHIFT:GPI
2203 (match_operand:GPI 1 "register_operand" "r")
2204 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2206 "neg\\t%<w>0, %<w>1, <shift> %2"
2207 [(set_attr "v8type" "alu_shift")
2208 (set_attr "type" "alu_shift_imm")
2209 (set_attr "mode" "<MODE>")]
2212 ;; zero_extend version of above
2213 (define_insn "*neg_<shift>_si2_uxtw"
2214 [(set (match_operand:DI 0 "register_operand" "=r")
2217 (match_operand:SI 1 "register_operand" "r")
2218 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2220 "neg\\t%w0, %w1, <shift> %2"
2221 [(set_attr "v8type" "alu_shift")
2222 (set_attr "type" "alu_shift_imm")
2223 (set_attr "mode" "SI")]
2226 (define_insn "*neg_mul_imm_<mode>2"
2227 [(set (match_operand:GPI 0 "register_operand" "=r")
2229 (match_operand:GPI 1 "register_operand" "r")
2230 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2232 "neg\\t%<w>0, %<w>1, lsl %p2"
2233 [(set_attr "v8type" "alu_shift")
2234 (set_attr "type" "alu_shift_imm")
2235 (set_attr "mode" "<MODE>")]
2238 ;; zero_extend version of above
2239 (define_insn "*neg_mul_imm_si2_uxtw"
2240 [(set (match_operand:DI 0 "register_operand" "=r")
2243 (match_operand:SI 1 "register_operand" "r")
2244 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2246 "neg\\t%w0, %w1, lsl %p2"
2247 [(set_attr "v8type" "alu_shift")
2248 (set_attr "type" "alu_shift_imm")
2249 (set_attr "mode" "SI")]
2252 (define_insn "mul<mode>3"
2253 [(set (match_operand:GPI 0 "register_operand" "=r")
2254 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2255 (match_operand:GPI 2 "register_operand" "r")))]
2257 "mul\\t%<w>0, %<w>1, %<w>2"
2258 [(set_attr "v8type" "mult")
2259 (set_attr "type" "mul")
2260 (set_attr "mode" "<MODE>")]
2263 ;; zero_extend version of above
2264 (define_insn "*mulsi3_uxtw"
2265 [(set (match_operand:DI 0 "register_operand" "=r")
2267 (mult:SI (match_operand:SI 1 "register_operand" "r")
2268 (match_operand:SI 2 "register_operand" "r"))))]
2270 "mul\\t%w0, %w1, %w2"
2271 [(set_attr "v8type" "mult")
2272 (set_attr "type" "mul")
2273 (set_attr "mode" "SI")]
2276 (define_insn "*madd<mode>"
2277 [(set (match_operand:GPI 0 "register_operand" "=r")
2278 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2279 (match_operand:GPI 2 "register_operand" "r"))
2280 (match_operand:GPI 3 "register_operand" "r")))]
2282 "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2283 [(set_attr "v8type" "madd")
2284 (set_attr "type" "mul")
2285 (set_attr "mode" "<MODE>")]
2288 ;; zero_extend version of above
2289 (define_insn "*maddsi_uxtw"
2290 [(set (match_operand:DI 0 "register_operand" "=r")
2292 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2293 (match_operand:SI 2 "register_operand" "r"))
2294 (match_operand:SI 3 "register_operand" "r"))))]
2296 "madd\\t%w0, %w1, %w2, %w3"
2297 [(set_attr "v8type" "madd")
2298 (set_attr "type" "mul")
2299 (set_attr "mode" "SI")]
2302 (define_insn "*msub<mode>"
2303 [(set (match_operand:GPI 0 "register_operand" "=r")
2304 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2305 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2306 (match_operand:GPI 2 "register_operand" "r"))))]
2309 "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2310 [(set_attr "v8type" "madd")
2311 (set_attr "type" "mul")
2312 (set_attr "mode" "<MODE>")]
2315 ;; zero_extend version of above
2316 (define_insn "*msubsi_uxtw"
2317 [(set (match_operand:DI 0 "register_operand" "=r")
2319 (minus:SI (match_operand:SI 3 "register_operand" "r")
2320 (mult:SI (match_operand:SI 1 "register_operand" "r")
2321 (match_operand:SI 2 "register_operand" "r")))))]
2324 "msub\\t%w0, %w1, %w2, %w3"
2325 [(set_attr "v8type" "madd")
2326 (set_attr "type" "mul")
2327 (set_attr "mode" "SI")]
2330 (define_insn "*mul<mode>_neg"
2331 [(set (match_operand:GPI 0 "register_operand" "=r")
2332 (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2333 (match_operand:GPI 2 "register_operand" "r")))]
2336 "mneg\\t%<w>0, %<w>1, %<w>2"
2337 [(set_attr "v8type" "mult")
2338 (set_attr "type" "mul")
2339 (set_attr "mode" "<MODE>")]
2342 ;; zero_extend version of above
2343 (define_insn "*mulsi_neg_uxtw"
2344 [(set (match_operand:DI 0 "register_operand" "=r")
2346 (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2347 (match_operand:SI 2 "register_operand" "r"))))]
2350 "mneg\\t%w0, %w1, %w2"
2351 [(set_attr "v8type" "mult")
2352 (set_attr "type" "mul")
2353 (set_attr "mode" "SI")]
2356 (define_insn "<su_optab>mulsidi3"
2357 [(set (match_operand:DI 0 "register_operand" "=r")
2358 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2359 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2361 "<su>mull\\t%0, %w1, %w2"
2362 [(set_attr "v8type" "mull")
2363 (set_attr "type" "<su>mull")
2364 (set_attr "mode" "DI")]
2367 (define_insn "<su_optab>maddsidi4"
2368 [(set (match_operand:DI 0 "register_operand" "=r")
2370 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2371 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2372 (match_operand:DI 3 "register_operand" "r")))]
2374 "<su>maddl\\t%0, %w1, %w2, %3"
2375 [(set_attr "v8type" "maddl")
2376 (set_attr "type" "mul")
2377 (set_attr "mode" "DI")]
2380 (define_insn "<su_optab>msubsidi4"
2381 [(set (match_operand:DI 0 "register_operand" "=r")
2383 (match_operand:DI 3 "register_operand" "r")
2384 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2386 (match_operand:SI 2 "register_operand" "r")))))]
2388 "<su>msubl\\t%0, %w1, %w2, %3"
2389 [(set_attr "v8type" "maddl")
2390 (set_attr "type" "mul")
2391 (set_attr "mode" "DI")]
2394 (define_insn "*<su_optab>mulsidi_neg"
2395 [(set (match_operand:DI 0 "register_operand" "=r")
2397 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2398 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2400 "<su>mnegl\\t%0, %w1, %w2"
2401 [(set_attr "v8type" "mull")
2402 (set_attr "type" "<su>mull")
2403 (set_attr "mode" "DI")]
2406 (define_insn "<su>muldi3_highpart"
2407 [(set (match_operand:DI 0 "register_operand" "=r")
2411 (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2412 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2415 "<su>mulh\\t%0, %1, %2"
2416 [(set_attr "v8type" "mulh")
2417 (set_attr "type" "<su>mull")
2418 (set_attr "mode" "DI")]
2421 (define_insn "<su_optab>div<mode>3"
2422 [(set (match_operand:GPI 0 "register_operand" "=r")
2423 (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2424 (match_operand:GPI 2 "register_operand" "r")))]
2426 "<su>div\\t%<w>0, %<w>1, %<w>2"
2427 [(set_attr "v8type" "<su>div")
2428 (set_attr "type" "<su>div")
2429 (set_attr "mode" "<MODE>")]
2432 ;; zero_extend version of above
2433 (define_insn "*<su_optab>divsi3_uxtw"
2434 [(set (match_operand:DI 0 "register_operand" "=r")
2436 (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2437 (match_operand:SI 2 "register_operand" "r"))))]
2439 "<su>div\\t%w0, %w1, %w2"
2440 [(set_attr "v8type" "<su>div")
2441 (set_attr "type" "<su>div")
2442 (set_attr "mode" "SI")]
2445 ;; -------------------------------------------------------------------
2447 ;; -------------------------------------------------------------------
2449 (define_insn "*cmp<mode>"
2450 [(set (reg:CC CC_REGNUM)
2451 (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2452 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2458 [(set_attr "v8type" "alus")
2459 (set_attr "type" "alus_reg,alus_imm,alus_imm")
2460 (set_attr "mode" "<MODE>")]
2463 (define_insn "*cmp<mode>"
2464 [(set (reg:CCFP CC_REGNUM)
2465 (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2466 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2470 fcmp\\t%<s>0, %<s>1"
2471 [(set_attr "v8type" "fcmp")
2472 (set_attr "type" "fcmp<s>")
2473 (set_attr "mode" "<MODE>")]
2476 (define_insn "*cmpe<mode>"
2477 [(set (reg:CCFPE CC_REGNUM)
2478 (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2479 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2483 fcmpe\\t%<s>0, %<s>1"
2484 [(set_attr "v8type" "fcmp")
2485 (set_attr "type" "fcmp<s>")
2486 (set_attr "mode" "<MODE>")]
2489 (define_insn "*cmp_swp_<shift>_reg<mode>"
2490 [(set (reg:CC_SWP CC_REGNUM)
2491 (compare:CC_SWP (ASHIFT:GPI
2492 (match_operand:GPI 0 "register_operand" "r")
2493 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2494 (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2496 "cmp\\t%<w>2, %<w>0, <shift> %1"
2497 [(set_attr "v8type" "alus_shift")
2498 (set_attr "type" "alus_shift_imm")
2499 (set_attr "mode" "<MODE>")]
2502 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2503 [(set (reg:CC_SWP CC_REGNUM)
2504 (compare:CC_SWP (ANY_EXTEND:GPI
2505 (match_operand:ALLX 0 "register_operand" "r"))
2506 (match_operand:GPI 1 "register_operand" "r")))]
2508 "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2509 [(set_attr "v8type" "alus_ext")
2510 (set_attr "type" "alus_ext")
2511 (set_attr "mode" "<GPI:MODE>")]
2514 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2515 [(set (reg:CC_SWP CC_REGNUM)
2516 (compare:CC_SWP (ashift:GPI
2518 (match_operand:ALLX 0 "register_operand" "r"))
2519 (match_operand 1 "aarch64_imm3" "Ui3"))
2520 (match_operand:GPI 2 "register_operand" "r")))]
2522 "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2523 [(set_attr "v8type" "alus_ext")
2524 (set_attr "type" "alus_ext")
2525 (set_attr "mode" "<GPI:MODE>")]
2528 ;; -------------------------------------------------------------------
2529 ;; Store-flag and conditional select insns
2530 ;; -------------------------------------------------------------------
2532 (define_expand "cstore<mode>4"
2533 [(set (match_operand:SI 0 "register_operand" "")
2534 (match_operator:SI 1 "aarch64_comparison_operator"
2535 [(match_operand:GPI 2 "register_operand" "")
2536 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2539 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2541 operands[3] = const0_rtx;
2545 (define_expand "cstore<mode>4"
2546 [(set (match_operand:SI 0 "register_operand" "")
2547 (match_operator:SI 1 "aarch64_comparison_operator"
2548 [(match_operand:GPF 2 "register_operand" "")
2549 (match_operand:GPF 3 "register_operand" "")]))]
2552 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2554 operands[3] = const0_rtx;
2558 (define_insn "*cstore<mode>_insn"
2559 [(set (match_operand:ALLI 0 "register_operand" "=r")
2560 (match_operator:ALLI 1 "aarch64_comparison_operator"
2561 [(match_operand 2 "cc_register" "") (const_int 0)]))]
2564 [(set_attr "v8type" "csel")
2565 (set_attr "type" "csel")
2566 (set_attr "mode" "<MODE>")]
2569 ;; zero_extend version of the above
2570 (define_insn "*cstoresi_insn_uxtw"
2571 [(set (match_operand:DI 0 "register_operand" "=r")
2573 (match_operator:SI 1 "aarch64_comparison_operator"
2574 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2577 [(set_attr "v8type" "csel")
2578 (set_attr "type" "csel")
2579 (set_attr "mode" "SI")]
2582 (define_insn "cstore<mode>_neg"
2583 [(set (match_operand:ALLI 0 "register_operand" "=r")
2584 (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2585 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2587 "csetm\\t%<w>0, %m1"
2588 [(set_attr "v8type" "csel")
2589 (set_attr "type" "csel")
2590 (set_attr "mode" "<MODE>")]
2593 ;; zero_extend version of the above
2594 (define_insn "*cstoresi_neg_uxtw"
2595 [(set (match_operand:DI 0 "register_operand" "=r")
2597 (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2598 [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2601 [(set_attr "v8type" "csel")
2602 (set_attr "type" "csel")
2603 (set_attr "mode" "SI")]
2606 (define_expand "cmov<mode>6"
2607 [(set (match_operand:GPI 0 "register_operand" "")
2609 (match_operator 1 "aarch64_comparison_operator"
2610 [(match_operand:GPI 2 "register_operand" "")
2611 (match_operand:GPI 3 "aarch64_plus_operand" "")])
2612 (match_operand:GPI 4 "register_operand" "")
2613 (match_operand:GPI 5 "register_operand" "")))]
2616 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2618 operands[3] = const0_rtx;
2622 (define_expand "cmov<mode>6"
2623 [(set (match_operand:GPF 0 "register_operand" "")
2625 (match_operator 1 "aarch64_comparison_operator"
2626 [(match_operand:GPF 2 "register_operand" "")
2627 (match_operand:GPF 3 "register_operand" "")])
2628 (match_operand:GPF 4 "register_operand" "")
2629 (match_operand:GPF 5 "register_operand" "")))]
2632 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2634 operands[3] = const0_rtx;
2638 (define_insn "*cmov<mode>_insn"
2639 [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2641 (match_operator 1 "aarch64_comparison_operator"
2642 [(match_operand 2 "cc_register" "") (const_int 0)])
2643 (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2644 (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2645 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2646 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2647 ;; Final two alternatives should be unreachable, but included for completeness
2649 csel\\t%<w>0, %<w>3, %<w>4, %m1
2650 csinv\\t%<w>0, %<w>3, <w>zr, %m1
2651 csinv\\t%<w>0, %<w>4, <w>zr, %M1
2652 csinc\\t%<w>0, %<w>3, <w>zr, %m1
2653 csinc\\t%<w>0, %<w>4, <w>zr, %M1
2656 [(set_attr "v8type" "csel")
2657 (set_attr "type" "csel")
2658 (set_attr "mode" "<MODE>")]
2661 ;; zero_extend version of above
2662 (define_insn "*cmovsi_insn_uxtw"
2663 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2666 (match_operator 1 "aarch64_comparison_operator"
2667 [(match_operand 2 "cc_register" "") (const_int 0)])
2668 (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2669 (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2670 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2671 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2672 ;; Final two alternatives should be unreachable, but included for completeness
2674 csel\\t%w0, %w3, %w4, %m1
2675 csinv\\t%w0, %w3, wzr, %m1
2676 csinv\\t%w0, %w4, wzr, %M1
2677 csinc\\t%w0, %w3, wzr, %m1
2678 csinc\\t%w0, %w4, wzr, %M1
2681 [(set_attr "v8type" "csel")
2682 (set_attr "type" "csel")
2683 (set_attr "mode" "SI")]
2686 (define_insn "*cmov<mode>_insn"
2687 [(set (match_operand:GPF 0 "register_operand" "=w")
2689 (match_operator 1 "aarch64_comparison_operator"
2690 [(match_operand 2 "cc_register" "") (const_int 0)])
2691 (match_operand:GPF 3 "register_operand" "w")
2692 (match_operand:GPF 4 "register_operand" "w")))]
2694 "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2695 [(set_attr "v8type" "fcsel")
2696 (set_attr "type" "fcsel")
2697 (set_attr "mode" "<MODE>")]
2700 (define_expand "mov<mode>cc"
2701 [(set (match_operand:ALLI 0 "register_operand" "")
2702 (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2703 (match_operand:ALLI 2 "register_operand" "")
2704 (match_operand:ALLI 3 "register_operand" "")))]
2708 enum rtx_code code = GET_CODE (operands[1]);
2710 if (code == UNEQ || code == LTGT)
2713 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2714 XEXP (operands[1], 1));
2715 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2719 (define_expand "mov<GPF:mode><GPI:mode>cc"
2720 [(set (match_operand:GPI 0 "register_operand" "")
2721 (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2722 (match_operand:GPF 2 "register_operand" "")
2723 (match_operand:GPF 3 "register_operand" "")))]
2727 enum rtx_code code = GET_CODE (operands[1]);
2729 if (code == UNEQ || code == LTGT)
2732 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2733 XEXP (operands[1], 1));
2734 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2738 (define_insn "*csinc2<mode>_insn"
2739 [(set (match_operand:GPI 0 "register_operand" "=r")
2740 (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator"
2741 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
2742 (match_operand:GPI 1 "register_operand" "r")))]
2744 "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2745 [(set_attr "v8type" "csel")
2746 (set_attr "type" "csel")
2747 (set_attr "mode" "<MODE>")])
2749 (define_insn "csinc3<mode>_insn"
2750 [(set (match_operand:GPI 0 "register_operand" "=r")
2752 (match_operator:GPI 1 "aarch64_comparison_operator"
2753 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2754 (plus:GPI (match_operand:GPI 3 "register_operand" "r")
2756 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2758 "csinc\\t%<w>0, %<w>4, %<w>3, %M1"
2759 [(set_attr "v8type" "csel")
2760 (set_attr "type" "csel")
2761 (set_attr "mode" "<MODE>")]
2764 (define_insn "*csinv3<mode>_insn"
2765 [(set (match_operand:GPI 0 "register_operand" "=r")
2767 (match_operator:GPI 1 "aarch64_comparison_operator"
2768 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2769 (not:GPI (match_operand:GPI 3 "register_operand" "r"))
2770 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2772 "csinv\\t%<w>0, %<w>4, %<w>3, %M1"
2773 [(set_attr "v8type" "csel")
2774 (set_attr "type" "csel")
2775 (set_attr "mode" "<MODE>")])
2777 (define_insn "*csneg3<mode>_insn"
2778 [(set (match_operand:GPI 0 "register_operand" "=r")
2780 (match_operator:GPI 1 "aarch64_comparison_operator"
2781 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2782 (neg:GPI (match_operand:GPI 3 "register_operand" "r"))
2783 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2785 "csneg\\t%<w>0, %<w>4, %<w>3, %M1"
2786 [(set_attr "v8type" "csel")
2787 (set_attr "type" "csel")
2788 (set_attr "mode" "<MODE>")])
2790 ;; -------------------------------------------------------------------
2791 ;; Logical operations
2792 ;; -------------------------------------------------------------------
2794 (define_insn "<optab><mode>3"
2795 [(set (match_operand:GPI 0 "register_operand" "=r,rk")
2796 (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2797 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
2799 "<logical>\\t%<w>0, %<w>1, %<w>2"
2800 [(set_attr "v8type" "logic,logic_imm")
2801 (set_attr "type" "logic_reg,logic_imm")
2802 (set_attr "mode" "<MODE>")])
2804 ;; zero_extend version of above
2805 (define_insn "*<optab>si3_uxtw"
2806 [(set (match_operand:DI 0 "register_operand" "=r,rk")
2808 (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2809 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2811 "<logical>\\t%w0, %w1, %w2"
2812 [(set_attr "v8type" "logic,logic_imm")
2813 (set_attr "type" "logic_reg,logic_imm")
2814 (set_attr "mode" "SI")])
2816 (define_insn "*and<mode>3_compare0"
2817 [(set (reg:CC_NZ CC_REGNUM)
2819 (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2820 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2822 (set (match_operand:GPI 0 "register_operand" "=r,r")
2823 (and:GPI (match_dup 1) (match_dup 2)))]
2825 "ands\\t%<w>0, %<w>1, %<w>2"
2826 [(set_attr "v8type" "logics,logics_imm")
2827 (set_attr "type" "logics_reg,logics_imm")
2828 (set_attr "mode" "<MODE>")]
2831 ;; zero_extend version of above
2832 (define_insn "*andsi3_compare0_uxtw"
2833 [(set (reg:CC_NZ CC_REGNUM)
2835 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2836 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2838 (set (match_operand:DI 0 "register_operand" "=r,r")
2839 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2841 "ands\\t%w0, %w1, %w2"
2842 [(set_attr "v8type" "logics,logics_imm")
2843 (set_attr "type" "logics_reg,logics_imm")
2844 (set_attr "mode" "SI")]
2847 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2848 [(set (reg:CC_NZ CC_REGNUM)
2851 (match_operand:GPI 1 "register_operand" "r")
2852 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2853 (match_operand:GPI 3 "register_operand" "r"))
2855 (set (match_operand:GPI 0 "register_operand" "=r")
2856 (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2858 "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2859 [(set_attr "v8type" "logics_shift")
2860 (set_attr "type" "logics_shift_imm")
2861 (set_attr "mode" "<MODE>")]
2864 ;; zero_extend version of above
2865 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2866 [(set (reg:CC_NZ CC_REGNUM)
2869 (match_operand:SI 1 "register_operand" "r")
2870 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2871 (match_operand:SI 3 "register_operand" "r"))
2873 (set (match_operand:DI 0 "register_operand" "=r")
2874 (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2877 "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2878 [(set_attr "v8type" "logics_shift")
2879 (set_attr "type" "logics_shift_imm")
2880 (set_attr "mode" "SI")]
2883 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2884 [(set (match_operand:GPI 0 "register_operand" "=r")
2885 (LOGICAL:GPI (SHIFT:GPI
2886 (match_operand:GPI 1 "register_operand" "r")
2887 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2888 (match_operand:GPI 3 "register_operand" "r")))]
2890 "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2891 [(set_attr "v8type" "logic_shift")
2892 (set_attr "type" "logic_shift_imm")
2893 (set_attr "mode" "<MODE>")])
2895 ;; zero_extend version of above
2896 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
2897 [(set (match_operand:DI 0 "register_operand" "=r")
2899 (LOGICAL:SI (SHIFT:SI
2900 (match_operand:SI 1 "register_operand" "r")
2901 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2902 (match_operand:SI 3 "register_operand" "r"))))]
2904 "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2905 [(set_attr "v8type" "logic_shift")
2906 (set_attr "type" "logic_shift_imm")
2907 (set_attr "mode" "SI")])
2909 (define_insn "one_cmpl<mode>2"
2910 [(set (match_operand:GPI 0 "register_operand" "=r")
2911 (not:GPI (match_operand:GPI 1 "register_operand" "r")))]
2913 "mvn\\t%<w>0, %<w>1"
2914 [(set_attr "v8type" "logic")
2915 (set_attr "type" "logic_reg")
2916 (set_attr "mode" "<MODE>")])
2918 (define_insn "*one_cmpl_<optab><mode>2"
2919 [(set (match_operand:GPI 0 "register_operand" "=r")
2920 (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
2921 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2923 "mvn\\t%<w>0, %<w>1, <shift> %2"
2924 [(set_attr "v8type" "logic_shift")
2925 (set_attr "type" "logic_shift_imm")
2926 (set_attr "mode" "<MODE>")])
2928 (define_insn "*<LOGICAL:optab>_one_cmpl<mode>3"
2929 [(set (match_operand:GPI 0 "register_operand" "=r")
2930 (LOGICAL:GPI (not:GPI
2931 (match_operand:GPI 1 "register_operand" "r"))
2932 (match_operand:GPI 2 "register_operand" "r")))]
2934 "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1"
2935 [(set_attr "v8type" "logic")
2936 (set_attr "type" "logic_reg")
2937 (set_attr "mode" "<MODE>")])
2939 (define_insn "*and_one_cmpl<mode>3_compare0"
2940 [(set (reg:CC_NZ CC_REGNUM)
2943 (match_operand:GPI 1 "register_operand" "r"))
2944 (match_operand:GPI 2 "register_operand" "r"))
2946 (set (match_operand:GPI 0 "register_operand" "=r")
2947 (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
2949 "bics\\t%<w>0, %<w>2, %<w>1"
2950 [(set_attr "v8type" "logics")
2951 (set_attr "type" "logics_reg")
2952 (set_attr "mode" "<MODE>")])
2954 ;; zero_extend version of above
2955 (define_insn "*and_one_cmplsi3_compare0_uxtw"
2956 [(set (reg:CC_NZ CC_REGNUM)
2959 (match_operand:SI 1 "register_operand" "r"))
2960 (match_operand:SI 2 "register_operand" "r"))
2962 (set (match_operand:DI 0 "register_operand" "=r")
2963 (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
2965 "bics\\t%w0, %w2, %w1"
2966 [(set_attr "v8type" "logics")
2967 (set_attr "type" "logics_reg")
2968 (set_attr "mode" "SI")])
2970 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
2971 [(set (match_operand:GPI 0 "register_operand" "=r")
2972 (LOGICAL:GPI (not:GPI
2974 (match_operand:GPI 1 "register_operand" "r")
2975 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2976 (match_operand:GPI 3 "register_operand" "r")))]
2978 "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2979 [(set_attr "v8type" "logic_shift")
2980 (set_attr "type" "logics_shift_imm")
2981 (set_attr "mode" "<MODE>")])
2983 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
2984 [(set (reg:CC_NZ CC_REGNUM)
2988 (match_operand:GPI 1 "register_operand" "r")
2989 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2990 (match_operand:GPI 3 "register_operand" "r"))
2992 (set (match_operand:GPI 0 "register_operand" "=r")
2995 (match_dup 1) (match_dup 2))) (match_dup 3)))]
2997 "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2998 [(set_attr "v8type" "logics_shift")
2999 (set_attr "type" "logics_shift_imm")
3000 (set_attr "mode" "<MODE>")])
3002 ;; zero_extend version of above
3003 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
3004 [(set (reg:CC_NZ CC_REGNUM)
3008 (match_operand:SI 1 "register_operand" "r")
3009 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
3010 (match_operand:SI 3 "register_operand" "r"))
3012 (set (match_operand:DI 0 "register_operand" "=r")
3013 (zero_extend:DI (and:SI
3015 (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
3017 "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3018 [(set_attr "v8type" "logics_shift")
3019 (set_attr "type" "logics_shift_imm")
3020 (set_attr "mode" "SI")])
3022 (define_insn "clz<mode>2"
3023 [(set (match_operand:GPI 0 "register_operand" "=r")
3024 (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
3026 "clz\\t%<w>0, %<w>1"
3027 [(set_attr "v8type" "clz")
3028 (set_attr "type" "clz")
3029 (set_attr "mode" "<MODE>")])
3031 (define_expand "ffs<mode>2"
3032 [(match_operand:GPI 0 "register_operand")
3033 (match_operand:GPI 1 "register_operand")]
3036 rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
3037 rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
3039 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3040 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3041 emit_insn (gen_csinc3<mode>_insn (operands[0], x, ccreg, operands[0], const0_rtx));
3046 (define_insn "clrsb<mode>2"
3047 [(set (match_operand:GPI 0 "register_operand" "=r")
3048 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_CLS))]
3050 "cls\\t%<w>0, %<w>1"
3051 [(set_attr "v8type" "clz")
3052 (set_attr "type" "clz")
3053 (set_attr "mode" "<MODE>")])
3055 (define_insn "rbit<mode>2"
3056 [(set (match_operand:GPI 0 "register_operand" "=r")
3057 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
3059 "rbit\\t%<w>0, %<w>1"
3060 [(set_attr "v8type" "rbit")
3061 (set_attr "type" "rbit")
3062 (set_attr "mode" "<MODE>")])
3064 (define_expand "ctz<mode>2"
3065 [(match_operand:GPI 0 "register_operand")
3066 (match_operand:GPI 1 "register_operand")]
3069 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3070 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3075 (define_insn "*and<mode>3nr_compare0"
3076 [(set (reg:CC_NZ CC_REGNUM)
3078 (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
3079 (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
3082 "tst\\t%<w>0, %<w>1"
3083 [(set_attr "v8type" "logics")
3084 (set_attr "type" "logics_reg")
3085 (set_attr "mode" "<MODE>")])
3087 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
3088 [(set (reg:CC_NZ CC_REGNUM)
3091 (match_operand:GPI 0 "register_operand" "r")
3092 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
3093 (match_operand:GPI 2 "register_operand" "r"))
3096 "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
3097 [(set_attr "v8type" "logics_shift")
3098 (set_attr "type" "logics_shift_imm")
3099 (set_attr "mode" "<MODE>")])
3101 ;; -------------------------------------------------------------------
3103 ;; -------------------------------------------------------------------
3105 (define_expand "<optab><mode>3"
3106 [(set (match_operand:GPI 0 "register_operand")
3107 (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
3108 (match_operand:QI 2 "nonmemory_operand")))]
3111 if (CONST_INT_P (operands[2]))
3113 operands[2] = GEN_INT (INTVAL (operands[2])
3114 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3116 if (operands[2] == const0_rtx)
3118 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3125 (define_expand "ashl<mode>3"
3126 [(set (match_operand:SHORT 0 "register_operand")
3127 (ashift:SHORT (match_operand:SHORT 1 "register_operand")
3128 (match_operand:QI 2 "nonmemory_operand")))]
3131 if (CONST_INT_P (operands[2]))
3133 operands[2] = GEN_INT (INTVAL (operands[2])
3134 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3136 if (operands[2] == const0_rtx)
3138 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3145 (define_expand "rotr<mode>3"
3146 [(set (match_operand:GPI 0 "register_operand")
3147 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3148 (match_operand:QI 2 "nonmemory_operand")))]
3151 if (CONST_INT_P (operands[2]))
3153 operands[2] = GEN_INT (INTVAL (operands[2])
3154 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3156 if (operands[2] == const0_rtx)
3158 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3165 (define_expand "rotl<mode>3"
3166 [(set (match_operand:GPI 0 "register_operand")
3167 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3168 (match_operand:QI 2 "nonmemory_operand")))]
3171 /* (SZ - cnt) % SZ == -cnt % SZ */
3172 if (CONST_INT_P (operands[2]))
3174 operands[2] = GEN_INT ((-INTVAL (operands[2]))
3175 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3176 if (operands[2] == const0_rtx)
3178 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3183 operands[2] = expand_simple_unop (QImode, NEG, operands[2],
3188 ;; Logical left shift using SISD or Integer instruction
3189 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
3190 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3192 (match_operand:GPI 1 "register_operand" "w,w,r")
3193 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3196 shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3197 ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
3198 lsl\t%<w>0, %<w>1, %<w>2"
3199 [(set_attr "simd" "yes,yes,no")
3200 (set_attr "simd_type" "simd_shift_imm,simd_shift,*")
3201 (set_attr "simd_mode" "<MODE>,<MODE>,*")
3202 (set_attr "v8type" "*,*,shift")
3203 (set_attr "type" "*,*,shift_reg")
3204 (set_attr "mode" "*,*,<MODE>")]
3207 ;; Logical right shift using SISD or Integer instruction
3208 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3209 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3211 (match_operand:GPI 1 "register_operand" "w,w,r")
3212 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3215 ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3217 lsr\t%<w>0, %<w>1, %<w>2"
3218 [(set_attr "simd" "yes,yes,no")
3219 (set_attr "simd_type" "simd_shift_imm,simd_shift,*")
3220 (set_attr "simd_mode" "<MODE>,<MODE>,*")
3221 (set_attr "v8type" "*,*,shift")
3222 (set_attr "type" "*,*,shift_reg")
3223 (set_attr "mode" "*,*,<MODE>")]
3227 [(set (match_operand:DI 0 "aarch64_simd_register")
3229 (match_operand:DI 1 "aarch64_simd_register")
3230 (match_operand:QI 2 "aarch64_simd_register")))]
3231 "TARGET_SIMD && reload_completed"
3233 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3235 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_USHL))]
3240 [(set (match_operand:SI 0 "aarch64_simd_register")
3242 (match_operand:SI 1 "aarch64_simd_register")
3243 (match_operand:QI 2 "aarch64_simd_register")))]
3244 "TARGET_SIMD && reload_completed"
3246 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3248 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_USHL_2S))]
3252 ;; Arithmetic right shift using SISD or Integer instruction
3253 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3254 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3256 (match_operand:GPI 1 "register_operand" "w,w,r")
3257 (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,rUs<cmode>")))]
3260 sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3262 asr\t%<w>0, %<w>1, %<w>2"
3263 [(set_attr "simd" "yes,yes,no")
3264 (set_attr "simd_type" "simd_shift_imm,simd_shift,*")
3265 (set_attr "simd_mode" "<MODE>,<MODE>,*")
3266 (set_attr "v8type" "*,*,shift")
3267 (set_attr "type" "*,*,shift_reg")
3268 (set_attr "mode" "*,*,<MODE>")]
3272 [(set (match_operand:DI 0 "aarch64_simd_register")
3274 (match_operand:DI 1 "aarch64_simd_register")
3275 (match_operand:QI 2 "aarch64_simd_register")))]
3276 "TARGET_SIMD && reload_completed"
3278 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3280 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_SSHL))]
3285 [(set (match_operand:SI 0 "aarch64_simd_register")
3287 (match_operand:SI 1 "aarch64_simd_register")
3288 (match_operand:QI 2 "aarch64_simd_register")))]
3289 "TARGET_SIMD && reload_completed"
3291 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3293 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_SSHL_2S))]
3297 (define_insn "*aarch64_sisd_ushl"
3298 [(set (match_operand:DI 0 "register_operand" "=w")
3299 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3300 (match_operand:QI 2 "register_operand" "w")]
3303 "ushl\t%d0, %d1, %d2"
3304 [(set_attr "simd" "yes")
3305 (set_attr "simd_type" "simd_shift")
3306 (set_attr "simd_mode" "DI")]
3309 (define_insn "*aarch64_ushl_2s"
3310 [(set (match_operand:SI 0 "register_operand" "=w")
3311 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3312 (match_operand:QI 2 "register_operand" "w")]
3315 "ushl\t%0.2s, %1.2s, %2.2s"
3316 [(set_attr "simd" "yes")
3317 (set_attr "simd_type" "simd_shift")
3318 (set_attr "simd_mode" "DI")]
3321 (define_insn "*aarch64_sisd_sshl"
3322 [(set (match_operand:DI 0 "register_operand" "=w")
3323 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3324 (match_operand:QI 2 "register_operand" "w")]
3327 "sshl\t%d0, %d1, %d2"
3328 [(set_attr "simd" "yes")
3329 (set_attr "simd_type" "simd_shift")
3330 (set_attr "simd_mode" "DI")]
3333 (define_insn "*aarch64_sshl_2s"
3334 [(set (match_operand:SI 0 "register_operand" "=w")
3335 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3336 (match_operand:QI 2 "register_operand" "w")]
3339 "sshl\t%0.2s, %1.2s, %2.2s"
3340 [(set_attr "simd" "yes")
3341 (set_attr "simd_type" "simd_shift")
3342 (set_attr "simd_mode" "DI")]
3345 (define_insn "*aarch64_sisd_neg_qi"
3346 [(set (match_operand:QI 0 "register_operand" "=w")
3347 (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3351 [(set_attr "simd" "yes")
3352 (set_attr "simd_type" "simd_negabs")
3353 (set_attr "simd_mode" "QI")]
3357 (define_insn "*ror<mode>3_insn"
3358 [(set (match_operand:GPI 0 "register_operand" "=r")
3360 (match_operand:GPI 1 "register_operand" "r")
3361 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3363 "ror\\t%<w>0, %<w>1, %<w>2"
3364 [(set_attr "v8type" "shift")
3365 (set_attr "type" "shift_reg")
3366 (set_attr "mode" "<MODE>")]
3369 ;; zero_extend version of above
3370 (define_insn "*<optab>si3_insn_uxtw"
3371 [(set (match_operand:DI 0 "register_operand" "=r")
3372 (zero_extend:DI (SHIFT:SI
3373 (match_operand:SI 1 "register_operand" "r")
3374 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3376 "<shift>\\t%w0, %w1, %w2"
3377 [(set_attr "v8type" "shift")
3378 (set_attr "type" "shift_reg")
3379 (set_attr "mode" "SI")]
3382 (define_insn "*ashl<mode>3_insn"
3383 [(set (match_operand:SHORT 0 "register_operand" "=r")
3384 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3385 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
3387 "lsl\\t%<w>0, %<w>1, %<w>2"
3388 [(set_attr "v8type" "shift")
3389 (set_attr "type" "shift_reg")
3390 (set_attr "mode" "<MODE>")]
3393 (define_insn "*<optab><mode>3_insn"
3394 [(set (match_operand:SHORT 0 "register_operand" "=r")
3395 (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3396 (match_operand 2 "const_int_operand" "n")))]
3397 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3399 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3400 return "<bfshift>\t%w0, %w1, %2, %3";
3402 [(set_attr "v8type" "bfm")
3403 (set_attr "type" "bfm")
3404 (set_attr "mode" "<MODE>")]
3407 (define_insn "*extr<mode>5_insn"
3408 [(set (match_operand:GPI 0 "register_operand" "=r")
3409 (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3410 (match_operand 3 "const_int_operand" "n"))
3411 (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3412 (match_operand 4 "const_int_operand" "n"))))]
3413 "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3414 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3415 "extr\\t%<w>0, %<w>1, %<w>2, %4"
3416 [(set_attr "v8type" "shift")
3417 (set_attr "type" "shift_imm")
3418 (set_attr "mode" "<MODE>")]
3421 ;; zero_extend version of the above
3422 (define_insn "*extrsi5_insn_uxtw"
3423 [(set (match_operand:DI 0 "register_operand" "=r")
3425 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3426 (match_operand 3 "const_int_operand" "n"))
3427 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3428 (match_operand 4 "const_int_operand" "n")))))]
3429 "UINTVAL (operands[3]) < 32 &&
3430 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3431 "extr\\t%w0, %w1, %w2, %4"
3432 [(set_attr "v8type" "shift")
3433 (set_attr "type" "shift_imm")
3434 (set_attr "mode" "SI")]
3437 (define_insn "*ror<mode>3_insn"
3438 [(set (match_operand:GPI 0 "register_operand" "=r")
3439 (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3440 (match_operand 2 "const_int_operand" "n")))]
3441 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3443 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3444 return "ror\\t%<w>0, %<w>1, %3";
3446 [(set_attr "v8type" "shift")
3447 (set_attr "type" "shift_imm")
3448 (set_attr "mode" "<MODE>")]
3451 ;; zero_extend version of the above
3452 (define_insn "*rorsi3_insn_uxtw"
3453 [(set (match_operand:DI 0 "register_operand" "=r")
3455 (rotate:SI (match_operand:SI 1 "register_operand" "r")
3456 (match_operand 2 "const_int_operand" "n"))))]
3457 "UINTVAL (operands[2]) < 32"
3459 operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3460 return "ror\\t%w0, %w1, %3";
3462 [(set_attr "v8type" "shift")
3463 (set_attr "type" "shift_imm")
3464 (set_attr "mode" "SI")]
3467 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3468 [(set (match_operand:GPI 0 "register_operand" "=r")
3470 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3471 (match_operand 2 "const_int_operand" "n"))))]
3472 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3474 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3475 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3477 [(set_attr "v8type" "bfm")
3478 (set_attr "type" "bfm")
3479 (set_attr "mode" "<GPI:MODE>")]
3482 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3483 [(set (match_operand:GPI 0 "register_operand" "=r")
3485 (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3486 (match_operand 2 "const_int_operand" "n"))))]
3487 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3489 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3490 return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3492 [(set_attr "v8type" "bfm")
3493 (set_attr "type" "bfm")
3494 (set_attr "mode" "<GPI:MODE>")]
3497 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3498 [(set (match_operand:GPI 0 "register_operand" "=r")
3500 (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3501 (match_operand 2 "const_int_operand" "n"))))]
3502 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3504 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3505 return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3507 [(set_attr "v8type" "bfm")
3508 (set_attr "type" "bfm")
3509 (set_attr "mode" "<GPI:MODE>")]
3512 ;; -------------------------------------------------------------------
3514 ;; -------------------------------------------------------------------
3516 (define_expand "<optab>"
3517 [(set (match_operand:DI 0 "register_operand" "=r")
3518 (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3519 (match_operand 2 "const_int_operand" "n")
3520 (match_operand 3 "const_int_operand" "n")))]
3525 (define_insn "*<optab><mode>"
3526 [(set (match_operand:GPI 0 "register_operand" "=r")
3527 (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3528 (match_operand 2 "const_int_operand" "n")
3529 (match_operand 3 "const_int_operand" "n")))]
3531 "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3532 [(set_attr "v8type" "bfm")
3533 (set_attr "type" "bfm")
3534 (set_attr "mode" "<MODE>")]
3537 ;; Bitfield Insert (insv)
3538 (define_expand "insv<mode>"
3539 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3540 (match_operand 1 "const_int_operand")
3541 (match_operand 2 "const_int_operand"))
3542 (match_operand:GPI 3 "general_operand"))]
3545 unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3546 unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3547 rtx value = operands[3];
3549 if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3552 if (CONST_INT_P (value))
3554 unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3556 /* Prefer AND/OR for inserting all zeros or all ones. */
3557 if ((UINTVAL (value) & mask) == 0
3558 || (UINTVAL (value) & mask) == mask)
3561 /* 16-bit aligned 16-bit wide insert is handled by insv_imm. */
3562 if (width == 16 && (pos % 16) == 0)
3565 operands[3] = force_reg (<MODE>mode, value);
3568 (define_insn "*insv_reg<mode>"
3569 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3570 (match_operand 1 "const_int_operand" "n")
3571 (match_operand 2 "const_int_operand" "n"))
3572 (match_operand:GPI 3 "register_operand" "r"))]
3573 "!(UINTVAL (operands[1]) == 0
3574 || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3575 > GET_MODE_BITSIZE (<MODE>mode)))"
3576 "bfi\\t%<w>0, %<w>3, %2, %1"
3577 [(set_attr "v8type" "bfm")
3578 (set_attr "type" "bfm")
3579 (set_attr "mode" "<MODE>")]
3582 (define_insn "*extr_insv_lower_reg<mode>"
3583 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3584 (match_operand 1 "const_int_operand" "n")
3586 (zero_extract:GPI (match_operand:GPI 2 "register_operand" "+r")
3588 (match_operand 3 "const_int_operand" "n")))]
3589 "!(UINTVAL (operands[1]) == 0
3590 || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3591 > GET_MODE_BITSIZE (<MODE>mode)))"
3592 "bfxil\\t%<w>0, %<w>2, %3, %1"
3593 [(set_attr "v8type" "bfm")
3594 (set_attr "type" "bfm")
3595 (set_attr "mode" "<MODE>")]
3598 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3599 [(set (match_operand:GPI 0 "register_operand" "=r")
3600 (ashift:GPI (ANY_EXTEND:GPI
3601 (match_operand:ALLX 1 "register_operand" "r"))
3602 (match_operand 2 "const_int_operand" "n")))]
3603 "UINTVAL (operands[2]) < <GPI:sizen>"
3605 operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3606 ? GEN_INT (<ALLX:sizen>)
3607 : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3608 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3610 [(set_attr "v8type" "bfm")
3611 (set_attr "type" "bfm")
3612 (set_attr "mode" "<GPI:MODE>")]
3615 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3617 (define_insn "*andim_ashift<mode>_bfiz"
3618 [(set (match_operand:GPI 0 "register_operand" "=r")
3619 (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3620 (match_operand 2 "const_int_operand" "n"))
3621 (match_operand 3 "const_int_operand" "n")))]
3622 "exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3623 && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3624 "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3625 [(set_attr "v8type" "bfm")
3626 (set_attr "type" "bfm")
3627 (set_attr "mode" "<MODE>")]
3630 (define_insn "bswap<mode>2"
3631 [(set (match_operand:GPI 0 "register_operand" "=r")
3632 (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3634 "rev\\t%<w>0, %<w>1"
3635 [(set_attr "v8type" "rev")
3636 (set_attr "type" "rev")
3637 (set_attr "mode" "<MODE>")]
3640 (define_insn "bswaphi2"
3641 [(set (match_operand:HI 0 "register_operand" "=r")
3642 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3645 [(set_attr "v8type" "rev")
3646 (set_attr "type" "rev")
3647 (set_attr "mode" "HI")]
3650 ;; zero_extend version of above
3651 (define_insn "*bswapsi2_uxtw"
3652 [(set (match_operand:DI 0 "register_operand" "=r")
3653 (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3656 [(set_attr "v8type" "rev")
3657 (set_attr "type" "rev")
3658 (set_attr "mode" "SI")]
3661 ;; -------------------------------------------------------------------
3662 ;; Floating-point intrinsics
3663 ;; -------------------------------------------------------------------
3665 ;; frint floating-point round to integral standard patterns.
3666 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round.
3668 (define_insn "<frint_pattern><mode>2"
3669 [(set (match_operand:GPF 0 "register_operand" "=w")
3670 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3673 "frint<frint_suffix>\\t%<s>0, %<s>1"
3674 [(set_attr "v8type" "frint")
3675 (set_attr "type" "f_rint<s>")
3676 (set_attr "mode" "<MODE>")]
3679 ;; frcvt floating-point round to integer and convert standard patterns.
3680 ;; Expands to lbtrunc, lceil, lfloor, lround.
3681 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3682 [(set (match_operand:GPI 0 "register_operand" "=r")
3683 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3686 "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3687 [(set_attr "v8type" "fcvtf2i")
3688 (set_attr "type" "f_cvtf2i")
3689 (set_attr "mode" "<GPF:MODE>")
3690 (set_attr "mode2" "<GPI:MODE>")]
3695 (define_insn "fma<mode>4"
3696 [(set (match_operand:GPF 0 "register_operand" "=w")
3697 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3698 (match_operand:GPF 2 "register_operand" "w")
3699 (match_operand:GPF 3 "register_operand" "w")))]
3701 "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3702 [(set_attr "v8type" "fmadd")
3703 (set_attr "type" "fmac<s>")
3704 (set_attr "mode" "<MODE>")]
3707 (define_insn "fnma<mode>4"
3708 [(set (match_operand:GPF 0 "register_operand" "=w")
3709 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3710 (match_operand:GPF 2 "register_operand" "w")
3711 (match_operand:GPF 3 "register_operand" "w")))]
3713 "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3714 [(set_attr "v8type" "fmadd")
3715 (set_attr "type" "fmac<s>")
3716 (set_attr "mode" "<MODE>")]
3719 (define_insn "fms<mode>4"
3720 [(set (match_operand:GPF 0 "register_operand" "=w")
3721 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3722 (match_operand:GPF 2 "register_operand" "w")
3723 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3725 "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3726 [(set_attr "v8type" "fmadd")
3727 (set_attr "type" "fmac<s>")
3728 (set_attr "mode" "<MODE>")]
3731 (define_insn "fnms<mode>4"
3732 [(set (match_operand:GPF 0 "register_operand" "=w")
3733 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3734 (match_operand:GPF 2 "register_operand" "w")
3735 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3737 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3738 [(set_attr "v8type" "fmadd")
3739 (set_attr "type" "fmac<s>")
3740 (set_attr "mode" "<MODE>")]
3743 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3744 (define_insn "*fnmadd<mode>4"
3745 [(set (match_operand:GPF 0 "register_operand" "=w")
3746 (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3747 (match_operand:GPF 2 "register_operand" "w")
3748 (match_operand:GPF 3 "register_operand" "w"))))]
3749 "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3750 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3751 [(set_attr "v8type" "fmadd")
3752 (set_attr "type" "fmac<s>")
3753 (set_attr "mode" "<MODE>")]
3756 ;; -------------------------------------------------------------------
3757 ;; Floating-point conversions
3758 ;; -------------------------------------------------------------------
3760 (define_insn "extendsfdf2"
3761 [(set (match_operand:DF 0 "register_operand" "=w")
3762 (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3765 [(set_attr "v8type" "fcvt")
3766 (set_attr "type" "f_cvt")
3767 (set_attr "mode" "DF")
3768 (set_attr "mode2" "SF")]
3771 (define_insn "truncdfsf2"
3772 [(set (match_operand:SF 0 "register_operand" "=w")
3773 (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3776 [(set_attr "v8type" "fcvt")
3777 (set_attr "type" "f_cvt")
3778 (set_attr "mode" "SF")
3779 (set_attr "mode2" "DF")]
3782 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3783 [(set (match_operand:GPI 0 "register_operand" "=r")
3784 (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3786 "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3787 [(set_attr "v8type" "fcvtf2i")
3788 (set_attr "type" "f_cvtf2i")
3789 (set_attr "mode" "<GPF:MODE>")
3790 (set_attr "mode2" "<GPI:MODE>")]
3793 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3794 [(set (match_operand:GPI 0 "register_operand" "=r")
3795 (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3797 "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3798 [(set_attr "v8type" "fcvtf2i")
3799 (set_attr "type" "f_cvtf2i")
3800 (set_attr "mode" "<GPF:MODE>")
3801 (set_attr "mode2" "<GPI:MODE>")]
3804 (define_insn "float<GPI:mode><GPF:mode>2"
3805 [(set (match_operand:GPF 0 "register_operand" "=w")
3806 (float:GPF (match_operand:GPI 1 "register_operand" "r")))]
3808 "scvtf\\t%<GPF:s>0, %<GPI:w>1"
3809 [(set_attr "v8type" "fcvti2f")
3810 (set_attr "type" "f_cvti2f")
3811 (set_attr "mode" "<GPF:MODE>")
3812 (set_attr "mode2" "<GPI:MODE>")]
3815 (define_insn "floatuns<GPI:mode><GPF:mode>2"
3816 [(set (match_operand:GPF 0 "register_operand" "=w")
3817 (unsigned_float:GPF (match_operand:GPI 1 "register_operand" "r")))]
3819 "ucvtf\\t%<GPF:s>0, %<GPI:w>1"
3820 [(set_attr "v8type" "fcvt")
3821 (set_attr "type" "f_cvt")
3822 (set_attr "mode" "<GPF:MODE>")
3823 (set_attr "mode2" "<GPI:MODE>")]
3826 ;; -------------------------------------------------------------------
3827 ;; Floating-point arithmetic
3828 ;; -------------------------------------------------------------------
3830 (define_insn "add<mode>3"
3831 [(set (match_operand:GPF 0 "register_operand" "=w")
3833 (match_operand:GPF 1 "register_operand" "w")
3834 (match_operand:GPF 2 "register_operand" "w")))]
3836 "fadd\\t%<s>0, %<s>1, %<s>2"
3837 [(set_attr "v8type" "fadd")
3838 (set_attr "type" "fadd<s>")
3839 (set_attr "mode" "<MODE>")]
3842 (define_insn "sub<mode>3"
3843 [(set (match_operand:GPF 0 "register_operand" "=w")
3845 (match_operand:GPF 1 "register_operand" "w")
3846 (match_operand:GPF 2 "register_operand" "w")))]
3848 "fsub\\t%<s>0, %<s>1, %<s>2"
3849 [(set_attr "v8type" "fadd")
3850 (set_attr "type" "fadd<s>")
3851 (set_attr "mode" "<MODE>")]
3854 (define_insn "mul<mode>3"
3855 [(set (match_operand:GPF 0 "register_operand" "=w")
3857 (match_operand:GPF 1 "register_operand" "w")
3858 (match_operand:GPF 2 "register_operand" "w")))]
3860 "fmul\\t%<s>0, %<s>1, %<s>2"
3861 [(set_attr "v8type" "fmul")
3862 (set_attr "type" "fmul<s>")
3863 (set_attr "mode" "<MODE>")]
3866 (define_insn "*fnmul<mode>3"
3867 [(set (match_operand:GPF 0 "register_operand" "=w")
3869 (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3870 (match_operand:GPF 2 "register_operand" "w")))]
3872 "fnmul\\t%<s>0, %<s>1, %<s>2"
3873 [(set_attr "v8type" "fmul")
3874 (set_attr "type" "fmul<s>")
3875 (set_attr "mode" "<MODE>")]
3878 (define_insn "div<mode>3"
3879 [(set (match_operand:GPF 0 "register_operand" "=w")
3881 (match_operand:GPF 1 "register_operand" "w")
3882 (match_operand:GPF 2 "register_operand" "w")))]
3884 "fdiv\\t%<s>0, %<s>1, %<s>2"
3885 [(set_attr "v8type" "fdiv")
3886 (set_attr "type" "fdiv<s>")
3887 (set_attr "mode" "<MODE>")]
3890 (define_insn "neg<mode>2"
3891 [(set (match_operand:GPF 0 "register_operand" "=w")
3892 (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
3894 "fneg\\t%<s>0, %<s>1"
3895 [(set_attr "v8type" "ffarith")
3896 (set_attr "type" "ffarith<s>")
3897 (set_attr "mode" "<MODE>")]
3900 (define_insn "sqrt<mode>2"
3901 [(set (match_operand:GPF 0 "register_operand" "=w")
3902 (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
3904 "fsqrt\\t%<s>0, %<s>1"
3905 [(set_attr "v8type" "fsqrt")
3906 (set_attr "type" "fdiv<s>")
3907 (set_attr "mode" "<MODE>")]
3910 (define_insn "abs<mode>2"
3911 [(set (match_operand:GPF 0 "register_operand" "=w")
3912 (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
3914 "fabs\\t%<s>0, %<s>1"
3915 [(set_attr "v8type" "ffarith")
3916 (set_attr "type" "ffarith<s>")
3917 (set_attr "mode" "<MODE>")]
3920 ;; Given that smax/smin do not specify the result when either input is NaN,
3921 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
3924 (define_insn "smax<mode>3"
3925 [(set (match_operand:GPF 0 "register_operand" "=w")
3926 (smax:GPF (match_operand:GPF 1 "register_operand" "w")
3927 (match_operand:GPF 2 "register_operand" "w")))]
3929 "fmaxnm\\t%<s>0, %<s>1, %<s>2"
3930 [(set_attr "v8type" "fminmax")
3931 (set_attr "type" "f_minmax<s>")
3932 (set_attr "mode" "<MODE>")]
3935 (define_insn "smin<mode>3"
3936 [(set (match_operand:GPF 0 "register_operand" "=w")
3937 (smin:GPF (match_operand:GPF 1 "register_operand" "w")
3938 (match_operand:GPF 2 "register_operand" "w")))]
3940 "fminnm\\t%<s>0, %<s>1, %<s>2"
3941 [(set_attr "v8type" "fminmax")
3942 (set_attr "type" "f_minmax<s>")
3943 (set_attr "mode" "<MODE>")]
3946 ;; -------------------------------------------------------------------
3948 ;; -------------------------------------------------------------------
3950 ;; Reload SP+imm where imm cannot be handled by a single ADD instruction.
3951 ;; Must load imm into a scratch register and copy SP to the dest reg before
3952 ;; adding, since SP cannot be used as a source register in an ADD
3954 (define_expand "reload_sp_immediate"
3955 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
3956 (match_operand:DI 1 "" ""))
3957 (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
3960 rtx sp = XEXP (operands[1], 0);
3961 rtx val = XEXP (operands[1], 1);
3962 unsigned regno = REGNO (operands[2]);
3963 rtx scratch = operands[1];
3964 gcc_assert (GET_CODE (operands[1]) == PLUS);
3965 gcc_assert (sp == stack_pointer_rtx);
3966 gcc_assert (CONST_INT_P (val));
3968 /* It is possible that one of the registers we got for operands[2]
3969 might coincide with that of operands[0] (which is why we made
3970 it TImode). Pick the other one to use as our scratch. */
3971 if (regno == REGNO (operands[0]))
3973 scratch = gen_rtx_REG (DImode, regno);
3975 emit_move_insn (scratch, val);
3976 emit_move_insn (operands[0], sp);
3977 emit_insn (gen_adddi3 (operands[0], operands[0], scratch));
3982 (define_expand "aarch64_reload_mov<mode>"
3983 [(set (match_operand:TX 0 "register_operand" "=w")
3984 (match_operand:TX 1 "register_operand" "w"))
3985 (clobber (match_operand:DI 2 "register_operand" "=&r"))
3989 rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
3990 rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
3991 gen_aarch64_movtilow_tilow (op0, op1);
3992 gen_aarch64_movdi_tihigh (operands[2], op1);
3993 gen_aarch64_movtihigh_di (op0, operands[2]);
3998 ;; The following secondary reload helpers patterns are invoked
3999 ;; after or during reload as we don't want these patterns to start
4000 ;; kicking in during the combiner.
4002 (define_insn "aarch64_movdi_<mode>low"
4003 [(set (match_operand:DI 0 "register_operand" "=r")
4004 (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
4005 "reload_completed || reload_in_progress"
4007 [(set_attr "v8type" "fmovf2i")
4008 (set_attr "type" "f_mrc")
4009 (set_attr "mode" "DI")
4010 (set_attr "length" "4")
4013 (define_insn "aarch64_movdi_<mode>high"
4014 [(set (match_operand:DI 0 "register_operand" "=r")
4016 (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
4018 "reload_completed || reload_in_progress"
4019 "fmov\\t%x0, %1.d[1]"
4020 [(set_attr "v8type" "fmovf2i")
4021 (set_attr "type" "f_mrc")
4022 (set_attr "mode" "DI")
4023 (set_attr "length" "4")
4026 (define_insn "aarch64_mov<mode>high_di"
4027 [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
4028 (const_int 64) (const_int 64))
4029 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4030 "reload_completed || reload_in_progress"
4031 "fmov\\t%0.d[1], %x1"
4032 [(set_attr "v8type" "fmovi2f")
4033 (set_attr "type" "f_mcr")
4034 (set_attr "mode" "DI")
4035 (set_attr "length" "4")
4038 (define_insn "aarch64_mov<mode>low_di"
4039 [(set (match_operand:TX 0 "register_operand" "=w")
4040 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4041 "reload_completed || reload_in_progress"
4043 [(set_attr "v8type" "fmovi2f")
4044 (set_attr "type" "f_mcr")
4045 (set_attr "mode" "DI")
4046 (set_attr "length" "4")
4049 (define_insn "aarch64_movtilow_tilow"
4050 [(set (match_operand:TI 0 "register_operand" "=w")
4052 (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
4053 "reload_completed || reload_in_progress"
4055 [(set_attr "v8type" "fmovi2f")
4056 (set_attr "type" "f_mcr")
4057 (set_attr "mode" "DI")
4058 (set_attr "length" "4")
4061 ;; There is a deliberate reason why the parameters of high and lo_sum's
4062 ;; don't have modes for ADRP and ADD instructions. This is to allow high
4063 ;; and lo_sum's to be used with the labels defining the jump tables in
4066 (define_expand "add_losym"
4067 [(set (match_operand 0 "register_operand" "=r")
4068 (lo_sum (match_operand 1 "register_operand" "r")
4069 (match_operand 2 "aarch64_valid_symref" "S")))]
4072 enum machine_mode mode = GET_MODE (operands[0]);
4074 emit_insn ((mode == DImode
4076 : gen_add_losym_si) (operands[0],
4082 (define_insn "add_losym_<mode>"
4083 [(set (match_operand:P 0 "register_operand" "=r")
4084 (lo_sum:P (match_operand:P 1 "register_operand" "r")
4085 (match_operand 2 "aarch64_valid_symref" "S")))]
4087 "add\\t%<w>0, %<w>1, :lo12:%a2"
4088 [(set_attr "v8type" "alu")
4089 (set_attr "type" "alu_reg")
4090 (set_attr "mode" "<MODE>")]
4093 (define_insn "ldr_got_small_<mode>"
4094 [(set (match_operand:PTR 0 "register_operand" "=r")
4095 (unspec:PTR [(mem:PTR (lo_sum:PTR
4096 (match_operand:PTR 1 "register_operand" "r")
4097 (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
4098 UNSPEC_GOTSMALLPIC))]
4100 "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
4101 [(set_attr "v8type" "load1")
4102 (set_attr "type" "load1")
4103 (set_attr "mode" "<MODE>")]
4106 (define_insn "ldr_got_small_sidi"
4107 [(set (match_operand:DI 0 "register_operand" "=r")
4109 (unspec:SI [(mem:SI (lo_sum:DI
4110 (match_operand:DI 1 "register_operand" "r")
4111 (match_operand:DI 2 "aarch64_valid_symref" "S")))]
4112 UNSPEC_GOTSMALLPIC)))]
4114 "ldr\\t%w0, [%1, #:got_lo12:%a2]"
4115 [(set_attr "v8type" "load1")
4116 (set_attr "type" "load1")
4117 (set_attr "mode" "DI")]
4120 (define_insn "ldr_got_tiny"
4121 [(set (match_operand:DI 0 "register_operand" "=r")
4122 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
4123 UNSPEC_GOTTINYPIC))]
4126 [(set_attr "v8type" "load1")
4127 (set_attr "type" "load1")
4128 (set_attr "mode" "DI")]
4131 (define_insn "aarch64_load_tp_hard"
4132 [(set (match_operand:DI 0 "register_operand" "=r")
4133 (unspec:DI [(const_int 0)] UNSPEC_TLS))]
4135 "mrs\\t%0, tpidr_el0"
4136 [(set_attr "v8type" "mrs")
4137 (set_attr "type" "mov_reg")
4138 (set_attr "mode" "DI")]
4141 ;; The TLS ABI specifically requires that the compiler does not schedule
4142 ;; instructions in the TLS stubs, in order to enable linker relaxation.
4143 ;; Therefore we treat the stubs as an atomic sequence.
4144 (define_expand "tlsgd_small"
4145 [(parallel [(set (match_operand 0 "register_operand" "")
4146 (call (mem:DI (match_dup 2)) (const_int 1)))
4147 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
4148 (clobber (reg:DI LR_REGNUM))])]
4151 operands[2] = aarch64_tls_get_addr ();
4154 (define_insn "*tlsgd_small"
4155 [(set (match_operand 0 "register_operand" "")
4156 (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
4157 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
4158 (clobber (reg:DI LR_REGNUM))
4161 "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
4162 [(set_attr "v8type" "call")
4163 (set_attr "type" "call")
4164 (set_attr "length" "16")])
4166 (define_insn "tlsie_small"
4167 [(set (match_operand:DI 0 "register_operand" "=r")
4168 (unspec:DI [(match_operand:DI 1 "aarch64_tls_ie_symref" "S")]
4169 UNSPEC_GOTSMALLTLS))]
4171 "adrp\\t%0, %A1\;ldr\\t%0, [%0, #%L1]"
4172 [(set_attr "v8type" "load1")
4173 (set_attr "type" "load1")
4174 (set_attr "mode" "DI")
4175 (set_attr "length" "8")]
4178 (define_insn "tlsle_small"
4179 [(set (match_operand:DI 0 "register_operand" "=r")
4180 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
4181 (match_operand:DI 2 "aarch64_tls_le_symref" "S")]
4182 UNSPEC_GOTSMALLTLS))]
4184 "add\\t%0, %1, #%G2\;add\\t%0, %0, #%L2"
4185 [(set_attr "v8type" "alu")
4186 (set_attr "type" "alu_reg")
4187 (set_attr "mode" "DI")
4188 (set_attr "length" "8")]
4191 (define_insn "tlsdesc_small"
4192 [(set (reg:DI R0_REGNUM)
4193 (unspec:DI [(match_operand:DI 0 "aarch64_valid_symref" "S")]
4195 (clobber (reg:DI LR_REGNUM))
4196 (clobber (match_scratch:DI 1 "=r"))]
4198 "adrp\\tx0, %A0\;ldr\\t%1, [x0, #%L0]\;add\\tx0, x0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
4199 [(set_attr "v8type" "call")
4200 (set_attr "type" "call")
4201 (set_attr "length" "16")])
4203 (define_insn "stack_tie"
4204 [(set (mem:BLK (scratch))
4205 (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
4206 (match_operand:DI 1 "register_operand" "rk")]
4210 [(set_attr "length" "0")]
4213 ;; Named pattern for expanding thread pointer reference.
4214 (define_expand "get_thread_pointerdi"
4215 [(match_operand:DI 0 "register_operand" "=r")]
4218 rtx tmp = aarch64_load_tp (operands[0]);
4219 if (tmp != operands[0])
4220 emit_move_insn (operands[0], tmp);
4225 (include "aarch64-simd.md")
4227 ;; Atomic Operations
4228 (include "atomics.md")