1 ;; Machine description for AArch64 architecture.
2 ;; Copyright (C) 2009-2015 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-a57.md")
192 (include "thunderx.md")
193 (include "../arm/xgene1.md")
195 ;; -------------------------------------------------------------------
196 ;; Jumps and other miscellaneous insns
197 ;; -------------------------------------------------------------------
199 (define_insn "indirect_jump"
200 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
203 [(set_attr "type" "branch")]
207 [(set (pc) (label_ref (match_operand 0 "" "")))]
210 [(set_attr "type" "branch")]
213 (define_expand "cbranch<mode>4"
214 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
215 [(match_operand:GPI 1 "register_operand" "")
216 (match_operand:GPI 2 "aarch64_plus_operand" "")])
217 (label_ref (match_operand 3 "" ""))
221 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
223 operands[2] = const0_rtx;
227 (define_expand "cbranch<mode>4"
228 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
229 [(match_operand:GPF 1 "register_operand" "")
230 (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
231 (label_ref (match_operand 3 "" ""))
235 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
237 operands[2] = const0_rtx;
241 (define_expand "cbranchcc4"
242 [(set (pc) (if_then_else
243 (match_operator 0 "aarch64_comparison_operator"
244 [(match_operand 1 "cc_register" "")
245 (match_operand 2 "const0_operand")])
246 (label_ref (match_operand 3 "" ""))
251 (define_insn "ccmp_and<mode>"
252 [(set (match_operand 1 "ccmp_cc_register" "")
255 (match_operator 4 "aarch64_comparison_operator"
256 [(match_operand 0 "ccmp_cc_register" "")
258 (match_operator 5 "aarch64_comparison_operator"
259 [(match_operand:GPI 2 "register_operand" "r,r,r")
260 (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")]))
262 "aarch64_ccmp_mode_to_code (GET_MODE (operands[1])) == GET_CODE (operands[5])"
264 ccmp\\t%<w>2, %<w>3, %k5, %m4
265 ccmp\\t%<w>2, %<w>3, %k5, %m4
266 ccmn\\t%<w>2, #%n3, %k5, %m4"
267 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
270 (define_insn "ccmp_ior<mode>"
271 [(set (match_operand 1 "ccmp_cc_register" "")
274 (match_operator 4 "aarch64_comparison_operator"
275 [(match_operand 0 "ccmp_cc_register" "")
277 (match_operator 5 "aarch64_comparison_operator"
278 [(match_operand:GPI 2 "register_operand" "r,r,r")
279 (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")]))
281 "aarch64_ccmp_mode_to_code (GET_MODE (operands[1])) == GET_CODE (operands[5])"
283 ccmp\\t%<w>2, %<w>3, %K5, %M4
284 ccmp\\t%<w>2, %<w>3, %K5, %M4
285 ccmn\\t%<w>2, #%n3, %K5, %M4"
286 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
289 (define_expand "cmp<mode>"
290 [(set (match_operand 0 "cc_register" "")
291 (match_operator:CC 1 "aarch64_comparison_operator"
292 [(match_operand:GPI 2 "register_operand" "")
293 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
296 operands[1] = gen_rtx_fmt_ee (COMPARE,
297 SELECT_CC_MODE (GET_CODE (operands[1]),
298 operands[2], operands[3]),
299 operands[2], operands[3]);
303 (define_insn "*condjump"
304 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
305 [(match_operand 1 "cc_register" "") (const_int 0)])
306 (label_ref (match_operand 2 "" ""))
310 [(set_attr "type" "branch")]
313 (define_expand "casesi"
314 [(match_operand:SI 0 "register_operand" "") ; Index
315 (match_operand:SI 1 "const_int_operand" "") ; Lower bound
316 (match_operand:SI 2 "const_int_operand" "") ; Total range
317 (match_operand:DI 3 "" "") ; Table label
318 (match_operand:DI 4 "" "")] ; Out of range label
321 if (operands[1] != const0_rtx)
323 rtx reg = gen_reg_rtx (SImode);
325 /* Canonical RTL says that if you have:
329 then this should be emitted as:
333 The use of trunc_int_for_mode ensures that the resulting
334 constant can be represented in SImode, this is important
335 for the corner case where operand[1] is INT_MIN. */
337 operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
339 if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
340 (operands[1], SImode))
341 operands[1] = force_reg (SImode, operands[1]);
342 emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
346 if (!aarch64_plus_operand (operands[2], SImode))
347 operands[2] = force_reg (SImode, operands[2]);
348 emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
350 operands[0], operands[2], operands[4]));
352 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
353 emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
359 (define_insn "casesi_dispatch"
362 (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
363 (match_operand:SI 1 "register_operand" "r")]
365 (clobber (reg:CC CC_REGNUM))
366 (clobber (match_scratch:DI 3 "=r"))
367 (clobber (match_scratch:DI 4 "=r"))
368 (use (label_ref (match_operand 2 "" "")))])]
371 return aarch64_output_casesi (operands);
373 [(set_attr "length" "16")
374 (set_attr "type" "branch")]
378 [(unspec[(const_int 0)] UNSPEC_NOP)]
381 [(set_attr "type" "no_insn")]
384 (define_insn "prefetch"
385 [(prefetch (match_operand:DI 0 "address_operand" "r")
386 (match_operand:QI 1 "const_int_operand" "")
387 (match_operand:QI 2 "const_int_operand" ""))]
390 const char * pftype[2][4] =
392 {"prfm\\tPLDL1STRM, %a0",
393 "prfm\\tPLDL3KEEP, %a0",
394 "prfm\\tPLDL2KEEP, %a0",
395 "prfm\\tPLDL1KEEP, %a0"},
396 {"prfm\\tPSTL1STRM, %a0",
397 "prfm\\tPSTL3KEEP, %a0",
398 "prfm\\tPSTL2KEEP, %a0",
399 "prfm\\tPSTL1KEEP, %a0"},
402 int locality = INTVAL (operands[2]);
404 gcc_assert (IN_RANGE (locality, 0, 3));
406 return pftype[INTVAL(operands[1])][locality];
408 [(set_attr "type" "load1")]
412 [(trap_if (const_int 1) (const_int 8))]
415 [(set_attr "type" "trap")])
417 (define_expand "prologue"
418 [(clobber (const_int 0))]
421 aarch64_expand_prologue ();
426 (define_expand "epilogue"
427 [(clobber (const_int 0))]
430 aarch64_expand_epilogue (false);
435 (define_expand "sibcall_epilogue"
436 [(clobber (const_int 0))]
439 aarch64_expand_epilogue (true);
444 (define_insn "*do_return"
448 [(set_attr "type" "branch")]
451 (define_expand "return"
453 "aarch64_use_return_insn_p ()"
457 (define_insn "simple_return"
461 [(set_attr "type" "branch")]
464 (define_insn "eh_return"
465 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
469 [(set_attr "type" "branch")]
474 [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
477 [(set (match_dup 1) (match_dup 0))]
479 operands[1] = aarch64_final_eh_return_addr ();
483 (define_insn "*cb<optab><mode>1"
484 [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
486 (label_ref (match_operand 1 "" ""))
490 [(set_attr "type" "branch")]
494 (define_insn "*tb<optab><mode>1"
495 [(set (pc) (if_then_else
496 (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
498 (match_operand 1 "const_int_operand" "n"))
500 (label_ref (match_operand 2 "" ""))
502 (clobber (reg:CC CC_REGNUM))]
505 if (get_attr_length (insn) == 8)
507 operands[1] = GEN_INT (HOST_WIDE_INT_1U << UINTVAL (operands[1]));
508 return "tst\t%<w>0, %1\;<bcond>\t%l2";
511 return "<tbz>\t%<w>0, %1, %l2";
513 [(set_attr "type" "branch")
515 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
516 (lt (minus (match_dup 2) (pc)) (const_int 32764)))
521 (define_insn "*cb<optab><mode>1"
522 [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
524 (label_ref (match_operand 1 "" ""))
526 (clobber (reg:CC CC_REGNUM))]
529 if (get_attr_length (insn) == 8)
532 uint64_t val = ((uint64_t ) 1)
533 << (GET_MODE_SIZE (<MODE>mode) * BITS_PER_UNIT - 1);
534 sprintf (buf, "tst\t%%<w>0, %" PRId64, val);
535 output_asm_insn (buf, operands);
536 return "<bcond>\t%l1";
539 return "<tbz>\t%<w>0, <sizem1>, %l1";
541 [(set_attr "type" "branch")
543 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
544 (lt (minus (match_dup 1) (pc)) (const_int 32764)))
549 ;; -------------------------------------------------------------------
550 ;; Subroutine calls and sibcalls
551 ;; -------------------------------------------------------------------
553 (define_expand "call_internal"
554 [(parallel [(call (match_operand 0 "memory_operand" "")
555 (match_operand 1 "general_operand" ""))
556 (use (match_operand 2 "" ""))
557 (clobber (reg:DI LR_REGNUM))])])
559 (define_expand "call"
560 [(parallel [(call (match_operand 0 "memory_operand" "")
561 (match_operand 1 "general_operand" ""))
562 (use (match_operand 2 "" ""))
563 (clobber (reg:DI LR_REGNUM))])]
569 /* In an untyped call, we can get NULL for operand 2. */
570 if (operands[2] == NULL)
571 operands[2] = const0_rtx;
573 /* Decide if we should generate indirect calls by loading the
574 64-bit address of the callee into a register before performing
575 the branch-and-link. */
576 callee = XEXP (operands[0], 0);
577 if (GET_CODE (callee) == SYMBOL_REF
578 ? aarch64_is_long_call_p (callee)
580 XEXP (operands[0], 0) = force_reg (Pmode, callee);
582 pat = gen_call_internal (operands[0], operands[1], operands[2]);
583 aarch64_emit_call_insn (pat);
588 (define_insn "*call_reg"
589 [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
590 (match_operand 1 "" ""))
591 (use (match_operand 2 "" ""))
592 (clobber (reg:DI LR_REGNUM))]
595 [(set_attr "type" "call")]
598 (define_insn "*call_symbol"
599 [(call (mem:DI (match_operand:DI 0 "" ""))
600 (match_operand 1 "" ""))
601 (use (match_operand 2 "" ""))
602 (clobber (reg:DI LR_REGNUM))]
603 "GET_CODE (operands[0]) == SYMBOL_REF
604 && !aarch64_is_long_call_p (operands[0])"
606 [(set_attr "type" "call")]
609 (define_expand "call_value_internal"
610 [(parallel [(set (match_operand 0 "" "")
611 (call (match_operand 1 "memory_operand" "")
612 (match_operand 2 "general_operand" "")))
613 (use (match_operand 3 "" ""))
614 (clobber (reg:DI LR_REGNUM))])])
616 (define_expand "call_value"
617 [(parallel [(set (match_operand 0 "" "")
618 (call (match_operand 1 "memory_operand" "")
619 (match_operand 2 "general_operand" "")))
620 (use (match_operand 3 "" ""))
621 (clobber (reg:DI LR_REGNUM))])]
627 /* In an untyped call, we can get NULL for operand 3. */
628 if (operands[3] == NULL)
629 operands[3] = const0_rtx;
631 /* Decide if we should generate indirect calls by loading the
632 64-bit address of the callee into a register before performing
633 the branch-and-link. */
634 callee = XEXP (operands[1], 0);
635 if (GET_CODE (callee) == SYMBOL_REF
636 ? aarch64_is_long_call_p (callee)
638 XEXP (operands[1], 0) = force_reg (Pmode, callee);
640 pat = gen_call_value_internal (operands[0], operands[1], operands[2],
642 aarch64_emit_call_insn (pat);
647 (define_insn "*call_value_reg"
648 [(set (match_operand 0 "" "")
649 (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
650 (match_operand 2 "" "")))
651 (use (match_operand 3 "" ""))
652 (clobber (reg:DI LR_REGNUM))]
655 [(set_attr "type" "call")]
659 (define_insn "*call_value_symbol"
660 [(set (match_operand 0 "" "")
661 (call (mem:DI (match_operand:DI 1 "" ""))
662 (match_operand 2 "" "")))
663 (use (match_operand 3 "" ""))
664 (clobber (reg:DI LR_REGNUM))]
665 "GET_CODE (operands[1]) == SYMBOL_REF
666 && !aarch64_is_long_call_p (operands[1])"
668 [(set_attr "type" "call")]
671 (define_expand "sibcall_internal"
672 [(parallel [(call (match_operand 0 "memory_operand" "")
673 (match_operand 1 "general_operand" ""))
675 (use (match_operand 2 "" ""))])])
677 (define_expand "sibcall"
678 [(parallel [(call (match_operand 0 "memory_operand" "")
679 (match_operand 1 "general_operand" ""))
681 (use (match_operand 2 "" ""))])]
686 if (!REG_P (XEXP (operands[0], 0))
687 && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
688 XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
690 if (operands[2] == NULL_RTX)
691 operands[2] = const0_rtx;
693 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
694 aarch64_emit_call_insn (pat);
699 (define_expand "sibcall_value_internal"
700 [(parallel [(set (match_operand 0 "" "")
701 (call (match_operand 1 "memory_operand" "")
702 (match_operand 2 "general_operand" "")))
704 (use (match_operand 3 "" ""))])])
706 (define_expand "sibcall_value"
707 [(parallel [(set (match_operand 0 "" "")
708 (call (match_operand 1 "memory_operand" "")
709 (match_operand 2 "general_operand" "")))
711 (use (match_operand 3 "" ""))])]
716 if (!REG_P (XEXP (operands[1], 0))
717 && (GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF))
718 XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
720 if (operands[3] == NULL_RTX)
721 operands[3] = const0_rtx;
723 pat = gen_sibcall_value_internal (operands[0], operands[1], operands[2],
725 aarch64_emit_call_insn (pat);
730 (define_insn "*sibcall_insn"
731 [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucs, Usf"))
732 (match_operand 1 "" ""))
734 (use (match_operand 2 "" ""))]
735 "SIBLING_CALL_P (insn)"
739 [(set_attr "type" "branch, branch")]
742 (define_insn "*sibcall_value_insn"
743 [(set (match_operand 0 "" "")
745 (match_operand:DI 1 "aarch64_call_insn_operand" "Ucs, Usf"))
746 (match_operand 2 "" "")))
748 (use (match_operand 3 "" ""))]
749 "SIBLING_CALL_P (insn)"
753 [(set_attr "type" "branch, branch")]
756 ;; Call subroutine returning any type.
758 (define_expand "untyped_call"
759 [(parallel [(call (match_operand 0 "")
762 (match_operand 2 "")])]
767 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
769 for (i = 0; i < XVECLEN (operands[2], 0); i++)
771 rtx set = XVECEXP (operands[2], 0, i);
772 emit_move_insn (SET_DEST (set), SET_SRC (set));
775 /* The optimizer does not know that the call sets the function value
776 registers we stored in the result block. We avoid problems by
777 claiming that all hard registers are used and clobbered at this
779 emit_insn (gen_blockage ());
783 ;; -------------------------------------------------------------------
785 ;; -------------------------------------------------------------------
787 (define_expand "mov<mode>"
788 [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
789 (match_operand:SHORT 1 "general_operand" ""))]
792 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
793 operands[1] = force_reg (<MODE>mode, operands[1]);
797 (define_insn "*mov<mode>_aarch64"
798 [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r, *w,r,*w, m, m, r,*w,*w")
799 (match_operand:SHORT 1 "general_operand" " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
800 "(register_operand (operands[0], <MODE>mode)
801 || aarch64_reg_or_zero (operands[1], <MODE>mode))"
803 switch (which_alternative)
806 return "mov\t%w0, %w1";
808 return "mov\t%w0, %1";
810 return aarch64_output_scalar_simd_mov_immediate (operands[1],
813 return "ldr<size>\t%w0, %1";
815 return "ldr\t%<size>0, %1";
817 return "str<size>\t%w1, %0";
819 return "str\t%<size>1, %0";
821 return "umov\t%w0, %1.<v>[0]";
823 return "dup\t%0.<Vallxd>, %w1";
825 return "dup\t%<Vetype>0, %1.<v>[0]";
830 [(set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
831 neon_to_gp<q>,neon_from_gp<q>,neon_dup")
832 (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")]
835 (define_expand "mov<mode>"
836 [(set (match_operand:GPI 0 "nonimmediate_operand" "")
837 (match_operand:GPI 1 "general_operand" ""))]
840 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
841 operands[1] = force_reg (<MODE>mode, operands[1]);
843 /* FIXME: RR we still need to fix up what we are doing with
844 symbol_refs and other types of constants. */
845 if (CONSTANT_P (operands[1])
846 && !CONST_INT_P (operands[1]))
848 aarch64_expand_mov_immediate (operands[0], operands[1]);
854 (define_insn_and_split "*movsi_aarch64"
855 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,r,*w,m, m,r,r ,*w, r,*w")
856 (match_operand:SI 1 "aarch64_mov_operand" " r,r,k,M,n,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
857 "(register_operand (operands[0], SImode)
858 || aarch64_reg_or_zero (operands[1], SImode))"
874 "CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), SImode)
875 && GP_REGNUM_P (REGNO (operands[0]))"
878 aarch64_expand_mov_immediate (operands[0], operands[1]);
881 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
882 adr,adr,f_mcr,f_mrc,fmov")
883 (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
886 (define_insn_and_split "*movdi_aarch64"
887 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,r,*w,m, m,r,r, *w, r,*w,w")
888 (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,n,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))]
889 "(register_operand (operands[0], DImode)
890 || aarch64_reg_or_zero (operands[1], DImode))"
907 "(CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), DImode))
908 && GP_REGNUM_P (REGNO (operands[0]))"
911 aarch64_expand_mov_immediate (operands[0], operands[1]);
914 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
915 adr,adr,f_mcr,f_mrc,fmov,fmov")
916 (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
917 (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
920 (define_insn "insv_imm<mode>"
921 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
923 (match_operand:GPI 1 "const_int_operand" "n"))
924 (match_operand:GPI 2 "const_int_operand" "n"))]
925 "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
926 && UINTVAL (operands[1]) % 16 == 0"
927 "movk\\t%<w>0, %X2, lsl %1"
928 [(set_attr "type" "mov_imm")]
931 (define_expand "movti"
932 [(set (match_operand:TI 0 "nonimmediate_operand" "")
933 (match_operand:TI 1 "general_operand" ""))]
936 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
937 operands[1] = force_reg (TImode, operands[1]);
941 (define_insn "*movti_aarch64"
942 [(set (match_operand:TI 0
943 "nonimmediate_operand" "=r, *w,r ,*w,r ,Ump,Ump,*w,m")
945 "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r ,Z , m,*w"))]
946 "(register_operand (operands[0], TImode)
947 || aarch64_reg_or_zero (operands[1], TImode))"
952 orr\\t%0.16b, %1.16b, %1.16b
958 [(set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \
959 load2,store2,store2,f_loadd,f_stored")
960 (set_attr "length" "8,8,8,4,4,4,4,4,4")
961 (set_attr "simd" "*,*,*,yes,*,*,*,*,*")
962 (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
965 ;; Split a TImode register-register or register-immediate move into
966 ;; its component DImode pieces, taking care to handle overlapping
967 ;; source and dest registers.
969 [(set (match_operand:TI 0 "register_operand" "")
970 (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
971 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
974 aarch64_split_128bit_move (operands[0], operands[1]);
978 (define_expand "mov<mode>"
979 [(set (match_operand:GPF 0 "nonimmediate_operand" "")
980 (match_operand:GPF 1 "general_operand" ""))]
985 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
989 if (GET_CODE (operands[0]) == MEM)
990 operands[1] = force_reg (<MODE>mode, operands[1]);
994 (define_insn "*movsf_aarch64"
995 [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
996 (match_operand:SF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
997 "TARGET_FLOAT && (register_operand (operands[0], SFmode)
998 || register_operand (operands[1], SFmode))"
1009 [(set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
1010 f_loads,f_stores,f_loads,f_stores,mov_reg")]
1013 (define_insn "*movdf_aarch64"
1014 [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
1015 (match_operand:DF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
1016 "TARGET_FLOAT && (register_operand (operands[0], DFmode)
1017 || register_operand (operands[1], DFmode))"
1028 [(set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
1029 f_loadd,f_stored,f_loadd,f_stored,mov_reg")]
1032 (define_expand "movtf"
1033 [(set (match_operand:TF 0 "nonimmediate_operand" "")
1034 (match_operand:TF 1 "general_operand" ""))]
1039 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
1043 if (GET_CODE (operands[0]) == MEM)
1044 operands[1] = force_reg (TFmode, operands[1]);
1048 (define_insn "*movtf_aarch64"
1049 [(set (match_operand:TF 0
1050 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
1052 "general_operand" " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
1053 "TARGET_FLOAT && (register_operand (operands[0], TFmode)
1054 || register_operand (operands[1], TFmode))"
1056 orr\\t%0.16b, %1.16b, %1.16b
1066 [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,fconstd,fconstd,\
1067 f_loadd,f_stored,neon_load1_2reg,neon_store1_2reg")
1068 (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
1069 (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
1070 (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
1074 [(set (match_operand:TF 0 "register_operand" "")
1075 (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
1076 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
1079 aarch64_split_128bit_move (operands[0], operands[1]);
1086 ;; 2 is size of move in bytes
1089 (define_expand "movmemdi"
1090 [(match_operand:BLK 0 "memory_operand")
1091 (match_operand:BLK 1 "memory_operand")
1092 (match_operand:DI 2 "immediate_operand")
1093 (match_operand:DI 3 "immediate_operand")]
1096 if (aarch64_expand_movmem (operands))
1102 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1103 ;; fairly lax checking on the second memory operation.
1104 (define_insn "load_pairsi"
1105 [(set (match_operand:SI 0 "register_operand" "=r,*w")
1106 (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1107 (set (match_operand:SI 2 "register_operand" "=r,*w")
1108 (match_operand:SI 3 "memory_operand" "m,m"))]
1109 "rtx_equal_p (XEXP (operands[3], 0),
1110 plus_constant (Pmode,
1111 XEXP (operands[1], 0),
1112 GET_MODE_SIZE (SImode)))"
1116 [(set_attr "type" "load2,neon_load1_2reg")
1117 (set_attr "fp" "*,yes")]
1120 (define_insn "load_pairdi"
1121 [(set (match_operand:DI 0 "register_operand" "=r,*w")
1122 (match_operand:DI 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1123 (set (match_operand:DI 2 "register_operand" "=r,*w")
1124 (match_operand:DI 3 "memory_operand" "m,m"))]
1125 "rtx_equal_p (XEXP (operands[3], 0),
1126 plus_constant (Pmode,
1127 XEXP (operands[1], 0),
1128 GET_MODE_SIZE (DImode)))"
1132 [(set_attr "type" "load2,neon_load1_2reg")
1133 (set_attr "fp" "*,yes")]
1137 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1138 ;; fairly lax checking on the second memory operation.
1139 (define_insn "store_pairsi"
1140 [(set (match_operand:SI 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1141 (match_operand:SI 1 "aarch64_reg_or_zero" "rZ,*w"))
1142 (set (match_operand:SI 2 "memory_operand" "=m,m")
1143 (match_operand:SI 3 "aarch64_reg_or_zero" "rZ,*w"))]
1144 "rtx_equal_p (XEXP (operands[2], 0),
1145 plus_constant (Pmode,
1146 XEXP (operands[0], 0),
1147 GET_MODE_SIZE (SImode)))"
1151 [(set_attr "type" "store2,neon_store1_2reg")
1152 (set_attr "fp" "*,yes")]
1155 (define_insn "store_pairdi"
1156 [(set (match_operand:DI 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1157 (match_operand:DI 1 "aarch64_reg_or_zero" "rZ,*w"))
1158 (set (match_operand:DI 2 "memory_operand" "=m,m")
1159 (match_operand:DI 3 "aarch64_reg_or_zero" "rZ,*w"))]
1160 "rtx_equal_p (XEXP (operands[2], 0),
1161 plus_constant (Pmode,
1162 XEXP (operands[0], 0),
1163 GET_MODE_SIZE (DImode)))"
1167 [(set_attr "type" "store2,neon_store1_2reg")
1168 (set_attr "fp" "*,yes")]
1171 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1172 ;; fairly lax checking on the second memory operation.
1173 (define_insn "load_pairsf"
1174 [(set (match_operand:SF 0 "register_operand" "=w,*r")
1175 (match_operand:SF 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1176 (set (match_operand:SF 2 "register_operand" "=w,*r")
1177 (match_operand:SF 3 "memory_operand" "m,m"))]
1178 "rtx_equal_p (XEXP (operands[3], 0),
1179 plus_constant (Pmode,
1180 XEXP (operands[1], 0),
1181 GET_MODE_SIZE (SFmode)))"
1185 [(set_attr "type" "neon_load1_2reg,load2")
1186 (set_attr "fp" "yes,*")]
1189 (define_insn "load_pairdf"
1190 [(set (match_operand:DF 0 "register_operand" "=w,*r")
1191 (match_operand:DF 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1192 (set (match_operand:DF 2 "register_operand" "=w,*r")
1193 (match_operand:DF 3 "memory_operand" "m,m"))]
1194 "rtx_equal_p (XEXP (operands[3], 0),
1195 plus_constant (Pmode,
1196 XEXP (operands[1], 0),
1197 GET_MODE_SIZE (DFmode)))"
1201 [(set_attr "type" "neon_load1_2reg,load2")
1202 (set_attr "fp" "yes,*")]
1205 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1206 ;; fairly lax checking on the second memory operation.
1207 (define_insn "store_pairsf"
1208 [(set (match_operand:SF 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1209 (match_operand:SF 1 "register_operand" "w,*r"))
1210 (set (match_operand:SF 2 "memory_operand" "=m,m")
1211 (match_operand:SF 3 "register_operand" "w,*r"))]
1212 "rtx_equal_p (XEXP (operands[2], 0),
1213 plus_constant (Pmode,
1214 XEXP (operands[0], 0),
1215 GET_MODE_SIZE (SFmode)))"
1219 [(set_attr "type" "neon_store1_2reg,store2")
1220 (set_attr "fp" "yes,*")]
1223 (define_insn "store_pairdf"
1224 [(set (match_operand:DF 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1225 (match_operand:DF 1 "register_operand" "w,*r"))
1226 (set (match_operand:DF 2 "memory_operand" "=m,m")
1227 (match_operand:DF 3 "register_operand" "w,*r"))]
1228 "rtx_equal_p (XEXP (operands[2], 0),
1229 plus_constant (Pmode,
1230 XEXP (operands[0], 0),
1231 GET_MODE_SIZE (DFmode)))"
1235 [(set_attr "type" "neon_store1_2reg,store2")
1236 (set_attr "fp" "yes,*")]
1239 ;; Load pair with post-index writeback. This is primarily used in function
1241 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
1243 [(set (match_operand:P 0 "register_operand" "=k")
1244 (plus:P (match_operand:P 1 "register_operand" "0")
1245 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1246 (set (match_operand:GPI 2 "register_operand" "=r")
1247 (mem:GPI (match_dup 1)))
1248 (set (match_operand:GPI 3 "register_operand" "=r")
1249 (mem:GPI (plus:P (match_dup 1)
1250 (match_operand:P 5 "const_int_operand" "n"))))])]
1251 "INTVAL (operands[5]) == GET_MODE_SIZE (<GPI:MODE>mode)"
1252 "ldp\\t%<w>2, %<w>3, [%1], %4"
1253 [(set_attr "type" "load2")]
1256 (define_insn "loadwb_pair<GPF:mode>_<P:mode>"
1258 [(set (match_operand:P 0 "register_operand" "=k")
1259 (plus:P (match_operand:P 1 "register_operand" "0")
1260 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1261 (set (match_operand:GPF 2 "register_operand" "=w")
1262 (mem:GPF (match_dup 1)))
1263 (set (match_operand:GPF 3 "register_operand" "=w")
1264 (mem:GPF (plus:P (match_dup 1)
1265 (match_operand:P 5 "const_int_operand" "n"))))])]
1266 "INTVAL (operands[5]) == GET_MODE_SIZE (<GPF:MODE>mode)"
1267 "ldp\\t%<w>2, %<w>3, [%1], %4"
1268 [(set_attr "type" "neon_load1_2reg")]
1271 ;; Store pair with pre-index writeback. This is primarily used in function
1273 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
1275 [(set (match_operand:P 0 "register_operand" "=&k")
1276 (plus:P (match_operand:P 1 "register_operand" "0")
1277 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1278 (set (mem:GPI (plus:P (match_dup 0)
1280 (match_operand:GPI 2 "register_operand" "r"))
1281 (set (mem:GPI (plus:P (match_dup 0)
1282 (match_operand:P 5 "const_int_operand" "n")))
1283 (match_operand:GPI 3 "register_operand" "r"))])]
1284 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1285 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1286 [(set_attr "type" "store2")]
1289 (define_insn "storewb_pair<GPF:mode>_<P:mode>"
1291 [(set (match_operand:P 0 "register_operand" "=&k")
1292 (plus:P (match_operand:P 1 "register_operand" "0")
1293 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1294 (set (mem:GPF (plus:P (match_dup 0)
1296 (match_operand:GPF 2 "register_operand" "w"))
1297 (set (mem:GPF (plus:P (match_dup 0)
1298 (match_operand:P 5 "const_int_operand" "n")))
1299 (match_operand:GPF 3 "register_operand" "w"))])]
1300 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPF:MODE>mode)"
1301 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1302 [(set_attr "type" "neon_store1_2reg<q>")]
1305 ;; -------------------------------------------------------------------
1306 ;; Sign/Zero extension
1307 ;; -------------------------------------------------------------------
1309 (define_expand "<optab>sidi2"
1310 [(set (match_operand:DI 0 "register_operand")
1311 (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1315 (define_insn "*extendsidi2_aarch64"
1316 [(set (match_operand:DI 0 "register_operand" "=r,r")
1317 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1322 [(set_attr "type" "extend,load1")]
1325 (define_insn "*load_pair_extendsidi2_aarch64"
1326 [(set (match_operand:DI 0 "register_operand" "=r")
1327 (sign_extend:DI (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump")))
1328 (set (match_operand:DI 2 "register_operand" "=r")
1329 (sign_extend:DI (match_operand:SI 3 "memory_operand" "m")))]
1330 "rtx_equal_p (XEXP (operands[3], 0),
1331 plus_constant (Pmode,
1332 XEXP (operands[1], 0),
1333 GET_MODE_SIZE (SImode)))"
1334 "ldpsw\\t%0, %2, %1"
1335 [(set_attr "type" "load2")]
1338 (define_insn "*zero_extendsidi2_aarch64"
1339 [(set (match_operand:DI 0 "register_operand" "=r,r")
1340 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1345 [(set_attr "type" "extend,load1")]
1348 (define_insn "*load_pair_zero_extendsidi2_aarch64"
1349 [(set (match_operand:DI 0 "register_operand" "=r")
1350 (zero_extend:DI (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump")))
1351 (set (match_operand:DI 2 "register_operand" "=r")
1352 (zero_extend:DI (match_operand:SI 3 "memory_operand" "m")))]
1353 "rtx_equal_p (XEXP (operands[3], 0),
1354 plus_constant (Pmode,
1355 XEXP (operands[1], 0),
1356 GET_MODE_SIZE (SImode)))"
1357 "ldp\\t%w0, %w2, %1"
1358 [(set_attr "type" "load2")]
1361 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1362 [(set (match_operand:GPI 0 "register_operand")
1363 (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1367 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1368 [(set (match_operand:GPI 0 "register_operand" "=r,r")
1369 (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1372 sxt<SHORT:size>\t%<GPI:w>0, %w1
1373 ldrs<SHORT:size>\t%<GPI:w>0, %1"
1374 [(set_attr "type" "extend,load1")]
1377 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1378 [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1379 (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1382 uxt<SHORT:size>\t%<GPI:w>0, %w1
1383 ldr<SHORT:size>\t%w0, %1
1384 ldr\t%<SHORT:size>0, %1"
1385 [(set_attr "type" "extend,load1,load1")]
1388 (define_expand "<optab>qihi2"
1389 [(set (match_operand:HI 0 "register_operand")
1390 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1394 (define_insn "*<optab>qihi2_aarch64"
1395 [(set (match_operand:HI 0 "register_operand" "=r,r")
1396 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1401 [(set_attr "type" "extend,load1")]
1404 ;; -------------------------------------------------------------------
1405 ;; Simple arithmetic
1406 ;; -------------------------------------------------------------------
1408 (define_expand "add<mode>3"
1410 (match_operand:GPI 0 "register_operand" "")
1411 (plus:GPI (match_operand:GPI 1 "register_operand" "")
1412 (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1415 if (! aarch64_plus_operand (operands[2], VOIDmode))
1417 HOST_WIDE_INT imm = INTVAL (operands[2]);
1419 if (aarch64_move_imm (imm, <MODE>mode) && can_create_pseudo_p ())
1421 rtx tmp = gen_reg_rtx (<MODE>mode);
1422 emit_move_insn (tmp, operands[2]);
1427 rtx subtarget = ((optimize && can_create_pseudo_p ())
1428 ? gen_reg_rtx (<MODE>mode) : operands[0]);
1431 imm = -(-imm & ~0xfff);
1435 emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1436 operands[1] = subtarget;
1437 operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1443 (define_insn "*addsi3_aarch64"
1445 (match_operand:SI 0 "register_operand" "=rk,rk,w,rk")
1447 (match_operand:SI 1 "register_operand" "%rk,rk,w,rk")
1448 (match_operand:SI 2 "aarch64_plus_operand" "I,r,w,J")))]
1453 add\\t%0.2s, %1.2s, %2.2s
1454 sub\\t%w0, %w1, #%n2"
1455 [(set_attr "type" "alu_imm,alu_sreg,neon_add,alu_imm")
1456 (set_attr "simd" "*,*,yes,*")]
1459 ;; zero_extend version of above
1460 (define_insn "*addsi3_aarch64_uxtw"
1462 (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1464 (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1465 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1470 sub\\t%w0, %w1, #%n2"
1471 [(set_attr "type" "alu_imm,alu_sreg,alu_imm")]
1474 (define_insn "*adddi3_aarch64"
1476 (match_operand:DI 0 "register_operand" "=rk,rk,rk,w")
1478 (match_operand:DI 1 "register_operand" "%rk,rk,rk,w")
1479 (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,w")))]
1484 sub\\t%x0, %x1, #%n2
1485 add\\t%d0, %d1, %d2"
1486 [(set_attr "type" "alu_imm,alu_sreg,alu_imm,neon_add")
1487 (set_attr "simd" "*,*,*,yes")]
1490 (define_expand "addti3"
1491 [(set (match_operand:TI 0 "register_operand" "")
1492 (plus:TI (match_operand:TI 1 "register_operand" "")
1493 (match_operand:TI 2 "register_operand" "")))]
1496 rtx low = gen_reg_rtx (DImode);
1497 emit_insn (gen_adddi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1498 gen_lowpart (DImode, operands[2])));
1500 rtx high = gen_reg_rtx (DImode);
1501 emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]),
1502 gen_highpart (DImode, operands[2])));
1504 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1505 emit_move_insn (gen_highpart (DImode, operands[0]), high);
1509 (define_insn "add<mode>3_compare0"
1510 [(set (reg:CC_NZ CC_REGNUM)
1512 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1513 (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1515 (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1516 (plus:GPI (match_dup 1) (match_dup 2)))]
1519 adds\\t%<w>0, %<w>1, %<w>2
1520 adds\\t%<w>0, %<w>1, %<w>2
1521 subs\\t%<w>0, %<w>1, #%n2"
1522 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1525 ;; zero_extend version of above
1526 (define_insn "*addsi3_compare0_uxtw"
1527 [(set (reg:CC_NZ CC_REGNUM)
1529 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1530 (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1532 (set (match_operand:DI 0 "register_operand" "=r,r,r")
1533 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1536 adds\\t%w0, %w1, %w2
1537 adds\\t%w0, %w1, %w2
1538 subs\\t%w0, %w1, #%n2"
1539 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1542 (define_insn "*adds_shift_imm_<mode>"
1543 [(set (reg:CC_NZ CC_REGNUM)
1545 (plus:GPI (ASHIFT:GPI
1546 (match_operand:GPI 1 "register_operand" "r")
1547 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1548 (match_operand:GPI 3 "register_operand" "r"))
1550 (set (match_operand:GPI 0 "register_operand" "=r")
1551 (plus:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))
1554 "adds\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1555 [(set_attr "type" "alus_shift_imm")]
1558 (define_insn "*subs_shift_imm_<mode>"
1559 [(set (reg:CC_NZ CC_REGNUM)
1561 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1563 (match_operand:GPI 2 "register_operand" "r")
1564 (match_operand:QI 3 "aarch64_shift_imm_<mode>" "n")))
1566 (set (match_operand:GPI 0 "register_operand" "=r")
1567 (minus:GPI (match_dup 1)
1568 (ASHIFT:GPI (match_dup 2) (match_dup 3))))]
1570 "subs\\t%<w>0, %<w>1, %<w>2, <shift> %3"
1571 [(set_attr "type" "alus_shift_imm")]
1574 (define_insn "*adds_mul_imm_<mode>"
1575 [(set (reg:CC_NZ CC_REGNUM)
1578 (match_operand:GPI 1 "register_operand" "r")
1579 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1580 (match_operand:GPI 3 "register_operand" "r"))
1582 (set (match_operand:GPI 0 "register_operand" "=r")
1583 (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1586 "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1587 [(set_attr "type" "alus_shift_imm")]
1590 (define_insn "*subs_mul_imm_<mode>"
1591 [(set (reg:CC_NZ CC_REGNUM)
1593 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1595 (match_operand:GPI 2 "register_operand" "r")
1596 (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1598 (set (match_operand:GPI 0 "register_operand" "=r")
1599 (minus:GPI (match_dup 1)
1600 (mult:GPI (match_dup 2) (match_dup 3))))]
1602 "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1603 [(set_attr "type" "alus_shift_imm")]
1606 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1607 [(set (reg:CC_NZ CC_REGNUM)
1610 (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1611 (match_operand:GPI 2 "register_operand" "r"))
1613 (set (match_operand:GPI 0 "register_operand" "=r")
1614 (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1616 "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1617 [(set_attr "type" "alus_ext")]
1620 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1621 [(set (reg:CC_NZ CC_REGNUM)
1623 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1625 (match_operand:ALLX 2 "register_operand" "r")))
1627 (set (match_operand:GPI 0 "register_operand" "=r")
1628 (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1630 "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1631 [(set_attr "type" "alus_ext")]
1634 (define_insn "*adds_<optab><ALLX:mode>_shift_<GPI:mode>"
1635 [(set (reg:CC_NZ CC_REGNUM)
1637 (plus:GPI (ashift:GPI
1639 (match_operand:ALLX 1 "register_operand" "r"))
1640 (match_operand 2 "aarch64_imm3" "Ui3"))
1641 (match_operand:GPI 3 "register_operand" "r"))
1643 (set (match_operand:GPI 0 "register_operand" "=rk")
1644 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI (match_dup 1))
1648 "adds\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1649 [(set_attr "type" "alus_ext")]
1652 (define_insn "*subs_<optab><ALLX:mode>_shift_<GPI:mode>"
1653 [(set (reg:CC_NZ CC_REGNUM)
1655 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1658 (match_operand:ALLX 2 "register_operand" "r"))
1659 (match_operand 3 "aarch64_imm3" "Ui3")))
1661 (set (match_operand:GPI 0 "register_operand" "=rk")
1662 (minus:GPI (match_dup 1)
1663 (ashift:GPI (ANY_EXTEND:GPI (match_dup 2))
1666 "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1667 [(set_attr "type" "alus_ext")]
1670 (define_insn "*adds_<optab><mode>_multp2"
1671 [(set (reg:CC_NZ CC_REGNUM)
1673 (plus:GPI (ANY_EXTRACT:GPI
1674 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1675 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1676 (match_operand 3 "const_int_operand" "n")
1678 (match_operand:GPI 4 "register_operand" "r"))
1680 (set (match_operand:GPI 0 "register_operand" "=r")
1681 (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1685 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1686 "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1687 [(set_attr "type" "alus_ext")]
1690 (define_insn "*subs_<optab><mode>_multp2"
1691 [(set (reg:CC_NZ CC_REGNUM)
1693 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1695 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1696 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1697 (match_operand 3 "const_int_operand" "n")
1700 (set (match_operand:GPI 0 "register_operand" "=r")
1701 (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1702 (mult:GPI (match_dup 1) (match_dup 2))
1705 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1706 "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1707 [(set_attr "type" "alus_ext")]
1710 (define_insn "*add<mode>3nr_compare0"
1711 [(set (reg:CC_NZ CC_REGNUM)
1713 (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1714 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1721 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1724 (define_insn "*compare_neg<mode>"
1725 [(set (reg:CC_Z CC_REGNUM)
1727 (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1728 (match_operand:GPI 1 "register_operand" "r")))]
1730 "cmn\\t%<w>1, %<w>0"
1731 [(set_attr "type" "alus_sreg")]
1734 (define_insn "*add_<shift>_<mode>"
1735 [(set (match_operand:GPI 0 "register_operand" "=r")
1736 (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1737 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1738 (match_operand:GPI 3 "register_operand" "r")))]
1740 "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1741 [(set_attr "type" "alu_shift_imm")]
1744 ;; zero_extend version of above
1745 (define_insn "*add_<shift>_si_uxtw"
1746 [(set (match_operand:DI 0 "register_operand" "=r")
1748 (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1749 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1750 (match_operand:SI 3 "register_operand" "r"))))]
1752 "add\\t%w0, %w3, %w1, <shift> %2"
1753 [(set_attr "type" "alu_shift_imm")]
1756 (define_insn "*add_mul_imm_<mode>"
1757 [(set (match_operand:GPI 0 "register_operand" "=r")
1758 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1759 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1760 (match_operand:GPI 3 "register_operand" "r")))]
1762 "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1763 [(set_attr "type" "alu_shift_imm")]
1766 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1767 [(set (match_operand:GPI 0 "register_operand" "=rk")
1768 (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1769 (match_operand:GPI 2 "register_operand" "r")))]
1771 "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1772 [(set_attr "type" "alu_ext")]
1775 ;; zero_extend version of above
1776 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1777 [(set (match_operand:DI 0 "register_operand" "=rk")
1779 (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1780 (match_operand:GPI 2 "register_operand" "r"))))]
1782 "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1783 [(set_attr "type" "alu_ext")]
1786 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1787 [(set (match_operand:GPI 0 "register_operand" "=rk")
1788 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1789 (match_operand:ALLX 1 "register_operand" "r"))
1790 (match_operand 2 "aarch64_imm3" "Ui3"))
1791 (match_operand:GPI 3 "register_operand" "r")))]
1793 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1794 [(set_attr "type" "alu_ext")]
1797 ;; zero_extend version of above
1798 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1799 [(set (match_operand:DI 0 "register_operand" "=rk")
1801 (plus:SI (ashift:SI (ANY_EXTEND:SI
1802 (match_operand:SHORT 1 "register_operand" "r"))
1803 (match_operand 2 "aarch64_imm3" "Ui3"))
1804 (match_operand:SI 3 "register_operand" "r"))))]
1806 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1807 [(set_attr "type" "alu_ext")]
1810 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1811 [(set (match_operand:GPI 0 "register_operand" "=rk")
1812 (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1813 (match_operand:ALLX 1 "register_operand" "r"))
1814 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1815 (match_operand:GPI 3 "register_operand" "r")))]
1817 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1818 [(set_attr "type" "alu_ext")]
1821 ;; zero_extend version of above
1822 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1823 [(set (match_operand:DI 0 "register_operand" "=rk")
1824 (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1825 (match_operand:SHORT 1 "register_operand" "r"))
1826 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1827 (match_operand:SI 3 "register_operand" "r"))))]
1829 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1830 [(set_attr "type" "alu_ext")]
1833 (define_insn "*add_<optab><mode>_multp2"
1834 [(set (match_operand:GPI 0 "register_operand" "=rk")
1835 (plus:GPI (ANY_EXTRACT:GPI
1836 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1837 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1838 (match_operand 3 "const_int_operand" "n")
1840 (match_operand:GPI 4 "register_operand" "r")))]
1841 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1842 "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1843 [(set_attr "type" "alu_ext")]
1846 ;; zero_extend version of above
1847 (define_insn "*add_<optab>si_multp2_uxtw"
1848 [(set (match_operand:DI 0 "register_operand" "=rk")
1850 (plus:SI (ANY_EXTRACT:SI
1851 (mult:SI (match_operand:SI 1 "register_operand" "r")
1852 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1853 (match_operand 3 "const_int_operand" "n")
1855 (match_operand:SI 4 "register_operand" "r"))))]
1856 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1857 "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1858 [(set_attr "type" "alu_ext")]
1861 (define_insn "add<mode>3_carryin"
1863 (match_operand:GPI 0 "register_operand" "=r")
1864 (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1866 (match_operand:GPI 1 "register_operand" "r")
1867 (match_operand:GPI 2 "register_operand" "r"))))]
1869 "adc\\t%<w>0, %<w>1, %<w>2"
1870 [(set_attr "type" "adc_reg")]
1873 ;; zero_extend version of above
1874 (define_insn "*addsi3_carryin_uxtw"
1876 (match_operand:DI 0 "register_operand" "=r")
1878 (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1880 (match_operand:SI 1 "register_operand" "r")
1881 (match_operand:SI 2 "register_operand" "r")))))]
1883 "adc\\t%w0, %w1, %w2"
1884 [(set_attr "type" "adc_reg")]
1887 (define_insn "*add<mode>3_carryin_alt1"
1889 (match_operand:GPI 0 "register_operand" "=r")
1891 (match_operand:GPI 1 "register_operand" "r")
1892 (match_operand:GPI 2 "register_operand" "r"))
1893 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1895 "adc\\t%<w>0, %<w>1, %<w>2"
1896 [(set_attr "type" "adc_reg")]
1899 ;; zero_extend version of above
1900 (define_insn "*addsi3_carryin_alt1_uxtw"
1902 (match_operand:DI 0 "register_operand" "=r")
1905 (match_operand:SI 1 "register_operand" "r")
1906 (match_operand:SI 2 "register_operand" "r"))
1907 (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1909 "adc\\t%w0, %w1, %w2"
1910 [(set_attr "type" "adc_reg")]
1913 (define_insn "*add<mode>3_carryin_alt2"
1915 (match_operand:GPI 0 "register_operand" "=r")
1917 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1918 (match_operand:GPI 1 "register_operand" "r"))
1919 (match_operand:GPI 2 "register_operand" "r")))]
1921 "adc\\t%<w>0, %<w>1, %<w>2"
1922 [(set_attr "type" "adc_reg")]
1925 ;; zero_extend version of above
1926 (define_insn "*addsi3_carryin_alt2_uxtw"
1928 (match_operand:DI 0 "register_operand" "=r")
1931 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1932 (match_operand:SI 1 "register_operand" "r"))
1933 (match_operand:SI 2 "register_operand" "r"))))]
1935 "adc\\t%w0, %w1, %w2"
1936 [(set_attr "type" "adc_reg")]
1939 (define_insn "*add<mode>3_carryin_alt3"
1941 (match_operand:GPI 0 "register_operand" "=r")
1943 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1944 (match_operand:GPI 2 "register_operand" "r"))
1945 (match_operand:GPI 1 "register_operand" "r")))]
1947 "adc\\t%<w>0, %<w>1, %<w>2"
1948 [(set_attr "type" "adc_reg")]
1951 ;; zero_extend version of above
1952 (define_insn "*addsi3_carryin_alt3_uxtw"
1954 (match_operand:DI 0 "register_operand" "=r")
1957 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1958 (match_operand:SI 2 "register_operand" "r"))
1959 (match_operand:SI 1 "register_operand" "r"))))]
1961 "adc\\t%w0, %w1, %w2"
1962 [(set_attr "type" "adc_reg")]
1965 (define_insn "*add_uxt<mode>_shift2"
1966 [(set (match_operand:GPI 0 "register_operand" "=rk")
1968 (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
1969 (match_operand 2 "aarch64_imm3" "Ui3"))
1970 (match_operand 3 "const_int_operand" "n"))
1971 (match_operand:GPI 4 "register_operand" "r")))]
1972 "aarch64_uxt_size (INTVAL (operands[2]), INTVAL (operands[3])) != 0"
1974 operands[3] = GEN_INT (aarch64_uxt_size (INTVAL(operands[2]),
1975 INTVAL (operands[3])));
1976 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %2\";"
1977 [(set_attr "type" "alu_ext")]
1980 ;; zero_extend version of above
1981 (define_insn "*add_uxtsi_shift2_uxtw"
1982 [(set (match_operand:DI 0 "register_operand" "=rk")
1985 (ashift:SI (match_operand:SI 1 "register_operand" "r")
1986 (match_operand 2 "aarch64_imm3" "Ui3"))
1987 (match_operand 3 "const_int_operand" "n"))
1988 (match_operand:SI 4 "register_operand" "r"))))]
1989 "aarch64_uxt_size (INTVAL (operands[2]), INTVAL (operands[3])) != 0"
1991 operands[3] = GEN_INT (aarch64_uxt_size (INTVAL (operands[2]),
1992 INTVAL (operands[3])));
1993 return \"add\t%w0, %w4, %w1, uxt%e3 %2\";"
1994 [(set_attr "type" "alu_ext")]
1997 (define_insn "*add_uxt<mode>_multp2"
1998 [(set (match_operand:GPI 0 "register_operand" "=rk")
2000 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2001 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2002 (match_operand 3 "const_int_operand" "n"))
2003 (match_operand:GPI 4 "register_operand" "r")))]
2004 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
2006 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2007 INTVAL (operands[3])));
2008 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
2009 [(set_attr "type" "alu_ext")]
2012 ;; zero_extend version of above
2013 (define_insn "*add_uxtsi_multp2_uxtw"
2014 [(set (match_operand:DI 0 "register_operand" "=rk")
2017 (mult:SI (match_operand:SI 1 "register_operand" "r")
2018 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2019 (match_operand 3 "const_int_operand" "n"))
2020 (match_operand:SI 4 "register_operand" "r"))))]
2021 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
2023 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2024 INTVAL (operands[3])));
2025 return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
2026 [(set_attr "type" "alu_ext")]
2029 (define_insn "subsi3"
2030 [(set (match_operand:SI 0 "register_operand" "=rk")
2031 (minus:SI (match_operand:SI 1 "register_operand" "rk")
2032 (match_operand:SI 2 "register_operand" "r")))]
2034 "sub\\t%w0, %w1, %w2"
2035 [(set_attr "type" "alu_sreg")]
2038 ;; zero_extend version of above
2039 (define_insn "*subsi3_uxtw"
2040 [(set (match_operand:DI 0 "register_operand" "=rk")
2042 (minus:SI (match_operand:SI 1 "register_operand" "rk")
2043 (match_operand:SI 2 "register_operand" "r"))))]
2045 "sub\\t%w0, %w1, %w2"
2046 [(set_attr "type" "alu_sreg")]
2049 (define_insn "subdi3"
2050 [(set (match_operand:DI 0 "register_operand" "=rk,w")
2051 (minus:DI (match_operand:DI 1 "register_operand" "rk,w")
2052 (match_operand:DI 2 "register_operand" "r,w")))]
2056 sub\\t%d0, %d1, %d2"
2057 [(set_attr "type" "alu_sreg, neon_sub")
2058 (set_attr "simd" "*,yes")]
2061 (define_expand "subti3"
2062 [(set (match_operand:TI 0 "register_operand" "")
2063 (minus:TI (match_operand:TI 1 "register_operand" "")
2064 (match_operand:TI 2 "register_operand" "")))]
2067 rtx low = gen_reg_rtx (DImode);
2068 emit_insn (gen_subdi3_compare0 (low, gen_lowpart (DImode, operands[1]),
2069 gen_lowpart (DImode, operands[2])));
2071 rtx high = gen_reg_rtx (DImode);
2072 emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]),
2073 gen_highpart (DImode, operands[2])));
2075 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2076 emit_move_insn (gen_highpart (DImode, operands[0]), high);
2080 (define_insn "sub<mode>3_compare0"
2081 [(set (reg:CC_NZ CC_REGNUM)
2082 (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
2083 (match_operand:GPI 2 "register_operand" "r"))
2085 (set (match_operand:GPI 0 "register_operand" "=r")
2086 (minus:GPI (match_dup 1) (match_dup 2)))]
2088 "subs\\t%<w>0, %<w>1, %<w>2"
2089 [(set_attr "type" "alus_sreg")]
2092 ;; zero_extend version of above
2093 (define_insn "*subsi3_compare0_uxtw"
2094 [(set (reg:CC_NZ CC_REGNUM)
2095 (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
2096 (match_operand:SI 2 "register_operand" "r"))
2098 (set (match_operand:DI 0 "register_operand" "=r")
2099 (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
2101 "subs\\t%w0, %w1, %w2"
2102 [(set_attr "type" "alus_sreg")]
2105 (define_insn "*sub_<shift>_<mode>"
2106 [(set (match_operand:GPI 0 "register_operand" "=r")
2107 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2109 (match_operand:GPI 1 "register_operand" "r")
2110 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2112 "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
2113 [(set_attr "type" "alu_shift_imm")]
2116 ;; zero_extend version of above
2117 (define_insn "*sub_<shift>_si_uxtw"
2118 [(set (match_operand:DI 0 "register_operand" "=r")
2120 (minus:SI (match_operand:SI 3 "register_operand" "r")
2122 (match_operand:SI 1 "register_operand" "r")
2123 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2125 "sub\\t%w0, %w3, %w1, <shift> %2"
2126 [(set_attr "type" "alu_shift_imm")]
2129 (define_insn "*sub_mul_imm_<mode>"
2130 [(set (match_operand:GPI 0 "register_operand" "=r")
2131 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2133 (match_operand:GPI 1 "register_operand" "r")
2134 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2136 "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
2137 [(set_attr "type" "alu_shift_imm")]
2140 ;; zero_extend version of above
2141 (define_insn "*sub_mul_imm_si_uxtw"
2142 [(set (match_operand:DI 0 "register_operand" "=r")
2144 (minus:SI (match_operand:SI 3 "register_operand" "r")
2146 (match_operand:SI 1 "register_operand" "r")
2147 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2149 "sub\\t%w0, %w3, %w1, lsl %p2"
2150 [(set_attr "type" "alu_shift_imm")]
2153 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
2154 [(set (match_operand:GPI 0 "register_operand" "=rk")
2155 (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
2157 (match_operand:ALLX 2 "register_operand" "r"))))]
2159 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
2160 [(set_attr "type" "alu_ext")]
2163 ;; zero_extend version of above
2164 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
2165 [(set (match_operand:DI 0 "register_operand" "=rk")
2167 (minus:SI (match_operand:SI 1 "register_operand" "rk")
2169 (match_operand:SHORT 2 "register_operand" "r")))))]
2171 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
2172 [(set_attr "type" "alu_ext")]
2175 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
2176 [(set (match_operand:GPI 0 "register_operand" "=rk")
2177 (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
2178 (ashift:GPI (ANY_EXTEND:GPI
2179 (match_operand:ALLX 2 "register_operand" "r"))
2180 (match_operand 3 "aarch64_imm3" "Ui3"))))]
2182 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
2183 [(set_attr "type" "alu_ext")]
2186 ;; zero_extend version of above
2187 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
2188 [(set (match_operand:DI 0 "register_operand" "=rk")
2190 (minus:SI (match_operand:SI 1 "register_operand" "rk")
2191 (ashift:SI (ANY_EXTEND:SI
2192 (match_operand:SHORT 2 "register_operand" "r"))
2193 (match_operand 3 "aarch64_imm3" "Ui3")))))]
2195 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
2196 [(set_attr "type" "alu_ext")]
2199 (define_insn "*sub_<optab><mode>_multp2"
2200 [(set (match_operand:GPI 0 "register_operand" "=rk")
2201 (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
2203 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2204 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2205 (match_operand 3 "const_int_operand" "n")
2207 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
2208 "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
2209 [(set_attr "type" "alu_ext")]
2212 ;; zero_extend version of above
2213 (define_insn "*sub_<optab>si_multp2_uxtw"
2214 [(set (match_operand:DI 0 "register_operand" "=rk")
2216 (minus:SI (match_operand:SI 4 "register_operand" "rk")
2218 (mult:SI (match_operand:SI 1 "register_operand" "r")
2219 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2220 (match_operand 3 "const_int_operand" "n")
2222 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
2223 "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
2224 [(set_attr "type" "alu_ext")]
2227 (define_insn "sub<mode>3_carryin"
2229 (match_operand:GPI 0 "register_operand" "=r")
2230 (minus:GPI (minus:GPI
2231 (match_operand:GPI 1 "register_operand" "r")
2232 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2233 (match_operand:GPI 2 "register_operand" "r")))]
2235 "sbc\\t%<w>0, %<w>1, %<w>2"
2236 [(set_attr "type" "adc_reg")]
2239 ;; zero_extend version of the above
2240 (define_insn "*subsi3_carryin_uxtw"
2242 (match_operand:DI 0 "register_operand" "=r")
2245 (match_operand:SI 1 "register_operand" "r")
2246 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2247 (match_operand:SI 2 "register_operand" "r"))))]
2249 "sbc\\t%w0, %w1, %w2"
2250 [(set_attr "type" "adc_reg")]
2253 (define_insn "*sub_uxt<mode>_shift2"
2254 [(set (match_operand:GPI 0 "register_operand" "=rk")
2255 (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
2257 (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
2258 (match_operand 2 "aarch64_imm3" "Ui3"))
2259 (match_operand 3 "const_int_operand" "n"))))]
2260 "aarch64_uxt_size (INTVAL (operands[2]),INTVAL (operands[3])) != 0"
2262 operands[3] = GEN_INT (aarch64_uxt_size (INTVAL (operands[2]),
2263 INTVAL (operands[3])));
2264 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %2\";"
2265 [(set_attr "type" "alu_ext")]
2268 ;; zero_extend version of above
2269 (define_insn "*sub_uxtsi_shift2_uxtw"
2270 [(set (match_operand:DI 0 "register_operand" "=rk")
2272 (minus:SI (match_operand:SI 4 "register_operand" "rk")
2274 (ashift:SI (match_operand:SI 1 "register_operand" "r")
2275 (match_operand 2 "aarch64_imm3" "Ui3"))
2276 (match_operand 3 "const_int_operand" "n")))))]
2277 "aarch64_uxt_size (INTVAL (operands[2]),INTVAL (operands[3])) != 0"
2279 operands[3] = GEN_INT (aarch64_uxt_size (INTVAL (operands[2]),
2280 INTVAL (operands[3])));
2281 return \"sub\t%w0, %w4, %w1, uxt%e3 %2\";"
2282 [(set_attr "type" "alu_ext")]
2285 (define_insn "*sub_uxt<mode>_multp2"
2286 [(set (match_operand:GPI 0 "register_operand" "=rk")
2287 (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
2289 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2290 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2291 (match_operand 3 "const_int_operand" "n"))))]
2292 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2294 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2295 INTVAL (operands[3])));
2296 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
2297 [(set_attr "type" "alu_ext")]
2300 ;; zero_extend version of above
2301 (define_insn "*sub_uxtsi_multp2_uxtw"
2302 [(set (match_operand:DI 0 "register_operand" "=rk")
2304 (minus:SI (match_operand:SI 4 "register_operand" "rk")
2306 (mult:SI (match_operand:SI 1 "register_operand" "r")
2307 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2308 (match_operand 3 "const_int_operand" "n")))))]
2309 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2311 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2312 INTVAL (operands[3])));
2313 return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
2314 [(set_attr "type" "alu_ext")]
2317 (define_expand "abs<mode>2"
2318 [(match_operand:GPI 0 "register_operand" "")
2319 (match_operand:GPI 1 "register_operand" "")]
2322 rtx ccreg = aarch64_gen_compare_reg (LT, operands[1], const0_rtx);
2323 rtx x = gen_rtx_LT (VOIDmode, ccreg, const0_rtx);
2324 emit_insn (gen_csneg3<mode>_insn (operands[0], x, operands[1], operands[1]));
2329 (define_insn "neg<mode>2"
2330 [(set (match_operand:GPI 0 "register_operand" "=r,w")
2331 (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
2335 neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
2336 [(set_attr "type" "alu_sreg, neon_neg<q>")
2337 (set_attr "simd" "*,yes")]
2340 ;; zero_extend version of above
2341 (define_insn "*negsi2_uxtw"
2342 [(set (match_operand:DI 0 "register_operand" "=r")
2343 (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
2346 [(set_attr "type" "alu_sreg")]
2349 (define_insn "*ngc<mode>"
2350 [(set (match_operand:GPI 0 "register_operand" "=r")
2351 (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2352 (match_operand:GPI 1 "register_operand" "r")))]
2354 "ngc\\t%<w>0, %<w>1"
2355 [(set_attr "type" "adc_reg")]
2358 (define_insn "*ngcsi_uxtw"
2359 [(set (match_operand:DI 0 "register_operand" "=r")
2361 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2362 (match_operand:SI 1 "register_operand" "r"))))]
2365 [(set_attr "type" "adc_reg")]
2368 (define_insn "*neg<mode>2_compare0"
2369 [(set (reg:CC_NZ CC_REGNUM)
2370 (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2372 (set (match_operand:GPI 0 "register_operand" "=r")
2373 (neg:GPI (match_dup 1)))]
2375 "negs\\t%<w>0, %<w>1"
2376 [(set_attr "type" "alus_sreg")]
2379 ;; zero_extend version of above
2380 (define_insn "*negsi2_compare0_uxtw"
2381 [(set (reg:CC_NZ CC_REGNUM)
2382 (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
2384 (set (match_operand:DI 0 "register_operand" "=r")
2385 (zero_extend:DI (neg:SI (match_dup 1))))]
2388 [(set_attr "type" "alus_sreg")]
2391 (define_insn "*neg_<shift><mode>3_compare0"
2392 [(set (reg:CC_NZ CC_REGNUM)
2394 (neg:GPI (ASHIFT:GPI
2395 (match_operand:GPI 1 "register_operand" "r")
2396 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2398 (set (match_operand:GPI 0 "register_operand" "=r")
2399 (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2401 "negs\\t%<w>0, %<w>1, <shift> %2"
2402 [(set_attr "type" "alus_shift_imm")]
2405 (define_insn "*neg_<shift>_<mode>2"
2406 [(set (match_operand:GPI 0 "register_operand" "=r")
2407 (neg:GPI (ASHIFT:GPI
2408 (match_operand:GPI 1 "register_operand" "r")
2409 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2411 "neg\\t%<w>0, %<w>1, <shift> %2"
2412 [(set_attr "type" "alu_shift_imm")]
2415 ;; zero_extend version of above
2416 (define_insn "*neg_<shift>_si2_uxtw"
2417 [(set (match_operand:DI 0 "register_operand" "=r")
2420 (match_operand:SI 1 "register_operand" "r")
2421 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2423 "neg\\t%w0, %w1, <shift> %2"
2424 [(set_attr "type" "alu_shift_imm")]
2427 (define_insn "*neg_mul_imm_<mode>2"
2428 [(set (match_operand:GPI 0 "register_operand" "=r")
2430 (match_operand:GPI 1 "register_operand" "r")
2431 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2433 "neg\\t%<w>0, %<w>1, lsl %p2"
2434 [(set_attr "type" "alu_shift_imm")]
2437 ;; zero_extend version of above
2438 (define_insn "*neg_mul_imm_si2_uxtw"
2439 [(set (match_operand:DI 0 "register_operand" "=r")
2442 (match_operand:SI 1 "register_operand" "r")
2443 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2445 "neg\\t%w0, %w1, lsl %p2"
2446 [(set_attr "type" "alu_shift_imm")]
2449 (define_insn "mul<mode>3"
2450 [(set (match_operand:GPI 0 "register_operand" "=r")
2451 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2452 (match_operand:GPI 2 "register_operand" "r")))]
2454 "mul\\t%<w>0, %<w>1, %<w>2"
2455 [(set_attr "type" "mul")]
2458 ;; zero_extend version of above
2459 (define_insn "*mulsi3_uxtw"
2460 [(set (match_operand:DI 0 "register_operand" "=r")
2462 (mult:SI (match_operand:SI 1 "register_operand" "r")
2463 (match_operand:SI 2 "register_operand" "r"))))]
2465 "mul\\t%w0, %w1, %w2"
2466 [(set_attr "type" "mul")]
2469 (define_insn "madd<mode>"
2470 [(set (match_operand:GPI 0 "register_operand" "=r")
2471 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2472 (match_operand:GPI 2 "register_operand" "r"))
2473 (match_operand:GPI 3 "register_operand" "r")))]
2475 "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2476 [(set_attr "type" "mla")]
2479 ;; zero_extend version of above
2480 (define_insn "*maddsi_uxtw"
2481 [(set (match_operand:DI 0 "register_operand" "=r")
2483 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2484 (match_operand:SI 2 "register_operand" "r"))
2485 (match_operand:SI 3 "register_operand" "r"))))]
2487 "madd\\t%w0, %w1, %w2, %w3"
2488 [(set_attr "type" "mla")]
2491 (define_insn "*msub<mode>"
2492 [(set (match_operand:GPI 0 "register_operand" "=r")
2493 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2494 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2495 (match_operand:GPI 2 "register_operand" "r"))))]
2498 "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2499 [(set_attr "type" "mla")]
2502 ;; zero_extend version of above
2503 (define_insn "*msubsi_uxtw"
2504 [(set (match_operand:DI 0 "register_operand" "=r")
2506 (minus:SI (match_operand:SI 3 "register_operand" "r")
2507 (mult:SI (match_operand:SI 1 "register_operand" "r")
2508 (match_operand:SI 2 "register_operand" "r")))))]
2511 "msub\\t%w0, %w1, %w2, %w3"
2512 [(set_attr "type" "mla")]
2515 (define_insn "*mul<mode>_neg"
2516 [(set (match_operand:GPI 0 "register_operand" "=r")
2517 (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2518 (match_operand:GPI 2 "register_operand" "r")))]
2521 "mneg\\t%<w>0, %<w>1, %<w>2"
2522 [(set_attr "type" "mul")]
2525 ;; zero_extend version of above
2526 (define_insn "*mulsi_neg_uxtw"
2527 [(set (match_operand:DI 0 "register_operand" "=r")
2529 (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2530 (match_operand:SI 2 "register_operand" "r"))))]
2533 "mneg\\t%w0, %w1, %w2"
2534 [(set_attr "type" "mul")]
2537 (define_insn "<su_optab>mulsidi3"
2538 [(set (match_operand:DI 0 "register_operand" "=r")
2539 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2540 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2542 "<su>mull\\t%0, %w1, %w2"
2543 [(set_attr "type" "<su>mull")]
2546 (define_insn "<su_optab>maddsidi4"
2547 [(set (match_operand:DI 0 "register_operand" "=r")
2549 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2550 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2551 (match_operand:DI 3 "register_operand" "r")))]
2553 "<su>maddl\\t%0, %w1, %w2, %3"
2554 [(set_attr "type" "<su>mlal")]
2557 (define_insn "<su_optab>msubsidi4"
2558 [(set (match_operand:DI 0 "register_operand" "=r")
2560 (match_operand:DI 3 "register_operand" "r")
2561 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2563 (match_operand:SI 2 "register_operand" "r")))))]
2565 "<su>msubl\\t%0, %w1, %w2, %3"
2566 [(set_attr "type" "<su>mlal")]
2569 (define_insn "*<su_optab>mulsidi_neg"
2570 [(set (match_operand:DI 0 "register_operand" "=r")
2572 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2573 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2575 "<su>mnegl\\t%0, %w1, %w2"
2576 [(set_attr "type" "<su>mull")]
2579 (define_expand "<su_optab>mulditi3"
2580 [(set (match_operand:TI 0 "register_operand")
2581 (mult:TI (ANY_EXTEND:TI (match_operand:DI 1 "register_operand"))
2582 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand"))))]
2585 rtx low = gen_reg_rtx (DImode);
2586 emit_insn (gen_muldi3 (low, operands[1], operands[2]));
2588 rtx high = gen_reg_rtx (DImode);
2589 emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2]));
2591 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2592 emit_move_insn (gen_highpart (DImode, operands[0]), high);
2596 ;; The default expansion of multi3 using umuldi3_highpart will perform
2597 ;; the additions in an order that fails to combine into two madd insns.
2598 (define_expand "multi3"
2599 [(set (match_operand:TI 0 "register_operand")
2600 (mult:TI (match_operand:TI 1 "register_operand")
2601 (match_operand:TI 2 "register_operand")))]
2604 rtx l0 = gen_reg_rtx (DImode);
2605 rtx l1 = gen_lowpart (DImode, operands[1]);
2606 rtx l2 = gen_lowpart (DImode, operands[2]);
2607 rtx h0 = gen_reg_rtx (DImode);
2608 rtx h1 = gen_highpart (DImode, operands[1]);
2609 rtx h2 = gen_highpart (DImode, operands[2]);
2611 emit_insn (gen_muldi3 (l0, l1, l2));
2612 emit_insn (gen_umuldi3_highpart (h0, l1, l2));
2613 emit_insn (gen_madddi (h0, h1, l2, h0));
2614 emit_insn (gen_madddi (h0, l1, h2, h0));
2616 emit_move_insn (gen_lowpart (DImode, operands[0]), l0);
2617 emit_move_insn (gen_highpart (DImode, operands[0]), h0);
2621 (define_insn "<su>muldi3_highpart"
2622 [(set (match_operand:DI 0 "register_operand" "=r")
2626 (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2627 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2630 "<su>mulh\\t%0, %1, %2"
2631 [(set_attr "type" "<su>mull")]
2634 (define_insn "<su_optab>div<mode>3"
2635 [(set (match_operand:GPI 0 "register_operand" "=r")
2636 (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2637 (match_operand:GPI 2 "register_operand" "r")))]
2639 "<su>div\\t%<w>0, %<w>1, %<w>2"
2640 [(set_attr "type" "<su>div")]
2643 ;; zero_extend version of above
2644 (define_insn "*<su_optab>divsi3_uxtw"
2645 [(set (match_operand:DI 0 "register_operand" "=r")
2647 (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2648 (match_operand:SI 2 "register_operand" "r"))))]
2650 "<su>div\\t%w0, %w1, %w2"
2651 [(set_attr "type" "<su>div")]
2654 ;; -------------------------------------------------------------------
2656 ;; -------------------------------------------------------------------
2658 (define_insn "*cmp<mode>"
2659 [(set (reg:CC CC_REGNUM)
2660 (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2661 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2667 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
2670 (define_insn "*cmp<mode>"
2671 [(set (reg:CCFP CC_REGNUM)
2672 (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2673 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2677 fcmp\\t%<s>0, %<s>1"
2678 [(set_attr "type" "fcmp<s>")]
2681 (define_insn "*cmpe<mode>"
2682 [(set (reg:CCFPE CC_REGNUM)
2683 (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2684 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2688 fcmpe\\t%<s>0, %<s>1"
2689 [(set_attr "type" "fcmp<s>")]
2692 (define_insn "*cmp_swp_<shift>_reg<mode>"
2693 [(set (reg:CC_SWP CC_REGNUM)
2694 (compare:CC_SWP (ASHIFT:GPI
2695 (match_operand:GPI 0 "register_operand" "r")
2696 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2697 (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2699 "cmp\\t%<w>2, %<w>0, <shift> %1"
2700 [(set_attr "type" "alus_shift_imm")]
2703 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2704 [(set (reg:CC_SWP CC_REGNUM)
2705 (compare:CC_SWP (ANY_EXTEND:GPI
2706 (match_operand:ALLX 0 "register_operand" "r"))
2707 (match_operand:GPI 1 "register_operand" "r")))]
2709 "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2710 [(set_attr "type" "alus_ext")]
2713 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2714 [(set (reg:CC_SWP CC_REGNUM)
2715 (compare:CC_SWP (ashift:GPI
2717 (match_operand:ALLX 0 "register_operand" "r"))
2718 (match_operand 1 "aarch64_imm3" "Ui3"))
2719 (match_operand:GPI 2 "register_operand" "r")))]
2721 "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2722 [(set_attr "type" "alus_ext")]
2725 ;; -------------------------------------------------------------------
2726 ;; Store-flag and conditional select insns
2727 ;; -------------------------------------------------------------------
2729 (define_expand "cstore<mode>4"
2730 [(set (match_operand:SI 0 "register_operand" "")
2731 (match_operator:SI 1 "aarch64_comparison_operator"
2732 [(match_operand:GPI 2 "register_operand" "")
2733 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2736 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2738 operands[3] = const0_rtx;
2742 (define_expand "cstorecc4"
2743 [(set (match_operand:SI 0 "register_operand")
2744 (match_operator 1 "aarch64_comparison_operator"
2745 [(match_operand 2 "ccmp_cc_register")
2746 (match_operand 3 "const0_operand")]))]
2749 emit_insn (gen_rtx_SET (operands[0], operands[1]));
2754 (define_expand "cstore<mode>4"
2755 [(set (match_operand:SI 0 "register_operand" "")
2756 (match_operator:SI 1 "aarch64_comparison_operator"
2757 [(match_operand:GPF 2 "register_operand" "")
2758 (match_operand:GPF 3 "register_operand" "")]))]
2761 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2763 operands[3] = const0_rtx;
2767 (define_insn "*cstore<mode>_insn"
2768 [(set (match_operand:ALLI 0 "register_operand" "=r")
2769 (match_operator:ALLI 1 "aarch64_comparison_operator"
2770 [(match_operand 2 "cc_register" "") (const_int 0)]))]
2773 [(set_attr "type" "csel")]
2776 ;; zero_extend version of the above
2777 (define_insn "*cstoresi_insn_uxtw"
2778 [(set (match_operand:DI 0 "register_operand" "=r")
2780 (match_operator:SI 1 "aarch64_comparison_operator"
2781 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2784 [(set_attr "type" "csel")]
2787 (define_insn "cstore<mode>_neg"
2788 [(set (match_operand:ALLI 0 "register_operand" "=r")
2789 (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2790 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2792 "csetm\\t%<w>0, %m1"
2793 [(set_attr "type" "csel")]
2796 ;; zero_extend version of the above
2797 (define_insn "*cstoresi_neg_uxtw"
2798 [(set (match_operand:DI 0 "register_operand" "=r")
2800 (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2801 [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2804 [(set_attr "type" "csel")]
2807 (define_expand "cmov<mode>6"
2808 [(set (match_operand:GPI 0 "register_operand" "")
2810 (match_operator 1 "aarch64_comparison_operator"
2811 [(match_operand:GPI 2 "register_operand" "")
2812 (match_operand:GPI 3 "aarch64_plus_operand" "")])
2813 (match_operand:GPI 4 "register_operand" "")
2814 (match_operand:GPI 5 "register_operand" "")))]
2817 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2819 operands[3] = const0_rtx;
2823 (define_expand "cmov<mode>6"
2824 [(set (match_operand:GPF 0 "register_operand" "")
2826 (match_operator 1 "aarch64_comparison_operator"
2827 [(match_operand:GPF 2 "register_operand" "")
2828 (match_operand:GPF 3 "register_operand" "")])
2829 (match_operand:GPF 4 "register_operand" "")
2830 (match_operand:GPF 5 "register_operand" "")))]
2833 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2835 operands[3] = const0_rtx;
2839 (define_insn "*cmov<mode>_insn"
2840 [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2842 (match_operator 1 "aarch64_comparison_operator"
2843 [(match_operand 2 "cc_register" "") (const_int 0)])
2844 (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2845 (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2846 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2847 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2848 ;; Final two alternatives should be unreachable, but included for completeness
2850 csel\\t%<w>0, %<w>3, %<w>4, %m1
2851 csinv\\t%<w>0, %<w>3, <w>zr, %m1
2852 csinv\\t%<w>0, %<w>4, <w>zr, %M1
2853 csinc\\t%<w>0, %<w>3, <w>zr, %m1
2854 csinc\\t%<w>0, %<w>4, <w>zr, %M1
2857 [(set_attr "type" "csel")]
2860 ;; zero_extend version of above
2861 (define_insn "*cmovsi_insn_uxtw"
2862 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2865 (match_operator 1 "aarch64_comparison_operator"
2866 [(match_operand 2 "cc_register" "") (const_int 0)])
2867 (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2868 (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2869 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2870 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2871 ;; Final two alternatives should be unreachable, but included for completeness
2873 csel\\t%w0, %w3, %w4, %m1
2874 csinv\\t%w0, %w3, wzr, %m1
2875 csinv\\t%w0, %w4, wzr, %M1
2876 csinc\\t%w0, %w3, wzr, %m1
2877 csinc\\t%w0, %w4, wzr, %M1
2880 [(set_attr "type" "csel")]
2883 (define_insn "*cmov<mode>_insn"
2884 [(set (match_operand:GPF 0 "register_operand" "=w")
2886 (match_operator 1 "aarch64_comparison_operator"
2887 [(match_operand 2 "cc_register" "") (const_int 0)])
2888 (match_operand:GPF 3 "register_operand" "w")
2889 (match_operand:GPF 4 "register_operand" "w")))]
2891 "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2892 [(set_attr "type" "fcsel")]
2895 (define_expand "mov<mode>cc"
2896 [(set (match_operand:ALLI 0 "register_operand" "")
2897 (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2898 (match_operand:ALLI 2 "register_operand" "")
2899 (match_operand:ALLI 3 "register_operand" "")))]
2902 enum rtx_code code = GET_CODE (operands[1]);
2904 if (code == UNEQ || code == LTGT)
2907 if (!ccmp_cc_register (XEXP (operands[1], 0),
2908 GET_MODE (XEXP (operands[1], 0))))
2911 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2912 XEXP (operands[1], 1));
2913 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2918 (define_expand "mov<GPF:mode><GPI:mode>cc"
2919 [(set (match_operand:GPI 0 "register_operand" "")
2920 (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2921 (match_operand:GPF 2 "register_operand" "")
2922 (match_operand:GPF 3 "register_operand" "")))]
2926 enum rtx_code code = GET_CODE (operands[1]);
2928 if (code == UNEQ || code == LTGT)
2931 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2932 XEXP (operands[1], 1));
2933 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2937 (define_expand "mov<mode>cc"
2938 [(set (match_operand:GPF 0 "register_operand" "")
2939 (if_then_else:GPF (match_operand 1 "aarch64_comparison_operator" "")
2940 (match_operand:GPF 2 "register_operand" "")
2941 (match_operand:GPF 3 "register_operand" "")))]
2945 enum rtx_code code = GET_CODE (operands[1]);
2947 if (code == UNEQ || code == LTGT)
2950 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2951 XEXP (operands[1], 1));
2952 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2957 ;; CRC32 instructions.
2958 (define_insn "aarch64_<crc_variant>"
2959 [(set (match_operand:SI 0 "register_operand" "=r")
2960 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2961 (match_operand:<crc_mode> 2 "register_operand" "r")]
2965 if (GET_MODE_BITSIZE (GET_MODE (operands[2])) >= 64)
2966 return "<crc_variant>\\t%w0, %w1, %x2";
2968 return "<crc_variant>\\t%w0, %w1, %w2";
2970 [(set_attr "type" "crc")]
2973 (define_insn "*csinc2<mode>_insn"
2974 [(set (match_operand:GPI 0 "register_operand" "=r")
2975 (plus:GPI (match_operand 2 "aarch64_comparison_operation" "")
2976 (match_operand:GPI 1 "register_operand" "r")))]
2978 "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2979 [(set_attr "type" "csel")]
2982 (define_insn "csinc3<mode>_insn"
2983 [(set (match_operand:GPI 0 "register_operand" "=r")
2985 (match_operand 1 "aarch64_comparison_operation" "")
2986 (plus:GPI (match_operand:GPI 2 "register_operand" "r")
2988 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2990 "csinc\\t%<w>0, %<w>3, %<w>2, %M1"
2991 [(set_attr "type" "csel")]
2994 (define_insn "*csinv3<mode>_insn"
2995 [(set (match_operand:GPI 0 "register_operand" "=r")
2997 (match_operand 1 "aarch64_comparison_operation" "")
2998 (not:GPI (match_operand:GPI 2 "register_operand" "r"))
2999 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
3001 "csinv\\t%<w>0, %<w>3, %<w>2, %M1"
3002 [(set_attr "type" "csel")]
3005 (define_insn "csneg3<mode>_insn"
3006 [(set (match_operand:GPI 0 "register_operand" "=r")
3008 (match_operand 1 "aarch64_comparison_operation" "")
3009 (neg:GPI (match_operand:GPI 2 "register_operand" "r"))
3010 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
3012 "csneg\\t%<w>0, %<w>3, %<w>2, %M1"
3013 [(set_attr "type" "csel")]
3016 ;; -------------------------------------------------------------------
3017 ;; Logical operations
3018 ;; -------------------------------------------------------------------
3020 (define_insn "<optab><mode>3"
3021 [(set (match_operand:GPI 0 "register_operand" "=r,rk,w")
3022 (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r,w")
3023 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>,w")))]
3026 <logical>\\t%<w>0, %<w>1, %<w>2
3027 <logical>\\t%<w>0, %<w>1, %<w>2
3028 <logical>\\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
3029 [(set_attr "type" "logic_reg,logic_imm,neon_logic")
3030 (set_attr "simd" "*,*,yes")]
3033 ;; zero_extend version of above
3034 (define_insn "*<optab>si3_uxtw"
3035 [(set (match_operand:DI 0 "register_operand" "=r,rk")
3037 (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
3038 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
3040 "<logical>\\t%w0, %w1, %w2"
3041 [(set_attr "type" "logic_reg,logic_imm")]
3044 (define_insn "*and<mode>3_compare0"
3045 [(set (reg:CC_NZ CC_REGNUM)
3047 (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
3048 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
3050 (set (match_operand:GPI 0 "register_operand" "=r,r")
3051 (and:GPI (match_dup 1) (match_dup 2)))]
3053 "ands\\t%<w>0, %<w>1, %<w>2"
3054 [(set_attr "type" "logics_reg,logics_imm")]
3057 ;; zero_extend version of above
3058 (define_insn "*andsi3_compare0_uxtw"
3059 [(set (reg:CC_NZ CC_REGNUM)
3061 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
3062 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
3064 (set (match_operand:DI 0 "register_operand" "=r,r")
3065 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
3067 "ands\\t%w0, %w1, %w2"
3068 [(set_attr "type" "logics_reg,logics_imm")]
3071 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
3072 [(set (reg:CC_NZ CC_REGNUM)
3075 (match_operand:GPI 1 "register_operand" "r")
3076 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3077 (match_operand:GPI 3 "register_operand" "r"))
3079 (set (match_operand:GPI 0 "register_operand" "=r")
3080 (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
3082 "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3083 [(set_attr "type" "logics_shift_imm")]
3086 ;; zero_extend version of above
3087 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
3088 [(set (reg:CC_NZ CC_REGNUM)
3091 (match_operand:SI 1 "register_operand" "r")
3092 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3093 (match_operand:SI 3 "register_operand" "r"))
3095 (set (match_operand:DI 0 "register_operand" "=r")
3096 (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
3099 "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3100 [(set_attr "type" "logics_shift_imm")]
3103 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
3104 [(set (match_operand:GPI 0 "register_operand" "=r")
3105 (LOGICAL:GPI (SHIFT:GPI
3106 (match_operand:GPI 1 "register_operand" "r")
3107 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3108 (match_operand:GPI 3 "register_operand" "r")))]
3110 "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3111 [(set_attr "type" "logic_shift_imm")]
3114 (define_insn "*<optab>_rol<mode>3"
3115 [(set (match_operand:GPI 0 "register_operand" "=r")
3116 (LOGICAL:GPI (rotate:GPI
3117 (match_operand:GPI 1 "register_operand" "r")
3118 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3119 (match_operand:GPI 3 "register_operand" "r")))]
3121 "<logical>\\t%<w>0, %<w>3, %<w>1, ror (<sizen> - %2)"
3122 [(set_attr "type" "logic_shift_imm")]
3125 ;; zero_extend versions of above
3126 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
3127 [(set (match_operand:DI 0 "register_operand" "=r")
3129 (LOGICAL:SI (SHIFT:SI
3130 (match_operand:SI 1 "register_operand" "r")
3131 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3132 (match_operand:SI 3 "register_operand" "r"))))]
3134 "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3135 [(set_attr "type" "logic_shift_imm")]
3138 (define_insn "*<optab>_rolsi3_uxtw"
3139 [(set (match_operand:DI 0 "register_operand" "=r")
3141 (LOGICAL:SI (rotate:SI
3142 (match_operand:SI 1 "register_operand" "r")
3143 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3144 (match_operand:SI 3 "register_operand" "r"))))]
3146 "<logical>\\t%w0, %w3, %w1, ror (32 - %2)"
3147 [(set_attr "type" "logic_shift_imm")]
3150 (define_insn "one_cmpl<mode>2"
3151 [(set (match_operand:GPI 0 "register_operand" "=r,w")
3152 (not:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
3157 [(set_attr "type" "logic_reg,neon_logic")
3158 (set_attr "simd" "*,yes")]
3161 (define_insn "*one_cmpl_<optab><mode>2"
3162 [(set (match_operand:GPI 0 "register_operand" "=r")
3163 (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
3164 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
3166 "mvn\\t%<w>0, %<w>1, <shift> %2"
3167 [(set_attr "type" "logic_shift_imm")]
3170 ;; Binary logical operators negating one operand, i.e. (a & !b), (a | !b).
3172 (define_insn "*<NLOGICAL:optab>_one_cmpl<mode>3"
3173 [(set (match_operand:GPI 0 "register_operand" "=r,w")
3174 (NLOGICAL:GPI (not:GPI (match_operand:GPI 1 "register_operand" "r,w"))
3175 (match_operand:GPI 2 "register_operand" "r,w")))]
3178 <NLOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1
3179 <NLOGICAL:nlogical>\\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>"
3180 [(set_attr "type" "logic_reg,neon_logic")
3181 (set_attr "simd" "*,yes")]
3184 (define_insn "*<NLOGICAL:optab>_one_cmplsidi3_ze"
3185 [(set (match_operand:DI 0 "register_operand" "=r")
3187 (NLOGICAL:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3188 (match_operand:SI 2 "register_operand" "r"))))]
3190 "<NLOGICAL:nlogical>\\t%w0, %w2, %w1"
3191 [(set_attr "type" "logic_reg")]
3194 (define_insn "*xor_one_cmplsidi3_ze"
3195 [(set (match_operand:DI 0 "register_operand" "=r")
3197 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "r")
3198 (match_operand:SI 2 "register_operand" "r")))))]
3200 "eon\\t%w0, %w1, %w2"
3201 [(set_attr "type" "logic_reg")]
3204 ;; (xor (not a) b) is simplify_rtx-ed down to (not (xor a b)).
3205 ;; eon does not operate on SIMD registers so the vector variant must be split.
3206 (define_insn_and_split "*xor_one_cmpl<mode>3"
3207 [(set (match_operand:GPI 0 "register_operand" "=r,w")
3208 (not:GPI (xor:GPI (match_operand:GPI 1 "register_operand" "r,?w")
3209 (match_operand:GPI 2 "register_operand" "r,w"))))]
3212 eon\\t%<w>0, %<w>1, %<w>2
3214 "reload_completed && FP_REGNUM_P (REGNO (operands[0]))" ;; For SIMD registers.
3215 [(set (match_operand:GPI 0 "register_operand" "=w")
3216 (xor:GPI (match_operand:GPI 1 "register_operand" "w")
3217 (match_operand:GPI 2 "register_operand" "w")))
3218 (set (match_dup 0) (not:GPI (match_dup 0)))]
3220 [(set_attr "type" "logic_reg,multiple")
3221 (set_attr "simd" "*,yes")]
3224 (define_insn "*and_one_cmpl<mode>3_compare0"
3225 [(set (reg:CC_NZ CC_REGNUM)
3228 (match_operand:GPI 1 "register_operand" "r"))
3229 (match_operand:GPI 2 "register_operand" "r"))
3231 (set (match_operand:GPI 0 "register_operand" "=r")
3232 (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
3234 "bics\\t%<w>0, %<w>2, %<w>1"
3235 [(set_attr "type" "logics_reg")]
3238 ;; zero_extend version of above
3239 (define_insn "*and_one_cmplsi3_compare0_uxtw"
3240 [(set (reg:CC_NZ CC_REGNUM)
3243 (match_operand:SI 1 "register_operand" "r"))
3244 (match_operand:SI 2 "register_operand" "r"))
3246 (set (match_operand:DI 0 "register_operand" "=r")
3247 (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
3249 "bics\\t%w0, %w2, %w1"
3250 [(set_attr "type" "logics_reg")]
3253 (define_insn "*and_one_cmpl<mode>3_compare0_no_reuse"
3254 [(set (reg:CC_NZ CC_REGNUM)
3257 (match_operand:GPI 0 "register_operand" "r"))
3258 (match_operand:GPI 1 "register_operand" "r"))
3261 "bics\\t<w>zr, %<w>1, %<w>0"
3262 [(set_attr "type" "logics_reg")]
3265 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
3266 [(set (match_operand:GPI 0 "register_operand" "=r")
3267 (LOGICAL:GPI (not:GPI
3269 (match_operand:GPI 1 "register_operand" "r")
3270 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
3271 (match_operand:GPI 3 "register_operand" "r")))]
3273 "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3274 [(set_attr "type" "logic_shift_imm")]
3277 (define_insn "*eor_one_cmpl_<SHIFT:optab><mode>3_alt"
3278 [(set (match_operand:GPI 0 "register_operand" "=r")
3281 (match_operand:GPI 1 "register_operand" "r")
3282 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3283 (match_operand:GPI 3 "register_operand" "r"))))]
3285 "eon\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3286 [(set_attr "type" "logic_shift_imm")]
3289 ;; Zero-extend version of the above.
3290 (define_insn "*eor_one_cmpl_<SHIFT:optab>sidi3_alt_ze"
3291 [(set (match_operand:DI 0 "register_operand" "=r")
3295 (match_operand:SI 1 "register_operand" "r")
3296 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3297 (match_operand:SI 3 "register_operand" "r")))))]
3299 "eon\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3300 [(set_attr "type" "logic_shift_imm")]
3303 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
3304 [(set (reg:CC_NZ CC_REGNUM)
3308 (match_operand:GPI 1 "register_operand" "r")
3309 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
3310 (match_operand:GPI 3 "register_operand" "r"))
3312 (set (match_operand:GPI 0 "register_operand" "=r")
3315 (match_dup 1) (match_dup 2))) (match_dup 3)))]
3317 "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3318 [(set_attr "type" "logics_shift_imm")]
3321 ;; zero_extend version of above
3322 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
3323 [(set (reg:CC_NZ CC_REGNUM)
3327 (match_operand:SI 1 "register_operand" "r")
3328 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
3329 (match_operand:SI 3 "register_operand" "r"))
3331 (set (match_operand:DI 0 "register_operand" "=r")
3332 (zero_extend:DI (and:SI
3334 (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
3336 "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3337 [(set_attr "type" "logics_shift_imm")]
3340 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0_no_reuse"
3341 [(set (reg:CC_NZ CC_REGNUM)
3345 (match_operand:GPI 0 "register_operand" "r")
3346 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n")))
3347 (match_operand:GPI 2 "register_operand" "r"))
3350 "bics\\t<w>zr, %<w>2, %<w>0, <SHIFT:shift> %1"
3351 [(set_attr "type" "logics_shift_imm")]
3354 (define_insn "clz<mode>2"
3355 [(set (match_operand:GPI 0 "register_operand" "=r")
3356 (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
3358 "clz\\t%<w>0, %<w>1"
3359 [(set_attr "type" "clz")]
3362 (define_expand "ffs<mode>2"
3363 [(match_operand:GPI 0 "register_operand")
3364 (match_operand:GPI 1 "register_operand")]
3367 rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
3368 rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
3370 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3371 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3372 emit_insn (gen_csinc3<mode>_insn (operands[0], x, operands[0], const0_rtx));
3377 (define_insn "clrsb<mode>2"
3378 [(set (match_operand:GPI 0 "register_operand" "=r")
3379 (clrsb:GPI (match_operand:GPI 1 "register_operand" "r")))]
3381 "cls\\t%<w>0, %<w>1"
3382 [(set_attr "type" "clz")]
3385 (define_insn "rbit<mode>2"
3386 [(set (match_operand:GPI 0 "register_operand" "=r")
3387 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
3389 "rbit\\t%<w>0, %<w>1"
3390 [(set_attr "type" "rbit")]
3393 (define_expand "ctz<mode>2"
3394 [(match_operand:GPI 0 "register_operand")
3395 (match_operand:GPI 1 "register_operand")]
3398 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3399 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3404 (define_insn "*and<mode>3nr_compare0"
3405 [(set (reg:CC_NZ CC_REGNUM)
3407 (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
3408 (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
3411 "tst\\t%<w>0, %<w>1"
3412 [(set_attr "type" "logics_reg")]
3415 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
3416 [(set (reg:CC_NZ CC_REGNUM)
3419 (match_operand:GPI 0 "register_operand" "r")
3420 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
3421 (match_operand:GPI 2 "register_operand" "r"))
3424 "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
3425 [(set_attr "type" "logics_shift_imm")]
3428 ;; -------------------------------------------------------------------
3430 ;; -------------------------------------------------------------------
3432 (define_expand "<optab><mode>3"
3433 [(set (match_operand:GPI 0 "register_operand")
3434 (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
3435 (match_operand:QI 2 "nonmemory_operand")))]
3438 if (CONST_INT_P (operands[2]))
3440 operands[2] = GEN_INT (INTVAL (operands[2])
3441 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3443 if (operands[2] == const0_rtx)
3445 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3452 (define_expand "ashl<mode>3"
3453 [(set (match_operand:SHORT 0 "register_operand")
3454 (ashift:SHORT (match_operand:SHORT 1 "register_operand")
3455 (match_operand:QI 2 "nonmemory_operand")))]
3458 if (CONST_INT_P (operands[2]))
3460 operands[2] = GEN_INT (INTVAL (operands[2])
3461 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3463 if (operands[2] == const0_rtx)
3465 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3474 (define_expand "rotr<mode>3"
3475 [(set (match_operand:GPI 0 "register_operand")
3476 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3477 (match_operand:QI 2 "nonmemory_operand")))]
3480 if (CONST_INT_P (operands[2]))
3482 operands[2] = GEN_INT (INTVAL (operands[2])
3483 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3485 if (operands[2] == const0_rtx)
3487 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3494 (define_expand "rotl<mode>3"
3495 [(set (match_operand:GPI 0 "register_operand")
3496 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3497 (match_operand:QI 2 "nonmemory_operand")))]
3500 /* (SZ - cnt) % SZ == -cnt % SZ */
3501 if (CONST_INT_P (operands[2]))
3503 operands[2] = GEN_INT ((-INTVAL (operands[2]))
3504 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3505 if (operands[2] == const0_rtx)
3507 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3512 operands[2] = expand_simple_unop (QImode, NEG, operands[2],
3517 ;; Logical left shift using SISD or Integer instruction
3518 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
3519 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3521 (match_operand:GPI 1 "register_operand" "w,w,r")
3522 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3525 shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3526 ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
3527 lsl\t%<w>0, %<w>1, %<w>2"
3528 [(set_attr "simd" "yes,yes,no")
3529 (set_attr "type" "neon_shift_imm<q>, neon_shift_reg<q>,shift_reg")]
3532 ;; Logical right shift using SISD or Integer instruction
3533 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3534 [(set (match_operand:GPI 0 "register_operand" "=w,&w,r")
3536 (match_operand:GPI 1 "register_operand" "w,w,r")
3537 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3540 ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3542 lsr\t%<w>0, %<w>1, %<w>2"
3543 [(set_attr "simd" "yes,yes,no")
3544 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")]
3548 [(set (match_operand:DI 0 "aarch64_simd_register")
3550 (match_operand:DI 1 "aarch64_simd_register")
3551 (match_operand:QI 2 "aarch64_simd_register")))]
3552 "TARGET_SIMD && reload_completed"
3554 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3556 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_USHL))]
3558 operands[3] = gen_lowpart (QImode, operands[0]);
3563 [(set (match_operand:SI 0 "aarch64_simd_register")
3565 (match_operand:SI 1 "aarch64_simd_register")
3566 (match_operand:QI 2 "aarch64_simd_register")))]
3567 "TARGET_SIMD && reload_completed"
3569 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3571 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_USHL_2S))]
3573 operands[3] = gen_lowpart (QImode, operands[0]);
3577 ;; Arithmetic right shift using SISD or Integer instruction
3578 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3579 [(set (match_operand:GPI 0 "register_operand" "=w,&w,&w,r")
3581 (match_operand:GPI 1 "register_operand" "w,w,w,r")
3582 (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,0,rUs<cmode>")))]
3585 sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3588 asr\t%<w>0, %<w>1, %<w>2"
3589 [(set_attr "simd" "yes,yes,yes,no")
3590 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>,shift_reg")]
3594 [(set (match_operand:DI 0 "aarch64_simd_register")
3596 (match_operand:DI 1 "aarch64_simd_register")
3597 (match_operand:QI 2 "aarch64_simd_register")))]
3598 "TARGET_SIMD && reload_completed"
3600 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3602 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_SSHL))]
3604 operands[3] = gen_lowpart (QImode, operands[0]);
3609 [(set (match_operand:SI 0 "aarch64_simd_register")
3611 (match_operand:SI 1 "aarch64_simd_register")
3612 (match_operand:QI 2 "aarch64_simd_register")))]
3613 "TARGET_SIMD && reload_completed"
3615 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3617 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_SSHL_2S))]
3619 operands[3] = gen_lowpart (QImode, operands[0]);
3623 (define_insn "*aarch64_sisd_ushl"
3624 [(set (match_operand:DI 0 "register_operand" "=w")
3625 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3626 (match_operand:QI 2 "register_operand" "w")]
3629 "ushl\t%d0, %d1, %d2"
3630 [(set_attr "simd" "yes")
3631 (set_attr "type" "neon_shift_reg")]
3634 (define_insn "*aarch64_ushl_2s"
3635 [(set (match_operand:SI 0 "register_operand" "=w")
3636 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3637 (match_operand:QI 2 "register_operand" "w")]
3640 "ushl\t%0.2s, %1.2s, %2.2s"
3641 [(set_attr "simd" "yes")
3642 (set_attr "type" "neon_shift_reg")]
3645 (define_insn "*aarch64_sisd_sshl"
3646 [(set (match_operand:DI 0 "register_operand" "=w")
3647 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3648 (match_operand:QI 2 "register_operand" "w")]
3651 "sshl\t%d0, %d1, %d2"
3652 [(set_attr "simd" "yes")
3653 (set_attr "type" "neon_shift_reg")]
3656 (define_insn "*aarch64_sshl_2s"
3657 [(set (match_operand:SI 0 "register_operand" "=w")
3658 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3659 (match_operand:QI 2 "register_operand" "w")]
3662 "sshl\t%0.2s, %1.2s, %2.2s"
3663 [(set_attr "simd" "yes")
3664 (set_attr "type" "neon_shift_reg")]
3667 (define_insn "*aarch64_sisd_neg_qi"
3668 [(set (match_operand:QI 0 "register_operand" "=w")
3669 (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3673 [(set_attr "simd" "yes")
3674 (set_attr "type" "neon_neg")]
3678 (define_insn "*ror<mode>3_insn"
3679 [(set (match_operand:GPI 0 "register_operand" "=r")
3681 (match_operand:GPI 1 "register_operand" "r")
3682 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3684 "ror\\t%<w>0, %<w>1, %<w>2"
3685 [(set_attr "type" "shift_reg")]
3688 ;; zero_extend version of above
3689 (define_insn "*<optab>si3_insn_uxtw"
3690 [(set (match_operand:DI 0 "register_operand" "=r")
3691 (zero_extend:DI (SHIFT:SI
3692 (match_operand:SI 1 "register_operand" "r")
3693 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3695 "<shift>\\t%w0, %w1, %w2"
3696 [(set_attr "type" "shift_reg")]
3699 (define_insn "*<optab><mode>3_insn"
3700 [(set (match_operand:SHORT 0 "register_operand" "=r")
3701 (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3702 (match_operand 2 "const_int_operand" "n")))]
3703 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3705 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3706 return "<bfshift>\t%w0, %w1, %2, %3";
3708 [(set_attr "type" "bfm")]
3711 (define_insn "*extr<mode>5_insn"
3712 [(set (match_operand:GPI 0 "register_operand" "=r")
3713 (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3714 (match_operand 3 "const_int_operand" "n"))
3715 (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3716 (match_operand 4 "const_int_operand" "n"))))]
3717 "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3718 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3719 "extr\\t%<w>0, %<w>1, %<w>2, %4"
3720 [(set_attr "type" "shift_imm")]
3723 ;; There are no canonicalisation rules for ashift and lshiftrt inside an ior
3724 ;; so we have to match both orderings.
3725 (define_insn "*extr<mode>5_insn_alt"
3726 [(set (match_operand:GPI 0 "register_operand" "=r")
3727 (ior:GPI (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3728 (match_operand 4 "const_int_operand" "n"))
3729 (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3730 (match_operand 3 "const_int_operand" "n"))))]
3731 "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode)
3732 && (UINTVAL (operands[3]) + UINTVAL (operands[4])
3733 == GET_MODE_BITSIZE (<MODE>mode))"
3734 "extr\\t%<w>0, %<w>1, %<w>2, %4"
3735 [(set_attr "type" "shift_imm")]
3738 ;; zero_extend version of the above
3739 (define_insn "*extrsi5_insn_uxtw"
3740 [(set (match_operand:DI 0 "register_operand" "=r")
3742 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3743 (match_operand 3 "const_int_operand" "n"))
3744 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3745 (match_operand 4 "const_int_operand" "n")))))]
3746 "UINTVAL (operands[3]) < 32 &&
3747 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3748 "extr\\t%w0, %w1, %w2, %4"
3749 [(set_attr "type" "shift_imm")]
3752 (define_insn "*extrsi5_insn_uxtw_alt"
3753 [(set (match_operand:DI 0 "register_operand" "=r")
3755 (ior:SI (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3756 (match_operand 4 "const_int_operand" "n"))
3757 (ashift:SI (match_operand:SI 1 "register_operand" "r")
3758 (match_operand 3 "const_int_operand" "n")))))]
3759 "UINTVAL (operands[3]) < 32 &&
3760 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3761 "extr\\t%w0, %w1, %w2, %4"
3762 [(set_attr "type" "shift_imm")]
3765 (define_insn "*ror<mode>3_insn"
3766 [(set (match_operand:GPI 0 "register_operand" "=r")
3767 (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3768 (match_operand 2 "const_int_operand" "n")))]
3769 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3771 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3772 return "ror\\t%<w>0, %<w>1, %3";
3774 [(set_attr "type" "shift_imm")]
3777 ;; zero_extend version of the above
3778 (define_insn "*rorsi3_insn_uxtw"
3779 [(set (match_operand:DI 0 "register_operand" "=r")
3781 (rotate:SI (match_operand:SI 1 "register_operand" "r")
3782 (match_operand 2 "const_int_operand" "n"))))]
3783 "UINTVAL (operands[2]) < 32"
3785 operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3786 return "ror\\t%w0, %w1, %3";
3788 [(set_attr "type" "shift_imm")]
3791 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3792 [(set (match_operand:GPI 0 "register_operand" "=r")
3794 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3795 (match_operand 2 "const_int_operand" "n"))))]
3796 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3798 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3799 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3801 [(set_attr "type" "bfm")]
3804 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3805 [(set (match_operand:GPI 0 "register_operand" "=r")
3807 (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3808 (match_operand 2 "const_int_operand" "n"))))]
3809 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3811 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3812 return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3814 [(set_attr "type" "bfm")]
3817 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3818 [(set (match_operand:GPI 0 "register_operand" "=r")
3820 (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3821 (match_operand 2 "const_int_operand" "n"))))]
3822 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3824 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3825 return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3827 [(set_attr "type" "bfm")]
3830 ;; -------------------------------------------------------------------
3832 ;; -------------------------------------------------------------------
3834 (define_expand "<optab>"
3835 [(set (match_operand:DI 0 "register_operand" "=r")
3836 (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3837 (match_operand 2 "const_int_operand" "n")
3838 (match_operand 3 "const_int_operand" "n")))]
3843 (define_insn "*<optab><mode>"
3844 [(set (match_operand:GPI 0 "register_operand" "=r")
3845 (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3846 (match_operand 2 "const_int_operand" "n")
3847 (match_operand 3 "const_int_operand" "n")))]
3849 "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3850 [(set_attr "type" "bfm")]
3853 ;; Bitfield Insert (insv)
3854 (define_expand "insv<mode>"
3855 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3856 (match_operand 1 "const_int_operand")
3857 (match_operand 2 "const_int_operand"))
3858 (match_operand:GPI 3 "general_operand"))]
3861 unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3862 unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3863 rtx value = operands[3];
3865 if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3868 if (CONST_INT_P (value))
3870 unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3872 /* Prefer AND/OR for inserting all zeros or all ones. */
3873 if ((UINTVAL (value) & mask) == 0
3874 || (UINTVAL (value) & mask) == mask)
3877 /* 16-bit aligned 16-bit wide insert is handled by insv_imm. */
3878 if (width == 16 && (pos % 16) == 0)
3881 operands[3] = force_reg (<MODE>mode, value);
3884 (define_insn "*insv_reg<mode>"
3885 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3886 (match_operand 1 "const_int_operand" "n")
3887 (match_operand 2 "const_int_operand" "n"))
3888 (match_operand:GPI 3 "register_operand" "r"))]
3889 "!(UINTVAL (operands[1]) == 0
3890 || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3891 > GET_MODE_BITSIZE (<MODE>mode)))"
3892 "bfi\\t%<w>0, %<w>3, %2, %1"
3893 [(set_attr "type" "bfm")]
3896 (define_insn "*extr_insv_lower_reg<mode>"
3897 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3898 (match_operand 1 "const_int_operand" "n")
3900 (zero_extract:GPI (match_operand:GPI 2 "register_operand" "r")
3902 (match_operand 3 "const_int_operand" "n")))]
3903 "!(UINTVAL (operands[1]) == 0
3904 || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3905 > GET_MODE_BITSIZE (<MODE>mode)))"
3906 "bfxil\\t%<w>0, %<w>2, %3, %1"
3907 [(set_attr "type" "bfm")]
3910 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3911 [(set (match_operand:GPI 0 "register_operand" "=r")
3912 (ashift:GPI (ANY_EXTEND:GPI
3913 (match_operand:ALLX 1 "register_operand" "r"))
3914 (match_operand 2 "const_int_operand" "n")))]
3915 "UINTVAL (operands[2]) < <GPI:sizen>"
3917 operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3918 ? GEN_INT (<ALLX:sizen>)
3919 : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3920 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3922 [(set_attr "type" "bfm")]
3925 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3927 (define_insn "*andim_ashift<mode>_bfiz"
3928 [(set (match_operand:GPI 0 "register_operand" "=r")
3929 (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3930 (match_operand 2 "const_int_operand" "n"))
3931 (match_operand 3 "const_int_operand" "n")))]
3932 "(INTVAL (operands[2]) < (<GPI:sizen>))
3933 && exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3934 && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3935 "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3936 [(set_attr "type" "bfm")]
3939 (define_insn "bswap<mode>2"
3940 [(set (match_operand:GPI 0 "register_operand" "=r")
3941 (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3943 "rev\\t%<w>0, %<w>1"
3944 [(set_attr "type" "rev")]
3947 (define_insn "bswaphi2"
3948 [(set (match_operand:HI 0 "register_operand" "=r")
3949 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3952 [(set_attr "type" "rev")]
3955 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
3956 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
3957 ;; each valid permutation.
3959 (define_insn "rev16<mode>2"
3960 [(set (match_operand:GPI 0 "register_operand" "=r")
3961 (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3963 (match_operand:GPI 3 "const_int_operand" "n"))
3964 (and:GPI (lshiftrt:GPI (match_dup 1)
3966 (match_operand:GPI 2 "const_int_operand" "n"))))]
3967 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3968 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3969 "rev16\\t%<w>0, %<w>1"
3970 [(set_attr "type" "rev")]
3973 (define_insn "rev16<mode>2_alt"
3974 [(set (match_operand:GPI 0 "register_operand" "=r")
3975 (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r")
3977 (match_operand:GPI 2 "const_int_operand" "n"))
3978 (and:GPI (ashift:GPI (match_dup 1)
3980 (match_operand:GPI 3 "const_int_operand" "n"))))]
3981 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3982 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3983 "rev16\\t%<w>0, %<w>1"
3984 [(set_attr "type" "rev")]
3987 ;; zero_extend version of above
3988 (define_insn "*bswapsi2_uxtw"
3989 [(set (match_operand:DI 0 "register_operand" "=r")
3990 (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3993 [(set_attr "type" "rev")]
3996 ;; -------------------------------------------------------------------
3997 ;; Floating-point intrinsics
3998 ;; -------------------------------------------------------------------
4000 ;; frint floating-point round to integral standard patterns.
4001 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round, frintn.
4003 (define_insn "<frint_pattern><mode>2"
4004 [(set (match_operand:GPF 0 "register_operand" "=w")
4005 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
4008 "frint<frint_suffix>\\t%<s>0, %<s>1"
4009 [(set_attr "type" "f_rint<s>")]
4012 ;; frcvt floating-point round to integer and convert standard patterns.
4013 ;; Expands to lbtrunc, lceil, lfloor, lround.
4014 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
4015 [(set (match_operand:GPI 0 "register_operand" "=r")
4016 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
4019 "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
4020 [(set_attr "type" "f_cvtf2i")]
4025 (define_insn "fma<mode>4"
4026 [(set (match_operand:GPF 0 "register_operand" "=w")
4027 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
4028 (match_operand:GPF 2 "register_operand" "w")
4029 (match_operand:GPF 3 "register_operand" "w")))]
4031 "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
4032 [(set_attr "type" "fmac<s>")]
4035 (define_insn "fnma<mode>4"
4036 [(set (match_operand:GPF 0 "register_operand" "=w")
4037 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
4038 (match_operand:GPF 2 "register_operand" "w")
4039 (match_operand:GPF 3 "register_operand" "w")))]
4041 "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
4042 [(set_attr "type" "fmac<s>")]
4045 (define_insn "fms<mode>4"
4046 [(set (match_operand:GPF 0 "register_operand" "=w")
4047 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
4048 (match_operand:GPF 2 "register_operand" "w")
4049 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
4051 "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
4052 [(set_attr "type" "fmac<s>")]
4055 (define_insn "fnms<mode>4"
4056 [(set (match_operand:GPF 0 "register_operand" "=w")
4057 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
4058 (match_operand:GPF 2 "register_operand" "w")
4059 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
4061 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
4062 [(set_attr "type" "fmac<s>")]
4065 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
4066 (define_insn "*fnmadd<mode>4"
4067 [(set (match_operand:GPF 0 "register_operand" "=w")
4068 (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
4069 (match_operand:GPF 2 "register_operand" "w")
4070 (match_operand:GPF 3 "register_operand" "w"))))]
4071 "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
4072 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
4073 [(set_attr "type" "fmac<s>")]
4076 ;; -------------------------------------------------------------------
4077 ;; Floating-point conversions
4078 ;; -------------------------------------------------------------------
4080 (define_insn "extendsfdf2"
4081 [(set (match_operand:DF 0 "register_operand" "=w")
4082 (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
4085 [(set_attr "type" "f_cvt")]
4088 (define_insn "truncdfsf2"
4089 [(set (match_operand:SF 0 "register_operand" "=w")
4090 (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
4093 [(set_attr "type" "f_cvt")]
4096 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
4097 [(set (match_operand:GPI 0 "register_operand" "=r")
4098 (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
4100 "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
4101 [(set_attr "type" "f_cvtf2i")]
4104 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
4105 [(set (match_operand:GPI 0 "register_operand" "=r")
4106 (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
4108 "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
4109 [(set_attr "type" "f_cvtf2i")]
4112 (define_insn "<optab><fcvt_target><GPF:mode>2"
4113 [(set (match_operand:GPF 0 "register_operand" "=w,w")
4114 (FLOATUORS:GPF (match_operand:<FCVT_TARGET> 1 "register_operand" "w,r")))]
4117 <su_optab>cvtf\t%<GPF:s>0, %<s>1
4118 <su_optab>cvtf\t%<GPF:s>0, %<w1>1"
4119 [(set_attr "simd" "yes,no")
4120 (set_attr "fp" "no,yes")
4121 (set_attr "type" "neon_int_to_fp_<Vetype>,f_cvti2f")]
4124 (define_insn "<optab><fcvt_iesize><GPF:mode>2"
4125 [(set (match_operand:GPF 0 "register_operand" "=w")
4126 (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand" "r")))]
4128 "<su_optab>cvtf\t%<GPF:s>0, %<w2>1"
4129 [(set_attr "type" "f_cvti2f")]
4132 ;; -------------------------------------------------------------------
4133 ;; Floating-point arithmetic
4134 ;; -------------------------------------------------------------------
4136 (define_insn "add<mode>3"
4137 [(set (match_operand:GPF 0 "register_operand" "=w")
4139 (match_operand:GPF 1 "register_operand" "w")
4140 (match_operand:GPF 2 "register_operand" "w")))]
4142 "fadd\\t%<s>0, %<s>1, %<s>2"
4143 [(set_attr "type" "fadd<s>")]
4146 (define_insn "sub<mode>3"
4147 [(set (match_operand:GPF 0 "register_operand" "=w")
4149 (match_operand:GPF 1 "register_operand" "w")
4150 (match_operand:GPF 2 "register_operand" "w")))]
4152 "fsub\\t%<s>0, %<s>1, %<s>2"
4153 [(set_attr "type" "fadd<s>")]
4156 (define_insn "mul<mode>3"
4157 [(set (match_operand:GPF 0 "register_operand" "=w")
4159 (match_operand:GPF 1 "register_operand" "w")
4160 (match_operand:GPF 2 "register_operand" "w")))]
4162 "fmul\\t%<s>0, %<s>1, %<s>2"
4163 [(set_attr "type" "fmul<s>")]
4166 (define_insn "*fnmul<mode>3"
4167 [(set (match_operand:GPF 0 "register_operand" "=w")
4169 (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
4170 (match_operand:GPF 2 "register_operand" "w")))]
4172 "fnmul\\t%<s>0, %<s>1, %<s>2"
4173 [(set_attr "type" "fmul<s>")]
4176 (define_insn "div<mode>3"
4177 [(set (match_operand:GPF 0 "register_operand" "=w")
4179 (match_operand:GPF 1 "register_operand" "w")
4180 (match_operand:GPF 2 "register_operand" "w")))]
4182 "fdiv\\t%<s>0, %<s>1, %<s>2"
4183 [(set_attr "type" "fdiv<s>")]
4186 (define_insn "neg<mode>2"
4187 [(set (match_operand:GPF 0 "register_operand" "=w")
4188 (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
4190 "fneg\\t%<s>0, %<s>1"
4191 [(set_attr "type" "ffarith<s>")]
4194 (define_insn "sqrt<mode>2"
4195 [(set (match_operand:GPF 0 "register_operand" "=w")
4196 (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
4198 "fsqrt\\t%<s>0, %<s>1"
4199 [(set_attr "type" "fsqrt<s>")]
4202 (define_insn "abs<mode>2"
4203 [(set (match_operand:GPF 0 "register_operand" "=w")
4204 (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
4206 "fabs\\t%<s>0, %<s>1"
4207 [(set_attr "type" "ffarith<s>")]
4210 ;; Given that smax/smin do not specify the result when either input is NaN,
4211 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
4214 (define_insn "smax<mode>3"
4215 [(set (match_operand:GPF 0 "register_operand" "=w")
4216 (smax:GPF (match_operand:GPF 1 "register_operand" "w")
4217 (match_operand:GPF 2 "register_operand" "w")))]
4219 "fmaxnm\\t%<s>0, %<s>1, %<s>2"
4220 [(set_attr "type" "f_minmax<s>")]
4223 (define_insn "smin<mode>3"
4224 [(set (match_operand:GPF 0 "register_operand" "=w")
4225 (smin:GPF (match_operand:GPF 1 "register_operand" "w")
4226 (match_operand:GPF 2 "register_operand" "w")))]
4228 "fminnm\\t%<s>0, %<s>1, %<s>2"
4229 [(set_attr "type" "f_minmax<s>")]
4232 ;; -------------------------------------------------------------------
4234 ;; -------------------------------------------------------------------
4236 (define_expand "aarch64_reload_mov<mode>"
4237 [(set (match_operand:TX 0 "register_operand" "=w")
4238 (match_operand:TX 1 "register_operand" "w"))
4239 (clobber (match_operand:DI 2 "register_operand" "=&r"))
4243 rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
4244 rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
4245 gen_aarch64_movtilow_tilow (op0, op1);
4246 gen_aarch64_movdi_tihigh (operands[2], op1);
4247 gen_aarch64_movtihigh_di (op0, operands[2]);
4252 ;; The following secondary reload helpers patterns are invoked
4253 ;; after or during reload as we don't want these patterns to start
4254 ;; kicking in during the combiner.
4256 (define_insn "aarch64_movdi_<mode>low"
4257 [(set (match_operand:DI 0 "register_operand" "=r")
4258 (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
4259 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4261 [(set_attr "type" "f_mrc")
4262 (set_attr "length" "4")
4265 (define_insn "aarch64_movdi_<mode>high"
4266 [(set (match_operand:DI 0 "register_operand" "=r")
4268 (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
4270 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4271 "fmov\\t%x0, %1.d[1]"
4272 [(set_attr "type" "f_mrc")
4273 (set_attr "length" "4")
4276 (define_insn "aarch64_mov<mode>high_di"
4277 [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
4278 (const_int 64) (const_int 64))
4279 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4280 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4281 "fmov\\t%0.d[1], %x1"
4282 [(set_attr "type" "f_mcr")
4283 (set_attr "length" "4")
4286 (define_insn "aarch64_mov<mode>low_di"
4287 [(set (match_operand:TX 0 "register_operand" "=w")
4288 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4289 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4291 [(set_attr "type" "f_mcr")
4292 (set_attr "length" "4")
4295 (define_insn "aarch64_movtilow_tilow"
4296 [(set (match_operand:TI 0 "register_operand" "=w")
4298 (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
4299 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4301 [(set_attr "type" "fmov")
4302 (set_attr "length" "4")
4305 ;; There is a deliberate reason why the parameters of high and lo_sum's
4306 ;; don't have modes for ADRP and ADD instructions. This is to allow high
4307 ;; and lo_sum's to be used with the labels defining the jump tables in
4310 (define_expand "add_losym"
4311 [(set (match_operand 0 "register_operand" "=r")
4312 (lo_sum (match_operand 1 "register_operand" "r")
4313 (match_operand 2 "aarch64_valid_symref" "S")))]
4316 machine_mode mode = GET_MODE (operands[0]);
4318 emit_insn ((mode == DImode
4320 : gen_add_losym_si) (operands[0],
4326 (define_insn "add_losym_<mode>"
4327 [(set (match_operand:P 0 "register_operand" "=r")
4328 (lo_sum:P (match_operand:P 1 "register_operand" "r")
4329 (match_operand 2 "aarch64_valid_symref" "S")))]
4331 "add\\t%<w>0, %<w>1, :lo12:%a2"
4332 [(set_attr "type" "alu_imm")]
4335 (define_insn "ldr_got_small_<mode>"
4336 [(set (match_operand:PTR 0 "register_operand" "=r")
4337 (unspec:PTR [(mem:PTR (lo_sum:PTR
4338 (match_operand:PTR 1 "register_operand" "r")
4339 (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
4340 UNSPEC_GOTSMALLPIC))]
4342 "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
4343 [(set_attr "type" "load1")]
4346 (define_insn "ldr_got_small_sidi"
4347 [(set (match_operand:DI 0 "register_operand" "=r")
4349 (unspec:SI [(mem:SI (lo_sum:DI
4350 (match_operand:DI 1 "register_operand" "r")
4351 (match_operand:DI 2 "aarch64_valid_symref" "S")))]
4352 UNSPEC_GOTSMALLPIC)))]
4354 "ldr\\t%w0, [%1, #:got_lo12:%a2]"
4355 [(set_attr "type" "load1")]
4358 (define_insn "ldr_got_tiny"
4359 [(set (match_operand:DI 0 "register_operand" "=r")
4360 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
4361 UNSPEC_GOTTINYPIC))]
4364 [(set_attr "type" "load1")]
4367 (define_insn "aarch64_load_tp_hard"
4368 [(set (match_operand:DI 0 "register_operand" "=r")
4369 (unspec:DI [(const_int 0)] UNSPEC_TLS))]
4371 "mrs\\t%0, tpidr_el0"
4372 [(set_attr "type" "mrs")]
4375 ;; The TLS ABI specifically requires that the compiler does not schedule
4376 ;; instructions in the TLS stubs, in order to enable linker relaxation.
4377 ;; Therefore we treat the stubs as an atomic sequence.
4378 (define_expand "tlsgd_small"
4379 [(parallel [(set (match_operand 0 "register_operand" "")
4380 (call (mem:DI (match_dup 2)) (const_int 1)))
4381 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
4382 (clobber (reg:DI LR_REGNUM))])]
4385 operands[2] = aarch64_tls_get_addr ();
4388 (define_insn "*tlsgd_small"
4389 [(set (match_operand 0 "register_operand" "")
4390 (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
4391 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
4392 (clobber (reg:DI LR_REGNUM))
4395 "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
4396 [(set_attr "type" "call")
4397 (set_attr "length" "16")])
4399 (define_insn "tlsie_small_<mode>"
4400 [(set (match_operand:PTR 0 "register_operand" "=r")
4401 (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
4402 UNSPEC_GOTSMALLTLS))]
4404 "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
4405 [(set_attr "type" "load1")
4406 (set_attr "length" "8")]
4409 (define_insn "tlsie_small_sidi"
4410 [(set (match_operand:DI 0 "register_operand" "=r")
4412 (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")]
4413 UNSPEC_GOTSMALLTLS)))]
4415 "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
4416 [(set_attr "type" "load1")
4417 (set_attr "length" "8")]
4420 (define_expand "tlsle_small"
4421 [(set (match_operand 0 "register_operand" "=r")
4422 (unspec [(match_operand 1 "register_operand" "r")
4423 (match_operand 2 "aarch64_tls_le_symref" "S")]
4424 UNSPEC_GOTSMALLTLS))]
4427 machine_mode mode = GET_MODE (operands[0]);
4428 emit_insn ((mode == DImode
4429 ? gen_tlsle_small_di
4430 : gen_tlsle_small_si) (operands[0],
4436 (define_insn "tlsle_small_<mode>"
4437 [(set (match_operand:P 0 "register_operand" "=r")
4438 (unspec:P [(match_operand:P 1 "register_operand" "r")
4439 (match_operand 2 "aarch64_tls_le_symref" "S")]
4440 UNSPEC_GOTSMALLTLS))]
4442 "add\\t%<w>0, %<w>1, #%G2, lsl #12\;add\\t%<w>0, %<w>0, #%L2"
4443 [(set_attr "type" "alu_sreg")
4444 (set_attr "length" "8")]
4447 (define_insn "tlsdesc_small_<mode>"
4448 [(set (reg:PTR R0_REGNUM)
4449 (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
4451 (clobber (reg:DI LR_REGNUM))
4452 (clobber (reg:CC CC_REGNUM))
4453 (clobber (match_scratch:DI 1 "=r"))]
4455 "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
4456 [(set_attr "type" "call")
4457 (set_attr "length" "16")])
4459 (define_insn "stack_tie"
4460 [(set (mem:BLK (scratch))
4461 (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
4462 (match_operand:DI 1 "register_operand" "rk")]
4466 [(set_attr "length" "0")]
4469 ;; Named pattern for expanding thread pointer reference.
4470 (define_expand "get_thread_pointerdi"
4471 [(match_operand:DI 0 "register_operand" "=r")]
4474 rtx tmp = aarch64_load_tp (operands[0]);
4475 if (tmp != operands[0])
4476 emit_move_insn (operands[0], tmp);
4480 ;; Named patterns for stack smashing protection.
4481 (define_expand "stack_protect_set"
4482 [(match_operand 0 "memory_operand")
4483 (match_operand 1 "memory_operand")]
4486 machine_mode mode = GET_MODE (operands[0]);
4488 emit_insn ((mode == DImode
4489 ? gen_stack_protect_set_di
4490 : gen_stack_protect_set_si) (operands[0], operands[1]));
4494 (define_insn "stack_protect_set_<mode>"
4495 [(set (match_operand:PTR 0 "memory_operand" "=m")
4496 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
4498 (set (match_scratch:PTR 2 "=&r") (const_int 0))]
4500 "ldr\\t%<w>2, %1\;str\\t%<w>2, %0\;mov\t%<w>2,0"
4501 [(set_attr "length" "12")
4502 (set_attr "type" "multiple")])
4504 (define_expand "stack_protect_test"
4505 [(match_operand 0 "memory_operand")
4506 (match_operand 1 "memory_operand")
4511 machine_mode mode = GET_MODE (operands[0]);
4513 result = gen_reg_rtx(mode);
4515 emit_insn ((mode == DImode
4516 ? gen_stack_protect_test_di
4517 : gen_stack_protect_test_si) (result,
4522 emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4523 result, const0_rtx, operands[2]));
4525 emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4526 result, const0_rtx, operands[2]));
4530 (define_insn "stack_protect_test_<mode>"
4531 [(set (match_operand:PTR 0 "register_operand" "=r")
4532 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
4533 (match_operand:PTR 2 "memory_operand" "m")]
4535 (clobber (match_scratch:PTR 3 "=&r"))]
4537 "ldr\t%<w>3, %x1\;ldr\t%<w>0, %x2\;eor\t%<w>0, %<w>3, %<w>0"
4538 [(set_attr "length" "12")
4539 (set_attr "type" "multiple")])
4541 ;; Write Floating-point Control Register.
4542 (define_insn "set_fpcr"
4543 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
4546 [(set_attr "type" "mrs")])
4548 ;; Read Floating-point Control Register.
4549 (define_insn "get_fpcr"
4550 [(set (match_operand:SI 0 "register_operand" "=r")
4551 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
4554 [(set_attr "type" "mrs")])
4556 ;; Write Floating-point Status Register.
4557 (define_insn "set_fpsr"
4558 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
4561 [(set_attr "type" "mrs")])
4563 ;; Read Floating-point Status Register.
4564 (define_insn "get_fpsr"
4565 [(set (match_operand:SI 0 "register_operand" "=r")
4566 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
4569 [(set_attr "type" "mrs")])
4572 ;; Define the subtract-one-and-jump insns so loop.c
4573 ;; knows what to generate.
4574 (define_expand "doloop_end"
4575 [(use (match_operand 0 "" "")) ; loop pseudo
4576 (use (match_operand 1 "" ""))] ; label
4577 "optimize > 0 && flag_modulo_sched"
4586 /* Currently SMS relies on the do-loop pattern to recognize loops
4587 where (1) the control part consists of all insns defining and/or
4588 using a certain 'count' register and (2) the loop count can be
4589 adjusted by modifying this register prior to the loop.
4590 ??? The possible introduction of a new block to initialize the
4591 new IV can potentially affect branch optimizations. */
4593 if (GET_MODE (operands[0]) != DImode)
4597 insn = emit_insn (gen_adddi3_compare0 (s0, s0, GEN_INT (-1)));
4599 cmp = XVECEXP (PATTERN (insn), 0, 0);
4600 cc_reg = SET_DEST (cmp);
4601 bcomp = gen_rtx_NE (VOIDmode, cc_reg, const0_rtx);
4602 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
4603 emit_jump_insn (gen_rtx_SET (pc_rtx,
4604 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
4610 (include "aarch64-simd.md")
4612 ;; Atomic Operations
4613 (include "atomics.md")
4615 ;; ldp/stp peephole patterns
4616 (include "aarch64-ldpstp.md")