1 ;; Machine description for AArch64 architecture.
2 ;; Copyright (C) 2009-2013 Free Software Foundation, Inc.
3 ;; Contributed by ARM Ltd.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; GCC is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ;; General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
68 (define_c_enum "unspec" [
104 (define_c_enum "unspecv" [
105 UNSPECV_EH_RETURN ; Represent EH_RETURN
109 ;; If further include files are added the defintion of MD_INCLUDES
112 (include "constraints.md")
113 (include "predicates.md")
114 (include "iterators.md")
116 ;; -------------------------------------------------------------------
117 ;; Instruction types and attributes
118 ;; -------------------------------------------------------------------
120 ;; Main data types used by the insntructions
122 (define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
123 (const_string "unknown"))
125 (define_attr "mode2" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
126 (const_string "unknown"))
128 ; The "v8type" attribute is used to for fine grained classification of
129 ; AArch64 instructions. This table briefly explains the meaning of each type.
131 ; adc add/subtract with carry.
132 ; adcs add/subtract with carry (setting condition flags).
133 ; adr calculate address.
134 ; alu simple alu instruction (no memory or fp regs access).
135 ; alu_ext simple alu instruction (sign/zero-extended register).
136 ; alu_shift simple alu instruction, with a source operand shifted by a constant.
137 ; alus simple alu instruction (setting condition flags).
138 ; alus_ext simple alu instruction (sign/zero-extended register, setting condition flags).
139 ; alus_shift simple alu instruction, with a source operand shifted by a constant (setting condition flags).
140 ; bfm bitfield move operation.
142 ; call subroutine call.
143 ; ccmp conditional compare.
144 ; clz count leading zeros/sign bits.
145 ; csel conditional select.
146 ; dmb data memory barrier.
147 ; extend sign/zero-extend (specialised bitfield move).
148 ; extr extract register-sized bitfield encoding.
149 ; fpsimd_load load single floating point / simd scalar register from memory.
150 ; fpsimd_load2 load pair of floating point / simd scalar registers from memory.
151 ; fpsimd_store store single floating point / simd scalar register to memory.
152 ; fpsimd_store2 store pair floating point / simd scalar registers to memory.
153 ; fadd floating point add/sub.
154 ; fccmp floating point conditional compare.
155 ; fcmp floating point comparison.
156 ; fconst floating point load immediate.
157 ; fcsel floating point conditional select.
158 ; fcvt floating point convert (float to float).
159 ; fcvtf2i floating point convert (float to integer).
160 ; fcvti2f floating point convert (integer to float).
161 ; fdiv floating point division operation.
162 ; ffarith floating point abs, neg or cpy.
163 ; fmadd floating point multiply-add/sub.
164 ; fminmax floating point min/max.
165 ; fmov floating point move (float to float).
166 ; fmovf2i floating point move (float to integer).
167 ; fmovi2f floating point move (integer to float).
168 ; fmul floating point multiply.
169 ; frint floating point round to integral.
170 ; fsqrt floating point square root.
171 ; load_acq load-acquire.
172 ; load load single general register from memory
173 ; load2 load pair of general registers from memory
174 ; logic logical operation (register).
175 ; logic_imm and/or/xor operation (immediate).
176 ; logic_shift logical operation with shift.
177 ; logics logical operation (register, setting condition flags).
178 ; logics_imm and/or/xor operation (immediate, setting condition flags).
179 ; logics_shift logical operation with shift (setting condition flags).
180 ; madd integer multiply-add/sub.
181 ; maddl widening integer multiply-add/sub.
182 ; misc miscellaneous - any type that doesn't fit into the rest.
183 ; move integer move operation.
184 ; move2 double integer move operation.
185 ; movk move 16-bit immediate with keep.
186 ; movz move 16-bit immmediate with zero/one.
187 ; mrs system/special register move.
188 ; mulh 64x64 to 128-bit multiply (high part).
189 ; mull widening multiply.
190 ; mult integer multiply instruction.
191 ; prefetch memory prefetch.
194 ; sdiv integer division operation (signed).
195 ; shift variable shift operation.
196 ; shift_imm immediate shift operation (specialised bitfield move).
197 ; store_rel store-release.
198 ; store store single general register to memory.
199 ; store2 store pair of general registers to memory.
200 ; udiv integer division operation (unsigned).
202 (define_attr "v8type"
275 (const_string "alu"))
277 ; The "type" attribute is is included here from AArch32 backend to be able
278 ; to share pipeline descriptions.
279 (include "../arm/types.md")
281 ;; Attribute that specifies whether or not the instruction touches fp
283 (define_attr "fp" "no,yes" (const_string "no"))
285 ;; Attribute that specifies whether or not the instruction touches simd
287 (define_attr "simd" "no,yes" (const_string "no"))
289 (define_attr "length" ""
292 ;; Attribute that controls whether an alternative is enabled or not.
293 ;; Currently it is only used to disable alternatives which touch fp or simd
294 ;; registers when -mgeneral-regs-only is specified.
295 (define_attr "enabled" "no,yes"
297 (and (eq_attr "fp" "yes")
298 (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
299 (and (eq_attr "simd" "yes")
300 (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
302 ] (const_string "yes")))
304 ;; -------------------------------------------------------------------
305 ;; Pipeline descriptions and scheduling
306 ;; -------------------------------------------------------------------
309 (include "aarch64-tune.md")
311 ;; True if the generic scheduling description should be used.
313 (define_attr "generic_sched" "yes,no"
315 (eq_attr "tune" "large,small,cortexa53")
317 (const_string "yes"))))
320 (include "aarch64-generic.md")
323 (include "../arm/cortex-a53.md")
325 ;; -------------------------------------------------------------------
326 ;; Jumps and other miscellaneous insns
327 ;; -------------------------------------------------------------------
329 (define_insn "indirect_jump"
330 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
333 [(set_attr "v8type" "branch")
334 (set_attr "type" "branch")]
338 [(set (pc) (label_ref (match_operand 0 "" "")))]
341 [(set_attr "v8type" "branch")
342 (set_attr "type" "branch")]
345 (define_expand "cbranch<mode>4"
346 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
347 [(match_operand:GPI 1 "register_operand" "")
348 (match_operand:GPI 2 "aarch64_plus_operand" "")])
349 (label_ref (match_operand 3 "" ""))
353 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
355 operands[2] = const0_rtx;
359 (define_expand "cbranch<mode>4"
360 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
361 [(match_operand:GPF 1 "register_operand" "")
362 (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
363 (label_ref (match_operand 3 "" ""))
367 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
369 operands[2] = const0_rtx;
373 (define_insn "*condjump"
374 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
375 [(match_operand 1 "cc_register" "") (const_int 0)])
376 (label_ref (match_operand 2 "" ""))
380 [(set_attr "v8type" "branch")
381 (set_attr "type" "branch")]
384 (define_expand "casesi"
385 [(match_operand:SI 0 "register_operand" "") ; Index
386 (match_operand:SI 1 "const_int_operand" "") ; Lower bound
387 (match_operand:SI 2 "const_int_operand" "") ; Total range
388 (match_operand:DI 3 "" "") ; Table label
389 (match_operand:DI 4 "" "")] ; Out of range label
392 if (operands[1] != const0_rtx)
394 rtx reg = gen_reg_rtx (SImode);
396 /* Canonical RTL says that if you have:
400 then this should be emitted as:
404 The use of trunc_int_for_mode ensures that the resulting
405 constant can be represented in SImode, this is important
406 for the corner case where operand[1] is INT_MIN. */
408 operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
410 if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
411 (operands[1], SImode))
412 operands[1] = force_reg (SImode, operands[1]);
413 emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
417 if (!aarch64_plus_operand (operands[2], SImode))
418 operands[2] = force_reg (SImode, operands[2]);
419 emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
421 operands[0], operands[2], operands[4]));
423 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
424 emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
430 (define_insn "casesi_dispatch"
433 (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
434 (match_operand:SI 1 "register_operand" "r")]
436 (clobber (reg:CC CC_REGNUM))
437 (clobber (match_scratch:DI 3 "=r"))
438 (clobber (match_scratch:DI 4 "=r"))
439 (use (label_ref (match_operand 2 "" "")))])]
442 return aarch64_output_casesi (operands);
444 [(set_attr "length" "16")
445 (set_attr "v8type" "branch")
446 (set_attr "type" "branch")]
450 [(unspec[(const_int 0)] UNSPEC_NOP)]
453 [(set_attr "v8type" "misc")]
456 (define_expand "prologue"
457 [(clobber (const_int 0))]
460 aarch64_expand_prologue ();
465 (define_expand "epilogue"
466 [(clobber (const_int 0))]
469 aarch64_expand_epilogue (false);
474 (define_expand "sibcall_epilogue"
475 [(clobber (const_int 0))]
478 aarch64_expand_epilogue (true);
483 (define_insn "*do_return"
487 [(set_attr "v8type" "branch")
488 (set_attr "type" "branch")]
491 (define_insn "eh_return"
492 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
496 [(set_attr "v8type" "branch")
497 (set_attr "type" "branch")]
502 [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
505 [(set (match_dup 1) (match_dup 0))]
507 operands[1] = aarch64_final_eh_return_addr ();
511 (define_insn "*cb<optab><mode>1"
512 [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
514 (label_ref (match_operand 1 "" ""))
518 [(set_attr "v8type" "branch")
519 (set_attr "type" "branch")]
523 (define_insn "*tb<optab><mode>1"
524 [(set (pc) (if_then_else
525 (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
527 (match_operand 1 "const_int_operand" "n"))
529 (label_ref (match_operand 2 "" ""))
531 (clobber (match_scratch:DI 3 "=r"))]
534 if (get_attr_length (insn) == 8)
535 return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
536 return \"<tbz>\\t%<w>0, %1, %l2\";
538 [(set_attr "v8type" "branch")
539 (set_attr "type" "branch")
540 (set_attr "mode" "<MODE>")
542 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
543 (lt (minus (match_dup 2) (pc)) (const_int 32764)))
548 (define_insn "*cb<optab><mode>1"
549 [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
551 (label_ref (match_operand 1 "" ""))
553 (clobber (match_scratch:DI 2 "=r"))]
556 if (get_attr_length (insn) == 8)
557 return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
558 return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
560 [(set_attr "v8type" "branch")
561 (set_attr "type" "branch")
562 (set_attr "mode" "<MODE>")
564 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
565 (lt (minus (match_dup 1) (pc)) (const_int 32764)))
570 ;; -------------------------------------------------------------------
571 ;; Subroutine calls and sibcalls
572 ;; -------------------------------------------------------------------
574 (define_expand "call"
575 [(parallel [(call (match_operand 0 "memory_operand" "")
576 (match_operand 1 "general_operand" ""))
577 (use (match_operand 2 "" ""))
578 (clobber (reg:DI LR_REGNUM))])]
584 /* In an untyped call, we can get NULL for operand 2. */
585 if (operands[2] == NULL)
586 operands[2] = const0_rtx;
588 /* Decide if we should generate indirect calls by loading the
589 64-bit address of the callee into a register before performing
590 the branch-and-link. */
591 callee = XEXP (operands[0], 0);
592 if (GET_CODE (callee) == SYMBOL_REF
593 ? aarch64_is_long_call_p (callee)
595 XEXP (operands[0], 0) = force_reg (Pmode, callee);
599 (define_insn "*call_reg"
600 [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
601 (match_operand 1 "" ""))
602 (use (match_operand 2 "" ""))
603 (clobber (reg:DI LR_REGNUM))]
606 [(set_attr "v8type" "call")
607 (set_attr "type" "call")]
610 (define_insn "*call_symbol"
611 [(call (mem:DI (match_operand:DI 0 "" ""))
612 (match_operand 1 "" ""))
613 (use (match_operand 2 "" ""))
614 (clobber (reg:DI LR_REGNUM))]
615 "GET_CODE (operands[0]) == SYMBOL_REF
616 && !aarch64_is_long_call_p (operands[0])"
618 [(set_attr "v8type" "call")
619 (set_attr "type" "call")]
622 (define_expand "call_value"
623 [(parallel [(set (match_operand 0 "" "")
624 (call (match_operand 1 "memory_operand" "")
625 (match_operand 2 "general_operand" "")))
626 (use (match_operand 3 "" ""))
627 (clobber (reg:DI LR_REGNUM))])]
633 /* In an untyped call, we can get NULL for operand 3. */
634 if (operands[3] == NULL)
635 operands[3] = const0_rtx;
637 /* Decide if we should generate indirect calls by loading the
638 64-bit address of the callee into a register before performing
639 the branch-and-link. */
640 callee = XEXP (operands[1], 0);
641 if (GET_CODE (callee) == SYMBOL_REF
642 ? aarch64_is_long_call_p (callee)
644 XEXP (operands[1], 0) = force_reg (Pmode, callee);
648 (define_insn "*call_value_reg"
649 [(set (match_operand 0 "" "")
650 (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
651 (match_operand 2 "" "")))
652 (use (match_operand 3 "" ""))
653 (clobber (reg:DI LR_REGNUM))]
656 [(set_attr "v8type" "call")
657 (set_attr "type" "call")]
661 (define_insn "*call_value_symbol"
662 [(set (match_operand 0 "" "")
663 (call (mem:DI (match_operand:DI 1 "" ""))
664 (match_operand 2 "" "")))
665 (use (match_operand 3 "" ""))
666 (clobber (reg:DI LR_REGNUM))]
667 "GET_CODE (operands[1]) == SYMBOL_REF
668 && !aarch64_is_long_call_p (operands[1])"
670 [(set_attr "v8type" "call")
671 (set_attr "type" "call")]
674 (define_expand "sibcall"
675 [(parallel [(call (match_operand 0 "memory_operand" "")
676 (match_operand 1 "general_operand" ""))
678 (use (match_operand 2 "" ""))])]
681 if (operands[2] == NULL_RTX)
682 operands[2] = const0_rtx;
686 (define_expand "sibcall_value"
687 [(parallel [(set (match_operand 0 "" "")
688 (call (match_operand 1 "memory_operand" "")
689 (match_operand 2 "general_operand" "")))
691 (use (match_operand 3 "" ""))])]
694 if (operands[3] == NULL_RTX)
695 operands[3] = const0_rtx;
699 (define_insn "*sibcall_insn"
700 [(call (mem:DI (match_operand:DI 0 "" "X"))
701 (match_operand 1 "" ""))
703 (use (match_operand 2 "" ""))]
704 "GET_CODE (operands[0]) == SYMBOL_REF"
706 [(set_attr "v8type" "branch")
707 (set_attr "type" "branch")]
711 (define_insn "*sibcall_value_insn"
712 [(set (match_operand 0 "" "")
713 (call (mem:DI (match_operand 1 "" "X"))
714 (match_operand 2 "" "")))
716 (use (match_operand 3 "" ""))]
717 "GET_CODE (operands[1]) == SYMBOL_REF"
719 [(set_attr "v8type" "branch")
720 (set_attr "type" "branch")]
723 ;; Call subroutine returning any type.
725 (define_expand "untyped_call"
726 [(parallel [(call (match_operand 0 "")
729 (match_operand 2 "")])]
734 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
736 for (i = 0; i < XVECLEN (operands[2], 0); i++)
738 rtx set = XVECEXP (operands[2], 0, i);
739 emit_move_insn (SET_DEST (set), SET_SRC (set));
742 /* The optimizer does not know that the call sets the function value
743 registers we stored in the result block. We avoid problems by
744 claiming that all hard registers are used and clobbered at this
746 emit_insn (gen_blockage ());
750 ;; -------------------------------------------------------------------
752 ;; -------------------------------------------------------------------
754 (define_expand "mov<mode>"
755 [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
756 (match_operand:SHORT 1 "general_operand" ""))]
759 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
760 operands[1] = force_reg (<MODE>mode, operands[1]);
764 (define_insn "*mov<mode>_aarch64"
765 [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r, *w,r,*w, m, m, r,*w,*w")
766 (match_operand:SHORT 1 "general_operand" " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
767 "(register_operand (operands[0], <MODE>mode)
768 || aarch64_reg_or_zero (operands[1], <MODE>mode))"
770 switch (which_alternative)
773 return "mov\t%w0, %w1";
775 return "mov\t%w0, %1";
777 return aarch64_output_scalar_simd_mov_immediate (operands[1],
780 return "ldr<size>\t%w0, %1";
782 return "ldr\t%<size>0, %1";
784 return "str<size>\t%w1, %0";
786 return "str\t%<size>1, %0";
788 return "umov\t%w0, %1.<v>[0]";
790 return "dup\t%0.<Vallxd>, %w1";
792 return "dup\t%0, %1.<v>[0]";
797 [(set_attr "v8type" "move,alu,alu,load1,load1,store1,store1,*,*,*")
798 (set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,*,*,*")
799 (set_attr "simd_type" "*,*,simd_move_imm,*,*,*,*,simd_movgp,simd_dupgp,simd_dup")
800 (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")
801 (set_attr "mode" "<MODE>")
802 (set_attr "simd_mode" "<MODE>")]
805 (define_expand "mov<mode>"
806 [(set (match_operand:GPI 0 "nonimmediate_operand" "")
807 (match_operand:GPI 1 "general_operand" ""))]
810 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
811 operands[1] = force_reg (<MODE>mode, operands[1]);
813 if (CONSTANT_P (operands[1]))
815 aarch64_expand_mov_immediate (operands[0], operands[1]);
821 (define_insn "*movsi_aarch64"
822 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m, m,r,r ,*w, r,*w")
823 (match_operand:SI 1 "aarch64_mov_operand" " r,r,k,M,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
824 "(register_operand (operands[0], SImode)
825 || aarch64_reg_or_zero (operands[1], SImode))"
840 [(set_attr "v8type" "move,move,move,alu,load1,load1,store1,store1,adr,adr,fmov,fmov,fmov")
841 (set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
842 adr,adr,fmov,fmov,fmov")
843 (set_attr "mode" "SI")
844 (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
847 (define_insn "*movdi_aarch64"
848 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m, m,r,r, *w, r,*w,w")
849 (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))]
850 "(register_operand (operands[0], DImode)
851 || aarch64_reg_or_zero (operands[1], DImode))"
867 [(set_attr "v8type" "move,move,move,alu,load1,load1,store1,store1,adr,adr,fmov,fmov,fmov,fmov")
868 (set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
869 adr,adr,fmov,fmov,fmov,fmov")
870 (set_attr "mode" "DI")
871 (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
872 (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
875 (define_insn "insv_imm<mode>"
876 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
878 (match_operand:GPI 1 "const_int_operand" "n"))
879 (match_operand:GPI 2 "const_int_operand" "n"))]
880 "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
881 && UINTVAL (operands[1]) % 16 == 0"
882 "movk\\t%<w>0, %X2, lsl %1"
883 [(set_attr "v8type" "movk")
884 (set_attr "type" "mov_imm")
885 (set_attr "mode" "<MODE>")]
888 (define_expand "movti"
889 [(set (match_operand:TI 0 "nonimmediate_operand" "")
890 (match_operand:TI 1 "general_operand" ""))]
893 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
894 operands[1] = force_reg (TImode, operands[1]);
898 (define_insn "*movti_aarch64"
899 [(set (match_operand:TI 0
900 "nonimmediate_operand" "=r, *w,r ,*w,r ,Ump,Ump,*w,m")
902 "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r ,Z , m,*w"))]
903 "(register_operand (operands[0], TImode)
904 || aarch64_reg_or_zero (operands[1], TImode))"
909 orr\\t%0.16b, %1.16b, %1.16b
915 [(set_attr "v8type" "move2,fmovi2f,fmovf2i,*, \
916 load2,store2,store2,fpsimd_load,fpsimd_store")
917 (set_attr "type" "multiple,f_mcr,f_mrc,*, \
918 load2,store2,store2,f_loadd,f_stored")
919 (set_attr "simd_type" "*,*,*,simd_move,*,*,*,*,*")
920 (set_attr "mode" "DI,DI,DI,TI,DI,DI,DI,TI,TI")
921 (set_attr "length" "8,8,8,4,4,4,4,4,4")
922 (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")
923 (set_attr "simd" "*,*,*,yes,*,*,*,*,*")])
925 ;; Split a TImode register-register or register-immediate move into
926 ;; its component DImode pieces, taking care to handle overlapping
927 ;; source and dest registers.
929 [(set (match_operand:TI 0 "register_operand" "")
930 (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
931 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
934 aarch64_split_128bit_move (operands[0], operands[1]);
938 (define_expand "mov<mode>"
939 [(set (match_operand:GPF 0 "nonimmediate_operand" "")
940 (match_operand:GPF 1 "general_operand" ""))]
945 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
949 if (GET_CODE (operands[0]) == MEM)
950 operands[1] = force_reg (<MODE>mode, operands[1]);
954 (define_insn "*movsf_aarch64"
955 [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
956 (match_operand:SF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
957 "TARGET_FLOAT && (register_operand (operands[0], SFmode)
958 || register_operand (operands[1], SFmode))"
969 [(set_attr "v8type" "fmovi2f,fmovf2i,\
970 fmov,fconst,fpsimd_load,\
971 fpsimd_store,fpsimd_load,fpsimd_store,fmov")
972 (set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
973 f_loads,f_stores,f_loads,f_stores,fmov")
974 (set_attr "mode" "SF")]
977 (define_insn "*movdf_aarch64"
978 [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
979 (match_operand:DF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
980 "TARGET_FLOAT && (register_operand (operands[0], DFmode)
981 || register_operand (operands[1], DFmode))"
992 [(set_attr "v8type" "fmovi2f,fmovf2i,\
993 fmov,fconst,fpsimd_load,\
994 fpsimd_store,fpsimd_load,fpsimd_store,move")
995 (set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
996 f_loadd,f_stored,f_loadd,f_stored,mov_reg")
997 (set_attr "mode" "DF")]
1000 (define_expand "movtf"
1001 [(set (match_operand:TF 0 "nonimmediate_operand" "")
1002 (match_operand:TF 1 "general_operand" ""))]
1007 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
1011 if (GET_CODE (operands[0]) == MEM)
1012 operands[1] = force_reg (TFmode, operands[1]);
1016 (define_insn "*movtf_aarch64"
1017 [(set (match_operand:TF 0
1018 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
1020 "general_operand" " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
1021 "TARGET_FLOAT && (register_operand (operands[0], TFmode)
1022 || register_operand (operands[1], TFmode))"
1024 orr\\t%0.16b, %1.16b, %1.16b
1034 [(set_attr "v8type" "logic,move2,fmovi2f,fmovf2i,fconst,fconst,fpsimd_load,fpsimd_store,fpsimd_load2,fpsimd_store2")
1035 (set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,fconstd,fconstd,\
1036 f_loadd,f_stored,neon_load1_2reg,neon_store1_2reg")
1037 (set_attr "mode" "DF,DF,DF,DF,DF,DF,TF,TF,DF,DF")
1038 (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
1039 (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
1040 (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
1044 [(set (match_operand:TF 0 "register_operand" "")
1045 (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
1046 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
1049 aarch64_split_128bit_move (operands[0], operands[1]);
1054 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1055 ;; fairly lax checking on the second memory operation.
1056 (define_insn "load_pair<mode>"
1057 [(set (match_operand:GPI 0 "register_operand" "=r")
1058 (match_operand:GPI 1 "aarch64_mem_pair_operand" "Ump"))
1059 (set (match_operand:GPI 2 "register_operand" "=r")
1060 (match_operand:GPI 3 "memory_operand" "m"))]
1061 "rtx_equal_p (XEXP (operands[3], 0),
1062 plus_constant (Pmode,
1063 XEXP (operands[1], 0),
1064 GET_MODE_SIZE (<MODE>mode)))"
1065 "ldp\\t%<w>0, %<w>2, %1"
1066 [(set_attr "v8type" "load2")
1067 (set_attr "type" "load2")
1068 (set_attr "mode" "<MODE>")]
1071 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1072 ;; fairly lax checking on the second memory operation.
1073 (define_insn "store_pair<mode>"
1074 [(set (match_operand:GPI 0 "aarch64_mem_pair_operand" "=Ump")
1075 (match_operand:GPI 1 "register_operand" "r"))
1076 (set (match_operand:GPI 2 "memory_operand" "=m")
1077 (match_operand:GPI 3 "register_operand" "r"))]
1078 "rtx_equal_p (XEXP (operands[2], 0),
1079 plus_constant (Pmode,
1080 XEXP (operands[0], 0),
1081 GET_MODE_SIZE (<MODE>mode)))"
1082 "stp\\t%<w>1, %<w>3, %0"
1083 [(set_attr "v8type" "store2")
1084 (set_attr "type" "store2")
1085 (set_attr "mode" "<MODE>")]
1088 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1089 ;; fairly lax checking on the second memory operation.
1090 (define_insn "load_pair<mode>"
1091 [(set (match_operand:GPF 0 "register_operand" "=w")
1092 (match_operand:GPF 1 "aarch64_mem_pair_operand" "Ump"))
1093 (set (match_operand:GPF 2 "register_operand" "=w")
1094 (match_operand:GPF 3 "memory_operand" "m"))]
1095 "rtx_equal_p (XEXP (operands[3], 0),
1096 plus_constant (Pmode,
1097 XEXP (operands[1], 0),
1098 GET_MODE_SIZE (<MODE>mode)))"
1099 "ldp\\t%<w>0, %<w>2, %1"
1100 [(set_attr "v8type" "fpsimd_load2")
1101 (set_attr "type" "neon_load1_2reg<q>")
1102 (set_attr "mode" "<MODE>")]
1105 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1106 ;; fairly lax checking on the second memory operation.
1107 (define_insn "store_pair<mode>"
1108 [(set (match_operand:GPF 0 "aarch64_mem_pair_operand" "=Ump")
1109 (match_operand:GPF 1 "register_operand" "w"))
1110 (set (match_operand:GPF 2 "memory_operand" "=m")
1111 (match_operand:GPF 3 "register_operand" "w"))]
1112 "rtx_equal_p (XEXP (operands[2], 0),
1113 plus_constant (Pmode,
1114 XEXP (operands[0], 0),
1115 GET_MODE_SIZE (<MODE>mode)))"
1116 "stp\\t%<w>1, %<w>3, %0"
1117 [(set_attr "v8type" "fpsimd_store2")
1118 (set_attr "type" "neon_store1_2reg<q>")
1119 (set_attr "mode" "<MODE>")]
1122 ;; Load pair with writeback. This is primarily used in function epilogues
1123 ;; when restoring [fp,lr]
1124 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
1126 [(set (match_operand:P 0 "register_operand" "=k")
1127 (plus:P (match_operand:P 1 "register_operand" "0")
1128 (match_operand:P 4 "const_int_operand" "n")))
1129 (set (match_operand:GPI 2 "register_operand" "=r")
1130 (mem:GPI (plus:P (match_dup 1)
1132 (set (match_operand:GPI 3 "register_operand" "=r")
1133 (mem:GPI (plus:P (match_dup 1)
1134 (match_operand:P 5 "const_int_operand" "n"))))])]
1135 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1136 "ldp\\t%<w>2, %<w>3, [%1], %4"
1137 [(set_attr "v8type" "load2")
1138 (set_attr "type" "load2")
1139 (set_attr "mode" "<GPI:MODE>")]
1142 ;; Store pair with writeback. This is primarily used in function prologues
1143 ;; when saving [fp,lr]
1144 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
1146 [(set (match_operand:P 0 "register_operand" "=&k")
1147 (plus:P (match_operand:P 1 "register_operand" "0")
1148 (match_operand:P 4 "const_int_operand" "n")))
1149 (set (mem:GPI (plus:P (match_dup 0)
1151 (match_operand:GPI 2 "register_operand" "r"))
1152 (set (mem:GPI (plus:P (match_dup 0)
1153 (match_operand:P 5 "const_int_operand" "n")))
1154 (match_operand:GPI 3 "register_operand" "r"))])]
1155 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1156 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1157 [(set_attr "v8type" "store2")
1158 (set_attr "type" "store2")
1159 (set_attr "mode" "<GPI:MODE>")]
1162 ;; -------------------------------------------------------------------
1163 ;; Sign/Zero extension
1164 ;; -------------------------------------------------------------------
1166 (define_expand "<optab>sidi2"
1167 [(set (match_operand:DI 0 "register_operand")
1168 (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1172 (define_insn "*extendsidi2_aarch64"
1173 [(set (match_operand:DI 0 "register_operand" "=r,r")
1174 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1179 [(set_attr "v8type" "extend,load1")
1180 (set_attr "type" "extend,load1")
1181 (set_attr "mode" "DI")]
1184 (define_insn "*zero_extendsidi2_aarch64"
1185 [(set (match_operand:DI 0 "register_operand" "=r,r")
1186 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1191 [(set_attr "v8type" "extend,load1")
1192 (set_attr "type" "extend,load1")
1193 (set_attr "mode" "DI")]
1196 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1197 [(set (match_operand:GPI 0 "register_operand")
1198 (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1202 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1203 [(set (match_operand:GPI 0 "register_operand" "=r,r")
1204 (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1207 sxt<SHORT:size>\t%<GPI:w>0, %w1
1208 ldrs<SHORT:size>\t%<GPI:w>0, %1"
1209 [(set_attr "v8type" "extend,load1")
1210 (set_attr "type" "extend,load1")
1211 (set_attr "mode" "<GPI:MODE>")]
1214 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1215 [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1216 (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1219 uxt<SHORT:size>\t%<GPI:w>0, %w1
1220 ldr<SHORT:size>\t%w0, %1
1221 ldr\t%<SHORT:size>0, %1"
1222 [(set_attr "v8type" "extend,load1,load1")
1223 (set_attr "type" "extend,load1,load1")
1224 (set_attr "mode" "<GPI:MODE>")]
1227 (define_expand "<optab>qihi2"
1228 [(set (match_operand:HI 0 "register_operand")
1229 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1233 (define_insn "*<optab>qihi2_aarch64"
1234 [(set (match_operand:HI 0 "register_operand" "=r,r")
1235 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1240 [(set_attr "v8type" "extend,load1")
1241 (set_attr "type" "extend,load1")
1242 (set_attr "mode" "HI")]
1245 ;; -------------------------------------------------------------------
1246 ;; Simple arithmetic
1247 ;; -------------------------------------------------------------------
1249 (define_expand "add<mode>3"
1251 (match_operand:GPI 0 "register_operand" "")
1252 (plus:GPI (match_operand:GPI 1 "register_operand" "")
1253 (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1256 if (! aarch64_plus_operand (operands[2], VOIDmode))
1258 rtx subtarget = ((optimize && can_create_pseudo_p ())
1259 ? gen_reg_rtx (<MODE>mode) : operands[0]);
1260 HOST_WIDE_INT imm = INTVAL (operands[2]);
1263 imm = -(-imm & ~0xfff);
1267 emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1268 operands[1] = subtarget;
1269 operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1274 (define_insn "*addsi3_aarch64"
1276 (match_operand:SI 0 "register_operand" "=rk,rk,rk")
1278 (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1279 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J")))]
1284 sub\\t%w0, %w1, #%n2"
1285 [(set_attr "v8type" "alu")
1286 (set_attr "type" "alu_imm,alu_reg,alu_imm")
1287 (set_attr "mode" "SI")]
1290 ;; zero_extend version of above
1291 (define_insn "*addsi3_aarch64_uxtw"
1293 (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1295 (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1296 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1301 sub\\t%w0, %w1, #%n2"
1302 [(set_attr "v8type" "alu")
1303 (set_attr "type" "alu_imm,alu_reg,alu_imm")
1304 (set_attr "mode" "SI")]
1307 (define_insn "*adddi3_aarch64"
1309 (match_operand:DI 0 "register_operand" "=rk,rk,rk,!w")
1311 (match_operand:DI 1 "register_operand" "%rk,rk,rk,!w")
1312 (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,!w")))]
1317 sub\\t%x0, %x1, #%n2
1318 add\\t%d0, %d1, %d2"
1319 [(set_attr "v8type" "alu")
1320 (set_attr "type" "alu_imm,alu_reg,alu_imm,alu_reg")
1321 (set_attr "mode" "DI")
1322 (set_attr "simd" "*,*,*,yes")]
1325 (define_insn "*add<mode>3_compare0"
1326 [(set (reg:CC_NZ CC_REGNUM)
1328 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1329 (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1331 (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1332 (plus:GPI (match_dup 1) (match_dup 2)))]
1335 adds\\t%<w>0, %<w>1, %<w>2
1336 adds\\t%<w>0, %<w>1, %<w>2
1337 subs\\t%<w>0, %<w>1, #%n2"
1338 [(set_attr "v8type" "alus")
1339 (set_attr "type" "alus_reg,alus_imm,alus_imm")
1340 (set_attr "mode" "<MODE>")]
1343 ;; zero_extend version of above
1344 (define_insn "*addsi3_compare0_uxtw"
1345 [(set (reg:CC_NZ CC_REGNUM)
1347 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1348 (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1350 (set (match_operand:DI 0 "register_operand" "=r,r,r")
1351 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1354 adds\\t%w0, %w1, %w2
1355 adds\\t%w0, %w1, %w2
1356 subs\\t%w0, %w1, #%n2"
1357 [(set_attr "v8type" "alus")
1358 (set_attr "type" "alus_reg,alus_imm,alus_imm")
1359 (set_attr "mode" "SI")]
1362 (define_insn "*adds_mul_imm_<mode>"
1363 [(set (reg:CC_NZ CC_REGNUM)
1366 (match_operand:GPI 1 "register_operand" "r")
1367 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1368 (match_operand:GPI 3 "register_operand" "r"))
1370 (set (match_operand:GPI 0 "register_operand" "=r")
1371 (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1374 "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1375 [(set_attr "v8type" "alus_shift")
1376 (set_attr "type" "alus_shift_imm")
1377 (set_attr "mode" "<MODE>")]
1380 (define_insn "*subs_mul_imm_<mode>"
1381 [(set (reg:CC_NZ CC_REGNUM)
1383 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1385 (match_operand:GPI 2 "register_operand" "r")
1386 (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1388 (set (match_operand:GPI 0 "register_operand" "=r")
1389 (minus:GPI (match_dup 1)
1390 (mult:GPI (match_dup 2) (match_dup 3))))]
1392 "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1393 [(set_attr "v8type" "alus_shift")
1394 (set_attr "type" "alus_shift_imm")
1395 (set_attr "mode" "<MODE>")]
1398 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1399 [(set (reg:CC_NZ CC_REGNUM)
1402 (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1403 (match_operand:GPI 2 "register_operand" "r"))
1405 (set (match_operand:GPI 0 "register_operand" "=r")
1406 (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1408 "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1409 [(set_attr "v8type" "alus_ext")
1410 (set_attr "type" "alus_ext")
1411 (set_attr "mode" "<GPI:MODE>")]
1414 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1415 [(set (reg:CC_NZ CC_REGNUM)
1417 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1419 (match_operand:ALLX 2 "register_operand" "r")))
1421 (set (match_operand:GPI 0 "register_operand" "=r")
1422 (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1424 "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1425 [(set_attr "v8type" "alus_ext")
1426 (set_attr "type" "alus_ext")
1427 (set_attr "mode" "<GPI:MODE>")]
1430 (define_insn "*adds_<optab><mode>_multp2"
1431 [(set (reg:CC_NZ CC_REGNUM)
1433 (plus:GPI (ANY_EXTRACT:GPI
1434 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1435 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1436 (match_operand 3 "const_int_operand" "n")
1438 (match_operand:GPI 4 "register_operand" "r"))
1440 (set (match_operand:GPI 0 "register_operand" "=r")
1441 (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1445 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1446 "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1447 [(set_attr "v8type" "alus_ext")
1448 (set_attr "type" "alus_ext")
1449 (set_attr "mode" "<MODE>")]
1452 (define_insn "*subs_<optab><mode>_multp2"
1453 [(set (reg:CC_NZ CC_REGNUM)
1455 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1457 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1458 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1459 (match_operand 3 "const_int_operand" "n")
1462 (set (match_operand:GPI 0 "register_operand" "=r")
1463 (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1464 (mult:GPI (match_dup 1) (match_dup 2))
1467 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1468 "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1469 [(set_attr "v8type" "alus_ext")
1470 (set_attr "type" "alus_ext")
1471 (set_attr "mode" "<MODE>")]
1474 (define_insn "*add<mode>3nr_compare0"
1475 [(set (reg:CC_NZ CC_REGNUM)
1477 (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1478 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1485 [(set_attr "v8type" "alus")
1486 (set_attr "type" "alus_reg,alus_imm,alus_imm")
1487 (set_attr "mode" "<MODE>")]
1490 (define_insn "*compare_neg<mode>"
1491 [(set (reg:CC_SWP CC_REGNUM)
1493 (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1494 (match_operand:GPI 1 "register_operand" "r")))]
1496 "cmn\\t%<w>1, %<w>0"
1497 [(set_attr "v8type" "alus")
1498 (set_attr "type" "alus_reg")
1499 (set_attr "mode" "<MODE>")]
1502 (define_insn "*add_<shift>_<mode>"
1503 [(set (match_operand:GPI 0 "register_operand" "=r")
1504 (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1505 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1506 (match_operand:GPI 3 "register_operand" "r")))]
1508 "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1509 [(set_attr "v8type" "alu_shift")
1510 (set_attr "type" "alu_shift_imm")
1511 (set_attr "mode" "<MODE>")]
1514 ;; zero_extend version of above
1515 (define_insn "*add_<shift>_si_uxtw"
1516 [(set (match_operand:DI 0 "register_operand" "=r")
1518 (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1519 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1520 (match_operand:SI 3 "register_operand" "r"))))]
1522 "add\\t%w0, %w3, %w1, <shift> %2"
1523 [(set_attr "v8type" "alu_shift")
1524 (set_attr "type" "alu_shift_imm")
1525 (set_attr "mode" "SI")]
1528 (define_insn "*add_mul_imm_<mode>"
1529 [(set (match_operand:GPI 0 "register_operand" "=r")
1530 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1531 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1532 (match_operand:GPI 3 "register_operand" "r")))]
1534 "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1535 [(set_attr "v8type" "alu_shift")
1536 (set_attr "type" "alu_shift_imm")
1537 (set_attr "mode" "<MODE>")]
1540 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1541 [(set (match_operand:GPI 0 "register_operand" "=rk")
1542 (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1543 (match_operand:GPI 2 "register_operand" "r")))]
1545 "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1546 [(set_attr "v8type" "alu_ext")
1547 (set_attr "type" "alu_ext")
1548 (set_attr "mode" "<GPI:MODE>")]
1551 ;; zero_extend version of above
1552 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1553 [(set (match_operand:DI 0 "register_operand" "=rk")
1555 (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1556 (match_operand:GPI 2 "register_operand" "r"))))]
1558 "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1559 [(set_attr "v8type" "alu_ext")
1560 (set_attr "type" "alu_ext")
1561 (set_attr "mode" "SI")]
1564 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1565 [(set (match_operand:GPI 0 "register_operand" "=rk")
1566 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1567 (match_operand:ALLX 1 "register_operand" "r"))
1568 (match_operand 2 "aarch64_imm3" "Ui3"))
1569 (match_operand:GPI 3 "register_operand" "r")))]
1571 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1572 [(set_attr "v8type" "alu_ext")
1573 (set_attr "type" "alu_ext")
1574 (set_attr "mode" "<GPI:MODE>")]
1577 ;; zero_extend version of above
1578 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1579 [(set (match_operand:DI 0 "register_operand" "=rk")
1581 (plus:SI (ashift:SI (ANY_EXTEND:SI
1582 (match_operand:SHORT 1 "register_operand" "r"))
1583 (match_operand 2 "aarch64_imm3" "Ui3"))
1584 (match_operand:SI 3 "register_operand" "r"))))]
1586 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1587 [(set_attr "v8type" "alu_ext")
1588 (set_attr "type" "alu_ext")
1589 (set_attr "mode" "SI")]
1592 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1593 [(set (match_operand:GPI 0 "register_operand" "=rk")
1594 (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1595 (match_operand:ALLX 1 "register_operand" "r"))
1596 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1597 (match_operand:GPI 3 "register_operand" "r")))]
1599 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1600 [(set_attr "v8type" "alu_ext")
1601 (set_attr "type" "alu_ext")
1602 (set_attr "mode" "<GPI:MODE>")]
1605 ;; zero_extend version of above
1606 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1607 [(set (match_operand:DI 0 "register_operand" "=rk")
1608 (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1609 (match_operand:SHORT 1 "register_operand" "r"))
1610 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1611 (match_operand:SI 3 "register_operand" "r"))))]
1613 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1614 [(set_attr "v8type" "alu_ext")
1615 (set_attr "type" "alu_ext")
1616 (set_attr "mode" "SI")]
1619 (define_insn "*add_<optab><mode>_multp2"
1620 [(set (match_operand:GPI 0 "register_operand" "=rk")
1621 (plus:GPI (ANY_EXTRACT:GPI
1622 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1623 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1624 (match_operand 3 "const_int_operand" "n")
1626 (match_operand:GPI 4 "register_operand" "r")))]
1627 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1628 "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1629 [(set_attr "v8type" "alu_ext")
1630 (set_attr "type" "alu_ext")
1631 (set_attr "mode" "<MODE>")]
1634 ;; zero_extend version of above
1635 (define_insn "*add_<optab>si_multp2_uxtw"
1636 [(set (match_operand:DI 0 "register_operand" "=rk")
1638 (plus:SI (ANY_EXTRACT:SI
1639 (mult:SI (match_operand:SI 1 "register_operand" "r")
1640 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1641 (match_operand 3 "const_int_operand" "n")
1643 (match_operand:SI 4 "register_operand" "r"))))]
1644 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1645 "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1646 [(set_attr "v8type" "alu_ext")
1647 (set_attr "type" "alu_ext")
1648 (set_attr "mode" "SI")]
1651 (define_insn "*add<mode>3_carryin"
1653 (match_operand:GPI 0 "register_operand" "=r")
1654 (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1656 (match_operand:GPI 1 "register_operand" "r")
1657 (match_operand:GPI 2 "register_operand" "r"))))]
1659 "adc\\t%<w>0, %<w>1, %<w>2"
1660 [(set_attr "v8type" "adc")
1661 (set_attr "type" "adc_reg")
1662 (set_attr "mode" "<MODE>")]
1665 ;; zero_extend version of above
1666 (define_insn "*addsi3_carryin_uxtw"
1668 (match_operand:DI 0 "register_operand" "=r")
1670 (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1672 (match_operand:SI 1 "register_operand" "r")
1673 (match_operand:SI 2 "register_operand" "r")))))]
1675 "adc\\t%w0, %w1, %w2"
1676 [(set_attr "v8type" "adc")
1677 (set_attr "type" "adc_reg")
1678 (set_attr "mode" "SI")]
1681 (define_insn "*add<mode>3_carryin_alt1"
1683 (match_operand:GPI 0 "register_operand" "=r")
1685 (match_operand:GPI 1 "register_operand" "r")
1686 (match_operand:GPI 2 "register_operand" "r"))
1687 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1689 "adc\\t%<w>0, %<w>1, %<w>2"
1690 [(set_attr "v8type" "adc")
1691 (set_attr "type" "adc_reg")
1692 (set_attr "mode" "<MODE>")]
1695 ;; zero_extend version of above
1696 (define_insn "*addsi3_carryin_alt1_uxtw"
1698 (match_operand:DI 0 "register_operand" "=r")
1701 (match_operand:SI 1 "register_operand" "r")
1702 (match_operand:SI 2 "register_operand" "r"))
1703 (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1705 "adc\\t%w0, %w1, %w2"
1706 [(set_attr "v8type" "adc")
1707 (set_attr "type" "adc_reg")
1708 (set_attr "mode" "SI")]
1711 (define_insn "*add<mode>3_carryin_alt2"
1713 (match_operand:GPI 0 "register_operand" "=r")
1715 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1716 (match_operand:GPI 1 "register_operand" "r"))
1717 (match_operand:GPI 2 "register_operand" "r")))]
1719 "adc\\t%<w>0, %<w>1, %<w>2"
1720 [(set_attr "v8type" "adc")
1721 (set_attr "type" "adc_reg")
1722 (set_attr "mode" "<MODE>")]
1725 ;; zero_extend version of above
1726 (define_insn "*addsi3_carryin_alt2_uxtw"
1728 (match_operand:DI 0 "register_operand" "=r")
1731 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1732 (match_operand:SI 1 "register_operand" "r"))
1733 (match_operand:SI 2 "register_operand" "r"))))]
1735 "adc\\t%w0, %w1, %w2"
1736 [(set_attr "v8type" "adc")
1737 (set_attr "type" "adc_reg")
1738 (set_attr "mode" "SI")]
1741 (define_insn "*add<mode>3_carryin_alt3"
1743 (match_operand:GPI 0 "register_operand" "=r")
1745 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1746 (match_operand:GPI 2 "register_operand" "r"))
1747 (match_operand:GPI 1 "register_operand" "r")))]
1749 "adc\\t%<w>0, %<w>1, %<w>2"
1750 [(set_attr "v8type" "adc")
1751 (set_attr "type" "adc_reg")
1752 (set_attr "mode" "<MODE>")]
1755 ;; zero_extend version of above
1756 (define_insn "*addsi3_carryin_alt3_uxtw"
1758 (match_operand:DI 0 "register_operand" "=r")
1761 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1762 (match_operand:SI 2 "register_operand" "r"))
1763 (match_operand:SI 1 "register_operand" "r"))))]
1765 "adc\\t%w0, %w1, %w2"
1766 [(set_attr "v8type" "adc")
1767 (set_attr "type" "adc_reg")
1768 (set_attr "mode" "SI")]
1771 (define_insn "*add_uxt<mode>_multp2"
1772 [(set (match_operand:GPI 0 "register_operand" "=rk")
1774 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1775 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1776 (match_operand 3 "const_int_operand" "n"))
1777 (match_operand:GPI 4 "register_operand" "r")))]
1778 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1780 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1781 INTVAL (operands[3])));
1782 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1783 [(set_attr "v8type" "alu_ext")
1784 (set_attr "type" "alu_ext")
1785 (set_attr "mode" "<MODE>")]
1788 ;; zero_extend version of above
1789 (define_insn "*add_uxtsi_multp2_uxtw"
1790 [(set (match_operand:DI 0 "register_operand" "=rk")
1793 (mult:SI (match_operand:SI 1 "register_operand" "r")
1794 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1795 (match_operand 3 "const_int_operand" "n"))
1796 (match_operand:SI 4 "register_operand" "r"))))]
1797 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1799 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1800 INTVAL (operands[3])));
1801 return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1802 [(set_attr "v8type" "alu_ext")
1803 (set_attr "type" "alu_ext")
1804 (set_attr "mode" "SI")]
1807 (define_insn "subsi3"
1808 [(set (match_operand:SI 0 "register_operand" "=rk")
1809 (minus:SI (match_operand:SI 1 "register_operand" "r")
1810 (match_operand:SI 2 "register_operand" "r")))]
1812 "sub\\t%w0, %w1, %w2"
1813 [(set_attr "v8type" "alu")
1814 (set_attr "type" "alu_reg")
1815 (set_attr "mode" "SI")]
1818 ;; zero_extend version of above
1819 (define_insn "*subsi3_uxtw"
1820 [(set (match_operand:DI 0 "register_operand" "=rk")
1822 (minus:SI (match_operand:SI 1 "register_operand" "r")
1823 (match_operand:SI 2 "register_operand" "r"))))]
1825 "sub\\t%w0, %w1, %w2"
1826 [(set_attr "v8type" "alu")
1827 (set_attr "type" "alu_reg")
1828 (set_attr "mode" "SI")]
1831 (define_insn "subdi3"
1832 [(set (match_operand:DI 0 "register_operand" "=rk,!w")
1833 (minus:DI (match_operand:DI 1 "register_operand" "r,!w")
1834 (match_operand:DI 2 "register_operand" "r,!w")))]
1838 sub\\t%d0, %d1, %d2"
1839 [(set_attr "v8type" "alu")
1840 (set_attr "type" "alu_reg")
1841 (set_attr "mode" "DI")
1842 (set_attr "simd" "*,yes")]
1846 (define_insn "*sub<mode>3_compare0"
1847 [(set (reg:CC_NZ CC_REGNUM)
1848 (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1849 (match_operand:GPI 2 "register_operand" "r"))
1851 (set (match_operand:GPI 0 "register_operand" "=r")
1852 (minus:GPI (match_dup 1) (match_dup 2)))]
1854 "subs\\t%<w>0, %<w>1, %<w>2"
1855 [(set_attr "v8type" "alus")
1856 (set_attr "type" "alus_reg")
1857 (set_attr "mode" "<MODE>")]
1860 ;; zero_extend version of above
1861 (define_insn "*subsi3_compare0_uxtw"
1862 [(set (reg:CC_NZ CC_REGNUM)
1863 (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1864 (match_operand:SI 2 "register_operand" "r"))
1866 (set (match_operand:DI 0 "register_operand" "=r")
1867 (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1869 "subs\\t%w0, %w1, %w2"
1870 [(set_attr "v8type" "alus")
1871 (set_attr "type" "alus_reg")
1872 (set_attr "mode" "SI")]
1875 (define_insn "*sub_<shift>_<mode>"
1876 [(set (match_operand:GPI 0 "register_operand" "=r")
1877 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1879 (match_operand:GPI 1 "register_operand" "r")
1880 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1882 "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1883 [(set_attr "v8type" "alu_shift")
1884 (set_attr "type" "alu_shift_imm")
1885 (set_attr "mode" "<MODE>")]
1888 ;; zero_extend version of above
1889 (define_insn "*sub_<shift>_si_uxtw"
1890 [(set (match_operand:DI 0 "register_operand" "=r")
1892 (minus:SI (match_operand:SI 3 "register_operand" "r")
1894 (match_operand:SI 1 "register_operand" "r")
1895 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1897 "sub\\t%w0, %w3, %w1, <shift> %2"
1898 [(set_attr "v8type" "alu_shift")
1899 (set_attr "type" "alu_shift_imm")
1900 (set_attr "mode" "SI")]
1903 (define_insn "*sub_mul_imm_<mode>"
1904 [(set (match_operand:GPI 0 "register_operand" "=r")
1905 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1907 (match_operand:GPI 1 "register_operand" "r")
1908 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1910 "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1911 [(set_attr "v8type" "alu_shift")
1912 (set_attr "type" "alu_shift_imm")
1913 (set_attr "mode" "<MODE>")]
1916 ;; zero_extend version of above
1917 (define_insn "*sub_mul_imm_si_uxtw"
1918 [(set (match_operand:DI 0 "register_operand" "=r")
1920 (minus:SI (match_operand:SI 3 "register_operand" "r")
1922 (match_operand:SI 1 "register_operand" "r")
1923 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
1925 "sub\\t%w0, %w3, %w1, lsl %p2"
1926 [(set_attr "v8type" "alu_shift")
1927 (set_attr "type" "alu_shift_imm")
1928 (set_attr "mode" "SI")]
1931 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
1932 [(set (match_operand:GPI 0 "register_operand" "=rk")
1933 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1935 (match_operand:ALLX 2 "register_operand" "r"))))]
1937 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1938 [(set_attr "v8type" "alu_ext")
1939 (set_attr "type" "alu_ext")
1940 (set_attr "mode" "<GPI:MODE>")]
1943 ;; zero_extend version of above
1944 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
1945 [(set (match_operand:DI 0 "register_operand" "=rk")
1947 (minus:SI (match_operand:SI 1 "register_operand" "r")
1949 (match_operand:SHORT 2 "register_operand" "r")))))]
1951 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
1952 [(set_attr "v8type" "alu_ext")
1953 (set_attr "type" "alu_ext")
1954 (set_attr "mode" "SI")]
1957 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
1958 [(set (match_operand:GPI 0 "register_operand" "=rk")
1959 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1960 (ashift:GPI (ANY_EXTEND:GPI
1961 (match_operand:ALLX 2 "register_operand" "r"))
1962 (match_operand 3 "aarch64_imm3" "Ui3"))))]
1964 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1965 [(set_attr "v8type" "alu_ext")
1966 (set_attr "type" "alu_ext")
1967 (set_attr "mode" "<GPI:MODE>")]
1970 ;; zero_extend version of above
1971 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
1972 [(set (match_operand:DI 0 "register_operand" "=rk")
1974 (minus:SI (match_operand:SI 1 "register_operand" "r")
1975 (ashift:SI (ANY_EXTEND:SI
1976 (match_operand:SHORT 2 "register_operand" "r"))
1977 (match_operand 3 "aarch64_imm3" "Ui3")))))]
1979 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
1980 [(set_attr "v8type" "alu_ext")
1981 (set_attr "type" "alu_ext")
1982 (set_attr "mode" "SI")]
1985 (define_insn "*sub_<optab><mode>_multp2"
1986 [(set (match_operand:GPI 0 "register_operand" "=rk")
1987 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1989 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1990 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1991 (match_operand 3 "const_int_operand" "n")
1993 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1994 "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1995 [(set_attr "v8type" "alu_ext")
1996 (set_attr "type" "alu_ext")
1997 (set_attr "mode" "<MODE>")]
2000 ;; zero_extend version of above
2001 (define_insn "*sub_<optab>si_multp2_uxtw"
2002 [(set (match_operand:DI 0 "register_operand" "=rk")
2004 (minus:SI (match_operand:SI 4 "register_operand" "r")
2006 (mult:SI (match_operand:SI 1 "register_operand" "r")
2007 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2008 (match_operand 3 "const_int_operand" "n")
2010 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
2011 "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
2012 [(set_attr "v8type" "alu_ext")
2013 (set_attr "type" "alu_ext")
2014 (set_attr "mode" "SI")]
2017 (define_insn "*sub<mode>3_carryin"
2019 (match_operand:GPI 0 "register_operand" "=r")
2020 (minus:GPI (minus:GPI
2021 (match_operand:GPI 1 "register_operand" "r")
2022 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2023 (match_operand:GPI 2 "register_operand" "r")))]
2025 "sbc\\t%<w>0, %<w>1, %<w>2"
2026 [(set_attr "v8type" "adc")
2027 (set_attr "type" "adc_reg")
2028 (set_attr "mode" "<MODE>")]
2031 ;; zero_extend version of the above
2032 (define_insn "*subsi3_carryin_uxtw"
2034 (match_operand:DI 0 "register_operand" "=r")
2037 (match_operand:SI 1 "register_operand" "r")
2038 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2039 (match_operand:SI 2 "register_operand" "r"))))]
2041 "sbc\\t%w0, %w1, %w2"
2042 [(set_attr "v8type" "adc")
2043 (set_attr "type" "adc_reg")
2044 (set_attr "mode" "SI")]
2047 (define_insn "*sub_uxt<mode>_multp2"
2048 [(set (match_operand:GPI 0 "register_operand" "=rk")
2049 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
2051 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2052 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2053 (match_operand 3 "const_int_operand" "n"))))]
2054 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2056 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2057 INTVAL (operands[3])));
2058 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
2059 [(set_attr "v8type" "alu_ext")
2060 (set_attr "type" "alu_ext")
2061 (set_attr "mode" "<MODE>")]
2064 ;; zero_extend version of above
2065 (define_insn "*sub_uxtsi_multp2_uxtw"
2066 [(set (match_operand:DI 0 "register_operand" "=rk")
2068 (minus:SI (match_operand:SI 4 "register_operand" "r")
2070 (mult:SI (match_operand:SI 1 "register_operand" "r")
2071 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2072 (match_operand 3 "const_int_operand" "n")))))]
2073 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2075 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2076 INTVAL (operands[3])));
2077 return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
2078 [(set_attr "v8type" "alu_ext")
2079 (set_attr "type" "alu_ext")
2080 (set_attr "mode" "SI")]
2083 (define_insn_and_split "absdi2"
2084 [(set (match_operand:DI 0 "register_operand" "=r,w")
2085 (abs:DI (match_operand:DI 1 "register_operand" "r,w")))
2086 (clobber (match_scratch:DI 2 "=&r,X"))]
2092 && GP_REGNUM_P (REGNO (operands[0]))
2093 && GP_REGNUM_P (REGNO (operands[1]))"
2096 emit_insn (gen_rtx_SET (VOIDmode, operands[2],
2097 gen_rtx_XOR (DImode,
2098 gen_rtx_ASHIFTRT (DImode,
2102 emit_insn (gen_rtx_SET (VOIDmode,
2104 gen_rtx_MINUS (DImode,
2106 gen_rtx_ASHIFTRT (DImode,
2111 [(set_attr "v8type" "alu")
2112 (set_attr "type" "alu_reg")
2113 (set_attr "mode" "DI")]
2116 (define_insn "neg<mode>2"
2117 [(set (match_operand:GPI 0 "register_operand" "=r,w")
2118 (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
2122 neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
2123 [(set_attr "v8type" "alu")
2124 (set_attr "type" "alu_reg")
2125 (set_attr "simd_type" "*,simd_negabs")
2126 (set_attr "simd" "*,yes")
2127 (set_attr "mode" "<MODE>")
2128 (set_attr "simd_mode" "<MODE>")]
2131 ;; zero_extend version of above
2132 (define_insn "*negsi2_uxtw"
2133 [(set (match_operand:DI 0 "register_operand" "=r")
2134 (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
2137 [(set_attr "v8type" "alu")
2138 (set_attr "type" "alu_reg")
2139 (set_attr "mode" "SI")]
2142 (define_insn "*ngc<mode>"
2143 [(set (match_operand:GPI 0 "register_operand" "=r")
2144 (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2145 (match_operand:GPI 1 "register_operand" "r")))]
2147 "ngc\\t%<w>0, %<w>1"
2148 [(set_attr "v8type" "adc")
2149 (set_attr "type" "adc_reg")
2150 (set_attr "mode" "<MODE>")]
2153 (define_insn "*ngcsi_uxtw"
2154 [(set (match_operand:DI 0 "register_operand" "=r")
2156 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2157 (match_operand:SI 1 "register_operand" "r"))))]
2160 [(set_attr "v8type" "adc")
2161 (set_attr "type" "adc_reg")
2162 (set_attr "mode" "SI")]
2165 (define_insn "*neg<mode>2_compare0"
2166 [(set (reg:CC_NZ CC_REGNUM)
2167 (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2169 (set (match_operand:GPI 0 "register_operand" "=r")
2170 (neg:GPI (match_dup 1)))]
2172 "negs\\t%<w>0, %<w>1"
2173 [(set_attr "v8type" "alus")
2174 (set_attr "type" "alus_reg")
2175 (set_attr "mode" "<MODE>")]
2178 ;; zero_extend version of above
2179 (define_insn "*negsi2_compare0_uxtw"
2180 [(set (reg:CC_NZ CC_REGNUM)
2181 (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
2183 (set (match_operand:DI 0 "register_operand" "=r")
2184 (zero_extend:DI (neg:SI (match_dup 1))))]
2187 [(set_attr "v8type" "alus")
2188 (set_attr "type" "alus_reg")
2189 (set_attr "mode" "SI")]
2192 (define_insn "*neg_<shift><mode>3_compare0"
2193 [(set (reg:CC_NZ CC_REGNUM)
2195 (neg:GPI (ASHIFT:GPI
2196 (match_operand:GPI 1 "register_operand" "r")
2197 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2199 (set (match_operand:GPI 0 "register_operand" "=r")
2200 (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2202 "negs\\t%<w>0, %<w>1, <shift> %2"
2203 [(set_attr "v8type" "alus_shift")
2204 (set_attr "type" "alus_shift_imm")
2205 (set_attr "mode" "<MODE>")]
2208 (define_insn "*neg_<shift>_<mode>2"
2209 [(set (match_operand:GPI 0 "register_operand" "=r")
2210 (neg:GPI (ASHIFT:GPI
2211 (match_operand:GPI 1 "register_operand" "r")
2212 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2214 "neg\\t%<w>0, %<w>1, <shift> %2"
2215 [(set_attr "v8type" "alu_shift")
2216 (set_attr "type" "alu_shift_imm")
2217 (set_attr "mode" "<MODE>")]
2220 ;; zero_extend version of above
2221 (define_insn "*neg_<shift>_si2_uxtw"
2222 [(set (match_operand:DI 0 "register_operand" "=r")
2225 (match_operand:SI 1 "register_operand" "r")
2226 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2228 "neg\\t%w0, %w1, <shift> %2"
2229 [(set_attr "v8type" "alu_shift")
2230 (set_attr "type" "alu_shift_imm")
2231 (set_attr "mode" "SI")]
2234 (define_insn "*neg_mul_imm_<mode>2"
2235 [(set (match_operand:GPI 0 "register_operand" "=r")
2237 (match_operand:GPI 1 "register_operand" "r")
2238 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2240 "neg\\t%<w>0, %<w>1, lsl %p2"
2241 [(set_attr "v8type" "alu_shift")
2242 (set_attr "type" "alu_shift_imm")
2243 (set_attr "mode" "<MODE>")]
2246 ;; zero_extend version of above
2247 (define_insn "*neg_mul_imm_si2_uxtw"
2248 [(set (match_operand:DI 0 "register_operand" "=r")
2251 (match_operand:SI 1 "register_operand" "r")
2252 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2254 "neg\\t%w0, %w1, lsl %p2"
2255 [(set_attr "v8type" "alu_shift")
2256 (set_attr "type" "alu_shift_imm")
2257 (set_attr "mode" "SI")]
2260 (define_insn "mul<mode>3"
2261 [(set (match_operand:GPI 0 "register_operand" "=r")
2262 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2263 (match_operand:GPI 2 "register_operand" "r")))]
2265 "mul\\t%<w>0, %<w>1, %<w>2"
2266 [(set_attr "v8type" "mult")
2267 (set_attr "type" "mul")
2268 (set_attr "mode" "<MODE>")]
2271 ;; zero_extend version of above
2272 (define_insn "*mulsi3_uxtw"
2273 [(set (match_operand:DI 0 "register_operand" "=r")
2275 (mult:SI (match_operand:SI 1 "register_operand" "r")
2276 (match_operand:SI 2 "register_operand" "r"))))]
2278 "mul\\t%w0, %w1, %w2"
2279 [(set_attr "v8type" "mult")
2280 (set_attr "type" "mul")
2281 (set_attr "mode" "SI")]
2284 (define_insn "*madd<mode>"
2285 [(set (match_operand:GPI 0 "register_operand" "=r")
2286 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2287 (match_operand:GPI 2 "register_operand" "r"))
2288 (match_operand:GPI 3 "register_operand" "r")))]
2290 "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2291 [(set_attr "v8type" "madd")
2292 (set_attr "type" "mla")
2293 (set_attr "mode" "<MODE>")]
2296 ;; zero_extend version of above
2297 (define_insn "*maddsi_uxtw"
2298 [(set (match_operand:DI 0 "register_operand" "=r")
2300 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2301 (match_operand:SI 2 "register_operand" "r"))
2302 (match_operand:SI 3 "register_operand" "r"))))]
2304 "madd\\t%w0, %w1, %w2, %w3"
2305 [(set_attr "v8type" "madd")
2306 (set_attr "type" "mla")
2307 (set_attr "mode" "SI")]
2310 (define_insn "*msub<mode>"
2311 [(set (match_operand:GPI 0 "register_operand" "=r")
2312 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2313 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2314 (match_operand:GPI 2 "register_operand" "r"))))]
2317 "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2318 [(set_attr "v8type" "madd")
2319 (set_attr "type" "mla")
2320 (set_attr "mode" "<MODE>")]
2323 ;; zero_extend version of above
2324 (define_insn "*msubsi_uxtw"
2325 [(set (match_operand:DI 0 "register_operand" "=r")
2327 (minus:SI (match_operand:SI 3 "register_operand" "r")
2328 (mult:SI (match_operand:SI 1 "register_operand" "r")
2329 (match_operand:SI 2 "register_operand" "r")))))]
2332 "msub\\t%w0, %w1, %w2, %w3"
2333 [(set_attr "v8type" "madd")
2334 (set_attr "type" "mla")
2335 (set_attr "mode" "SI")]
2338 (define_insn "*mul<mode>_neg"
2339 [(set (match_operand:GPI 0 "register_operand" "=r")
2340 (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2341 (match_operand:GPI 2 "register_operand" "r")))]
2344 "mneg\\t%<w>0, %<w>1, %<w>2"
2345 [(set_attr "v8type" "mult")
2346 (set_attr "type" "mul")
2347 (set_attr "mode" "<MODE>")]
2350 ;; zero_extend version of above
2351 (define_insn "*mulsi_neg_uxtw"
2352 [(set (match_operand:DI 0 "register_operand" "=r")
2354 (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2355 (match_operand:SI 2 "register_operand" "r"))))]
2358 "mneg\\t%w0, %w1, %w2"
2359 [(set_attr "v8type" "mult")
2360 (set_attr "type" "mul")
2361 (set_attr "mode" "SI")]
2364 (define_insn "<su_optab>mulsidi3"
2365 [(set (match_operand:DI 0 "register_operand" "=r")
2366 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2367 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2369 "<su>mull\\t%0, %w1, %w2"
2370 [(set_attr "v8type" "mull")
2371 (set_attr "type" "<su>mull")
2372 (set_attr "mode" "DI")]
2375 (define_insn "<su_optab>maddsidi4"
2376 [(set (match_operand:DI 0 "register_operand" "=r")
2378 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2379 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2380 (match_operand:DI 3 "register_operand" "r")))]
2382 "<su>maddl\\t%0, %w1, %w2, %3"
2383 [(set_attr "v8type" "maddl")
2384 (set_attr "type" "<su>mlal")
2385 (set_attr "mode" "DI")]
2388 (define_insn "<su_optab>msubsidi4"
2389 [(set (match_operand:DI 0 "register_operand" "=r")
2391 (match_operand:DI 3 "register_operand" "r")
2392 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2394 (match_operand:SI 2 "register_operand" "r")))))]
2396 "<su>msubl\\t%0, %w1, %w2, %3"
2397 [(set_attr "v8type" "maddl")
2398 (set_attr "type" "<su>mlal")
2399 (set_attr "mode" "DI")]
2402 (define_insn "*<su_optab>mulsidi_neg"
2403 [(set (match_operand:DI 0 "register_operand" "=r")
2405 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2406 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2408 "<su>mnegl\\t%0, %w1, %w2"
2409 [(set_attr "v8type" "mull")
2410 (set_attr "type" "<su>mull")
2411 (set_attr "mode" "DI")]
2414 (define_insn "<su>muldi3_highpart"
2415 [(set (match_operand:DI 0 "register_operand" "=r")
2419 (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2420 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2423 "<su>mulh\\t%0, %1, %2"
2424 [(set_attr "v8type" "mulh")
2425 (set_attr "type" "<su>mull")
2426 (set_attr "mode" "DI")]
2429 (define_insn "<su_optab>div<mode>3"
2430 [(set (match_operand:GPI 0 "register_operand" "=r")
2431 (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2432 (match_operand:GPI 2 "register_operand" "r")))]
2434 "<su>div\\t%<w>0, %<w>1, %<w>2"
2435 [(set_attr "v8type" "<su>div")
2436 (set_attr "type" "<su>div")
2437 (set_attr "mode" "<MODE>")]
2440 ;; zero_extend version of above
2441 (define_insn "*<su_optab>divsi3_uxtw"
2442 [(set (match_operand:DI 0 "register_operand" "=r")
2444 (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2445 (match_operand:SI 2 "register_operand" "r"))))]
2447 "<su>div\\t%w0, %w1, %w2"
2448 [(set_attr "v8type" "<su>div")
2449 (set_attr "type" "<su>div")
2450 (set_attr "mode" "SI")]
2453 ;; -------------------------------------------------------------------
2455 ;; -------------------------------------------------------------------
2457 (define_insn "*cmp<mode>"
2458 [(set (reg:CC CC_REGNUM)
2459 (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2460 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2466 [(set_attr "v8type" "alus")
2467 (set_attr "type" "alus_reg,alus_imm,alus_imm")
2468 (set_attr "mode" "<MODE>")]
2471 (define_insn "*cmp<mode>"
2472 [(set (reg:CCFP CC_REGNUM)
2473 (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2474 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2478 fcmp\\t%<s>0, %<s>1"
2479 [(set_attr "v8type" "fcmp")
2480 (set_attr "type" "fcmp<s>")
2481 (set_attr "mode" "<MODE>")]
2484 (define_insn "*cmpe<mode>"
2485 [(set (reg:CCFPE CC_REGNUM)
2486 (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2487 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2491 fcmpe\\t%<s>0, %<s>1"
2492 [(set_attr "v8type" "fcmp")
2493 (set_attr "type" "fcmp<s>")
2494 (set_attr "mode" "<MODE>")]
2497 (define_insn "*cmp_swp_<shift>_reg<mode>"
2498 [(set (reg:CC_SWP CC_REGNUM)
2499 (compare:CC_SWP (ASHIFT:GPI
2500 (match_operand:GPI 0 "register_operand" "r")
2501 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2502 (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2504 "cmp\\t%<w>2, %<w>0, <shift> %1"
2505 [(set_attr "v8type" "alus_shift")
2506 (set_attr "type" "alus_shift_imm")
2507 (set_attr "mode" "<MODE>")]
2510 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2511 [(set (reg:CC_SWP CC_REGNUM)
2512 (compare:CC_SWP (ANY_EXTEND:GPI
2513 (match_operand:ALLX 0 "register_operand" "r"))
2514 (match_operand:GPI 1 "register_operand" "r")))]
2516 "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2517 [(set_attr "v8type" "alus_ext")
2518 (set_attr "type" "alus_ext")
2519 (set_attr "mode" "<GPI:MODE>")]
2522 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2523 [(set (reg:CC_SWP CC_REGNUM)
2524 (compare:CC_SWP (ashift:GPI
2526 (match_operand:ALLX 0 "register_operand" "r"))
2527 (match_operand 1 "aarch64_imm3" "Ui3"))
2528 (match_operand:GPI 2 "register_operand" "r")))]
2530 "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2531 [(set_attr "v8type" "alus_ext")
2532 (set_attr "type" "alus_ext")
2533 (set_attr "mode" "<GPI:MODE>")]
2536 ;; -------------------------------------------------------------------
2537 ;; Store-flag and conditional select insns
2538 ;; -------------------------------------------------------------------
2540 (define_expand "cstore<mode>4"
2541 [(set (match_operand:SI 0 "register_operand" "")
2542 (match_operator:SI 1 "aarch64_comparison_operator"
2543 [(match_operand:GPI 2 "register_operand" "")
2544 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2547 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2549 operands[3] = const0_rtx;
2553 (define_expand "cstore<mode>4"
2554 [(set (match_operand:SI 0 "register_operand" "")
2555 (match_operator:SI 1 "aarch64_comparison_operator"
2556 [(match_operand:GPF 2 "register_operand" "")
2557 (match_operand:GPF 3 "register_operand" "")]))]
2560 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2562 operands[3] = const0_rtx;
2566 (define_insn "*cstore<mode>_insn"
2567 [(set (match_operand:ALLI 0 "register_operand" "=r")
2568 (match_operator:ALLI 1 "aarch64_comparison_operator"
2569 [(match_operand 2 "cc_register" "") (const_int 0)]))]
2572 [(set_attr "v8type" "csel")
2573 (set_attr "type" "csel")
2574 (set_attr "mode" "<MODE>")]
2577 ;; zero_extend version of the above
2578 (define_insn "*cstoresi_insn_uxtw"
2579 [(set (match_operand:DI 0 "register_operand" "=r")
2581 (match_operator:SI 1 "aarch64_comparison_operator"
2582 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2585 [(set_attr "v8type" "csel")
2586 (set_attr "type" "csel")
2587 (set_attr "mode" "SI")]
2590 (define_insn "cstore<mode>_neg"
2591 [(set (match_operand:ALLI 0 "register_operand" "=r")
2592 (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2593 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2595 "csetm\\t%<w>0, %m1"
2596 [(set_attr "v8type" "csel")
2597 (set_attr "type" "csel")
2598 (set_attr "mode" "<MODE>")]
2601 ;; zero_extend version of the above
2602 (define_insn "*cstoresi_neg_uxtw"
2603 [(set (match_operand:DI 0 "register_operand" "=r")
2605 (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2606 [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2609 [(set_attr "v8type" "csel")
2610 (set_attr "type" "csel")
2611 (set_attr "mode" "SI")]
2614 (define_expand "cmov<mode>6"
2615 [(set (match_operand:GPI 0 "register_operand" "")
2617 (match_operator 1 "aarch64_comparison_operator"
2618 [(match_operand:GPI 2 "register_operand" "")
2619 (match_operand:GPI 3 "aarch64_plus_operand" "")])
2620 (match_operand:GPI 4 "register_operand" "")
2621 (match_operand:GPI 5 "register_operand" "")))]
2624 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2626 operands[3] = const0_rtx;
2630 (define_expand "cmov<mode>6"
2631 [(set (match_operand:GPF 0 "register_operand" "")
2633 (match_operator 1 "aarch64_comparison_operator"
2634 [(match_operand:GPF 2 "register_operand" "")
2635 (match_operand:GPF 3 "register_operand" "")])
2636 (match_operand:GPF 4 "register_operand" "")
2637 (match_operand:GPF 5 "register_operand" "")))]
2640 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2642 operands[3] = const0_rtx;
2646 (define_insn "*cmov<mode>_insn"
2647 [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2649 (match_operator 1 "aarch64_comparison_operator"
2650 [(match_operand 2 "cc_register" "") (const_int 0)])
2651 (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2652 (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2653 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2654 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2655 ;; Final two alternatives should be unreachable, but included for completeness
2657 csel\\t%<w>0, %<w>3, %<w>4, %m1
2658 csinv\\t%<w>0, %<w>3, <w>zr, %m1
2659 csinv\\t%<w>0, %<w>4, <w>zr, %M1
2660 csinc\\t%<w>0, %<w>3, <w>zr, %m1
2661 csinc\\t%<w>0, %<w>4, <w>zr, %M1
2664 [(set_attr "v8type" "csel")
2665 (set_attr "type" "csel")
2666 (set_attr "mode" "<MODE>")]
2669 ;; zero_extend version of above
2670 (define_insn "*cmovsi_insn_uxtw"
2671 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2674 (match_operator 1 "aarch64_comparison_operator"
2675 [(match_operand 2 "cc_register" "") (const_int 0)])
2676 (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2677 (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2678 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2679 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2680 ;; Final two alternatives should be unreachable, but included for completeness
2682 csel\\t%w0, %w3, %w4, %m1
2683 csinv\\t%w0, %w3, wzr, %m1
2684 csinv\\t%w0, %w4, wzr, %M1
2685 csinc\\t%w0, %w3, wzr, %m1
2686 csinc\\t%w0, %w4, wzr, %M1
2689 [(set_attr "v8type" "csel")
2690 (set_attr "type" "csel")
2691 (set_attr "mode" "SI")]
2694 (define_insn "*cmov<mode>_insn"
2695 [(set (match_operand:GPF 0 "register_operand" "=w")
2697 (match_operator 1 "aarch64_comparison_operator"
2698 [(match_operand 2 "cc_register" "") (const_int 0)])
2699 (match_operand:GPF 3 "register_operand" "w")
2700 (match_operand:GPF 4 "register_operand" "w")))]
2702 "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2703 [(set_attr "v8type" "fcsel")
2704 (set_attr "type" "fcsel")
2705 (set_attr "mode" "<MODE>")]
2708 (define_expand "mov<mode>cc"
2709 [(set (match_operand:ALLI 0 "register_operand" "")
2710 (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2711 (match_operand:ALLI 2 "register_operand" "")
2712 (match_operand:ALLI 3 "register_operand" "")))]
2716 enum rtx_code code = GET_CODE (operands[1]);
2718 if (code == UNEQ || code == LTGT)
2721 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2722 XEXP (operands[1], 1));
2723 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2727 (define_expand "mov<GPF:mode><GPI:mode>cc"
2728 [(set (match_operand:GPI 0 "register_operand" "")
2729 (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2730 (match_operand:GPF 2 "register_operand" "")
2731 (match_operand:GPF 3 "register_operand" "")))]
2735 enum rtx_code code = GET_CODE (operands[1]);
2737 if (code == UNEQ || code == LTGT)
2740 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2741 XEXP (operands[1], 1));
2742 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2746 (define_insn "*csinc2<mode>_insn"
2747 [(set (match_operand:GPI 0 "register_operand" "=r")
2748 (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator"
2749 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
2750 (match_operand:GPI 1 "register_operand" "r")))]
2752 "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2753 [(set_attr "v8type" "csel")
2754 (set_attr "type" "csel")
2755 (set_attr "mode" "<MODE>")])
2757 (define_insn "csinc3<mode>_insn"
2758 [(set (match_operand:GPI 0 "register_operand" "=r")
2760 (match_operator:GPI 1 "aarch64_comparison_operator"
2761 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2762 (plus:GPI (match_operand:GPI 3 "register_operand" "r")
2764 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2766 "csinc\\t%<w>0, %<w>4, %<w>3, %M1"
2767 [(set_attr "v8type" "csel")
2768 (set_attr "type" "csel")
2769 (set_attr "mode" "<MODE>")]
2772 (define_insn "*csinv3<mode>_insn"
2773 [(set (match_operand:GPI 0 "register_operand" "=r")
2775 (match_operator:GPI 1 "aarch64_comparison_operator"
2776 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2777 (not:GPI (match_operand:GPI 3 "register_operand" "r"))
2778 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2780 "csinv\\t%<w>0, %<w>4, %<w>3, %M1"
2781 [(set_attr "v8type" "csel")
2782 (set_attr "type" "csel")
2783 (set_attr "mode" "<MODE>")])
2785 (define_insn "*csneg3<mode>_insn"
2786 [(set (match_operand:GPI 0 "register_operand" "=r")
2788 (match_operator:GPI 1 "aarch64_comparison_operator"
2789 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2790 (neg:GPI (match_operand:GPI 3 "register_operand" "r"))
2791 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2793 "csneg\\t%<w>0, %<w>4, %<w>3, %M1"
2794 [(set_attr "v8type" "csel")
2795 (set_attr "type" "csel")
2796 (set_attr "mode" "<MODE>")])
2798 ;; -------------------------------------------------------------------
2799 ;; Logical operations
2800 ;; -------------------------------------------------------------------
2802 (define_insn "<optab><mode>3"
2803 [(set (match_operand:GPI 0 "register_operand" "=r,rk")
2804 (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2805 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
2807 "<logical>\\t%<w>0, %<w>1, %<w>2"
2808 [(set_attr "v8type" "logic,logic_imm")
2809 (set_attr "type" "logic_reg,logic_imm")
2810 (set_attr "mode" "<MODE>")])
2812 ;; zero_extend version of above
2813 (define_insn "*<optab>si3_uxtw"
2814 [(set (match_operand:DI 0 "register_operand" "=r,rk")
2816 (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2817 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2819 "<logical>\\t%w0, %w1, %w2"
2820 [(set_attr "v8type" "logic,logic_imm")
2821 (set_attr "type" "logic_reg,logic_imm")
2822 (set_attr "mode" "SI")])
2824 (define_insn "*and<mode>3_compare0"
2825 [(set (reg:CC_NZ CC_REGNUM)
2827 (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2828 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2830 (set (match_operand:GPI 0 "register_operand" "=r,r")
2831 (and:GPI (match_dup 1) (match_dup 2)))]
2833 "ands\\t%<w>0, %<w>1, %<w>2"
2834 [(set_attr "v8type" "logics,logics_imm")
2835 (set_attr "type" "logics_reg,logics_imm")
2836 (set_attr "mode" "<MODE>")]
2839 ;; zero_extend version of above
2840 (define_insn "*andsi3_compare0_uxtw"
2841 [(set (reg:CC_NZ CC_REGNUM)
2843 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2844 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2846 (set (match_operand:DI 0 "register_operand" "=r,r")
2847 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2849 "ands\\t%w0, %w1, %w2"
2850 [(set_attr "v8type" "logics,logics_imm")
2851 (set_attr "type" "logics_reg,logics_imm")
2852 (set_attr "mode" "SI")]
2855 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2856 [(set (reg:CC_NZ CC_REGNUM)
2859 (match_operand:GPI 1 "register_operand" "r")
2860 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2861 (match_operand:GPI 3 "register_operand" "r"))
2863 (set (match_operand:GPI 0 "register_operand" "=r")
2864 (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2866 "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2867 [(set_attr "v8type" "logics_shift")
2868 (set_attr "type" "logics_shift_imm")
2869 (set_attr "mode" "<MODE>")]
2872 ;; zero_extend version of above
2873 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2874 [(set (reg:CC_NZ CC_REGNUM)
2877 (match_operand:SI 1 "register_operand" "r")
2878 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2879 (match_operand:SI 3 "register_operand" "r"))
2881 (set (match_operand:DI 0 "register_operand" "=r")
2882 (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2885 "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2886 [(set_attr "v8type" "logics_shift")
2887 (set_attr "type" "logics_shift_imm")
2888 (set_attr "mode" "SI")]
2891 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2892 [(set (match_operand:GPI 0 "register_operand" "=r")
2893 (LOGICAL:GPI (SHIFT:GPI
2894 (match_operand:GPI 1 "register_operand" "r")
2895 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2896 (match_operand:GPI 3 "register_operand" "r")))]
2898 "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2899 [(set_attr "v8type" "logic_shift")
2900 (set_attr "type" "logic_shift_imm")
2901 (set_attr "mode" "<MODE>")])
2903 ;; zero_extend version of above
2904 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
2905 [(set (match_operand:DI 0 "register_operand" "=r")
2907 (LOGICAL:SI (SHIFT:SI
2908 (match_operand:SI 1 "register_operand" "r")
2909 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2910 (match_operand:SI 3 "register_operand" "r"))))]
2912 "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2913 [(set_attr "v8type" "logic_shift")
2914 (set_attr "type" "logic_shift_imm")
2915 (set_attr "mode" "SI")])
2917 (define_insn "one_cmpl<mode>2"
2918 [(set (match_operand:GPI 0 "register_operand" "=r")
2919 (not:GPI (match_operand:GPI 1 "register_operand" "r")))]
2921 "mvn\\t%<w>0, %<w>1"
2922 [(set_attr "v8type" "logic")
2923 (set_attr "type" "logic_reg")
2924 (set_attr "mode" "<MODE>")])
2926 (define_insn "*one_cmpl_<optab><mode>2"
2927 [(set (match_operand:GPI 0 "register_operand" "=r")
2928 (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
2929 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2931 "mvn\\t%<w>0, %<w>1, <shift> %2"
2932 [(set_attr "v8type" "logic_shift")
2933 (set_attr "type" "logic_shift_imm")
2934 (set_attr "mode" "<MODE>")])
2936 (define_insn "*<LOGICAL:optab>_one_cmpl<mode>3"
2937 [(set (match_operand:GPI 0 "register_operand" "=r")
2938 (LOGICAL:GPI (not:GPI
2939 (match_operand:GPI 1 "register_operand" "r"))
2940 (match_operand:GPI 2 "register_operand" "r")))]
2942 "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1"
2943 [(set_attr "v8type" "logic")
2944 (set_attr "type" "logic_reg")
2945 (set_attr "mode" "<MODE>")])
2947 (define_insn "*and_one_cmpl<mode>3_compare0"
2948 [(set (reg:CC_NZ CC_REGNUM)
2951 (match_operand:GPI 1 "register_operand" "r"))
2952 (match_operand:GPI 2 "register_operand" "r"))
2954 (set (match_operand:GPI 0 "register_operand" "=r")
2955 (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
2957 "bics\\t%<w>0, %<w>2, %<w>1"
2958 [(set_attr "v8type" "logics")
2959 (set_attr "type" "logics_reg")
2960 (set_attr "mode" "<MODE>")])
2962 ;; zero_extend version of above
2963 (define_insn "*and_one_cmplsi3_compare0_uxtw"
2964 [(set (reg:CC_NZ CC_REGNUM)
2967 (match_operand:SI 1 "register_operand" "r"))
2968 (match_operand:SI 2 "register_operand" "r"))
2970 (set (match_operand:DI 0 "register_operand" "=r")
2971 (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
2973 "bics\\t%w0, %w2, %w1"
2974 [(set_attr "v8type" "logics")
2975 (set_attr "type" "logics_reg")
2976 (set_attr "mode" "SI")])
2978 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
2979 [(set (match_operand:GPI 0 "register_operand" "=r")
2980 (LOGICAL:GPI (not:GPI
2982 (match_operand:GPI 1 "register_operand" "r")
2983 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2984 (match_operand:GPI 3 "register_operand" "r")))]
2986 "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2987 [(set_attr "v8type" "logic_shift")
2988 (set_attr "type" "logics_shift_imm")
2989 (set_attr "mode" "<MODE>")])
2991 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
2992 [(set (reg:CC_NZ CC_REGNUM)
2996 (match_operand:GPI 1 "register_operand" "r")
2997 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2998 (match_operand:GPI 3 "register_operand" "r"))
3000 (set (match_operand:GPI 0 "register_operand" "=r")
3003 (match_dup 1) (match_dup 2))) (match_dup 3)))]
3005 "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3006 [(set_attr "v8type" "logics_shift")
3007 (set_attr "type" "logics_shift_imm")
3008 (set_attr "mode" "<MODE>")])
3010 ;; zero_extend version of above
3011 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
3012 [(set (reg:CC_NZ CC_REGNUM)
3016 (match_operand:SI 1 "register_operand" "r")
3017 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
3018 (match_operand:SI 3 "register_operand" "r"))
3020 (set (match_operand:DI 0 "register_operand" "=r")
3021 (zero_extend:DI (and:SI
3023 (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
3025 "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3026 [(set_attr "v8type" "logics_shift")
3027 (set_attr "type" "logics_shift_imm")
3028 (set_attr "mode" "SI")])
3030 (define_insn "clz<mode>2"
3031 [(set (match_operand:GPI 0 "register_operand" "=r")
3032 (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
3034 "clz\\t%<w>0, %<w>1"
3035 [(set_attr "v8type" "clz")
3036 (set_attr "type" "clz")
3037 (set_attr "mode" "<MODE>")])
3039 (define_expand "ffs<mode>2"
3040 [(match_operand:GPI 0 "register_operand")
3041 (match_operand:GPI 1 "register_operand")]
3044 rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
3045 rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
3047 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3048 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3049 emit_insn (gen_csinc3<mode>_insn (operands[0], x, ccreg, operands[0], const0_rtx));
3054 (define_insn "clrsb<mode>2"
3055 [(set (match_operand:GPI 0 "register_operand" "=r")
3056 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_CLS))]
3058 "cls\\t%<w>0, %<w>1"
3059 [(set_attr "v8type" "clz")
3060 (set_attr "type" "clz")
3061 (set_attr "mode" "<MODE>")])
3063 (define_insn "rbit<mode>2"
3064 [(set (match_operand:GPI 0 "register_operand" "=r")
3065 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
3067 "rbit\\t%<w>0, %<w>1"
3068 [(set_attr "v8type" "rbit")
3069 (set_attr "type" "rbit")
3070 (set_attr "mode" "<MODE>")])
3072 (define_expand "ctz<mode>2"
3073 [(match_operand:GPI 0 "register_operand")
3074 (match_operand:GPI 1 "register_operand")]
3077 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3078 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3083 (define_insn "*and<mode>3nr_compare0"
3084 [(set (reg:CC_NZ CC_REGNUM)
3086 (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
3087 (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
3090 "tst\\t%<w>0, %<w>1"
3091 [(set_attr "v8type" "logics")
3092 (set_attr "type" "logics_reg")
3093 (set_attr "mode" "<MODE>")])
3095 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
3096 [(set (reg:CC_NZ CC_REGNUM)
3099 (match_operand:GPI 0 "register_operand" "r")
3100 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
3101 (match_operand:GPI 2 "register_operand" "r"))
3104 "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
3105 [(set_attr "v8type" "logics_shift")
3106 (set_attr "type" "logics_shift_imm")
3107 (set_attr "mode" "<MODE>")])
3109 ;; -------------------------------------------------------------------
3111 ;; -------------------------------------------------------------------
3113 (define_expand "<optab><mode>3"
3114 [(set (match_operand:GPI 0 "register_operand")
3115 (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
3116 (match_operand:QI 2 "nonmemory_operand")))]
3119 if (CONST_INT_P (operands[2]))
3121 operands[2] = GEN_INT (INTVAL (operands[2])
3122 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3124 if (operands[2] == const0_rtx)
3126 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3133 (define_expand "ashl<mode>3"
3134 [(set (match_operand:SHORT 0 "register_operand")
3135 (ashift:SHORT (match_operand:SHORT 1 "register_operand")
3136 (match_operand:QI 2 "nonmemory_operand")))]
3139 if (CONST_INT_P (operands[2]))
3141 operands[2] = GEN_INT (INTVAL (operands[2])
3142 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3144 if (operands[2] == const0_rtx)
3146 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3153 (define_expand "rotr<mode>3"
3154 [(set (match_operand:GPI 0 "register_operand")
3155 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3156 (match_operand:QI 2 "nonmemory_operand")))]
3159 if (CONST_INT_P (operands[2]))
3161 operands[2] = GEN_INT (INTVAL (operands[2])
3162 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3164 if (operands[2] == const0_rtx)
3166 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3173 (define_expand "rotl<mode>3"
3174 [(set (match_operand:GPI 0 "register_operand")
3175 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3176 (match_operand:QI 2 "nonmemory_operand")))]
3179 /* (SZ - cnt) % SZ == -cnt % SZ */
3180 if (CONST_INT_P (operands[2]))
3182 operands[2] = GEN_INT ((-INTVAL (operands[2]))
3183 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3184 if (operands[2] == const0_rtx)
3186 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3191 operands[2] = expand_simple_unop (QImode, NEG, operands[2],
3196 ;; Logical left shift using SISD or Integer instruction
3197 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
3198 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3200 (match_operand:GPI 1 "register_operand" "w,w,r")
3201 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3204 shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3205 ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
3206 lsl\t%<w>0, %<w>1, %<w>2"
3207 [(set_attr "simd" "yes,yes,no")
3208 (set_attr "simd_type" "simd_shift_imm,simd_shift,*")
3209 (set_attr "simd_mode" "<MODE>,<MODE>,*")
3210 (set_attr "v8type" "*,*,shift")
3211 (set_attr "type" "*,*,shift_reg")
3212 (set_attr "mode" "*,*,<MODE>")]
3215 ;; Logical right shift using SISD or Integer instruction
3216 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3217 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3219 (match_operand:GPI 1 "register_operand" "w,w,r")
3220 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3223 ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3225 lsr\t%<w>0, %<w>1, %<w>2"
3226 [(set_attr "simd" "yes,yes,no")
3227 (set_attr "simd_type" "simd_shift_imm,simd_shift,*")
3228 (set_attr "simd_mode" "<MODE>,<MODE>,*")
3229 (set_attr "v8type" "*,*,shift")
3230 (set_attr "type" "*,*,shift_reg")
3231 (set_attr "mode" "*,*,<MODE>")]
3235 [(set (match_operand:DI 0 "aarch64_simd_register")
3237 (match_operand:DI 1 "aarch64_simd_register")
3238 (match_operand:QI 2 "aarch64_simd_register")))]
3239 "TARGET_SIMD && reload_completed"
3241 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3243 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_USHL))]
3248 [(set (match_operand:SI 0 "aarch64_simd_register")
3250 (match_operand:SI 1 "aarch64_simd_register")
3251 (match_operand:QI 2 "aarch64_simd_register")))]
3252 "TARGET_SIMD && reload_completed"
3254 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3256 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_USHL_2S))]
3260 ;; Arithmetic right shift using SISD or Integer instruction
3261 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3262 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3264 (match_operand:GPI 1 "register_operand" "w,w,r")
3265 (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,rUs<cmode>")))]
3268 sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3270 asr\t%<w>0, %<w>1, %<w>2"
3271 [(set_attr "simd" "yes,yes,no")
3272 (set_attr "simd_type" "simd_shift_imm,simd_shift,*")
3273 (set_attr "simd_mode" "<MODE>,<MODE>,*")
3274 (set_attr "v8type" "*,*,shift")
3275 (set_attr "type" "*,*,shift_reg")
3276 (set_attr "mode" "*,*,<MODE>")]
3280 [(set (match_operand:DI 0 "aarch64_simd_register")
3282 (match_operand:DI 1 "aarch64_simd_register")
3283 (match_operand:QI 2 "aarch64_simd_register")))]
3284 "TARGET_SIMD && reload_completed"
3286 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3288 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_SSHL))]
3293 [(set (match_operand:SI 0 "aarch64_simd_register")
3295 (match_operand:SI 1 "aarch64_simd_register")
3296 (match_operand:QI 2 "aarch64_simd_register")))]
3297 "TARGET_SIMD && reload_completed"
3299 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3301 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_SSHL_2S))]
3305 (define_insn "*aarch64_sisd_ushl"
3306 [(set (match_operand:DI 0 "register_operand" "=w")
3307 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3308 (match_operand:QI 2 "register_operand" "w")]
3311 "ushl\t%d0, %d1, %d2"
3312 [(set_attr "simd" "yes")
3313 (set_attr "simd_type" "simd_shift")
3314 (set_attr "simd_mode" "DI")]
3317 (define_insn "*aarch64_ushl_2s"
3318 [(set (match_operand:SI 0 "register_operand" "=w")
3319 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3320 (match_operand:QI 2 "register_operand" "w")]
3323 "ushl\t%0.2s, %1.2s, %2.2s"
3324 [(set_attr "simd" "yes")
3325 (set_attr "simd_type" "simd_shift")
3326 (set_attr "simd_mode" "DI")]
3329 (define_insn "*aarch64_sisd_sshl"
3330 [(set (match_operand:DI 0 "register_operand" "=w")
3331 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3332 (match_operand:QI 2 "register_operand" "w")]
3335 "sshl\t%d0, %d1, %d2"
3336 [(set_attr "simd" "yes")
3337 (set_attr "simd_type" "simd_shift")
3338 (set_attr "simd_mode" "DI")]
3341 (define_insn "*aarch64_sshl_2s"
3342 [(set (match_operand:SI 0 "register_operand" "=w")
3343 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3344 (match_operand:QI 2 "register_operand" "w")]
3347 "sshl\t%0.2s, %1.2s, %2.2s"
3348 [(set_attr "simd" "yes")
3349 (set_attr "simd_type" "simd_shift")
3350 (set_attr "simd_mode" "DI")]
3353 (define_insn "*aarch64_sisd_neg_qi"
3354 [(set (match_operand:QI 0 "register_operand" "=w")
3355 (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3359 [(set_attr "simd" "yes")
3360 (set_attr "simd_type" "simd_negabs")
3361 (set_attr "simd_mode" "QI")]
3365 (define_insn "*ror<mode>3_insn"
3366 [(set (match_operand:GPI 0 "register_operand" "=r")
3368 (match_operand:GPI 1 "register_operand" "r")
3369 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3371 "ror\\t%<w>0, %<w>1, %<w>2"
3372 [(set_attr "v8type" "shift")
3373 (set_attr "type" "shift_reg")
3374 (set_attr "mode" "<MODE>")]
3377 ;; zero_extend version of above
3378 (define_insn "*<optab>si3_insn_uxtw"
3379 [(set (match_operand:DI 0 "register_operand" "=r")
3380 (zero_extend:DI (SHIFT:SI
3381 (match_operand:SI 1 "register_operand" "r")
3382 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3384 "<shift>\\t%w0, %w1, %w2"
3385 [(set_attr "v8type" "shift")
3386 (set_attr "type" "shift_reg")
3387 (set_attr "mode" "SI")]
3390 (define_insn "*ashl<mode>3_insn"
3391 [(set (match_operand:SHORT 0 "register_operand" "=r")
3392 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3393 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
3395 "lsl\\t%<w>0, %<w>1, %<w>2"
3396 [(set_attr "v8type" "shift")
3397 (set_attr "type" "shift_reg")
3398 (set_attr "mode" "<MODE>")]
3401 (define_insn "*<optab><mode>3_insn"
3402 [(set (match_operand:SHORT 0 "register_operand" "=r")
3403 (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3404 (match_operand 2 "const_int_operand" "n")))]
3405 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3407 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3408 return "<bfshift>\t%w0, %w1, %2, %3";
3410 [(set_attr "v8type" "bfm")
3411 (set_attr "type" "bfm")
3412 (set_attr "mode" "<MODE>")]
3415 (define_insn "*extr<mode>5_insn"
3416 [(set (match_operand:GPI 0 "register_operand" "=r")
3417 (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3418 (match_operand 3 "const_int_operand" "n"))
3419 (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3420 (match_operand 4 "const_int_operand" "n"))))]
3421 "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3422 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3423 "extr\\t%<w>0, %<w>1, %<w>2, %4"
3424 [(set_attr "v8type" "shift")
3425 (set_attr "type" "shift_imm")
3426 (set_attr "mode" "<MODE>")]
3429 ;; zero_extend version of the above
3430 (define_insn "*extrsi5_insn_uxtw"
3431 [(set (match_operand:DI 0 "register_operand" "=r")
3433 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3434 (match_operand 3 "const_int_operand" "n"))
3435 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3436 (match_operand 4 "const_int_operand" "n")))))]
3437 "UINTVAL (operands[3]) < 32 &&
3438 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3439 "extr\\t%w0, %w1, %w2, %4"
3440 [(set_attr "v8type" "shift")
3441 (set_attr "type" "shift_imm")
3442 (set_attr "mode" "SI")]
3445 (define_insn "*ror<mode>3_insn"
3446 [(set (match_operand:GPI 0 "register_operand" "=r")
3447 (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3448 (match_operand 2 "const_int_operand" "n")))]
3449 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3451 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3452 return "ror\\t%<w>0, %<w>1, %3";
3454 [(set_attr "v8type" "shift")
3455 (set_attr "type" "shift_imm")
3456 (set_attr "mode" "<MODE>")]
3459 ;; zero_extend version of the above
3460 (define_insn "*rorsi3_insn_uxtw"
3461 [(set (match_operand:DI 0 "register_operand" "=r")
3463 (rotate:SI (match_operand:SI 1 "register_operand" "r")
3464 (match_operand 2 "const_int_operand" "n"))))]
3465 "UINTVAL (operands[2]) < 32"
3467 operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3468 return "ror\\t%w0, %w1, %3";
3470 [(set_attr "v8type" "shift")
3471 (set_attr "type" "shift_imm")
3472 (set_attr "mode" "SI")]
3475 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3476 [(set (match_operand:GPI 0 "register_operand" "=r")
3478 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3479 (match_operand 2 "const_int_operand" "n"))))]
3480 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3482 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3483 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3485 [(set_attr "v8type" "bfm")
3486 (set_attr "type" "bfm")
3487 (set_attr "mode" "<GPI:MODE>")]
3490 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3491 [(set (match_operand:GPI 0 "register_operand" "=r")
3493 (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3494 (match_operand 2 "const_int_operand" "n"))))]
3495 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3497 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3498 return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3500 [(set_attr "v8type" "bfm")
3501 (set_attr "type" "bfm")
3502 (set_attr "mode" "<GPI:MODE>")]
3505 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3506 [(set (match_operand:GPI 0 "register_operand" "=r")
3508 (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3509 (match_operand 2 "const_int_operand" "n"))))]
3510 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3512 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3513 return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3515 [(set_attr "v8type" "bfm")
3516 (set_attr "type" "bfm")
3517 (set_attr "mode" "<GPI:MODE>")]
3520 ;; -------------------------------------------------------------------
3522 ;; -------------------------------------------------------------------
3524 (define_expand "<optab>"
3525 [(set (match_operand:DI 0 "register_operand" "=r")
3526 (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3527 (match_operand 2 "const_int_operand" "n")
3528 (match_operand 3 "const_int_operand" "n")))]
3533 (define_insn "*<optab><mode>"
3534 [(set (match_operand:GPI 0 "register_operand" "=r")
3535 (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3536 (match_operand 2 "const_int_operand" "n")
3537 (match_operand 3 "const_int_operand" "n")))]
3539 "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3540 [(set_attr "v8type" "bfm")
3541 (set_attr "type" "bfm")
3542 (set_attr "mode" "<MODE>")]
3545 ;; Bitfield Insert (insv)
3546 (define_expand "insv<mode>"
3547 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3548 (match_operand 1 "const_int_operand")
3549 (match_operand 2 "const_int_operand"))
3550 (match_operand:GPI 3 "general_operand"))]
3553 unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3554 unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3555 rtx value = operands[3];
3557 if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3560 if (CONST_INT_P (value))
3562 unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3564 /* Prefer AND/OR for inserting all zeros or all ones. */
3565 if ((UINTVAL (value) & mask) == 0
3566 || (UINTVAL (value) & mask) == mask)
3569 /* 16-bit aligned 16-bit wide insert is handled by insv_imm. */
3570 if (width == 16 && (pos % 16) == 0)
3573 operands[3] = force_reg (<MODE>mode, value);
3576 (define_insn "*insv_reg<mode>"
3577 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3578 (match_operand 1 "const_int_operand" "n")
3579 (match_operand 2 "const_int_operand" "n"))
3580 (match_operand:GPI 3 "register_operand" "r"))]
3581 "!(UINTVAL (operands[1]) == 0
3582 || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3583 > GET_MODE_BITSIZE (<MODE>mode)))"
3584 "bfi\\t%<w>0, %<w>3, %2, %1"
3585 [(set_attr "v8type" "bfm")
3586 (set_attr "type" "bfm")
3587 (set_attr "mode" "<MODE>")]
3590 (define_insn "*extr_insv_lower_reg<mode>"
3591 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3592 (match_operand 1 "const_int_operand" "n")
3594 (zero_extract:GPI (match_operand:GPI 2 "register_operand" "+r")
3596 (match_operand 3 "const_int_operand" "n")))]
3597 "!(UINTVAL (operands[1]) == 0
3598 || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3599 > GET_MODE_BITSIZE (<MODE>mode)))"
3600 "bfxil\\t%<w>0, %<w>2, %3, %1"
3601 [(set_attr "v8type" "bfm")
3602 (set_attr "type" "bfm")
3603 (set_attr "mode" "<MODE>")]
3606 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3607 [(set (match_operand:GPI 0 "register_operand" "=r")
3608 (ashift:GPI (ANY_EXTEND:GPI
3609 (match_operand:ALLX 1 "register_operand" "r"))
3610 (match_operand 2 "const_int_operand" "n")))]
3611 "UINTVAL (operands[2]) < <GPI:sizen>"
3613 operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3614 ? GEN_INT (<ALLX:sizen>)
3615 : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3616 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3618 [(set_attr "v8type" "bfm")
3619 (set_attr "type" "bfm")
3620 (set_attr "mode" "<GPI:MODE>")]
3623 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3625 (define_insn "*andim_ashift<mode>_bfiz"
3626 [(set (match_operand:GPI 0 "register_operand" "=r")
3627 (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3628 (match_operand 2 "const_int_operand" "n"))
3629 (match_operand 3 "const_int_operand" "n")))]
3630 "exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3631 && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3632 "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3633 [(set_attr "v8type" "bfm")
3634 (set_attr "type" "bfm")
3635 (set_attr "mode" "<MODE>")]
3638 (define_insn "bswap<mode>2"
3639 [(set (match_operand:GPI 0 "register_operand" "=r")
3640 (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3642 "rev\\t%<w>0, %<w>1"
3643 [(set_attr "v8type" "rev")
3644 (set_attr "type" "rev")
3645 (set_attr "mode" "<MODE>")]
3648 (define_insn "bswaphi2"
3649 [(set (match_operand:HI 0 "register_operand" "=r")
3650 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3653 [(set_attr "v8type" "rev")
3654 (set_attr "type" "rev")
3655 (set_attr "mode" "HI")]
3658 ;; zero_extend version of above
3659 (define_insn "*bswapsi2_uxtw"
3660 [(set (match_operand:DI 0 "register_operand" "=r")
3661 (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3664 [(set_attr "v8type" "rev")
3665 (set_attr "type" "rev")
3666 (set_attr "mode" "SI")]
3669 ;; -------------------------------------------------------------------
3670 ;; Floating-point intrinsics
3671 ;; -------------------------------------------------------------------
3673 ;; frint floating-point round to integral standard patterns.
3674 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round.
3676 (define_insn "<frint_pattern><mode>2"
3677 [(set (match_operand:GPF 0 "register_operand" "=w")
3678 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3681 "frint<frint_suffix>\\t%<s>0, %<s>1"
3682 [(set_attr "v8type" "frint")
3683 (set_attr "type" "f_rint<s>")
3684 (set_attr "mode" "<MODE>")]
3687 ;; frcvt floating-point round to integer and convert standard patterns.
3688 ;; Expands to lbtrunc, lceil, lfloor, lround.
3689 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3690 [(set (match_operand:GPI 0 "register_operand" "=r")
3691 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3694 "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3695 [(set_attr "v8type" "fcvtf2i")
3696 (set_attr "type" "f_cvtf2i")
3697 (set_attr "mode" "<GPF:MODE>")
3698 (set_attr "mode2" "<GPI:MODE>")]
3703 (define_insn "fma<mode>4"
3704 [(set (match_operand:GPF 0 "register_operand" "=w")
3705 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3706 (match_operand:GPF 2 "register_operand" "w")
3707 (match_operand:GPF 3 "register_operand" "w")))]
3709 "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3710 [(set_attr "v8type" "fmadd")
3711 (set_attr "type" "fmac<s>")
3712 (set_attr "mode" "<MODE>")]
3715 (define_insn "fnma<mode>4"
3716 [(set (match_operand:GPF 0 "register_operand" "=w")
3717 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3718 (match_operand:GPF 2 "register_operand" "w")
3719 (match_operand:GPF 3 "register_operand" "w")))]
3721 "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3722 [(set_attr "v8type" "fmadd")
3723 (set_attr "type" "fmac<s>")
3724 (set_attr "mode" "<MODE>")]
3727 (define_insn "fms<mode>4"
3728 [(set (match_operand:GPF 0 "register_operand" "=w")
3729 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3730 (match_operand:GPF 2 "register_operand" "w")
3731 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3733 "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3734 [(set_attr "v8type" "fmadd")
3735 (set_attr "type" "fmac<s>")
3736 (set_attr "mode" "<MODE>")]
3739 (define_insn "fnms<mode>4"
3740 [(set (match_operand:GPF 0 "register_operand" "=w")
3741 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3742 (match_operand:GPF 2 "register_operand" "w")
3743 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3745 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3746 [(set_attr "v8type" "fmadd")
3747 (set_attr "type" "fmac<s>")
3748 (set_attr "mode" "<MODE>")]
3751 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3752 (define_insn "*fnmadd<mode>4"
3753 [(set (match_operand:GPF 0 "register_operand" "=w")
3754 (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3755 (match_operand:GPF 2 "register_operand" "w")
3756 (match_operand:GPF 3 "register_operand" "w"))))]
3757 "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3758 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3759 [(set_attr "v8type" "fmadd")
3760 (set_attr "type" "fmac<s>")
3761 (set_attr "mode" "<MODE>")]
3764 ;; -------------------------------------------------------------------
3765 ;; Floating-point conversions
3766 ;; -------------------------------------------------------------------
3768 (define_insn "extendsfdf2"
3769 [(set (match_operand:DF 0 "register_operand" "=w")
3770 (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3773 [(set_attr "v8type" "fcvt")
3774 (set_attr "type" "f_cvt")
3775 (set_attr "mode" "DF")
3776 (set_attr "mode2" "SF")]
3779 (define_insn "truncdfsf2"
3780 [(set (match_operand:SF 0 "register_operand" "=w")
3781 (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3784 [(set_attr "v8type" "fcvt")
3785 (set_attr "type" "f_cvt")
3786 (set_attr "mode" "SF")
3787 (set_attr "mode2" "DF")]
3790 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3791 [(set (match_operand:GPI 0 "register_operand" "=r")
3792 (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3794 "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3795 [(set_attr "v8type" "fcvtf2i")
3796 (set_attr "type" "f_cvtf2i")
3797 (set_attr "mode" "<GPF:MODE>")
3798 (set_attr "mode2" "<GPI:MODE>")]
3801 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3802 [(set (match_operand:GPI 0 "register_operand" "=r")
3803 (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3805 "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3806 [(set_attr "v8type" "fcvtf2i")
3807 (set_attr "type" "f_cvtf2i")
3808 (set_attr "mode" "<GPF:MODE>")
3809 (set_attr "mode2" "<GPI:MODE>")]
3812 (define_insn "float<GPI:mode><GPF:mode>2"
3813 [(set (match_operand:GPF 0 "register_operand" "=w")
3814 (float:GPF (match_operand:GPI 1 "register_operand" "r")))]
3816 "scvtf\\t%<GPF:s>0, %<GPI:w>1"
3817 [(set_attr "v8type" "fcvti2f")
3818 (set_attr "type" "f_cvti2f")
3819 (set_attr "mode" "<GPF:MODE>")
3820 (set_attr "mode2" "<GPI:MODE>")]
3823 (define_insn "floatuns<GPI:mode><GPF:mode>2"
3824 [(set (match_operand:GPF 0 "register_operand" "=w")
3825 (unsigned_float:GPF (match_operand:GPI 1 "register_operand" "r")))]
3827 "ucvtf\\t%<GPF:s>0, %<GPI:w>1"
3828 [(set_attr "v8type" "fcvt")
3829 (set_attr "type" "f_cvt")
3830 (set_attr "mode" "<GPF:MODE>")
3831 (set_attr "mode2" "<GPI:MODE>")]
3834 ;; -------------------------------------------------------------------
3835 ;; Floating-point arithmetic
3836 ;; -------------------------------------------------------------------
3838 (define_insn "add<mode>3"
3839 [(set (match_operand:GPF 0 "register_operand" "=w")
3841 (match_operand:GPF 1 "register_operand" "w")
3842 (match_operand:GPF 2 "register_operand" "w")))]
3844 "fadd\\t%<s>0, %<s>1, %<s>2"
3845 [(set_attr "v8type" "fadd")
3846 (set_attr "type" "fadd<s>")
3847 (set_attr "mode" "<MODE>")]
3850 (define_insn "sub<mode>3"
3851 [(set (match_operand:GPF 0 "register_operand" "=w")
3853 (match_operand:GPF 1 "register_operand" "w")
3854 (match_operand:GPF 2 "register_operand" "w")))]
3856 "fsub\\t%<s>0, %<s>1, %<s>2"
3857 [(set_attr "v8type" "fadd")
3858 (set_attr "type" "fadd<s>")
3859 (set_attr "mode" "<MODE>")]
3862 (define_insn "mul<mode>3"
3863 [(set (match_operand:GPF 0 "register_operand" "=w")
3865 (match_operand:GPF 1 "register_operand" "w")
3866 (match_operand:GPF 2 "register_operand" "w")))]
3868 "fmul\\t%<s>0, %<s>1, %<s>2"
3869 [(set_attr "v8type" "fmul")
3870 (set_attr "type" "fmul<s>")
3871 (set_attr "mode" "<MODE>")]
3874 (define_insn "*fnmul<mode>3"
3875 [(set (match_operand:GPF 0 "register_operand" "=w")
3877 (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3878 (match_operand:GPF 2 "register_operand" "w")))]
3880 "fnmul\\t%<s>0, %<s>1, %<s>2"
3881 [(set_attr "v8type" "fmul")
3882 (set_attr "type" "fmul<s>")
3883 (set_attr "mode" "<MODE>")]
3886 (define_insn "div<mode>3"
3887 [(set (match_operand:GPF 0 "register_operand" "=w")
3889 (match_operand:GPF 1 "register_operand" "w")
3890 (match_operand:GPF 2 "register_operand" "w")))]
3892 "fdiv\\t%<s>0, %<s>1, %<s>2"
3893 [(set_attr "v8type" "fdiv")
3894 (set_attr "type" "fdiv<s>")
3895 (set_attr "mode" "<MODE>")]
3898 (define_insn "neg<mode>2"
3899 [(set (match_operand:GPF 0 "register_operand" "=w")
3900 (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
3902 "fneg\\t%<s>0, %<s>1"
3903 [(set_attr "v8type" "ffarith")
3904 (set_attr "type" "ffarith<s>")
3905 (set_attr "mode" "<MODE>")]
3908 (define_insn "sqrt<mode>2"
3909 [(set (match_operand:GPF 0 "register_operand" "=w")
3910 (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
3912 "fsqrt\\t%<s>0, %<s>1"
3913 [(set_attr "v8type" "fsqrt")
3914 (set_attr "type" "fsqrt<s>")
3915 (set_attr "mode" "<MODE>")]
3918 (define_insn "abs<mode>2"
3919 [(set (match_operand:GPF 0 "register_operand" "=w")
3920 (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
3922 "fabs\\t%<s>0, %<s>1"
3923 [(set_attr "v8type" "ffarith")
3924 (set_attr "type" "ffarith<s>")
3925 (set_attr "mode" "<MODE>")]
3928 ;; Given that smax/smin do not specify the result when either input is NaN,
3929 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
3932 (define_insn "smax<mode>3"
3933 [(set (match_operand:GPF 0 "register_operand" "=w")
3934 (smax:GPF (match_operand:GPF 1 "register_operand" "w")
3935 (match_operand:GPF 2 "register_operand" "w")))]
3937 "fmaxnm\\t%<s>0, %<s>1, %<s>2"
3938 [(set_attr "v8type" "fminmax")
3939 (set_attr "type" "f_minmax<s>")
3940 (set_attr "mode" "<MODE>")]
3943 (define_insn "smin<mode>3"
3944 [(set (match_operand:GPF 0 "register_operand" "=w")
3945 (smin:GPF (match_operand:GPF 1 "register_operand" "w")
3946 (match_operand:GPF 2 "register_operand" "w")))]
3948 "fminnm\\t%<s>0, %<s>1, %<s>2"
3949 [(set_attr "v8type" "fminmax")
3950 (set_attr "type" "f_minmax<s>")
3951 (set_attr "mode" "<MODE>")]
3954 ;; -------------------------------------------------------------------
3956 ;; -------------------------------------------------------------------
3958 (define_expand "aarch64_reload_mov<mode>"
3959 [(set (match_operand:TX 0 "register_operand" "=w")
3960 (match_operand:TX 1 "register_operand" "w"))
3961 (clobber (match_operand:DI 2 "register_operand" "=&r"))
3965 rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
3966 rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
3967 gen_aarch64_movtilow_tilow (op0, op1);
3968 gen_aarch64_movdi_tihigh (operands[2], op1);
3969 gen_aarch64_movtihigh_di (op0, operands[2]);
3974 ;; The following secondary reload helpers patterns are invoked
3975 ;; after or during reload as we don't want these patterns to start
3976 ;; kicking in during the combiner.
3978 (define_insn "aarch64_movdi_<mode>low"
3979 [(set (match_operand:DI 0 "register_operand" "=r")
3980 (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
3981 "reload_completed || reload_in_progress"
3983 [(set_attr "v8type" "fmovf2i")
3984 (set_attr "type" "f_mrc")
3985 (set_attr "mode" "DI")
3986 (set_attr "length" "4")
3989 (define_insn "aarch64_movdi_<mode>high"
3990 [(set (match_operand:DI 0 "register_operand" "=r")
3992 (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
3994 "reload_completed || reload_in_progress"
3995 "fmov\\t%x0, %1.d[1]"
3996 [(set_attr "v8type" "fmovf2i")
3997 (set_attr "type" "f_mrc")
3998 (set_attr "mode" "DI")
3999 (set_attr "length" "4")
4002 (define_insn "aarch64_mov<mode>high_di"
4003 [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
4004 (const_int 64) (const_int 64))
4005 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4006 "reload_completed || reload_in_progress"
4007 "fmov\\t%0.d[1], %x1"
4008 [(set_attr "v8type" "fmovi2f")
4009 (set_attr "type" "f_mcr")
4010 (set_attr "mode" "DI")
4011 (set_attr "length" "4")
4014 (define_insn "aarch64_mov<mode>low_di"
4015 [(set (match_operand:TX 0 "register_operand" "=w")
4016 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4017 "reload_completed || reload_in_progress"
4019 [(set_attr "v8type" "fmovi2f")
4020 (set_attr "type" "f_mcr")
4021 (set_attr "mode" "DI")
4022 (set_attr "length" "4")
4025 (define_insn "aarch64_movtilow_tilow"
4026 [(set (match_operand:TI 0 "register_operand" "=w")
4028 (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
4029 "reload_completed || reload_in_progress"
4031 [(set_attr "v8type" "fmovi2f")
4032 (set_attr "type" "f_mcr")
4033 (set_attr "mode" "DI")
4034 (set_attr "length" "4")
4037 ;; There is a deliberate reason why the parameters of high and lo_sum's
4038 ;; don't have modes for ADRP and ADD instructions. This is to allow high
4039 ;; and lo_sum's to be used with the labels defining the jump tables in
4042 (define_expand "add_losym"
4043 [(set (match_operand 0 "register_operand" "=r")
4044 (lo_sum (match_operand 1 "register_operand" "r")
4045 (match_operand 2 "aarch64_valid_symref" "S")))]
4048 enum machine_mode mode = GET_MODE (operands[0]);
4050 emit_insn ((mode == DImode
4052 : gen_add_losym_si) (operands[0],
4058 (define_insn "add_losym_<mode>"
4059 [(set (match_operand:P 0 "register_operand" "=r")
4060 (lo_sum:P (match_operand:P 1 "register_operand" "r")
4061 (match_operand 2 "aarch64_valid_symref" "S")))]
4063 "add\\t%<w>0, %<w>1, :lo12:%a2"
4064 [(set_attr "v8type" "alu")
4065 (set_attr "type" "alu_reg")
4066 (set_attr "mode" "<MODE>")]
4069 (define_insn "ldr_got_small_<mode>"
4070 [(set (match_operand:PTR 0 "register_operand" "=r")
4071 (unspec:PTR [(mem:PTR (lo_sum:PTR
4072 (match_operand:PTR 1 "register_operand" "r")
4073 (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
4074 UNSPEC_GOTSMALLPIC))]
4076 "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
4077 [(set_attr "v8type" "load1")
4078 (set_attr "type" "load1")
4079 (set_attr "mode" "<MODE>")]
4082 (define_insn "ldr_got_small_sidi"
4083 [(set (match_operand:DI 0 "register_operand" "=r")
4085 (unspec:SI [(mem:SI (lo_sum:DI
4086 (match_operand:DI 1 "register_operand" "r")
4087 (match_operand:DI 2 "aarch64_valid_symref" "S")))]
4088 UNSPEC_GOTSMALLPIC)))]
4090 "ldr\\t%w0, [%1, #:got_lo12:%a2]"
4091 [(set_attr "v8type" "load1")
4092 (set_attr "type" "load1")
4093 (set_attr "mode" "DI")]
4096 (define_insn "ldr_got_tiny"
4097 [(set (match_operand:DI 0 "register_operand" "=r")
4098 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
4099 UNSPEC_GOTTINYPIC))]
4102 [(set_attr "v8type" "load1")
4103 (set_attr "type" "load1")
4104 (set_attr "mode" "DI")]
4107 (define_insn "aarch64_load_tp_hard"
4108 [(set (match_operand:DI 0 "register_operand" "=r")
4109 (unspec:DI [(const_int 0)] UNSPEC_TLS))]
4111 "mrs\\t%0, tpidr_el0"
4112 [(set_attr "v8type" "mrs")
4113 (set_attr "type" "mrs")
4114 (set_attr "mode" "DI")]
4117 ;; The TLS ABI specifically requires that the compiler does not schedule
4118 ;; instructions in the TLS stubs, in order to enable linker relaxation.
4119 ;; Therefore we treat the stubs as an atomic sequence.
4120 (define_expand "tlsgd_small"
4121 [(parallel [(set (match_operand 0 "register_operand" "")
4122 (call (mem:DI (match_dup 2)) (const_int 1)))
4123 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
4124 (clobber (reg:DI LR_REGNUM))])]
4127 operands[2] = aarch64_tls_get_addr ();
4130 (define_insn "*tlsgd_small"
4131 [(set (match_operand 0 "register_operand" "")
4132 (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
4133 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
4134 (clobber (reg:DI LR_REGNUM))
4137 "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
4138 [(set_attr "v8type" "call")
4139 (set_attr "type" "call")
4140 (set_attr "length" "16")])
4142 (define_insn "tlsie_small"
4143 [(set (match_operand:DI 0 "register_operand" "=r")
4144 (unspec:DI [(match_operand:DI 1 "aarch64_tls_ie_symref" "S")]
4145 UNSPEC_GOTSMALLTLS))]
4147 "adrp\\t%0, %A1\;ldr\\t%0, [%0, #%L1]"
4148 [(set_attr "v8type" "load1")
4149 (set_attr "type" "load1")
4150 (set_attr "mode" "DI")
4151 (set_attr "length" "8")]
4154 (define_insn "tlsle_small"
4155 [(set (match_operand:DI 0 "register_operand" "=r")
4156 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
4157 (match_operand:DI 2 "aarch64_tls_le_symref" "S")]
4158 UNSPEC_GOTSMALLTLS))]
4160 "add\\t%0, %1, #%G2\;add\\t%0, %0, #%L2"
4161 [(set_attr "v8type" "alu")
4162 (set_attr "type" "alu_reg")
4163 (set_attr "mode" "DI")
4164 (set_attr "length" "8")]
4167 (define_insn "tlsdesc_small"
4168 [(set (reg:DI R0_REGNUM)
4169 (unspec:DI [(match_operand:DI 0 "aarch64_valid_symref" "S")]
4171 (clobber (reg:DI LR_REGNUM))
4172 (clobber (match_scratch:DI 1 "=r"))]
4174 "adrp\\tx0, %A0\;ldr\\t%1, [x0, #%L0]\;add\\tx0, x0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
4175 [(set_attr "v8type" "call")
4176 (set_attr "type" "call")
4177 (set_attr "length" "16")])
4179 (define_insn "stack_tie"
4180 [(set (mem:BLK (scratch))
4181 (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
4182 (match_operand:DI 1 "register_operand" "rk")]
4186 [(set_attr "length" "0")]
4189 ;; Named pattern for expanding thread pointer reference.
4190 (define_expand "get_thread_pointerdi"
4191 [(match_operand:DI 0 "register_operand" "=r")]
4194 rtx tmp = aarch64_load_tp (operands[0]);
4195 if (tmp != operands[0])
4196 emit_move_insn (operands[0], tmp);
4201 (include "aarch64-simd.md")
4203 ;; Atomic Operations
4204 (include "atomics.md")