1 ;; Machine description for AArch64 architecture.
2 ;; Copyright (C) 2009-2014 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" [
125 (define_c_enum "unspecv" [
126 UNSPECV_EH_RETURN ; Represent EH_RETURN
127 UNSPECV_GET_FPCR ; Represent fetch of FPCR content.
128 UNSPECV_SET_FPCR ; Represent assign of FPCR content.
129 UNSPECV_GET_FPSR ; Represent fetch of FPSR content.
130 UNSPECV_SET_FPSR ; Represent assign of FPSR content.
134 ;; If further include files are added the defintion of MD_INCLUDES
137 (include "constraints.md")
138 (include "predicates.md")
139 (include "iterators.md")
141 ;; -------------------------------------------------------------------
142 ;; Instruction types and attributes
143 ;; -------------------------------------------------------------------
145 ; The "type" attribute is is included here from AArch32 backend to be able
146 ; to share pipeline descriptions.
147 (include "../arm/types.md")
149 ;; It is important to set the fp or simd attributes to yes when a pattern
150 ;; alternative uses the FP or SIMD register files, usually signified by use of
151 ;; the 'w' constraint. This will ensure that the alternative will be
152 ;; disabled when compiling with -mgeneral-regs-only or with the +nofp/+nosimd
153 ;; architecture extensions. If all the alternatives in a pattern use the
154 ;; FP or SIMD registers then the pattern predicate should include TARGET_FLOAT
157 ;; Attribute that specifies whether or not the instruction touches fp
158 ;; registers. When this is set to yes for an alternative, that alternative
159 ;; will be disabled when !TARGET_FLOAT.
160 (define_attr "fp" "no,yes" (const_string "no"))
162 ;; Attribute that specifies whether or not the instruction touches simd
163 ;; registers. When this is set to yes for an alternative, that alternative
164 ;; will be disabled when !TARGET_SIMD.
165 (define_attr "simd" "no,yes" (const_string "no"))
167 (define_attr "length" ""
170 ;; Attribute that controls whether an alternative is enabled or not.
171 ;; Currently it is only used to disable alternatives which touch fp or simd
172 ;; registers when -mgeneral-regs-only is specified.
173 (define_attr "enabled" "no,yes"
175 (and (eq_attr "fp" "yes")
176 (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
177 (and (eq_attr "simd" "yes")
178 (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
180 ] (const_string "yes")))
182 ;; -------------------------------------------------------------------
183 ;; Pipeline descriptions and scheduling
184 ;; -------------------------------------------------------------------
187 (include "aarch64-tune.md")
190 (include "../arm/cortex-a53.md")
191 (include "../arm/cortex-a15.md")
192 (include "thunderx.md")
194 ;; -------------------------------------------------------------------
195 ;; Jumps and other miscellaneous insns
196 ;; -------------------------------------------------------------------
198 (define_insn "indirect_jump"
199 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
202 [(set_attr "type" "branch")]
206 [(set (pc) (label_ref (match_operand 0 "" "")))]
209 [(set_attr "type" "branch")]
212 (define_expand "cbranch<mode>4"
213 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
214 [(match_operand:GPI 1 "register_operand" "")
215 (match_operand:GPI 2 "aarch64_plus_operand" "")])
216 (label_ref (match_operand 3 "" ""))
220 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
222 operands[2] = const0_rtx;
226 (define_expand "cbranch<mode>4"
227 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
228 [(match_operand:GPF 1 "register_operand" "")
229 (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
230 (label_ref (match_operand 3 "" ""))
234 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
236 operands[2] = const0_rtx;
240 (define_expand "cbranchcc4"
241 [(set (pc) (if_then_else
242 (match_operator 0 "aarch64_comparison_operator"
243 [(match_operand 1 "cc_register" "")
244 (match_operand 2 "const0_operand")])
245 (label_ref (match_operand 3 "" ""))
250 (define_insn "*ccmp_and"
251 [(set (match_operand 1 "ccmp_cc_register" "")
254 (match_operator 4 "aarch64_comparison_operator"
255 [(match_operand 0 "ccmp_cc_register" "")
257 (match_operator 5 "aarch64_comparison_operator"
258 [(match_operand:GPI 2 "register_operand" "r,r,r")
259 (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")]))
261 "aarch64_ccmp_mode_to_code (GET_MODE (operands[1])) == GET_CODE (operands[5])"
263 ccmp\\t%<w>2, %<w>3, %k5, %m4
264 ccmp\\t%<w>2, %<w>3, %k5, %m4
265 ccmn\\t%<w>2, #%n3, %k5, %m4"
266 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
269 (define_insn "*ccmp_ior"
270 [(set (match_operand 1 "ccmp_cc_register" "")
273 (match_operator 4 "aarch64_comparison_operator"
274 [(match_operand 0 "ccmp_cc_register" "")
276 (match_operator 5 "aarch64_comparison_operator"
277 [(match_operand:GPI 2 "register_operand" "r,r,r")
278 (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")]))
280 "aarch64_ccmp_mode_to_code (GET_MODE (operands[1])) == GET_CODE (operands[5])"
282 ccmp\\t%<w>2, %<w>3, %K5, %M4
283 ccmp\\t%<w>2, %<w>3, %K5, %M4
284 ccmn\\t%<w>2, #%n3, %K5, %M4"
285 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
288 (define_insn "*condjump"
289 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
290 [(match_operand 1 "cc_register" "") (const_int 0)])
291 (label_ref (match_operand 2 "" ""))
295 [(set_attr "type" "branch")]
298 (define_expand "casesi"
299 [(match_operand:SI 0 "register_operand" "") ; Index
300 (match_operand:SI 1 "const_int_operand" "") ; Lower bound
301 (match_operand:SI 2 "const_int_operand" "") ; Total range
302 (match_operand:DI 3 "" "") ; Table label
303 (match_operand:DI 4 "" "")] ; Out of range label
306 if (operands[1] != const0_rtx)
308 rtx reg = gen_reg_rtx (SImode);
310 /* Canonical RTL says that if you have:
314 then this should be emitted as:
318 The use of trunc_int_for_mode ensures that the resulting
319 constant can be represented in SImode, this is important
320 for the corner case where operand[1] is INT_MIN. */
322 operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
324 if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
325 (operands[1], SImode))
326 operands[1] = force_reg (SImode, operands[1]);
327 emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
331 if (!aarch64_plus_operand (operands[2], SImode))
332 operands[2] = force_reg (SImode, operands[2]);
333 emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
335 operands[0], operands[2], operands[4]));
337 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
338 emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
344 (define_insn "casesi_dispatch"
347 (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
348 (match_operand:SI 1 "register_operand" "r")]
350 (clobber (reg:CC CC_REGNUM))
351 (clobber (match_scratch:DI 3 "=r"))
352 (clobber (match_scratch:DI 4 "=r"))
353 (use (label_ref (match_operand 2 "" "")))])]
356 return aarch64_output_casesi (operands);
358 [(set_attr "length" "16")
359 (set_attr "type" "branch")]
363 [(unspec[(const_int 0)] UNSPEC_NOP)]
366 [(set_attr "type" "no_insn")]
369 (define_insn "prefetch"
370 [(prefetch (match_operand:DI 0 "address_operand" "r")
371 (match_operand:QI 1 "const_int_operand" "")
372 (match_operand:QI 2 "const_int_operand" ""))]
375 const char * pftype[2][4] =
377 {"prfm\\tPLDL1STRM, %a0",
378 "prfm\\tPLDL3KEEP, %a0",
379 "prfm\\tPLDL2KEEP, %a0",
380 "prfm\\tPLDL1KEEP, %a0"},
381 {"prfm\\tPSTL1STRM, %a0",
382 "prfm\\tPSTL3KEEP, %a0",
383 "prfm\\tPSTL2KEEP, %a0",
384 "prfm\\tPSTL1KEEP, %a0"},
387 int locality = INTVAL (operands[2]);
389 gcc_assert (IN_RANGE (locality, 0, 3));
391 return pftype[INTVAL(operands[1])][locality];
393 [(set_attr "type" "load1")]
397 [(trap_if (const_int 1) (const_int 8))]
400 [(set_attr "type" "trap")])
402 (define_expand "prologue"
403 [(clobber (const_int 0))]
406 aarch64_expand_prologue ();
411 (define_expand "epilogue"
412 [(clobber (const_int 0))]
415 aarch64_expand_epilogue (false);
420 (define_expand "sibcall_epilogue"
421 [(clobber (const_int 0))]
424 aarch64_expand_epilogue (true);
429 (define_insn "*do_return"
433 [(set_attr "type" "branch")]
436 (define_expand "return"
438 "aarch64_use_return_insn_p ()"
442 (define_insn "simple_return"
446 [(set_attr "type" "branch")]
449 (define_insn "eh_return"
450 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
454 [(set_attr "type" "branch")]
459 [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
462 [(set (match_dup 1) (match_dup 0))]
464 operands[1] = aarch64_final_eh_return_addr ();
468 (define_insn "*cb<optab><mode>1"
469 [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
471 (label_ref (match_operand 1 "" ""))
475 [(set_attr "type" "branch")]
479 (define_insn "*tb<optab><mode>1"
480 [(set (pc) (if_then_else
481 (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
483 (match_operand 1 "const_int_operand" "n"))
485 (label_ref (match_operand 2 "" ""))
487 (clobber (match_scratch:DI 3 "=r"))]
490 if (get_attr_length (insn) == 8)
491 return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
492 return \"<tbz>\\t%<w>0, %1, %l2\";
494 [(set_attr "type" "branch")
496 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
497 (lt (minus (match_dup 2) (pc)) (const_int 32764)))
502 (define_insn "*cb<optab><mode>1"
503 [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
505 (label_ref (match_operand 1 "" ""))
507 (clobber (match_scratch:DI 2 "=r"))]
510 if (get_attr_length (insn) == 8)
511 return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
512 return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
514 [(set_attr "type" "branch")
516 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
517 (lt (minus (match_dup 1) (pc)) (const_int 32764)))
522 ;; -------------------------------------------------------------------
523 ;; Subroutine calls and sibcalls
524 ;; -------------------------------------------------------------------
526 (define_expand "call_internal"
527 [(parallel [(call (match_operand 0 "memory_operand" "")
528 (match_operand 1 "general_operand" ""))
529 (use (match_operand 2 "" ""))
530 (clobber (reg:DI LR_REGNUM))])])
532 (define_expand "call"
533 [(parallel [(call (match_operand 0 "memory_operand" "")
534 (match_operand 1 "general_operand" ""))
535 (use (match_operand 2 "" ""))
536 (clobber (reg:DI LR_REGNUM))])]
542 /* In an untyped call, we can get NULL for operand 2. */
543 if (operands[2] == NULL)
544 operands[2] = const0_rtx;
546 /* Decide if we should generate indirect calls by loading the
547 64-bit address of the callee into a register before performing
548 the branch-and-link. */
549 callee = XEXP (operands[0], 0);
550 if (GET_CODE (callee) == SYMBOL_REF
551 ? aarch64_is_long_call_p (callee)
553 XEXP (operands[0], 0) = force_reg (Pmode, callee);
555 pat = gen_call_internal (operands[0], operands[1], operands[2]);
556 aarch64_emit_call_insn (pat);
561 (define_insn "*call_reg"
562 [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
563 (match_operand 1 "" ""))
564 (use (match_operand 2 "" ""))
565 (clobber (reg:DI LR_REGNUM))]
568 [(set_attr "type" "call")]
571 (define_insn "*call_symbol"
572 [(call (mem:DI (match_operand:DI 0 "" ""))
573 (match_operand 1 "" ""))
574 (use (match_operand 2 "" ""))
575 (clobber (reg:DI LR_REGNUM))]
576 "GET_CODE (operands[0]) == SYMBOL_REF
577 && !aarch64_is_long_call_p (operands[0])"
579 [(set_attr "type" "call")]
582 (define_expand "call_value_internal"
583 [(parallel [(set (match_operand 0 "" "")
584 (call (match_operand 1 "memory_operand" "")
585 (match_operand 2 "general_operand" "")))
586 (use (match_operand 3 "" ""))
587 (clobber (reg:DI LR_REGNUM))])])
589 (define_expand "call_value"
590 [(parallel [(set (match_operand 0 "" "")
591 (call (match_operand 1 "memory_operand" "")
592 (match_operand 2 "general_operand" "")))
593 (use (match_operand 3 "" ""))
594 (clobber (reg:DI LR_REGNUM))])]
600 /* In an untyped call, we can get NULL for operand 3. */
601 if (operands[3] == NULL)
602 operands[3] = const0_rtx;
604 /* Decide if we should generate indirect calls by loading the
605 64-bit address of the callee into a register before performing
606 the branch-and-link. */
607 callee = XEXP (operands[1], 0);
608 if (GET_CODE (callee) == SYMBOL_REF
609 ? aarch64_is_long_call_p (callee)
611 XEXP (operands[1], 0) = force_reg (Pmode, callee);
613 pat = gen_call_value_internal (operands[0], operands[1], operands[2],
615 aarch64_emit_call_insn (pat);
620 (define_insn "*call_value_reg"
621 [(set (match_operand 0 "" "")
622 (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
623 (match_operand 2 "" "")))
624 (use (match_operand 3 "" ""))
625 (clobber (reg:DI LR_REGNUM))]
628 [(set_attr "type" "call")]
632 (define_insn "*call_value_symbol"
633 [(set (match_operand 0 "" "")
634 (call (mem:DI (match_operand:DI 1 "" ""))
635 (match_operand 2 "" "")))
636 (use (match_operand 3 "" ""))
637 (clobber (reg:DI LR_REGNUM))]
638 "GET_CODE (operands[1]) == SYMBOL_REF
639 && !aarch64_is_long_call_p (operands[1])"
641 [(set_attr "type" "call")]
644 (define_expand "sibcall_internal"
645 [(parallel [(call (match_operand 0 "memory_operand" "")
646 (match_operand 1 "general_operand" ""))
648 (use (match_operand 2 "" ""))])])
650 (define_expand "sibcall"
651 [(parallel [(call (match_operand 0 "memory_operand" "")
652 (match_operand 1 "general_operand" ""))
654 (use (match_operand 2 "" ""))])]
659 if (!REG_P (XEXP (operands[0], 0))
660 && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
661 XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
663 if (operands[2] == NULL_RTX)
664 operands[2] = const0_rtx;
666 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
667 aarch64_emit_call_insn (pat);
672 (define_expand "sibcall_value_internal"
673 [(parallel [(set (match_operand 0 "" "")
674 (call (match_operand 1 "memory_operand" "")
675 (match_operand 2 "general_operand" "")))
677 (use (match_operand 3 "" ""))])])
679 (define_expand "sibcall_value"
680 [(parallel [(set (match_operand 0 "" "")
681 (call (match_operand 1 "memory_operand" "")
682 (match_operand 2 "general_operand" "")))
684 (use (match_operand 3 "" ""))])]
689 if (!REG_P (XEXP (operands[1], 0))
690 && (GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF))
691 XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
693 if (operands[3] == NULL_RTX)
694 operands[3] = const0_rtx;
696 pat = gen_sibcall_value_internal (operands[0], operands[1], operands[2],
698 aarch64_emit_call_insn (pat);
703 (define_insn "*sibcall_insn"
704 [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucs, Usf"))
705 (match_operand 1 "" ""))
707 (use (match_operand 2 "" ""))]
708 "SIBLING_CALL_P (insn)"
712 [(set_attr "type" "branch, branch")]
715 (define_insn "*sibcall_value_insn"
716 [(set (match_operand 0 "" "")
718 (match_operand:DI 1 "aarch64_call_insn_operand" "Ucs, Usf"))
719 (match_operand 2 "" "")))
721 (use (match_operand 3 "" ""))]
722 "SIBLING_CALL_P (insn)"
726 [(set_attr "type" "branch, branch")]
729 ;; Call subroutine returning any type.
731 (define_expand "untyped_call"
732 [(parallel [(call (match_operand 0 "")
735 (match_operand 2 "")])]
740 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
742 for (i = 0; i < XVECLEN (operands[2], 0); i++)
744 rtx set = XVECEXP (operands[2], 0, i);
745 emit_move_insn (SET_DEST (set), SET_SRC (set));
748 /* The optimizer does not know that the call sets the function value
749 registers we stored in the result block. We avoid problems by
750 claiming that all hard registers are used and clobbered at this
752 emit_insn (gen_blockage ());
756 ;; -------------------------------------------------------------------
758 ;; -------------------------------------------------------------------
760 (define_expand "mov<mode>"
761 [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
762 (match_operand:SHORT 1 "general_operand" ""))]
765 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
766 operands[1] = force_reg (<MODE>mode, operands[1]);
770 (define_insn "*mov<mode>_aarch64"
771 [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r, *w,r,*w, m, m, r,*w,*w")
772 (match_operand:SHORT 1 "general_operand" " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
773 "(register_operand (operands[0], <MODE>mode)
774 || aarch64_reg_or_zero (operands[1], <MODE>mode))"
776 switch (which_alternative)
779 return "mov\t%w0, %w1";
781 return "mov\t%w0, %1";
783 return aarch64_output_scalar_simd_mov_immediate (operands[1],
786 return "ldr<size>\t%w0, %1";
788 return "ldr\t%<size>0, %1";
790 return "str<size>\t%w1, %0";
792 return "str\t%<size>1, %0";
794 return "umov\t%w0, %1.<v>[0]";
796 return "dup\t%0.<Vallxd>, %w1";
798 return "dup\t%<Vetype>0, %1.<v>[0]";
803 [(set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
804 neon_from_gp<q>,neon_from_gp<q>, neon_dup")
805 (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")]
808 (define_expand "mov<mode>"
809 [(set (match_operand:GPI 0 "nonimmediate_operand" "")
810 (match_operand:GPI 1 "general_operand" ""))]
813 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
814 operands[1] = force_reg (<MODE>mode, operands[1]);
816 /* FIXME: RR we still need to fix up what we are doing with
817 symbol_refs and other types of constants. */
818 if (CONSTANT_P (operands[1])
819 && !CONST_INT_P (operands[1]))
821 aarch64_expand_mov_immediate (operands[0], operands[1]);
827 (define_insn_and_split "*movsi_aarch64"
828 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,r,*w,m, m,r,r ,*w, r,*w")
829 (match_operand:SI 1 "aarch64_mov_operand" " r,r,k,M,n,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
830 "(register_operand (operands[0], SImode)
831 || aarch64_reg_or_zero (operands[1], SImode))"
847 "CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), SImode)"
850 aarch64_expand_mov_immediate (operands[0], operands[1]);
853 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
854 adr,adr,f_mcr,f_mrc,fmov")
855 (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
858 (define_insn_and_split "*movdi_aarch64"
859 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,r,*w,m, m,r,r, *w, r,*w,w")
860 (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,n,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))]
861 "(register_operand (operands[0], DImode)
862 || aarch64_reg_or_zero (operands[1], DImode))"
879 "(CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), DImode))"
882 aarch64_expand_mov_immediate (operands[0], operands[1]);
885 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
886 adr,adr,f_mcr,f_mrc,fmov,fmov")
887 (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
888 (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
891 (define_insn "insv_imm<mode>"
892 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
894 (match_operand:GPI 1 "const_int_operand" "n"))
895 (match_operand:GPI 2 "const_int_operand" "n"))]
896 "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
897 && UINTVAL (operands[1]) % 16 == 0"
898 "movk\\t%<w>0, %X2, lsl %1"
899 [(set_attr "type" "mov_imm")]
902 (define_expand "movti"
903 [(set (match_operand:TI 0 "nonimmediate_operand" "")
904 (match_operand:TI 1 "general_operand" ""))]
907 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
908 operands[1] = force_reg (TImode, operands[1]);
912 (define_insn "*movti_aarch64"
913 [(set (match_operand:TI 0
914 "nonimmediate_operand" "=r, *w,r ,*w,r ,Ump,Ump,*w,m")
916 "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r ,Z , m,*w"))]
917 "(register_operand (operands[0], TImode)
918 || aarch64_reg_or_zero (operands[1], TImode))"
923 orr\\t%0.16b, %1.16b, %1.16b
929 [(set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \
930 load2,store2,store2,f_loadd,f_stored")
931 (set_attr "length" "8,8,8,4,4,4,4,4,4")
932 (set_attr "simd" "*,*,*,yes,*,*,*,*,*")
933 (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
936 ;; Split a TImode register-register or register-immediate move into
937 ;; its component DImode pieces, taking care to handle overlapping
938 ;; source and dest registers.
940 [(set (match_operand:TI 0 "register_operand" "")
941 (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
942 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
945 aarch64_split_128bit_move (operands[0], operands[1]);
949 (define_expand "mov<mode>"
950 [(set (match_operand:GPF 0 "nonimmediate_operand" "")
951 (match_operand:GPF 1 "general_operand" ""))]
956 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
960 if (GET_CODE (operands[0]) == MEM)
961 operands[1] = force_reg (<MODE>mode, operands[1]);
965 (define_insn "*movsf_aarch64"
966 [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
967 (match_operand:SF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
968 "TARGET_FLOAT && (register_operand (operands[0], SFmode)
969 || register_operand (operands[1], SFmode))"
980 [(set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
981 f_loads,f_stores,f_loads,f_stores,mov_reg")]
984 (define_insn "*movdf_aarch64"
985 [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
986 (match_operand:DF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
987 "TARGET_FLOAT && (register_operand (operands[0], DFmode)
988 || register_operand (operands[1], DFmode))"
999 [(set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
1000 f_loadd,f_stored,f_loadd,f_stored,mov_reg")]
1003 (define_expand "movtf"
1004 [(set (match_operand:TF 0 "nonimmediate_operand" "")
1005 (match_operand:TF 1 "general_operand" ""))]
1010 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
1014 if (GET_CODE (operands[0]) == MEM)
1015 operands[1] = force_reg (TFmode, operands[1]);
1019 (define_insn "*movtf_aarch64"
1020 [(set (match_operand:TF 0
1021 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
1023 "general_operand" " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
1024 "TARGET_FLOAT && (register_operand (operands[0], TFmode)
1025 || register_operand (operands[1], TFmode))"
1027 orr\\t%0.16b, %1.16b, %1.16b
1037 [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,fconstd,fconstd,\
1038 f_loadd,f_stored,neon_load1_2reg,neon_store1_2reg")
1039 (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
1040 (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
1041 (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
1045 [(set (match_operand:TF 0 "register_operand" "")
1046 (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
1047 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
1050 aarch64_split_128bit_move (operands[0], operands[1]);
1057 ;; 2 is size of move in bytes
1060 (define_expand "movmemdi"
1061 [(match_operand:BLK 0 "memory_operand")
1062 (match_operand:BLK 1 "memory_operand")
1063 (match_operand:DI 2 "immediate_operand")
1064 (match_operand:DI 3 "immediate_operand")]
1067 if (aarch64_expand_movmem (operands))
1073 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1074 ;; fairly lax checking on the second memory operation.
1075 (define_insn "load_pairsi"
1076 [(set (match_operand:SI 0 "register_operand" "=r,*w")
1077 (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1078 (set (match_operand:SI 2 "register_operand" "=r,*w")
1079 (match_operand:SI 3 "memory_operand" "m,m"))]
1080 "rtx_equal_p (XEXP (operands[3], 0),
1081 plus_constant (Pmode,
1082 XEXP (operands[1], 0),
1083 GET_MODE_SIZE (SImode)))"
1087 [(set_attr "type" "load2,neon_load1_2reg")
1088 (set_attr "fp" "*,yes")]
1091 (define_insn "load_pairdi"
1092 [(set (match_operand:DI 0 "register_operand" "=r,*w")
1093 (match_operand:DI 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1094 (set (match_operand:DI 2 "register_operand" "=r,*w")
1095 (match_operand:DI 3 "memory_operand" "m,m"))]
1096 "rtx_equal_p (XEXP (operands[3], 0),
1097 plus_constant (Pmode,
1098 XEXP (operands[1], 0),
1099 GET_MODE_SIZE (DImode)))"
1103 [(set_attr "type" "load2,neon_load1_2reg")
1104 (set_attr "fp" "*,yes")]
1108 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1109 ;; fairly lax checking on the second memory operation.
1110 (define_insn "store_pairsi"
1111 [(set (match_operand:SI 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1112 (match_operand:SI 1 "aarch64_reg_or_zero" "rZ,*w"))
1113 (set (match_operand:SI 2 "memory_operand" "=m,m")
1114 (match_operand:SI 3 "aarch64_reg_or_zero" "rZ,*w"))]
1115 "rtx_equal_p (XEXP (operands[2], 0),
1116 plus_constant (Pmode,
1117 XEXP (operands[0], 0),
1118 GET_MODE_SIZE (SImode)))"
1122 [(set_attr "type" "store2,neon_store1_2reg")
1123 (set_attr "fp" "*,yes")]
1126 (define_insn "store_pairdi"
1127 [(set (match_operand:DI 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1128 (match_operand:DI 1 "aarch64_reg_or_zero" "rZ,*w"))
1129 (set (match_operand:DI 2 "memory_operand" "=m,m")
1130 (match_operand:DI 3 "aarch64_reg_or_zero" "rZ,*w"))]
1131 "rtx_equal_p (XEXP (operands[2], 0),
1132 plus_constant (Pmode,
1133 XEXP (operands[0], 0),
1134 GET_MODE_SIZE (DImode)))"
1138 [(set_attr "type" "store2,neon_store1_2reg")
1139 (set_attr "fp" "*,yes")]
1142 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1143 ;; fairly lax checking on the second memory operation.
1144 (define_insn "load_pairsf"
1145 [(set (match_operand:SF 0 "register_operand" "=w,*r")
1146 (match_operand:SF 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1147 (set (match_operand:SF 2 "register_operand" "=w,*r")
1148 (match_operand:SF 3 "memory_operand" "m,m"))]
1149 "rtx_equal_p (XEXP (operands[3], 0),
1150 plus_constant (Pmode,
1151 XEXP (operands[1], 0),
1152 GET_MODE_SIZE (SFmode)))"
1156 [(set_attr "type" "neon_load1_2reg,load2")
1157 (set_attr "fp" "yes,*")]
1160 (define_insn "load_pairdf"
1161 [(set (match_operand:DF 0 "register_operand" "=w,*r")
1162 (match_operand:DF 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1163 (set (match_operand:DF 2 "register_operand" "=w,*r")
1164 (match_operand:DF 3 "memory_operand" "m,m"))]
1165 "rtx_equal_p (XEXP (operands[3], 0),
1166 plus_constant (Pmode,
1167 XEXP (operands[1], 0),
1168 GET_MODE_SIZE (DFmode)))"
1172 [(set_attr "type" "neon_load1_2reg,load2")
1173 (set_attr "fp" "yes,*")]
1176 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1177 ;; fairly lax checking on the second memory operation.
1178 (define_insn "store_pairsf"
1179 [(set (match_operand:SF 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1180 (match_operand:SF 1 "register_operand" "w,*r"))
1181 (set (match_operand:SF 2 "memory_operand" "=m,m")
1182 (match_operand:SF 3 "register_operand" "w,*r"))]
1183 "rtx_equal_p (XEXP (operands[2], 0),
1184 plus_constant (Pmode,
1185 XEXP (operands[0], 0),
1186 GET_MODE_SIZE (SFmode)))"
1190 [(set_attr "type" "neon_store1_2reg,store2")
1191 (set_attr "fp" "yes,*")]
1194 (define_insn "store_pairdf"
1195 [(set (match_operand:DF 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1196 (match_operand:DF 1 "register_operand" "w,*r"))
1197 (set (match_operand:DF 2 "memory_operand" "=m,m")
1198 (match_operand:DF 3 "register_operand" "w,*r"))]
1199 "rtx_equal_p (XEXP (operands[2], 0),
1200 plus_constant (Pmode,
1201 XEXP (operands[0], 0),
1202 GET_MODE_SIZE (DFmode)))"
1206 [(set_attr "type" "neon_store1_2reg,store2")
1207 (set_attr "fp" "yes,*")]
1210 ;; Load pair with post-index writeback. This is primarily used in function
1212 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
1214 [(set (match_operand:P 0 "register_operand" "=k")
1215 (plus:P (match_operand:P 1 "register_operand" "0")
1216 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1217 (set (match_operand:GPI 2 "register_operand" "=r")
1218 (mem:GPI (match_dup 1)))
1219 (set (match_operand:GPI 3 "register_operand" "=r")
1220 (mem:GPI (plus:P (match_dup 1)
1221 (match_operand:P 5 "const_int_operand" "n"))))])]
1222 "INTVAL (operands[5]) == GET_MODE_SIZE (<GPI:MODE>mode)"
1223 "ldp\\t%<w>2, %<w>3, [%1], %4"
1224 [(set_attr "type" "load2")]
1227 (define_insn "loadwb_pair<GPF:mode>_<P:mode>"
1229 [(set (match_operand:P 0 "register_operand" "=k")
1230 (plus:P (match_operand:P 1 "register_operand" "0")
1231 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1232 (set (match_operand:GPF 2 "register_operand" "=w")
1233 (mem:GPF (match_dup 1)))
1234 (set (match_operand:GPF 3 "register_operand" "=w")
1235 (mem:GPF (plus:P (match_dup 1)
1236 (match_operand:P 5 "const_int_operand" "n"))))])]
1237 "INTVAL (operands[5]) == GET_MODE_SIZE (<GPF:MODE>mode)"
1238 "ldp\\t%<w>2, %<w>3, [%1], %4"
1239 [(set_attr "type" "neon_load1_2reg")]
1242 ;; Store pair with pre-index writeback. This is primarily used in function
1244 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
1246 [(set (match_operand:P 0 "register_operand" "=&k")
1247 (plus:P (match_operand:P 1 "register_operand" "0")
1248 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1249 (set (mem:GPI (plus:P (match_dup 0)
1251 (match_operand:GPI 2 "register_operand" "r"))
1252 (set (mem:GPI (plus:P (match_dup 0)
1253 (match_operand:P 5 "const_int_operand" "n")))
1254 (match_operand:GPI 3 "register_operand" "r"))])]
1255 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1256 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1257 [(set_attr "type" "store2")]
1260 (define_insn "storewb_pair<GPF:mode>_<P:mode>"
1262 [(set (match_operand:P 0 "register_operand" "=&k")
1263 (plus:P (match_operand:P 1 "register_operand" "0")
1264 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1265 (set (mem:GPF (plus:P (match_dup 0)
1267 (match_operand:GPF 2 "register_operand" "w"))
1268 (set (mem:GPF (plus:P (match_dup 0)
1269 (match_operand:P 5 "const_int_operand" "n")))
1270 (match_operand:GPF 3 "register_operand" "w"))])]
1271 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPF:MODE>mode)"
1272 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1273 [(set_attr "type" "neon_store1_2reg<q>")]
1276 ;; -------------------------------------------------------------------
1277 ;; Sign/Zero extension
1278 ;; -------------------------------------------------------------------
1280 (define_expand "<optab>sidi2"
1281 [(set (match_operand:DI 0 "register_operand")
1282 (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1286 (define_insn "*extendsidi2_aarch64"
1287 [(set (match_operand:DI 0 "register_operand" "=r,r")
1288 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1293 [(set_attr "type" "extend,load1")]
1296 (define_insn "*load_pair_extendsidi2_aarch64"
1297 [(set (match_operand:DI 0 "register_operand" "=r")
1298 (sign_extend:DI (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump")))
1299 (set (match_operand:DI 2 "register_operand" "=r")
1300 (sign_extend:DI (match_operand:SI 3 "memory_operand" "m")))]
1301 "rtx_equal_p (XEXP (operands[3], 0),
1302 plus_constant (Pmode,
1303 XEXP (operands[1], 0),
1304 GET_MODE_SIZE (SImode)))"
1305 "ldpsw\\t%0, %2, %1"
1306 [(set_attr "type" "load2")]
1309 (define_insn "*zero_extendsidi2_aarch64"
1310 [(set (match_operand:DI 0 "register_operand" "=r,r")
1311 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1316 [(set_attr "type" "extend,load1")]
1319 (define_insn "*load_pair_zero_extendsidi2_aarch64"
1320 [(set (match_operand:DI 0 "register_operand" "=r")
1321 (zero_extend:DI (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump")))
1322 (set (match_operand:DI 2 "register_operand" "=r")
1323 (zero_extend:DI (match_operand:SI 3 "memory_operand" "m")))]
1324 "rtx_equal_p (XEXP (operands[3], 0),
1325 plus_constant (Pmode,
1326 XEXP (operands[1], 0),
1327 GET_MODE_SIZE (SImode)))"
1328 "ldp\\t%w0, %w2, %1"
1329 [(set_attr "type" "load2")]
1332 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1333 [(set (match_operand:GPI 0 "register_operand")
1334 (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1338 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1339 [(set (match_operand:GPI 0 "register_operand" "=r,r")
1340 (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1343 sxt<SHORT:size>\t%<GPI:w>0, %w1
1344 ldrs<SHORT:size>\t%<GPI:w>0, %1"
1345 [(set_attr "type" "extend,load1")]
1348 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1349 [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1350 (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1353 uxt<SHORT:size>\t%<GPI:w>0, %w1
1354 ldr<SHORT:size>\t%w0, %1
1355 ldr\t%<SHORT:size>0, %1"
1356 [(set_attr "type" "extend,load1,load1")]
1359 (define_expand "<optab>qihi2"
1360 [(set (match_operand:HI 0 "register_operand")
1361 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1365 (define_insn "*<optab>qihi2_aarch64"
1366 [(set (match_operand:HI 0 "register_operand" "=r,r")
1367 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1372 [(set_attr "type" "extend,load1")]
1375 ;; -------------------------------------------------------------------
1376 ;; Simple arithmetic
1377 ;; -------------------------------------------------------------------
1379 (define_expand "add<mode>3"
1381 (match_operand:GPI 0 "register_operand" "")
1382 (plus:GPI (match_operand:GPI 1 "register_operand" "")
1383 (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1386 if (! aarch64_plus_operand (operands[2], VOIDmode))
1388 rtx subtarget = ((optimize && can_create_pseudo_p ())
1389 ? gen_reg_rtx (<MODE>mode) : operands[0]);
1390 HOST_WIDE_INT imm = INTVAL (operands[2]);
1393 imm = -(-imm & ~0xfff);
1397 emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1398 operands[1] = subtarget;
1399 operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1404 (define_insn "*addsi3_aarch64"
1406 (match_operand:SI 0 "register_operand" "=rk,rk,w,rk")
1408 (match_operand:SI 1 "register_operand" "%rk,rk,w,rk")
1409 (match_operand:SI 2 "aarch64_plus_operand" "I,r,w,J")))]
1414 add\\t%0.2s, %1.2s, %2.2s
1415 sub\\t%w0, %w1, #%n2"
1416 [(set_attr "type" "alu_imm,alu_sreg,neon_add,alu_imm")
1417 (set_attr "simd" "*,*,yes,*")]
1420 ;; zero_extend version of above
1421 (define_insn "*addsi3_aarch64_uxtw"
1423 (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1425 (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1426 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1431 sub\\t%w0, %w1, #%n2"
1432 [(set_attr "type" "alu_imm,alu_sreg,alu_imm")]
1435 (define_insn "*adddi3_aarch64"
1437 (match_operand:DI 0 "register_operand" "=rk,rk,rk,w")
1439 (match_operand:DI 1 "register_operand" "%rk,rk,rk,w")
1440 (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,w")))]
1445 sub\\t%x0, %x1, #%n2
1446 add\\t%d0, %d1, %d2"
1447 [(set_attr "type" "alu_imm,alu_sreg,alu_imm,neon_add")
1448 (set_attr "simd" "*,*,*,yes")]
1451 (define_expand "addti3"
1452 [(set (match_operand:TI 0 "register_operand" "")
1453 (plus:TI (match_operand:TI 1 "register_operand" "")
1454 (match_operand:TI 2 "register_operand" "")))]
1457 rtx low = gen_reg_rtx (DImode);
1458 emit_insn (gen_adddi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1459 gen_lowpart (DImode, operands[2])));
1461 rtx high = gen_reg_rtx (DImode);
1462 emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]),
1463 gen_highpart (DImode, operands[2])));
1465 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1466 emit_move_insn (gen_highpart (DImode, operands[0]), high);
1470 (define_insn "add<mode>3_compare0"
1471 [(set (reg:CC_NZ CC_REGNUM)
1473 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1474 (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1476 (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1477 (plus:GPI (match_dup 1) (match_dup 2)))]
1480 adds\\t%<w>0, %<w>1, %<w>2
1481 adds\\t%<w>0, %<w>1, %<w>2
1482 subs\\t%<w>0, %<w>1, #%n2"
1483 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1486 ;; zero_extend version of above
1487 (define_insn "*addsi3_compare0_uxtw"
1488 [(set (reg:CC_NZ CC_REGNUM)
1490 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1491 (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1493 (set (match_operand:DI 0 "register_operand" "=r,r,r")
1494 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1497 adds\\t%w0, %w1, %w2
1498 adds\\t%w0, %w1, %w2
1499 subs\\t%w0, %w1, #%n2"
1500 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1503 (define_insn "*adds_mul_imm_<mode>"
1504 [(set (reg:CC_NZ CC_REGNUM)
1507 (match_operand:GPI 1 "register_operand" "r")
1508 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1509 (match_operand:GPI 3 "register_operand" "r"))
1511 (set (match_operand:GPI 0 "register_operand" "=r")
1512 (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1515 "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1516 [(set_attr "type" "alus_shift_imm")]
1519 (define_insn "*subs_mul_imm_<mode>"
1520 [(set (reg:CC_NZ CC_REGNUM)
1522 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1524 (match_operand:GPI 2 "register_operand" "r")
1525 (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1527 (set (match_operand:GPI 0 "register_operand" "=r")
1528 (minus:GPI (match_dup 1)
1529 (mult:GPI (match_dup 2) (match_dup 3))))]
1531 "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1532 [(set_attr "type" "alus_shift_imm")]
1535 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1536 [(set (reg:CC_NZ CC_REGNUM)
1539 (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1540 (match_operand:GPI 2 "register_operand" "r"))
1542 (set (match_operand:GPI 0 "register_operand" "=r")
1543 (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1545 "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1546 [(set_attr "type" "alus_ext")]
1549 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1550 [(set (reg:CC_NZ CC_REGNUM)
1552 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1554 (match_operand:ALLX 2 "register_operand" "r")))
1556 (set (match_operand:GPI 0 "register_operand" "=r")
1557 (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1559 "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1560 [(set_attr "type" "alus_ext")]
1563 (define_insn "*adds_<optab><mode>_multp2"
1564 [(set (reg:CC_NZ CC_REGNUM)
1566 (plus:GPI (ANY_EXTRACT:GPI
1567 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1568 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1569 (match_operand 3 "const_int_operand" "n")
1571 (match_operand:GPI 4 "register_operand" "r"))
1573 (set (match_operand:GPI 0 "register_operand" "=r")
1574 (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1578 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1579 "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1580 [(set_attr "type" "alus_ext")]
1583 (define_insn "*subs_<optab><mode>_multp2"
1584 [(set (reg:CC_NZ CC_REGNUM)
1586 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1588 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1589 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1590 (match_operand 3 "const_int_operand" "n")
1593 (set (match_operand:GPI 0 "register_operand" "=r")
1594 (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1595 (mult:GPI (match_dup 1) (match_dup 2))
1598 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1599 "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1600 [(set_attr "type" "alus_ext")]
1603 (define_insn "*add<mode>3nr_compare0"
1604 [(set (reg:CC_NZ CC_REGNUM)
1606 (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1607 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1614 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1617 (define_insn "*compare_neg<mode>"
1618 [(set (reg:CC_Z CC_REGNUM)
1620 (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1621 (match_operand:GPI 1 "register_operand" "r")))]
1623 "cmn\\t%<w>1, %<w>0"
1624 [(set_attr "type" "alus_sreg")]
1627 (define_insn "*add_<shift>_<mode>"
1628 [(set (match_operand:GPI 0 "register_operand" "=r")
1629 (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1630 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1631 (match_operand:GPI 3 "register_operand" "r")))]
1633 "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1634 [(set_attr "type" "alu_shift_imm")]
1637 ;; zero_extend version of above
1638 (define_insn "*add_<shift>_si_uxtw"
1639 [(set (match_operand:DI 0 "register_operand" "=r")
1641 (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1642 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1643 (match_operand:SI 3 "register_operand" "r"))))]
1645 "add\\t%w0, %w3, %w1, <shift> %2"
1646 [(set_attr "type" "alu_shift_imm")]
1649 (define_insn "*add_mul_imm_<mode>"
1650 [(set (match_operand:GPI 0 "register_operand" "=r")
1651 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1652 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1653 (match_operand:GPI 3 "register_operand" "r")))]
1655 "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1656 [(set_attr "type" "alu_shift_imm")]
1659 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1660 [(set (match_operand:GPI 0 "register_operand" "=rk")
1661 (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1662 (match_operand:GPI 2 "register_operand" "r")))]
1664 "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1665 [(set_attr "type" "alu_ext")]
1668 ;; zero_extend version of above
1669 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1670 [(set (match_operand:DI 0 "register_operand" "=rk")
1672 (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1673 (match_operand:GPI 2 "register_operand" "r"))))]
1675 "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1676 [(set_attr "type" "alu_ext")]
1679 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1680 [(set (match_operand:GPI 0 "register_operand" "=rk")
1681 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1682 (match_operand:ALLX 1 "register_operand" "r"))
1683 (match_operand 2 "aarch64_imm3" "Ui3"))
1684 (match_operand:GPI 3 "register_operand" "r")))]
1686 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1687 [(set_attr "type" "alu_ext")]
1690 ;; zero_extend version of above
1691 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1692 [(set (match_operand:DI 0 "register_operand" "=rk")
1694 (plus:SI (ashift:SI (ANY_EXTEND:SI
1695 (match_operand:SHORT 1 "register_operand" "r"))
1696 (match_operand 2 "aarch64_imm3" "Ui3"))
1697 (match_operand:SI 3 "register_operand" "r"))))]
1699 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1700 [(set_attr "type" "alu_ext")]
1703 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1704 [(set (match_operand:GPI 0 "register_operand" "=rk")
1705 (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1706 (match_operand:ALLX 1 "register_operand" "r"))
1707 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1708 (match_operand:GPI 3 "register_operand" "r")))]
1710 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1711 [(set_attr "type" "alu_ext")]
1714 ;; zero_extend version of above
1715 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1716 [(set (match_operand:DI 0 "register_operand" "=rk")
1717 (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1718 (match_operand:SHORT 1 "register_operand" "r"))
1719 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1720 (match_operand:SI 3 "register_operand" "r"))))]
1722 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1723 [(set_attr "type" "alu_ext")]
1726 (define_insn "*add_<optab><mode>_multp2"
1727 [(set (match_operand:GPI 0 "register_operand" "=rk")
1728 (plus:GPI (ANY_EXTRACT:GPI
1729 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1730 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1731 (match_operand 3 "const_int_operand" "n")
1733 (match_operand:GPI 4 "register_operand" "r")))]
1734 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1735 "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1736 [(set_attr "type" "alu_ext")]
1739 ;; zero_extend version of above
1740 (define_insn "*add_<optab>si_multp2_uxtw"
1741 [(set (match_operand:DI 0 "register_operand" "=rk")
1743 (plus:SI (ANY_EXTRACT:SI
1744 (mult:SI (match_operand:SI 1 "register_operand" "r")
1745 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1746 (match_operand 3 "const_int_operand" "n")
1748 (match_operand:SI 4 "register_operand" "r"))))]
1749 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1750 "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1751 [(set_attr "type" "alu_ext")]
1754 (define_insn "add<mode>3_carryin"
1756 (match_operand:GPI 0 "register_operand" "=r")
1757 (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1759 (match_operand:GPI 1 "register_operand" "r")
1760 (match_operand:GPI 2 "register_operand" "r"))))]
1762 "adc\\t%<w>0, %<w>1, %<w>2"
1763 [(set_attr "type" "adc_reg")]
1766 ;; zero_extend version of above
1767 (define_insn "*addsi3_carryin_uxtw"
1769 (match_operand:DI 0 "register_operand" "=r")
1771 (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1773 (match_operand:SI 1 "register_operand" "r")
1774 (match_operand:SI 2 "register_operand" "r")))))]
1776 "adc\\t%w0, %w1, %w2"
1777 [(set_attr "type" "adc_reg")]
1780 (define_insn "*add<mode>3_carryin_alt1"
1782 (match_operand:GPI 0 "register_operand" "=r")
1784 (match_operand:GPI 1 "register_operand" "r")
1785 (match_operand:GPI 2 "register_operand" "r"))
1786 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1788 "adc\\t%<w>0, %<w>1, %<w>2"
1789 [(set_attr "type" "adc_reg")]
1792 ;; zero_extend version of above
1793 (define_insn "*addsi3_carryin_alt1_uxtw"
1795 (match_operand:DI 0 "register_operand" "=r")
1798 (match_operand:SI 1 "register_operand" "r")
1799 (match_operand:SI 2 "register_operand" "r"))
1800 (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1802 "adc\\t%w0, %w1, %w2"
1803 [(set_attr "type" "adc_reg")]
1806 (define_insn "*add<mode>3_carryin_alt2"
1808 (match_operand:GPI 0 "register_operand" "=r")
1810 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1811 (match_operand:GPI 1 "register_operand" "r"))
1812 (match_operand:GPI 2 "register_operand" "r")))]
1814 "adc\\t%<w>0, %<w>1, %<w>2"
1815 [(set_attr "type" "adc_reg")]
1818 ;; zero_extend version of above
1819 (define_insn "*addsi3_carryin_alt2_uxtw"
1821 (match_operand:DI 0 "register_operand" "=r")
1824 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1825 (match_operand:SI 1 "register_operand" "r"))
1826 (match_operand:SI 2 "register_operand" "r"))))]
1828 "adc\\t%w0, %w1, %w2"
1829 [(set_attr "type" "adc_reg")]
1832 (define_insn "*add<mode>3_carryin_alt3"
1834 (match_operand:GPI 0 "register_operand" "=r")
1836 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1837 (match_operand:GPI 2 "register_operand" "r"))
1838 (match_operand:GPI 1 "register_operand" "r")))]
1840 "adc\\t%<w>0, %<w>1, %<w>2"
1841 [(set_attr "type" "adc_reg")]
1844 ;; zero_extend version of above
1845 (define_insn "*addsi3_carryin_alt3_uxtw"
1847 (match_operand:DI 0 "register_operand" "=r")
1850 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1851 (match_operand:SI 2 "register_operand" "r"))
1852 (match_operand:SI 1 "register_operand" "r"))))]
1854 "adc\\t%w0, %w1, %w2"
1855 [(set_attr "type" "adc_reg")]
1858 (define_insn "*add_uxt<mode>_multp2"
1859 [(set (match_operand:GPI 0 "register_operand" "=rk")
1861 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1862 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1863 (match_operand 3 "const_int_operand" "n"))
1864 (match_operand:GPI 4 "register_operand" "r")))]
1865 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1867 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1868 INTVAL (operands[3])));
1869 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1870 [(set_attr "type" "alu_ext")]
1873 ;; zero_extend version of above
1874 (define_insn "*add_uxtsi_multp2_uxtw"
1875 [(set (match_operand:DI 0 "register_operand" "=rk")
1878 (mult:SI (match_operand:SI 1 "register_operand" "r")
1879 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1880 (match_operand 3 "const_int_operand" "n"))
1881 (match_operand:SI 4 "register_operand" "r"))))]
1882 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1884 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1885 INTVAL (operands[3])));
1886 return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1887 [(set_attr "type" "alu_ext")]
1890 (define_insn "subsi3"
1891 [(set (match_operand:SI 0 "register_operand" "=rk")
1892 (minus:SI (match_operand:SI 1 "register_operand" "r")
1893 (match_operand:SI 2 "register_operand" "r")))]
1895 "sub\\t%w0, %w1, %w2"
1896 [(set_attr "type" "alu_sreg")]
1899 ;; zero_extend version of above
1900 (define_insn "*subsi3_uxtw"
1901 [(set (match_operand:DI 0 "register_operand" "=rk")
1903 (minus:SI (match_operand:SI 1 "register_operand" "r")
1904 (match_operand:SI 2 "register_operand" "r"))))]
1906 "sub\\t%w0, %w1, %w2"
1907 [(set_attr "type" "alu_sreg")]
1910 (define_insn "subdi3"
1911 [(set (match_operand:DI 0 "register_operand" "=rk,w")
1912 (minus:DI (match_operand:DI 1 "register_operand" "r,w")
1913 (match_operand:DI 2 "register_operand" "r,w")))]
1917 sub\\t%d0, %d1, %d2"
1918 [(set_attr "type" "alu_sreg, neon_sub")
1919 (set_attr "simd" "*,yes")]
1922 (define_expand "subti3"
1923 [(set (match_operand:TI 0 "register_operand" "")
1924 (minus:TI (match_operand:TI 1 "register_operand" "")
1925 (match_operand:TI 2 "register_operand" "")))]
1928 rtx low = gen_reg_rtx (DImode);
1929 emit_insn (gen_subdi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1930 gen_lowpart (DImode, operands[2])));
1932 rtx high = gen_reg_rtx (DImode);
1933 emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]),
1934 gen_highpart (DImode, operands[2])));
1936 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1937 emit_move_insn (gen_highpart (DImode, operands[0]), high);
1941 (define_insn "sub<mode>3_compare0"
1942 [(set (reg:CC_NZ CC_REGNUM)
1943 (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1944 (match_operand:GPI 2 "register_operand" "r"))
1946 (set (match_operand:GPI 0 "register_operand" "=r")
1947 (minus:GPI (match_dup 1) (match_dup 2)))]
1949 "subs\\t%<w>0, %<w>1, %<w>2"
1950 [(set_attr "type" "alus_sreg")]
1953 ;; zero_extend version of above
1954 (define_insn "*subsi3_compare0_uxtw"
1955 [(set (reg:CC_NZ CC_REGNUM)
1956 (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1957 (match_operand:SI 2 "register_operand" "r"))
1959 (set (match_operand:DI 0 "register_operand" "=r")
1960 (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1962 "subs\\t%w0, %w1, %w2"
1963 [(set_attr "type" "alus_sreg")]
1966 (define_insn "*sub_<shift>_<mode>"
1967 [(set (match_operand:GPI 0 "register_operand" "=r")
1968 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1970 (match_operand:GPI 1 "register_operand" "r")
1971 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1973 "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1974 [(set_attr "type" "alu_shift_imm")]
1977 ;; zero_extend version of above
1978 (define_insn "*sub_<shift>_si_uxtw"
1979 [(set (match_operand:DI 0 "register_operand" "=r")
1981 (minus:SI (match_operand:SI 3 "register_operand" "r")
1983 (match_operand:SI 1 "register_operand" "r")
1984 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1986 "sub\\t%w0, %w3, %w1, <shift> %2"
1987 [(set_attr "type" "alu_shift_imm")]
1990 (define_insn "*sub_mul_imm_<mode>"
1991 [(set (match_operand:GPI 0 "register_operand" "=r")
1992 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1994 (match_operand:GPI 1 "register_operand" "r")
1995 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1997 "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1998 [(set_attr "type" "alu_shift_imm")]
2001 ;; zero_extend version of above
2002 (define_insn "*sub_mul_imm_si_uxtw"
2003 [(set (match_operand:DI 0 "register_operand" "=r")
2005 (minus:SI (match_operand:SI 3 "register_operand" "r")
2007 (match_operand:SI 1 "register_operand" "r")
2008 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2010 "sub\\t%w0, %w3, %w1, lsl %p2"
2011 [(set_attr "type" "alu_shift_imm")]
2014 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
2015 [(set (match_operand:GPI 0 "register_operand" "=rk")
2016 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
2018 (match_operand:ALLX 2 "register_operand" "r"))))]
2020 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
2021 [(set_attr "type" "alu_ext")]
2024 ;; zero_extend version of above
2025 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
2026 [(set (match_operand:DI 0 "register_operand" "=rk")
2028 (minus:SI (match_operand:SI 1 "register_operand" "r")
2030 (match_operand:SHORT 2 "register_operand" "r")))))]
2032 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
2033 [(set_attr "type" "alu_ext")]
2036 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
2037 [(set (match_operand:GPI 0 "register_operand" "=rk")
2038 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
2039 (ashift:GPI (ANY_EXTEND:GPI
2040 (match_operand:ALLX 2 "register_operand" "r"))
2041 (match_operand 3 "aarch64_imm3" "Ui3"))))]
2043 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
2044 [(set_attr "type" "alu_ext")]
2047 ;; zero_extend version of above
2048 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
2049 [(set (match_operand:DI 0 "register_operand" "=rk")
2051 (minus:SI (match_operand:SI 1 "register_operand" "r")
2052 (ashift:SI (ANY_EXTEND:SI
2053 (match_operand:SHORT 2 "register_operand" "r"))
2054 (match_operand 3 "aarch64_imm3" "Ui3")))))]
2056 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
2057 [(set_attr "type" "alu_ext")]
2060 (define_insn "*sub_<optab><mode>_multp2"
2061 [(set (match_operand:GPI 0 "register_operand" "=rk")
2062 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
2064 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2065 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2066 (match_operand 3 "const_int_operand" "n")
2068 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
2069 "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
2070 [(set_attr "type" "alu_ext")]
2073 ;; zero_extend version of above
2074 (define_insn "*sub_<optab>si_multp2_uxtw"
2075 [(set (match_operand:DI 0 "register_operand" "=rk")
2077 (minus:SI (match_operand:SI 4 "register_operand" "r")
2079 (mult:SI (match_operand:SI 1 "register_operand" "r")
2080 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2081 (match_operand 3 "const_int_operand" "n")
2083 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
2084 "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
2085 [(set_attr "type" "alu_ext")]
2088 (define_insn "sub<mode>3_carryin"
2090 (match_operand:GPI 0 "register_operand" "=r")
2091 (minus:GPI (minus:GPI
2092 (match_operand:GPI 1 "register_operand" "r")
2093 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2094 (match_operand:GPI 2 "register_operand" "r")))]
2096 "sbc\\t%<w>0, %<w>1, %<w>2"
2097 [(set_attr "type" "adc_reg")]
2100 ;; zero_extend version of the above
2101 (define_insn "*subsi3_carryin_uxtw"
2103 (match_operand:DI 0 "register_operand" "=r")
2106 (match_operand:SI 1 "register_operand" "r")
2107 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2108 (match_operand:SI 2 "register_operand" "r"))))]
2110 "sbc\\t%w0, %w1, %w2"
2111 [(set_attr "type" "adc_reg")]
2114 (define_insn "*sub_uxt<mode>_multp2"
2115 [(set (match_operand:GPI 0 "register_operand" "=rk")
2116 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
2118 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2119 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2120 (match_operand 3 "const_int_operand" "n"))))]
2121 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2123 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2124 INTVAL (operands[3])));
2125 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
2126 [(set_attr "type" "alu_ext")]
2129 ;; zero_extend version of above
2130 (define_insn "*sub_uxtsi_multp2_uxtw"
2131 [(set (match_operand:DI 0 "register_operand" "=rk")
2133 (minus:SI (match_operand:SI 4 "register_operand" "r")
2135 (mult:SI (match_operand:SI 1 "register_operand" "r")
2136 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2137 (match_operand 3 "const_int_operand" "n")))))]
2138 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2140 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2141 INTVAL (operands[3])));
2142 return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
2143 [(set_attr "type" "alu_ext")]
2146 (define_insn_and_split "absdi2"
2147 [(set (match_operand:DI 0 "register_operand" "=&r,w")
2148 (abs:DI (match_operand:DI 1 "register_operand" "r,w")))]
2154 && GP_REGNUM_P (REGNO (operands[0]))
2155 && GP_REGNUM_P (REGNO (operands[1]))"
2158 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2159 gen_rtx_XOR (DImode,
2160 gen_rtx_ASHIFTRT (DImode,
2164 emit_insn (gen_rtx_SET (VOIDmode,
2166 gen_rtx_MINUS (DImode,
2168 gen_rtx_ASHIFTRT (DImode,
2173 [(set_attr "type" "alu_sreg")
2174 (set_attr "simd" "no,yes")]
2177 (define_insn "neg<mode>2"
2178 [(set (match_operand:GPI 0 "register_operand" "=r,w")
2179 (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
2183 neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
2184 [(set_attr "type" "alu_sreg, neon_neg<q>")
2185 (set_attr "simd" "*,yes")]
2188 ;; zero_extend version of above
2189 (define_insn "*negsi2_uxtw"
2190 [(set (match_operand:DI 0 "register_operand" "=r")
2191 (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
2194 [(set_attr "type" "alu_sreg")]
2197 (define_insn "*ngc<mode>"
2198 [(set (match_operand:GPI 0 "register_operand" "=r")
2199 (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2200 (match_operand:GPI 1 "register_operand" "r")))]
2202 "ngc\\t%<w>0, %<w>1"
2203 [(set_attr "type" "adc_reg")]
2206 (define_insn "*ngcsi_uxtw"
2207 [(set (match_operand:DI 0 "register_operand" "=r")
2209 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2210 (match_operand:SI 1 "register_operand" "r"))))]
2213 [(set_attr "type" "adc_reg")]
2216 (define_insn "*neg<mode>2_compare0"
2217 [(set (reg:CC_NZ CC_REGNUM)
2218 (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2220 (set (match_operand:GPI 0 "register_operand" "=r")
2221 (neg:GPI (match_dup 1)))]
2223 "negs\\t%<w>0, %<w>1"
2224 [(set_attr "type" "alus_sreg")]
2227 ;; zero_extend version of above
2228 (define_insn "*negsi2_compare0_uxtw"
2229 [(set (reg:CC_NZ CC_REGNUM)
2230 (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
2232 (set (match_operand:DI 0 "register_operand" "=r")
2233 (zero_extend:DI (neg:SI (match_dup 1))))]
2236 [(set_attr "type" "alus_sreg")]
2239 (define_insn "*neg_<shift><mode>3_compare0"
2240 [(set (reg:CC_NZ CC_REGNUM)
2242 (neg:GPI (ASHIFT:GPI
2243 (match_operand:GPI 1 "register_operand" "r")
2244 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2246 (set (match_operand:GPI 0 "register_operand" "=r")
2247 (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2249 "negs\\t%<w>0, %<w>1, <shift> %2"
2250 [(set_attr "type" "alus_shift_imm")]
2253 (define_insn "*neg_<shift>_<mode>2"
2254 [(set (match_operand:GPI 0 "register_operand" "=r")
2255 (neg:GPI (ASHIFT:GPI
2256 (match_operand:GPI 1 "register_operand" "r")
2257 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2259 "neg\\t%<w>0, %<w>1, <shift> %2"
2260 [(set_attr "type" "alu_shift_imm")]
2263 ;; zero_extend version of above
2264 (define_insn "*neg_<shift>_si2_uxtw"
2265 [(set (match_operand:DI 0 "register_operand" "=r")
2268 (match_operand:SI 1 "register_operand" "r")
2269 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2271 "neg\\t%w0, %w1, <shift> %2"
2272 [(set_attr "type" "alu_shift_imm")]
2275 (define_insn "*neg_mul_imm_<mode>2"
2276 [(set (match_operand:GPI 0 "register_operand" "=r")
2278 (match_operand:GPI 1 "register_operand" "r")
2279 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2281 "neg\\t%<w>0, %<w>1, lsl %p2"
2282 [(set_attr "type" "alu_shift_imm")]
2285 ;; zero_extend version of above
2286 (define_insn "*neg_mul_imm_si2_uxtw"
2287 [(set (match_operand:DI 0 "register_operand" "=r")
2290 (match_operand:SI 1 "register_operand" "r")
2291 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2293 "neg\\t%w0, %w1, lsl %p2"
2294 [(set_attr "type" "alu_shift_imm")]
2297 (define_insn "mul<mode>3"
2298 [(set (match_operand:GPI 0 "register_operand" "=r")
2299 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2300 (match_operand:GPI 2 "register_operand" "r")))]
2302 "mul\\t%<w>0, %<w>1, %<w>2"
2303 [(set_attr "type" "mul")]
2306 ;; zero_extend version of above
2307 (define_insn "*mulsi3_uxtw"
2308 [(set (match_operand:DI 0 "register_operand" "=r")
2310 (mult:SI (match_operand:SI 1 "register_operand" "r")
2311 (match_operand:SI 2 "register_operand" "r"))))]
2313 "mul\\t%w0, %w1, %w2"
2314 [(set_attr "type" "mul")]
2317 (define_insn "madd<mode>"
2318 [(set (match_operand:GPI 0 "register_operand" "=r")
2319 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2320 (match_operand:GPI 2 "register_operand" "r"))
2321 (match_operand:GPI 3 "register_operand" "r")))]
2323 "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2324 [(set_attr "type" "mla")]
2327 ;; zero_extend version of above
2328 (define_insn "*maddsi_uxtw"
2329 [(set (match_operand:DI 0 "register_operand" "=r")
2331 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2332 (match_operand:SI 2 "register_operand" "r"))
2333 (match_operand:SI 3 "register_operand" "r"))))]
2335 "madd\\t%w0, %w1, %w2, %w3"
2336 [(set_attr "type" "mla")]
2339 (define_insn "*msub<mode>"
2340 [(set (match_operand:GPI 0 "register_operand" "=r")
2341 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2342 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2343 (match_operand:GPI 2 "register_operand" "r"))))]
2346 "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2347 [(set_attr "type" "mla")]
2350 ;; zero_extend version of above
2351 (define_insn "*msubsi_uxtw"
2352 [(set (match_operand:DI 0 "register_operand" "=r")
2354 (minus:SI (match_operand:SI 3 "register_operand" "r")
2355 (mult:SI (match_operand:SI 1 "register_operand" "r")
2356 (match_operand:SI 2 "register_operand" "r")))))]
2359 "msub\\t%w0, %w1, %w2, %w3"
2360 [(set_attr "type" "mla")]
2363 (define_insn "*mul<mode>_neg"
2364 [(set (match_operand:GPI 0 "register_operand" "=r")
2365 (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2366 (match_operand:GPI 2 "register_operand" "r")))]
2369 "mneg\\t%<w>0, %<w>1, %<w>2"
2370 [(set_attr "type" "mul")]
2373 ;; zero_extend version of above
2374 (define_insn "*mulsi_neg_uxtw"
2375 [(set (match_operand:DI 0 "register_operand" "=r")
2377 (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2378 (match_operand:SI 2 "register_operand" "r"))))]
2381 "mneg\\t%w0, %w1, %w2"
2382 [(set_attr "type" "mul")]
2385 (define_insn "<su_optab>mulsidi3"
2386 [(set (match_operand:DI 0 "register_operand" "=r")
2387 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2388 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2390 "<su>mull\\t%0, %w1, %w2"
2391 [(set_attr "type" "<su>mull")]
2394 (define_insn "<su_optab>maddsidi4"
2395 [(set (match_operand:DI 0 "register_operand" "=r")
2397 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2398 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2399 (match_operand:DI 3 "register_operand" "r")))]
2401 "<su>maddl\\t%0, %w1, %w2, %3"
2402 [(set_attr "type" "<su>mlal")]
2405 (define_insn "<su_optab>msubsidi4"
2406 [(set (match_operand:DI 0 "register_operand" "=r")
2408 (match_operand:DI 3 "register_operand" "r")
2409 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2411 (match_operand:SI 2 "register_operand" "r")))))]
2413 "<su>msubl\\t%0, %w1, %w2, %3"
2414 [(set_attr "type" "<su>mlal")]
2417 (define_insn "*<su_optab>mulsidi_neg"
2418 [(set (match_operand:DI 0 "register_operand" "=r")
2420 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2421 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2423 "<su>mnegl\\t%0, %w1, %w2"
2424 [(set_attr "type" "<su>mull")]
2427 (define_expand "<su_optab>mulditi3"
2428 [(set (match_operand:TI 0 "register_operand")
2429 (mult:TI (ANY_EXTEND:TI (match_operand:DI 1 "register_operand"))
2430 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand"))))]
2433 rtx low = gen_reg_rtx (DImode);
2434 emit_insn (gen_muldi3 (low, operands[1], operands[2]));
2436 rtx high = gen_reg_rtx (DImode);
2437 emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2]));
2439 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2440 emit_move_insn (gen_highpart (DImode, operands[0]), high);
2444 ;; The default expansion of multi3 using umuldi3_highpart will perform
2445 ;; the additions in an order that fails to combine into two madd insns.
2446 (define_expand "multi3"
2447 [(set (match_operand:TI 0 "register_operand")
2448 (mult:TI (match_operand:TI 1 "register_operand")
2449 (match_operand:TI 2 "register_operand")))]
2452 rtx l0 = gen_reg_rtx (DImode);
2453 rtx l1 = gen_lowpart (DImode, operands[1]);
2454 rtx l2 = gen_lowpart (DImode, operands[2]);
2455 rtx h0 = gen_reg_rtx (DImode);
2456 rtx h1 = gen_highpart (DImode, operands[1]);
2457 rtx h2 = gen_highpart (DImode, operands[2]);
2459 emit_insn (gen_muldi3 (l0, l1, l2));
2460 emit_insn (gen_umuldi3_highpart (h0, l1, l2));
2461 emit_insn (gen_madddi (h0, h1, l2, h0));
2462 emit_insn (gen_madddi (h0, l1, h2, h0));
2464 emit_move_insn (gen_lowpart (DImode, operands[0]), l0);
2465 emit_move_insn (gen_highpart (DImode, operands[0]), h0);
2469 (define_insn "<su>muldi3_highpart"
2470 [(set (match_operand:DI 0 "register_operand" "=r")
2474 (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2475 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2478 "<su>mulh\\t%0, %1, %2"
2479 [(set_attr "type" "<su>mull")]
2482 (define_insn "<su_optab>div<mode>3"
2483 [(set (match_operand:GPI 0 "register_operand" "=r")
2484 (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2485 (match_operand:GPI 2 "register_operand" "r")))]
2487 "<su>div\\t%<w>0, %<w>1, %<w>2"
2488 [(set_attr "type" "<su>div")]
2491 ;; zero_extend version of above
2492 (define_insn "*<su_optab>divsi3_uxtw"
2493 [(set (match_operand:DI 0 "register_operand" "=r")
2495 (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2496 (match_operand:SI 2 "register_operand" "r"))))]
2498 "<su>div\\t%w0, %w1, %w2"
2499 [(set_attr "type" "<su>div")]
2502 ;; -------------------------------------------------------------------
2504 ;; -------------------------------------------------------------------
2506 (define_insn "*cmp<mode>"
2507 [(set (reg:CC CC_REGNUM)
2508 (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2509 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2515 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
2518 (define_insn "*cmp<mode>"
2519 [(set (reg:CCFP CC_REGNUM)
2520 (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2521 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2525 fcmp\\t%<s>0, %<s>1"
2526 [(set_attr "type" "fcmp<s>")]
2529 (define_insn "*cmpe<mode>"
2530 [(set (reg:CCFPE CC_REGNUM)
2531 (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2532 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2536 fcmpe\\t%<s>0, %<s>1"
2537 [(set_attr "type" "fcmp<s>")]
2540 (define_insn "*cmp_swp_<shift>_reg<mode>"
2541 [(set (reg:CC_SWP CC_REGNUM)
2542 (compare:CC_SWP (ASHIFT:GPI
2543 (match_operand:GPI 0 "register_operand" "r")
2544 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2545 (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2547 "cmp\\t%<w>2, %<w>0, <shift> %1"
2548 [(set_attr "type" "alus_shift_imm")]
2551 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2552 [(set (reg:CC_SWP CC_REGNUM)
2553 (compare:CC_SWP (ANY_EXTEND:GPI
2554 (match_operand:ALLX 0 "register_operand" "r"))
2555 (match_operand:GPI 1 "register_operand" "r")))]
2557 "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2558 [(set_attr "type" "alus_ext")]
2561 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2562 [(set (reg:CC_SWP CC_REGNUM)
2563 (compare:CC_SWP (ashift:GPI
2565 (match_operand:ALLX 0 "register_operand" "r"))
2566 (match_operand 1 "aarch64_imm3" "Ui3"))
2567 (match_operand:GPI 2 "register_operand" "r")))]
2569 "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2570 [(set_attr "type" "alus_ext")]
2573 ;; -------------------------------------------------------------------
2574 ;; Store-flag and conditional select insns
2575 ;; -------------------------------------------------------------------
2577 (define_expand "cstore<mode>4"
2578 [(set (match_operand:SI 0 "register_operand" "")
2579 (match_operator:SI 1 "aarch64_comparison_operator"
2580 [(match_operand:GPI 2 "register_operand" "")
2581 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2584 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2586 operands[3] = const0_rtx;
2590 (define_expand "cstorecc4"
2591 [(set (match_operand:SI 0 "register_operand")
2592 (match_operator 1 "aarch64_comparison_operator"
2593 [(match_operand 2 "ccmp_cc_register")
2594 (match_operand 3 "const0_operand")]))]
2597 emit_insn (gen_rtx_SET (SImode, operands[0], operands[1]));
2602 (define_expand "cstore<mode>4"
2603 [(set (match_operand:SI 0 "register_operand" "")
2604 (match_operator:SI 1 "aarch64_comparison_operator"
2605 [(match_operand:GPF 2 "register_operand" "")
2606 (match_operand:GPF 3 "register_operand" "")]))]
2609 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2611 operands[3] = const0_rtx;
2615 (define_insn "*cstore<mode>_insn"
2616 [(set (match_operand:ALLI 0 "register_operand" "=r")
2617 (match_operator:ALLI 1 "aarch64_comparison_operator"
2618 [(match_operand 2 "cc_register" "") (const_int 0)]))]
2621 [(set_attr "type" "csel")]
2624 ;; zero_extend version of the above
2625 (define_insn "*cstoresi_insn_uxtw"
2626 [(set (match_operand:DI 0 "register_operand" "=r")
2628 (match_operator:SI 1 "aarch64_comparison_operator"
2629 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2632 [(set_attr "type" "csel")]
2635 (define_insn "cstore<mode>_neg"
2636 [(set (match_operand:ALLI 0 "register_operand" "=r")
2637 (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2638 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2640 "csetm\\t%<w>0, %m1"
2641 [(set_attr "type" "csel")]
2644 ;; zero_extend version of the above
2645 (define_insn "*cstoresi_neg_uxtw"
2646 [(set (match_operand:DI 0 "register_operand" "=r")
2648 (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2649 [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2652 [(set_attr "type" "csel")]
2655 (define_expand "cmov<mode>6"
2656 [(set (match_operand:GPI 0 "register_operand" "")
2658 (match_operator 1 "aarch64_comparison_operator"
2659 [(match_operand:GPI 2 "register_operand" "")
2660 (match_operand:GPI 3 "aarch64_plus_operand" "")])
2661 (match_operand:GPI 4 "register_operand" "")
2662 (match_operand:GPI 5 "register_operand" "")))]
2665 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2667 operands[3] = const0_rtx;
2671 (define_expand "cmov<mode>6"
2672 [(set (match_operand:GPF 0 "register_operand" "")
2674 (match_operator 1 "aarch64_comparison_operator"
2675 [(match_operand:GPF 2 "register_operand" "")
2676 (match_operand:GPF 3 "register_operand" "")])
2677 (match_operand:GPF 4 "register_operand" "")
2678 (match_operand:GPF 5 "register_operand" "")))]
2681 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2683 operands[3] = const0_rtx;
2687 (define_insn "*cmov<mode>_insn"
2688 [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2690 (match_operator 1 "aarch64_comparison_operator"
2691 [(match_operand 2 "cc_register" "") (const_int 0)])
2692 (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2693 (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2694 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2695 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2696 ;; Final two alternatives should be unreachable, but included for completeness
2698 csel\\t%<w>0, %<w>3, %<w>4, %m1
2699 csinv\\t%<w>0, %<w>3, <w>zr, %m1
2700 csinv\\t%<w>0, %<w>4, <w>zr, %M1
2701 csinc\\t%<w>0, %<w>3, <w>zr, %m1
2702 csinc\\t%<w>0, %<w>4, <w>zr, %M1
2705 [(set_attr "type" "csel")]
2708 ;; zero_extend version of above
2709 (define_insn "*cmovsi_insn_uxtw"
2710 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2713 (match_operator 1 "aarch64_comparison_operator"
2714 [(match_operand 2 "cc_register" "") (const_int 0)])
2715 (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2716 (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2717 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2718 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2719 ;; Final two alternatives should be unreachable, but included for completeness
2721 csel\\t%w0, %w3, %w4, %m1
2722 csinv\\t%w0, %w3, wzr, %m1
2723 csinv\\t%w0, %w4, wzr, %M1
2724 csinc\\t%w0, %w3, wzr, %m1
2725 csinc\\t%w0, %w4, wzr, %M1
2728 [(set_attr "type" "csel")]
2731 (define_insn "*cmov<mode>_insn"
2732 [(set (match_operand:GPF 0 "register_operand" "=w")
2734 (match_operator 1 "aarch64_comparison_operator"
2735 [(match_operand 2 "cc_register" "") (const_int 0)])
2736 (match_operand:GPF 3 "register_operand" "w")
2737 (match_operand:GPF 4 "register_operand" "w")))]
2739 "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2740 [(set_attr "type" "fcsel")]
2743 (define_expand "mov<mode>cc"
2744 [(set (match_operand:ALLI 0 "register_operand" "")
2745 (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2746 (match_operand:ALLI 2 "register_operand" "")
2747 (match_operand:ALLI 3 "register_operand" "")))]
2750 enum rtx_code code = GET_CODE (operands[1]);
2752 if (code == UNEQ || code == LTGT)
2755 if (!ccmp_cc_register (XEXP (operands[1], 0),
2756 GET_MODE (XEXP (operands[1], 0))))
2759 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2760 XEXP (operands[1], 1));
2761 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2766 (define_expand "mov<GPF:mode><GPI:mode>cc"
2767 [(set (match_operand:GPI 0 "register_operand" "")
2768 (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2769 (match_operand:GPF 2 "register_operand" "")
2770 (match_operand:GPF 3 "register_operand" "")))]
2774 enum rtx_code code = GET_CODE (operands[1]);
2776 if (code == UNEQ || code == LTGT)
2779 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2780 XEXP (operands[1], 1));
2781 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2785 (define_expand "mov<mode>cc"
2786 [(set (match_operand:GPF 0 "register_operand" "")
2787 (if_then_else:GPF (match_operand 1 "aarch64_comparison_operator" "")
2788 (match_operand:GPF 2 "register_operand" "")
2789 (match_operand:GPF 3 "register_operand" "")))]
2793 enum rtx_code code = GET_CODE (operands[1]);
2795 if (code == UNEQ || code == LTGT)
2798 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2799 XEXP (operands[1], 1));
2800 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2805 ;; CRC32 instructions.
2806 (define_insn "aarch64_<crc_variant>"
2807 [(set (match_operand:SI 0 "register_operand" "=r")
2808 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2809 (match_operand:<crc_mode> 2 "register_operand" "r")]
2813 if (GET_MODE_BITSIZE (GET_MODE (operands[2])) >= 64)
2814 return "<crc_variant>\\t%w0, %w1, %x2";
2816 return "<crc_variant>\\t%w0, %w1, %w2";
2818 [(set_attr "type" "crc")]
2821 (define_insn "*csinc2<mode>_insn"
2822 [(set (match_operand:GPI 0 "register_operand" "=r")
2823 (plus:GPI (match_operand 2 "aarch64_comparison_operation" "")
2824 (match_operand:GPI 1 "register_operand" "r")))]
2826 "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2827 [(set_attr "type" "csel")]
2830 (define_insn "csinc3<mode>_insn"
2831 [(set (match_operand:GPI 0 "register_operand" "=r")
2833 (match_operand 1 "aarch64_comparison_operation" "")
2834 (plus:GPI (match_operand:GPI 2 "register_operand" "r")
2836 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2838 "csinc\\t%<w>0, %<w>3, %<w>2, %M1"
2839 [(set_attr "type" "csel")]
2842 (define_insn "*csinv3<mode>_insn"
2843 [(set (match_operand:GPI 0 "register_operand" "=r")
2845 (match_operand 1 "aarch64_comparison_operation" "")
2846 (not:GPI (match_operand:GPI 2 "register_operand" "r"))
2847 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2849 "csinv\\t%<w>0, %<w>3, %<w>2, %M1"
2850 [(set_attr "type" "csel")]
2853 (define_insn "*csneg3<mode>_insn"
2854 [(set (match_operand:GPI 0 "register_operand" "=r")
2856 (match_operand 1 "aarch64_comparison_operation" "")
2857 (neg:GPI (match_operand:GPI 2 "register_operand" "r"))
2858 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2860 "csneg\\t%<w>0, %<w>3, %<w>2, %M1"
2861 [(set_attr "type" "csel")]
2864 ;; -------------------------------------------------------------------
2865 ;; Logical operations
2866 ;; -------------------------------------------------------------------
2868 (define_insn "<optab><mode>3"
2869 [(set (match_operand:GPI 0 "register_operand" "=r,rk")
2870 (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2871 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
2873 "<logical>\\t%<w>0, %<w>1, %<w>2"
2874 [(set_attr "type" "logic_reg,logic_imm")]
2877 ;; zero_extend version of above
2878 (define_insn "*<optab>si3_uxtw"
2879 [(set (match_operand:DI 0 "register_operand" "=r,rk")
2881 (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2882 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2884 "<logical>\\t%w0, %w1, %w2"
2885 [(set_attr "type" "logic_reg,logic_imm")]
2888 (define_insn "*and<mode>3_compare0"
2889 [(set (reg:CC_NZ CC_REGNUM)
2891 (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2892 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2894 (set (match_operand:GPI 0 "register_operand" "=r,r")
2895 (and:GPI (match_dup 1) (match_dup 2)))]
2897 "ands\\t%<w>0, %<w>1, %<w>2"
2898 [(set_attr "type" "logics_reg,logics_imm")]
2901 ;; zero_extend version of above
2902 (define_insn "*andsi3_compare0_uxtw"
2903 [(set (reg:CC_NZ CC_REGNUM)
2905 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2906 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2908 (set (match_operand:DI 0 "register_operand" "=r,r")
2909 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2911 "ands\\t%w0, %w1, %w2"
2912 [(set_attr "type" "logics_reg,logics_imm")]
2915 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2916 [(set (reg:CC_NZ CC_REGNUM)
2919 (match_operand:GPI 1 "register_operand" "r")
2920 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2921 (match_operand:GPI 3 "register_operand" "r"))
2923 (set (match_operand:GPI 0 "register_operand" "=r")
2924 (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2926 "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2927 [(set_attr "type" "logics_shift_imm")]
2930 ;; zero_extend version of above
2931 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2932 [(set (reg:CC_NZ CC_REGNUM)
2935 (match_operand:SI 1 "register_operand" "r")
2936 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2937 (match_operand:SI 3 "register_operand" "r"))
2939 (set (match_operand:DI 0 "register_operand" "=r")
2940 (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2943 "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2944 [(set_attr "type" "logics_shift_imm")]
2947 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2948 [(set (match_operand:GPI 0 "register_operand" "=r")
2949 (LOGICAL:GPI (SHIFT:GPI
2950 (match_operand:GPI 1 "register_operand" "r")
2951 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2952 (match_operand:GPI 3 "register_operand" "r")))]
2954 "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2955 [(set_attr "type" "logic_shift_imm")]
2958 (define_insn "*<optab>_rol<mode>3"
2959 [(set (match_operand:GPI 0 "register_operand" "=r")
2960 (LOGICAL:GPI (rotate:GPI
2961 (match_operand:GPI 1 "register_operand" "r")
2962 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2963 (match_operand:GPI 3 "register_operand" "r")))]
2965 "<logical>\\t%<w>0, %<w>3, %<w>1, ror (<sizen> - %2)"
2966 [(set_attr "type" "logic_shift_imm")]
2969 ;; zero_extend versions of above
2970 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
2971 [(set (match_operand:DI 0 "register_operand" "=r")
2973 (LOGICAL:SI (SHIFT:SI
2974 (match_operand:SI 1 "register_operand" "r")
2975 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2976 (match_operand:SI 3 "register_operand" "r"))))]
2978 "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2979 [(set_attr "type" "logic_shift_imm")]
2982 (define_insn "*<optab>_rolsi3_uxtw"
2983 [(set (match_operand:DI 0 "register_operand" "=r")
2985 (LOGICAL:SI (rotate:SI
2986 (match_operand:SI 1 "register_operand" "r")
2987 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2988 (match_operand:SI 3 "register_operand" "r"))))]
2990 "<logical>\\t%w0, %w3, %w1, ror (32 - %2)"
2991 [(set_attr "type" "logic_shift_imm")]
2994 (define_insn "one_cmpl<mode>2"
2995 [(set (match_operand:GPI 0 "register_operand" "=r")
2996 (not:GPI (match_operand:GPI 1 "register_operand" "r")))]
2998 "mvn\\t%<w>0, %<w>1"
2999 [(set_attr "type" "logic_reg")]
3002 (define_insn "*one_cmpl_<optab><mode>2"
3003 [(set (match_operand:GPI 0 "register_operand" "=r")
3004 (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
3005 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
3007 "mvn\\t%<w>0, %<w>1, <shift> %2"
3008 [(set_attr "type" "logic_shift_imm")]
3011 (define_insn "*<LOGICAL:optab>_one_cmpl<mode>3"
3012 [(set (match_operand:GPI 0 "register_operand" "=r")
3013 (LOGICAL:GPI (not:GPI
3014 (match_operand:GPI 1 "register_operand" "r"))
3015 (match_operand:GPI 2 "register_operand" "r")))]
3017 "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1"
3018 [(set_attr "type" "logic_reg")]
3021 (define_insn "*and_one_cmpl<mode>3_compare0"
3022 [(set (reg:CC_NZ CC_REGNUM)
3025 (match_operand:GPI 1 "register_operand" "r"))
3026 (match_operand:GPI 2 "register_operand" "r"))
3028 (set (match_operand:GPI 0 "register_operand" "=r")
3029 (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
3031 "bics\\t%<w>0, %<w>2, %<w>1"
3032 [(set_attr "type" "logics_reg")]
3035 ;; zero_extend version of above
3036 (define_insn "*and_one_cmplsi3_compare0_uxtw"
3037 [(set (reg:CC_NZ CC_REGNUM)
3040 (match_operand:SI 1 "register_operand" "r"))
3041 (match_operand:SI 2 "register_operand" "r"))
3043 (set (match_operand:DI 0 "register_operand" "=r")
3044 (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
3046 "bics\\t%w0, %w2, %w1"
3047 [(set_attr "type" "logics_reg")]
3050 (define_insn "*and_one_cmpl<mode>3_compare0_no_reuse"
3051 [(set (reg:CC_NZ CC_REGNUM)
3054 (match_operand:GPI 0 "register_operand" "r"))
3055 (match_operand:GPI 1 "register_operand" "r"))
3058 "bics\\t<w>zr, %<w>1, %<w>0"
3059 [(set_attr "type" "logics_reg")]
3062 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
3063 [(set (match_operand:GPI 0 "register_operand" "=r")
3064 (LOGICAL:GPI (not:GPI
3066 (match_operand:GPI 1 "register_operand" "r")
3067 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
3068 (match_operand:GPI 3 "register_operand" "r")))]
3070 "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3071 [(set_attr "type" "logics_shift_imm")]
3074 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
3075 [(set (reg:CC_NZ CC_REGNUM)
3079 (match_operand:GPI 1 "register_operand" "r")
3080 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
3081 (match_operand:GPI 3 "register_operand" "r"))
3083 (set (match_operand:GPI 0 "register_operand" "=r")
3086 (match_dup 1) (match_dup 2))) (match_dup 3)))]
3088 "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3089 [(set_attr "type" "logics_shift_imm")]
3092 ;; zero_extend version of above
3093 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
3094 [(set (reg:CC_NZ CC_REGNUM)
3098 (match_operand:SI 1 "register_operand" "r")
3099 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
3100 (match_operand:SI 3 "register_operand" "r"))
3102 (set (match_operand:DI 0 "register_operand" "=r")
3103 (zero_extend:DI (and:SI
3105 (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
3107 "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3108 [(set_attr "type" "logics_shift_imm")]
3111 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0_no_reuse"
3112 [(set (reg:CC_NZ CC_REGNUM)
3116 (match_operand:GPI 0 "register_operand" "r")
3117 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n")))
3118 (match_operand:GPI 2 "register_operand" "r"))
3121 "bics\\t<w>zr, %<w>2, %<w>0, <SHIFT:shift> %1"
3122 [(set_attr "type" "logics_shift_imm")]
3125 (define_insn "clz<mode>2"
3126 [(set (match_operand:GPI 0 "register_operand" "=r")
3127 (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
3129 "clz\\t%<w>0, %<w>1"
3130 [(set_attr "type" "clz")]
3133 (define_expand "ffs<mode>2"
3134 [(match_operand:GPI 0 "register_operand")
3135 (match_operand:GPI 1 "register_operand")]
3138 rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
3139 rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
3141 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3142 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3143 emit_insn (gen_csinc3<mode>_insn (operands[0], x, operands[0], const0_rtx));
3148 (define_insn "clrsb<mode>2"
3149 [(set (match_operand:GPI 0 "register_operand" "=r")
3150 (clrsb:GPI (match_operand:GPI 1 "register_operand" "r")))]
3152 "cls\\t%<w>0, %<w>1"
3153 [(set_attr "type" "clz")]
3156 (define_insn "rbit<mode>2"
3157 [(set (match_operand:GPI 0 "register_operand" "=r")
3158 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
3160 "rbit\\t%<w>0, %<w>1"
3161 [(set_attr "type" "rbit")]
3164 (define_expand "ctz<mode>2"
3165 [(match_operand:GPI 0 "register_operand")
3166 (match_operand:GPI 1 "register_operand")]
3169 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3170 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3175 (define_insn "*and<mode>3nr_compare0"
3176 [(set (reg:CC_NZ CC_REGNUM)
3178 (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
3179 (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
3182 "tst\\t%<w>0, %<w>1"
3183 [(set_attr "type" "logics_reg")]
3186 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
3187 [(set (reg:CC_NZ CC_REGNUM)
3190 (match_operand:GPI 0 "register_operand" "r")
3191 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
3192 (match_operand:GPI 2 "register_operand" "r"))
3195 "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
3196 [(set_attr "type" "logics_shift_imm")]
3199 ;; -------------------------------------------------------------------
3201 ;; -------------------------------------------------------------------
3203 (define_expand "<optab><mode>3"
3204 [(set (match_operand:GPI 0 "register_operand")
3205 (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
3206 (match_operand:QI 2 "nonmemory_operand")))]
3209 if (CONST_INT_P (operands[2]))
3211 operands[2] = GEN_INT (INTVAL (operands[2])
3212 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3214 if (operands[2] == const0_rtx)
3216 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3223 (define_expand "ashl<mode>3"
3224 [(set (match_operand:SHORT 0 "register_operand")
3225 (ashift:SHORT (match_operand:SHORT 1 "register_operand")
3226 (match_operand:QI 2 "nonmemory_operand")))]
3229 if (CONST_INT_P (operands[2]))
3231 operands[2] = GEN_INT (INTVAL (operands[2])
3232 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3234 if (operands[2] == const0_rtx)
3236 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3243 (define_expand "rotr<mode>3"
3244 [(set (match_operand:GPI 0 "register_operand")
3245 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3246 (match_operand:QI 2 "nonmemory_operand")))]
3249 if (CONST_INT_P (operands[2]))
3251 operands[2] = GEN_INT (INTVAL (operands[2])
3252 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3254 if (operands[2] == const0_rtx)
3256 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3263 (define_expand "rotl<mode>3"
3264 [(set (match_operand:GPI 0 "register_operand")
3265 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3266 (match_operand:QI 2 "nonmemory_operand")))]
3269 /* (SZ - cnt) % SZ == -cnt % SZ */
3270 if (CONST_INT_P (operands[2]))
3272 operands[2] = GEN_INT ((-INTVAL (operands[2]))
3273 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3274 if (operands[2] == const0_rtx)
3276 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3281 operands[2] = expand_simple_unop (QImode, NEG, operands[2],
3286 ;; Logical left shift using SISD or Integer instruction
3287 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
3288 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3290 (match_operand:GPI 1 "register_operand" "w,w,r")
3291 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3294 shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3295 ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
3296 lsl\t%<w>0, %<w>1, %<w>2"
3297 [(set_attr "simd" "yes,yes,no")
3298 (set_attr "type" "neon_shift_imm<q>, neon_shift_reg<q>,shift_reg")]
3301 ;; Logical right shift using SISD or Integer instruction
3302 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3303 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3305 (match_operand:GPI 1 "register_operand" "w,w,r")
3306 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3309 ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3311 lsr\t%<w>0, %<w>1, %<w>2"
3312 [(set_attr "simd" "yes,yes,no")
3313 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")]
3317 [(set (match_operand:DI 0 "aarch64_simd_register")
3319 (match_operand:DI 1 "aarch64_simd_register")
3320 (match_operand:QI 2 "aarch64_simd_register")))]
3321 "TARGET_SIMD && reload_completed"
3323 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3325 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_USHL))]
3330 [(set (match_operand:SI 0 "aarch64_simd_register")
3332 (match_operand:SI 1 "aarch64_simd_register")
3333 (match_operand:QI 2 "aarch64_simd_register")))]
3334 "TARGET_SIMD && reload_completed"
3336 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3338 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_USHL_2S))]
3342 ;; Arithmetic right shift using SISD or Integer instruction
3343 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3344 [(set (match_operand:GPI 0 "register_operand" "=w,&w,&w,r")
3346 (match_operand:GPI 1 "register_operand" "w,w,w,r")
3347 (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,0,rUs<cmode>")))]
3350 sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3353 asr\t%<w>0, %<w>1, %<w>2"
3354 [(set_attr "simd" "yes,yes,yes,no")
3355 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>,shift_reg")]
3359 [(set (match_operand:DI 0 "aarch64_simd_register")
3361 (match_operand:DI 1 "aarch64_simd_register")
3362 (match_operand:QI 2 "aarch64_simd_register")))]
3363 "TARGET_SIMD && reload_completed"
3365 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3367 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_SSHL))]
3369 operands[3] = gen_lowpart (QImode, operands[0]);
3374 [(set (match_operand:SI 0 "aarch64_simd_register")
3376 (match_operand:SI 1 "aarch64_simd_register")
3377 (match_operand:QI 2 "aarch64_simd_register")))]
3378 "TARGET_SIMD && reload_completed"
3380 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3382 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_SSHL_2S))]
3384 operands[3] = gen_lowpart (QImode, operands[0]);
3388 (define_insn "*aarch64_sisd_ushl"
3389 [(set (match_operand:DI 0 "register_operand" "=w")
3390 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3391 (match_operand:QI 2 "register_operand" "w")]
3394 "ushl\t%d0, %d1, %d2"
3395 [(set_attr "simd" "yes")
3396 (set_attr "type" "neon_shift_reg")]
3399 (define_insn "*aarch64_ushl_2s"
3400 [(set (match_operand:SI 0 "register_operand" "=w")
3401 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3402 (match_operand:QI 2 "register_operand" "w")]
3405 "ushl\t%0.2s, %1.2s, %2.2s"
3406 [(set_attr "simd" "yes")
3407 (set_attr "type" "neon_shift_reg")]
3410 (define_insn "*aarch64_sisd_sshl"
3411 [(set (match_operand:DI 0 "register_operand" "=w")
3412 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3413 (match_operand:QI 2 "register_operand" "w")]
3416 "sshl\t%d0, %d1, %d2"
3417 [(set_attr "simd" "yes")
3418 (set_attr "type" "neon_shift_reg")]
3421 (define_insn "*aarch64_sshl_2s"
3422 [(set (match_operand:SI 0 "register_operand" "=w")
3423 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3424 (match_operand:QI 2 "register_operand" "w")]
3427 "sshl\t%0.2s, %1.2s, %2.2s"
3428 [(set_attr "simd" "yes")
3429 (set_attr "type" "neon_shift_reg")]
3432 (define_insn "*aarch64_sisd_neg_qi"
3433 [(set (match_operand:QI 0 "register_operand" "=w")
3434 (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3438 [(set_attr "simd" "yes")
3439 (set_attr "type" "neon_neg")]
3443 (define_insn "*ror<mode>3_insn"
3444 [(set (match_operand:GPI 0 "register_operand" "=r")
3446 (match_operand:GPI 1 "register_operand" "r")
3447 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3449 "ror\\t%<w>0, %<w>1, %<w>2"
3450 [(set_attr "type" "shift_reg")]
3453 ;; zero_extend version of above
3454 (define_insn "*<optab>si3_insn_uxtw"
3455 [(set (match_operand:DI 0 "register_operand" "=r")
3456 (zero_extend:DI (SHIFT:SI
3457 (match_operand:SI 1 "register_operand" "r")
3458 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3460 "<shift>\\t%w0, %w1, %w2"
3461 [(set_attr "type" "shift_reg")]
3464 (define_insn "*ashl<mode>3_insn"
3465 [(set (match_operand:SHORT 0 "register_operand" "=r")
3466 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3467 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
3469 "lsl\\t%<w>0, %<w>1, %<w>2"
3470 [(set_attr "type" "shift_reg")]
3473 (define_insn "*<optab><mode>3_insn"
3474 [(set (match_operand:SHORT 0 "register_operand" "=r")
3475 (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3476 (match_operand 2 "const_int_operand" "n")))]
3477 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3479 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3480 return "<bfshift>\t%w0, %w1, %2, %3";
3482 [(set_attr "type" "bfm")]
3485 (define_insn "*extr<mode>5_insn"
3486 [(set (match_operand:GPI 0 "register_operand" "=r")
3487 (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3488 (match_operand 3 "const_int_operand" "n"))
3489 (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3490 (match_operand 4 "const_int_operand" "n"))))]
3491 "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3492 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3493 "extr\\t%<w>0, %<w>1, %<w>2, %4"
3494 [(set_attr "type" "shift_imm")]
3497 ;; zero_extend version of the above
3498 (define_insn "*extrsi5_insn_uxtw"
3499 [(set (match_operand:DI 0 "register_operand" "=r")
3501 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3502 (match_operand 3 "const_int_operand" "n"))
3503 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3504 (match_operand 4 "const_int_operand" "n")))))]
3505 "UINTVAL (operands[3]) < 32 &&
3506 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3507 "extr\\t%w0, %w1, %w2, %4"
3508 [(set_attr "type" "shift_imm")]
3511 (define_insn "*ror<mode>3_insn"
3512 [(set (match_operand:GPI 0 "register_operand" "=r")
3513 (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3514 (match_operand 2 "const_int_operand" "n")))]
3515 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3517 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3518 return "ror\\t%<w>0, %<w>1, %3";
3520 [(set_attr "type" "shift_imm")]
3523 ;; zero_extend version of the above
3524 (define_insn "*rorsi3_insn_uxtw"
3525 [(set (match_operand:DI 0 "register_operand" "=r")
3527 (rotate:SI (match_operand:SI 1 "register_operand" "r")
3528 (match_operand 2 "const_int_operand" "n"))))]
3529 "UINTVAL (operands[2]) < 32"
3531 operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3532 return "ror\\t%w0, %w1, %3";
3534 [(set_attr "type" "shift_imm")]
3537 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3538 [(set (match_operand:GPI 0 "register_operand" "=r")
3540 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3541 (match_operand 2 "const_int_operand" "n"))))]
3542 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3544 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3545 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3547 [(set_attr "type" "bfm")]
3550 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3551 [(set (match_operand:GPI 0 "register_operand" "=r")
3553 (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3554 (match_operand 2 "const_int_operand" "n"))))]
3555 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3557 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3558 return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3560 [(set_attr "type" "bfm")]
3563 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3564 [(set (match_operand:GPI 0 "register_operand" "=r")
3566 (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3567 (match_operand 2 "const_int_operand" "n"))))]
3568 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3570 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3571 return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3573 [(set_attr "type" "bfm")]
3576 ;; -------------------------------------------------------------------
3578 ;; -------------------------------------------------------------------
3580 (define_expand "<optab>"
3581 [(set (match_operand:DI 0 "register_operand" "=r")
3582 (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3583 (match_operand 2 "const_int_operand" "n")
3584 (match_operand 3 "const_int_operand" "n")))]
3589 (define_insn "*<optab><mode>"
3590 [(set (match_operand:GPI 0 "register_operand" "=r")
3591 (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3592 (match_operand 2 "const_int_operand" "n")
3593 (match_operand 3 "const_int_operand" "n")))]
3595 "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3596 [(set_attr "type" "bfm")]
3599 ;; Bitfield Insert (insv)
3600 (define_expand "insv<mode>"
3601 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3602 (match_operand 1 "const_int_operand")
3603 (match_operand 2 "const_int_operand"))
3604 (match_operand:GPI 3 "general_operand"))]
3607 unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3608 unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3609 rtx value = operands[3];
3611 if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3614 if (CONST_INT_P (value))
3616 unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3618 /* Prefer AND/OR for inserting all zeros or all ones. */
3619 if ((UINTVAL (value) & mask) == 0
3620 || (UINTVAL (value) & mask) == mask)
3623 /* 16-bit aligned 16-bit wide insert is handled by insv_imm. */
3624 if (width == 16 && (pos % 16) == 0)
3627 operands[3] = force_reg (<MODE>mode, value);
3630 (define_insn "*insv_reg<mode>"
3631 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3632 (match_operand 1 "const_int_operand" "n")
3633 (match_operand 2 "const_int_operand" "n"))
3634 (match_operand:GPI 3 "register_operand" "r"))]
3635 "!(UINTVAL (operands[1]) == 0
3636 || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3637 > GET_MODE_BITSIZE (<MODE>mode)))"
3638 "bfi\\t%<w>0, %<w>3, %2, %1"
3639 [(set_attr "type" "bfm")]
3642 (define_insn "*extr_insv_lower_reg<mode>"
3643 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3644 (match_operand 1 "const_int_operand" "n")
3646 (zero_extract:GPI (match_operand:GPI 2 "register_operand" "r")
3648 (match_operand 3 "const_int_operand" "n")))]
3649 "!(UINTVAL (operands[1]) == 0
3650 || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3651 > GET_MODE_BITSIZE (<MODE>mode)))"
3652 "bfxil\\t%<w>0, %<w>2, %3, %1"
3653 [(set_attr "type" "bfm")]
3656 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3657 [(set (match_operand:GPI 0 "register_operand" "=r")
3658 (ashift:GPI (ANY_EXTEND:GPI
3659 (match_operand:ALLX 1 "register_operand" "r"))
3660 (match_operand 2 "const_int_operand" "n")))]
3661 "UINTVAL (operands[2]) < <GPI:sizen>"
3663 operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3664 ? GEN_INT (<ALLX:sizen>)
3665 : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3666 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3668 [(set_attr "type" "bfm")]
3671 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3673 (define_insn "*andim_ashift<mode>_bfiz"
3674 [(set (match_operand:GPI 0 "register_operand" "=r")
3675 (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3676 (match_operand 2 "const_int_operand" "n"))
3677 (match_operand 3 "const_int_operand" "n")))]
3678 "(INTVAL (operands[2]) < (<GPI:sizen>))
3679 && exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3680 && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3681 "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3682 [(set_attr "type" "bfm")]
3685 (define_insn "bswap<mode>2"
3686 [(set (match_operand:GPI 0 "register_operand" "=r")
3687 (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3689 "rev\\t%<w>0, %<w>1"
3690 [(set_attr "type" "rev")]
3693 (define_insn "bswaphi2"
3694 [(set (match_operand:HI 0 "register_operand" "=r")
3695 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3698 [(set_attr "type" "rev")]
3701 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
3702 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
3703 ;; each valid permutation.
3705 (define_insn "rev16<mode>2"
3706 [(set (match_operand:GPI 0 "register_operand" "=r")
3707 (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3709 (match_operand:GPI 3 "const_int_operand" "n"))
3710 (and:GPI (lshiftrt:GPI (match_dup 1)
3712 (match_operand:GPI 2 "const_int_operand" "n"))))]
3713 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3714 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3715 "rev16\\t%<w>0, %<w>1"
3716 [(set_attr "type" "rev")]
3719 (define_insn "rev16<mode>2_alt"
3720 [(set (match_operand:GPI 0 "register_operand" "=r")
3721 (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r")
3723 (match_operand:GPI 2 "const_int_operand" "n"))
3724 (and:GPI (ashift:GPI (match_dup 1)
3726 (match_operand:GPI 3 "const_int_operand" "n"))))]
3727 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3728 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3729 "rev16\\t%<w>0, %<w>1"
3730 [(set_attr "type" "rev")]
3733 ;; zero_extend version of above
3734 (define_insn "*bswapsi2_uxtw"
3735 [(set (match_operand:DI 0 "register_operand" "=r")
3736 (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3739 [(set_attr "type" "rev")]
3742 ;; -------------------------------------------------------------------
3743 ;; Floating-point intrinsics
3744 ;; -------------------------------------------------------------------
3746 ;; frint floating-point round to integral standard patterns.
3747 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round, frintn.
3749 (define_insn "<frint_pattern><mode>2"
3750 [(set (match_operand:GPF 0 "register_operand" "=w")
3751 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3754 "frint<frint_suffix>\\t%<s>0, %<s>1"
3755 [(set_attr "type" "f_rint<s>")]
3758 ;; frcvt floating-point round to integer and convert standard patterns.
3759 ;; Expands to lbtrunc, lceil, lfloor, lround.
3760 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3761 [(set (match_operand:GPI 0 "register_operand" "=r")
3762 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3765 "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3766 [(set_attr "type" "f_cvtf2i")]
3771 (define_insn "fma<mode>4"
3772 [(set (match_operand:GPF 0 "register_operand" "=w")
3773 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3774 (match_operand:GPF 2 "register_operand" "w")
3775 (match_operand:GPF 3 "register_operand" "w")))]
3777 "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3778 [(set_attr "type" "fmac<s>")]
3781 (define_insn "fnma<mode>4"
3782 [(set (match_operand:GPF 0 "register_operand" "=w")
3783 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3784 (match_operand:GPF 2 "register_operand" "w")
3785 (match_operand:GPF 3 "register_operand" "w")))]
3787 "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3788 [(set_attr "type" "fmac<s>")]
3791 (define_insn "fms<mode>4"
3792 [(set (match_operand:GPF 0 "register_operand" "=w")
3793 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3794 (match_operand:GPF 2 "register_operand" "w")
3795 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3797 "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3798 [(set_attr "type" "fmac<s>")]
3801 (define_insn "fnms<mode>4"
3802 [(set (match_operand:GPF 0 "register_operand" "=w")
3803 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3804 (match_operand:GPF 2 "register_operand" "w")
3805 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3807 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3808 [(set_attr "type" "fmac<s>")]
3811 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3812 (define_insn "*fnmadd<mode>4"
3813 [(set (match_operand:GPF 0 "register_operand" "=w")
3814 (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3815 (match_operand:GPF 2 "register_operand" "w")
3816 (match_operand:GPF 3 "register_operand" "w"))))]
3817 "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3818 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3819 [(set_attr "type" "fmac<s>")]
3822 ;; -------------------------------------------------------------------
3823 ;; Floating-point conversions
3824 ;; -------------------------------------------------------------------
3826 (define_insn "extendsfdf2"
3827 [(set (match_operand:DF 0 "register_operand" "=w")
3828 (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3831 [(set_attr "type" "f_cvt")]
3834 (define_insn "truncdfsf2"
3835 [(set (match_operand:SF 0 "register_operand" "=w")
3836 (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3839 [(set_attr "type" "f_cvt")]
3842 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3843 [(set (match_operand:GPI 0 "register_operand" "=r")
3844 (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3846 "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3847 [(set_attr "type" "f_cvtf2i")]
3850 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3851 [(set (match_operand:GPI 0 "register_operand" "=r")
3852 (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3854 "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3855 [(set_attr "type" "f_cvtf2i")]
3858 (define_insn "<optab><fcvt_target><GPF:mode>2"
3859 [(set (match_operand:GPF 0 "register_operand" "=w,w")
3860 (FLOATUORS:GPF (match_operand:<FCVT_TARGET> 1 "register_operand" "w,r")))]
3863 <su_optab>cvtf\t%<GPF:s>0, %<s>1
3864 <su_optab>cvtf\t%<GPF:s>0, %<w1>1"
3865 [(set_attr "simd" "yes,no")
3866 (set_attr "fp" "no,yes")
3867 (set_attr "type" "neon_int_to_fp_<Vetype>,f_cvti2f")]
3870 (define_insn "<optab><fcvt_iesize><GPF:mode>2"
3871 [(set (match_operand:GPF 0 "register_operand" "=w")
3872 (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand" "r")))]
3874 "<su_optab>cvtf\t%<GPF:s>0, %<w2>1"
3875 [(set_attr "type" "f_cvti2f")]
3878 ;; -------------------------------------------------------------------
3879 ;; Floating-point arithmetic
3880 ;; -------------------------------------------------------------------
3882 (define_insn "add<mode>3"
3883 [(set (match_operand:GPF 0 "register_operand" "=w")
3885 (match_operand:GPF 1 "register_operand" "w")
3886 (match_operand:GPF 2 "register_operand" "w")))]
3888 "fadd\\t%<s>0, %<s>1, %<s>2"
3889 [(set_attr "type" "fadd<s>")]
3892 (define_insn "sub<mode>3"
3893 [(set (match_operand:GPF 0 "register_operand" "=w")
3895 (match_operand:GPF 1 "register_operand" "w")
3896 (match_operand:GPF 2 "register_operand" "w")))]
3898 "fsub\\t%<s>0, %<s>1, %<s>2"
3899 [(set_attr "type" "fadd<s>")]
3902 (define_insn "mul<mode>3"
3903 [(set (match_operand:GPF 0 "register_operand" "=w")
3905 (match_operand:GPF 1 "register_operand" "w")
3906 (match_operand:GPF 2 "register_operand" "w")))]
3908 "fmul\\t%<s>0, %<s>1, %<s>2"
3909 [(set_attr "type" "fmul<s>")]
3912 (define_insn "*fnmul<mode>3"
3913 [(set (match_operand:GPF 0 "register_operand" "=w")
3915 (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3916 (match_operand:GPF 2 "register_operand" "w")))]
3918 "fnmul\\t%<s>0, %<s>1, %<s>2"
3919 [(set_attr "type" "fmul<s>")]
3922 (define_insn "div<mode>3"
3923 [(set (match_operand:GPF 0 "register_operand" "=w")
3925 (match_operand:GPF 1 "register_operand" "w")
3926 (match_operand:GPF 2 "register_operand" "w")))]
3928 "fdiv\\t%<s>0, %<s>1, %<s>2"
3929 [(set_attr "type" "fdiv<s>")]
3932 (define_insn "neg<mode>2"
3933 [(set (match_operand:GPF 0 "register_operand" "=w")
3934 (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
3936 "fneg\\t%<s>0, %<s>1"
3937 [(set_attr "type" "ffarith<s>")]
3940 (define_insn "sqrt<mode>2"
3941 [(set (match_operand:GPF 0 "register_operand" "=w")
3942 (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
3944 "fsqrt\\t%<s>0, %<s>1"
3945 [(set_attr "type" "fsqrt<s>")]
3948 (define_insn "abs<mode>2"
3949 [(set (match_operand:GPF 0 "register_operand" "=w")
3950 (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
3952 "fabs\\t%<s>0, %<s>1"
3953 [(set_attr "type" "ffarith<s>")]
3956 ;; Given that smax/smin do not specify the result when either input is NaN,
3957 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
3960 (define_insn "smax<mode>3"
3961 [(set (match_operand:GPF 0 "register_operand" "=w")
3962 (smax:GPF (match_operand:GPF 1 "register_operand" "w")
3963 (match_operand:GPF 2 "register_operand" "w")))]
3965 "fmaxnm\\t%<s>0, %<s>1, %<s>2"
3966 [(set_attr "type" "f_minmax<s>")]
3969 (define_insn "smin<mode>3"
3970 [(set (match_operand:GPF 0 "register_operand" "=w")
3971 (smin:GPF (match_operand:GPF 1 "register_operand" "w")
3972 (match_operand:GPF 2 "register_operand" "w")))]
3974 "fminnm\\t%<s>0, %<s>1, %<s>2"
3975 [(set_attr "type" "f_minmax<s>")]
3978 ;; -------------------------------------------------------------------
3980 ;; -------------------------------------------------------------------
3982 (define_expand "aarch64_reload_mov<mode>"
3983 [(set (match_operand:TX 0 "register_operand" "=w")
3984 (match_operand:TX 1 "register_operand" "w"))
3985 (clobber (match_operand:DI 2 "register_operand" "=&r"))
3989 rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
3990 rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
3991 gen_aarch64_movtilow_tilow (op0, op1);
3992 gen_aarch64_movdi_tihigh (operands[2], op1);
3993 gen_aarch64_movtihigh_di (op0, operands[2]);
3998 ;; The following secondary reload helpers patterns are invoked
3999 ;; after or during reload as we don't want these patterns to start
4000 ;; kicking in during the combiner.
4002 (define_insn "aarch64_movdi_<mode>low"
4003 [(set (match_operand:DI 0 "register_operand" "=r")
4004 (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
4005 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4007 [(set_attr "type" "f_mrc")
4008 (set_attr "length" "4")
4011 (define_insn "aarch64_movdi_<mode>high"
4012 [(set (match_operand:DI 0 "register_operand" "=r")
4014 (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
4016 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4017 "fmov\\t%x0, %1.d[1]"
4018 [(set_attr "type" "f_mrc")
4019 (set_attr "length" "4")
4022 (define_insn "aarch64_mov<mode>high_di"
4023 [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
4024 (const_int 64) (const_int 64))
4025 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4026 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4027 "fmov\\t%0.d[1], %x1"
4028 [(set_attr "type" "f_mcr")
4029 (set_attr "length" "4")
4032 (define_insn "aarch64_mov<mode>low_di"
4033 [(set (match_operand:TX 0 "register_operand" "=w")
4034 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4035 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4037 [(set_attr "type" "f_mcr")
4038 (set_attr "length" "4")
4041 (define_insn "aarch64_movtilow_tilow"
4042 [(set (match_operand:TI 0 "register_operand" "=w")
4044 (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
4045 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4047 [(set_attr "type" "fmov")
4048 (set_attr "length" "4")
4051 ;; There is a deliberate reason why the parameters of high and lo_sum's
4052 ;; don't have modes for ADRP and ADD instructions. This is to allow high
4053 ;; and lo_sum's to be used with the labels defining the jump tables in
4056 (define_expand "add_losym"
4057 [(set (match_operand 0 "register_operand" "=r")
4058 (lo_sum (match_operand 1 "register_operand" "r")
4059 (match_operand 2 "aarch64_valid_symref" "S")))]
4062 machine_mode mode = GET_MODE (operands[0]);
4064 emit_insn ((mode == DImode
4066 : gen_add_losym_si) (operands[0],
4072 (define_insn "add_losym_<mode>"
4073 [(set (match_operand:P 0 "register_operand" "=r")
4074 (lo_sum:P (match_operand:P 1 "register_operand" "r")
4075 (match_operand 2 "aarch64_valid_symref" "S")))]
4077 "add\\t%<w>0, %<w>1, :lo12:%a2"
4078 [(set_attr "type" "alu_imm")]
4081 (define_insn "ldr_got_small_<mode>"
4082 [(set (match_operand:PTR 0 "register_operand" "=r")
4083 (unspec:PTR [(mem:PTR (lo_sum:PTR
4084 (match_operand:PTR 1 "register_operand" "r")
4085 (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
4086 UNSPEC_GOTSMALLPIC))]
4088 "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
4089 [(set_attr "type" "load1")]
4092 (define_insn "ldr_got_small_sidi"
4093 [(set (match_operand:DI 0 "register_operand" "=r")
4095 (unspec:SI [(mem:SI (lo_sum:DI
4096 (match_operand:DI 1 "register_operand" "r")
4097 (match_operand:DI 2 "aarch64_valid_symref" "S")))]
4098 UNSPEC_GOTSMALLPIC)))]
4100 "ldr\\t%w0, [%1, #:got_lo12:%a2]"
4101 [(set_attr "type" "load1")]
4104 (define_insn "ldr_got_tiny"
4105 [(set (match_operand:DI 0 "register_operand" "=r")
4106 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
4107 UNSPEC_GOTTINYPIC))]
4110 [(set_attr "type" "load1")]
4113 (define_insn "aarch64_load_tp_hard"
4114 [(set (match_operand:DI 0 "register_operand" "=r")
4115 (unspec:DI [(const_int 0)] UNSPEC_TLS))]
4117 "mrs\\t%0, tpidr_el0"
4118 [(set_attr "type" "mrs")]
4121 ;; The TLS ABI specifically requires that the compiler does not schedule
4122 ;; instructions in the TLS stubs, in order to enable linker relaxation.
4123 ;; Therefore we treat the stubs as an atomic sequence.
4124 (define_expand "tlsgd_small"
4125 [(parallel [(set (match_operand 0 "register_operand" "")
4126 (call (mem:DI (match_dup 2)) (const_int 1)))
4127 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
4128 (clobber (reg:DI LR_REGNUM))])]
4131 operands[2] = aarch64_tls_get_addr ();
4134 (define_insn "*tlsgd_small"
4135 [(set (match_operand 0 "register_operand" "")
4136 (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
4137 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
4138 (clobber (reg:DI LR_REGNUM))
4141 "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
4142 [(set_attr "type" "call")
4143 (set_attr "length" "16")])
4145 (define_insn "tlsie_small_<mode>"
4146 [(set (match_operand:PTR 0 "register_operand" "=r")
4147 (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
4148 UNSPEC_GOTSMALLTLS))]
4150 "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
4151 [(set_attr "type" "load1")
4152 (set_attr "length" "8")]
4155 (define_insn "tlsie_small_sidi"
4156 [(set (match_operand:DI 0 "register_operand" "=r")
4158 (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")]
4159 UNSPEC_GOTSMALLTLS)))]
4161 "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
4162 [(set_attr "type" "load1")
4163 (set_attr "length" "8")]
4166 (define_expand "tlsle_small"
4167 [(set (match_operand 0 "register_operand" "=r")
4168 (unspec [(match_operand 1 "register_operand" "r")
4169 (match_operand 2 "aarch64_tls_le_symref" "S")]
4170 UNSPEC_GOTSMALLTLS))]
4173 machine_mode mode = GET_MODE (operands[0]);
4174 emit_insn ((mode == DImode
4175 ? gen_tlsle_small_di
4176 : gen_tlsle_small_si) (operands[0],
4182 (define_insn "tlsle_small_<mode>"
4183 [(set (match_operand:P 0 "register_operand" "=r")
4184 (unspec:P [(match_operand:P 1 "register_operand" "r")
4185 (match_operand 2 "aarch64_tls_le_symref" "S")]
4186 UNSPEC_GOTSMALLTLS))]
4188 "add\\t%<w>0, %<w>1, #%G2\;add\\t%<w>0, %<w>0, #%L2"
4189 [(set_attr "type" "alu_sreg")
4190 (set_attr "length" "8")]
4193 (define_insn "tlsdesc_small_<mode>"
4194 [(set (reg:PTR R0_REGNUM)
4195 (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
4197 (clobber (reg:DI LR_REGNUM))
4198 (clobber (reg:CC CC_REGNUM))
4199 (clobber (match_scratch:DI 1 "=r"))]
4201 "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
4202 [(set_attr "type" "call")
4203 (set_attr "length" "16")])
4205 (define_insn "stack_tie"
4206 [(set (mem:BLK (scratch))
4207 (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
4208 (match_operand:DI 1 "register_operand" "rk")]
4212 [(set_attr "length" "0")]
4215 ;; Named pattern for expanding thread pointer reference.
4216 (define_expand "get_thread_pointerdi"
4217 [(match_operand:DI 0 "register_operand" "=r")]
4220 rtx tmp = aarch64_load_tp (operands[0]);
4221 if (tmp != operands[0])
4222 emit_move_insn (operands[0], tmp);
4226 ;; Named patterns for stack smashing protection.
4227 (define_expand "stack_protect_set"
4228 [(match_operand 0 "memory_operand")
4229 (match_operand 1 "memory_operand")]
4232 machine_mode mode = GET_MODE (operands[0]);
4234 emit_insn ((mode == DImode
4235 ? gen_stack_protect_set_di
4236 : gen_stack_protect_set_si) (operands[0], operands[1]));
4240 (define_insn "stack_protect_set_<mode>"
4241 [(set (match_operand:PTR 0 "memory_operand" "=m")
4242 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
4244 (set (match_scratch:PTR 2 "=&r") (const_int 0))]
4246 "ldr\\t%<w>2, %1\;str\\t%<w>2, %0\;mov\t%<w>2,0"
4247 [(set_attr "length" "12")
4248 (set_attr "type" "multiple")])
4250 (define_expand "stack_protect_test"
4251 [(match_operand 0 "memory_operand")
4252 (match_operand 1 "memory_operand")
4257 machine_mode mode = GET_MODE (operands[0]);
4259 result = gen_reg_rtx(mode);
4261 emit_insn ((mode == DImode
4262 ? gen_stack_protect_test_di
4263 : gen_stack_protect_test_si) (result,
4268 emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4269 result, const0_rtx, operands[2]));
4271 emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4272 result, const0_rtx, operands[2]));
4276 (define_insn "stack_protect_test_<mode>"
4277 [(set (match_operand:PTR 0 "register_operand" "=r")
4278 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
4279 (match_operand:PTR 2 "memory_operand" "m")]
4281 (clobber (match_scratch:PTR 3 "=&r"))]
4283 "ldr\t%<w>3, %x1\;ldr\t%<w>0, %x2\;eor\t%<w>0, %<w>3, %<w>0"
4284 [(set_attr "length" "12")
4285 (set_attr "type" "multiple")])
4287 ;; Write Floating-point Control Register.
4288 (define_insn "set_fpcr"
4289 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
4292 [(set_attr "type" "mrs")])
4294 ;; Read Floating-point Control Register.
4295 (define_insn "get_fpcr"
4296 [(set (match_operand:SI 0 "register_operand" "=r")
4297 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
4300 [(set_attr "type" "mrs")])
4302 ;; Write Floating-point Status Register.
4303 (define_insn "set_fpsr"
4304 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
4307 [(set_attr "type" "mrs")])
4309 ;; Read Floating-point Status Register.
4310 (define_insn "get_fpsr"
4311 [(set (match_operand:SI 0 "register_operand" "=r")
4312 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
4315 [(set_attr "type" "mrs")])
4318 ;; Define the subtract-one-and-jump insns so loop.c
4319 ;; knows what to generate.
4320 (define_expand "doloop_end"
4321 [(use (match_operand 0 "" "")) ; loop pseudo
4322 (use (match_operand 1 "" ""))] ; label
4323 "optimize > 0 && flag_modulo_sched"
4332 /* Currently SMS relies on the do-loop pattern to recognize loops
4333 where (1) the control part consists of all insns defining and/or
4334 using a certain 'count' register and (2) the loop count can be
4335 adjusted by modifying this register prior to the loop.
4336 ??? The possible introduction of a new block to initialize the
4337 new IV can potentially affect branch optimizations. */
4339 if (GET_MODE (operands[0]) != DImode)
4343 insn = emit_insn (gen_adddi3_compare0 (s0, s0, GEN_INT (-1)));
4345 cmp = XVECEXP (PATTERN (insn), 0, 0);
4346 cc_reg = SET_DEST (cmp);
4347 bcomp = gen_rtx_NE (VOIDmode, cc_reg, const0_rtx);
4348 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
4349 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4350 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
4356 (include "aarch64-simd.md")
4358 ;; Atomic Operations
4359 (include "atomics.md")
4361 ;; ldp/stp peephole patterns
4362 (include "aarch64-ldpstp.md")