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,neon_move,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,neon_move")
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 aarch64_err_no_fpadvsimd (<MODE>mode, "code");
989 if (GET_CODE (operands[0]) == MEM
990 && ! (GET_CODE (operands[1]) == CONST_DOUBLE
991 && aarch64_float_const_zero_rtx_p (operands[1])))
992 operands[1] = force_reg (<MODE>mode, operands[1]);
996 (define_insn "*movsf_aarch64"
997 [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
998 (match_operand:SF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
999 "TARGET_FLOAT && (register_operand (operands[0], SFmode)
1000 || aarch64_reg_or_fp_zero (operands[1], SFmode))"
1011 [(set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
1012 f_loads,f_stores,load1,store1,mov_reg")]
1015 (define_insn "*movdf_aarch64"
1016 [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
1017 (match_operand:DF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
1018 "TARGET_FLOAT && (register_operand (operands[0], DFmode)
1019 || aarch64_reg_or_fp_zero (operands[1], DFmode))"
1030 [(set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
1031 f_loadd,f_stored,load1,store1,mov_reg")]
1034 (define_expand "movtf"
1035 [(set (match_operand:TF 0 "nonimmediate_operand" "")
1036 (match_operand:TF 1 "general_operand" ""))]
1041 aarch64_err_no_fpadvsimd (TFmode, "code");
1045 if (GET_CODE (operands[0]) == MEM
1046 && ! (GET_CODE (operands[1]) == CONST_DOUBLE
1047 && aarch64_float_const_zero_rtx_p (operands[1])))
1048 operands[1] = force_reg (TFmode, operands[1]);
1052 (define_insn "*movtf_aarch64"
1053 [(set (match_operand:TF 0
1054 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump,Ump")
1056 "general_operand" " w,?r, ?r,w ,Y,Y ,m,w,Ump,?r ,Y"))]
1057 "TARGET_FLOAT && (register_operand (operands[0], TFmode)
1058 || aarch64_reg_or_fp_zero (operands[1], TFmode))"
1060 orr\\t%0.16b, %1.16b, %1.16b
1071 [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,neon_move_q,fconstd,\
1072 f_loadd,f_stored,load2,store2,store2")
1073 (set_attr "length" "4,8,8,8,4,4,4,4,4,4,4")
1074 (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*,*")
1075 (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*,*")]
1079 [(set (match_operand:TF 0 "register_operand" "")
1080 (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
1081 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
1084 aarch64_split_128bit_move (operands[0], operands[1]);
1091 ;; 2 is size of move in bytes
1094 (define_expand "movmemdi"
1095 [(match_operand:BLK 0 "memory_operand")
1096 (match_operand:BLK 1 "memory_operand")
1097 (match_operand:DI 2 "immediate_operand")
1098 (match_operand:DI 3 "immediate_operand")]
1101 if (aarch64_expand_movmem (operands))
1107 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1108 ;; fairly lax checking on the second memory operation.
1109 (define_insn "load_pairsi"
1110 [(set (match_operand:SI 0 "register_operand" "=r,*w")
1111 (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1112 (set (match_operand:SI 2 "register_operand" "=r,*w")
1113 (match_operand:SI 3 "memory_operand" "m,m"))]
1114 "rtx_equal_p (XEXP (operands[3], 0),
1115 plus_constant (Pmode,
1116 XEXP (operands[1], 0),
1117 GET_MODE_SIZE (SImode)))"
1121 [(set_attr "type" "load2,neon_load1_2reg")
1122 (set_attr "fp" "*,yes")]
1125 (define_insn "load_pairdi"
1126 [(set (match_operand:DI 0 "register_operand" "=r,*w")
1127 (match_operand:DI 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1128 (set (match_operand:DI 2 "register_operand" "=r,*w")
1129 (match_operand:DI 3 "memory_operand" "m,m"))]
1130 "rtx_equal_p (XEXP (operands[3], 0),
1131 plus_constant (Pmode,
1132 XEXP (operands[1], 0),
1133 GET_MODE_SIZE (DImode)))"
1137 [(set_attr "type" "load2,neon_load1_2reg")
1138 (set_attr "fp" "*,yes")]
1142 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1143 ;; fairly lax checking on the second memory operation.
1144 (define_insn "store_pairsi"
1145 [(set (match_operand:SI 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1146 (match_operand:SI 1 "aarch64_reg_or_zero" "rZ,*w"))
1147 (set (match_operand:SI 2 "memory_operand" "=m,m")
1148 (match_operand:SI 3 "aarch64_reg_or_zero" "rZ,*w"))]
1149 "rtx_equal_p (XEXP (operands[2], 0),
1150 plus_constant (Pmode,
1151 XEXP (operands[0], 0),
1152 GET_MODE_SIZE (SImode)))"
1156 [(set_attr "type" "store2,neon_store1_2reg")
1157 (set_attr "fp" "*,yes")]
1160 (define_insn "store_pairdi"
1161 [(set (match_operand:DI 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1162 (match_operand:DI 1 "aarch64_reg_or_zero" "rZ,*w"))
1163 (set (match_operand:DI 2 "memory_operand" "=m,m")
1164 (match_operand:DI 3 "aarch64_reg_or_zero" "rZ,*w"))]
1165 "rtx_equal_p (XEXP (operands[2], 0),
1166 plus_constant (Pmode,
1167 XEXP (operands[0], 0),
1168 GET_MODE_SIZE (DImode)))"
1172 [(set_attr "type" "store2,neon_store1_2reg")
1173 (set_attr "fp" "*,yes")]
1176 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1177 ;; fairly lax checking on the second memory operation.
1178 (define_insn "load_pairsf"
1179 [(set (match_operand:SF 0 "register_operand" "=w,*r")
1180 (match_operand:SF 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1181 (set (match_operand:SF 2 "register_operand" "=w,*r")
1182 (match_operand:SF 3 "memory_operand" "m,m"))]
1183 "rtx_equal_p (XEXP (operands[3], 0),
1184 plus_constant (Pmode,
1185 XEXP (operands[1], 0),
1186 GET_MODE_SIZE (SFmode)))"
1190 [(set_attr "type" "neon_load1_2reg,load2")
1191 (set_attr "fp" "yes,*")]
1194 (define_insn "load_pairdf"
1195 [(set (match_operand:DF 0 "register_operand" "=w,*r")
1196 (match_operand:DF 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1197 (set (match_operand:DF 2 "register_operand" "=w,*r")
1198 (match_operand:DF 3 "memory_operand" "m,m"))]
1199 "rtx_equal_p (XEXP (operands[3], 0),
1200 plus_constant (Pmode,
1201 XEXP (operands[1], 0),
1202 GET_MODE_SIZE (DFmode)))"
1206 [(set_attr "type" "neon_load1_2reg,load2")
1207 (set_attr "fp" "yes,*")]
1210 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1211 ;; fairly lax checking on the second memory operation.
1212 (define_insn "store_pairsf"
1213 [(set (match_operand:SF 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1214 (match_operand:SF 1 "register_operand" "w,*r"))
1215 (set (match_operand:SF 2 "memory_operand" "=m,m")
1216 (match_operand:SF 3 "register_operand" "w,*r"))]
1217 "rtx_equal_p (XEXP (operands[2], 0),
1218 plus_constant (Pmode,
1219 XEXP (operands[0], 0),
1220 GET_MODE_SIZE (SFmode)))"
1224 [(set_attr "type" "neon_store1_2reg,store2")
1225 (set_attr "fp" "yes,*")]
1228 (define_insn "store_pairdf"
1229 [(set (match_operand:DF 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1230 (match_operand:DF 1 "register_operand" "w,*r"))
1231 (set (match_operand:DF 2 "memory_operand" "=m,m")
1232 (match_operand:DF 3 "register_operand" "w,*r"))]
1233 "rtx_equal_p (XEXP (operands[2], 0),
1234 plus_constant (Pmode,
1235 XEXP (operands[0], 0),
1236 GET_MODE_SIZE (DFmode)))"
1240 [(set_attr "type" "neon_store1_2reg,store2")
1241 (set_attr "fp" "yes,*")]
1244 ;; Load pair with post-index writeback. This is primarily used in function
1246 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
1248 [(set (match_operand:P 0 "register_operand" "=k")
1249 (plus:P (match_operand:P 1 "register_operand" "0")
1250 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1251 (set (match_operand:GPI 2 "register_operand" "=r")
1252 (mem:GPI (match_dup 1)))
1253 (set (match_operand:GPI 3 "register_operand" "=r")
1254 (mem:GPI (plus:P (match_dup 1)
1255 (match_operand:P 5 "const_int_operand" "n"))))])]
1256 "INTVAL (operands[5]) == GET_MODE_SIZE (<GPI:MODE>mode)"
1257 "ldp\\t%<w>2, %<w>3, [%1], %4"
1258 [(set_attr "type" "load2")]
1261 (define_insn "loadwb_pair<GPF:mode>_<P:mode>"
1263 [(set (match_operand:P 0 "register_operand" "=k")
1264 (plus:P (match_operand:P 1 "register_operand" "0")
1265 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1266 (set (match_operand:GPF 2 "register_operand" "=w")
1267 (mem:GPF (match_dup 1)))
1268 (set (match_operand:GPF 3 "register_operand" "=w")
1269 (mem:GPF (plus:P (match_dup 1)
1270 (match_operand:P 5 "const_int_operand" "n"))))])]
1271 "INTVAL (operands[5]) == GET_MODE_SIZE (<GPF:MODE>mode)"
1272 "ldp\\t%<w>2, %<w>3, [%1], %4"
1273 [(set_attr "type" "neon_load1_2reg")]
1276 ;; Store pair with pre-index writeback. This is primarily used in function
1278 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
1280 [(set (match_operand:P 0 "register_operand" "=&k")
1281 (plus:P (match_operand:P 1 "register_operand" "0")
1282 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1283 (set (mem:GPI (plus:P (match_dup 0)
1285 (match_operand:GPI 2 "register_operand" "r"))
1286 (set (mem:GPI (plus:P (match_dup 0)
1287 (match_operand:P 5 "const_int_operand" "n")))
1288 (match_operand:GPI 3 "register_operand" "r"))])]
1289 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1290 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1291 [(set_attr "type" "store2")]
1294 (define_insn "storewb_pair<GPF:mode>_<P:mode>"
1296 [(set (match_operand:P 0 "register_operand" "=&k")
1297 (plus:P (match_operand:P 1 "register_operand" "0")
1298 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1299 (set (mem:GPF (plus:P (match_dup 0)
1301 (match_operand:GPF 2 "register_operand" "w"))
1302 (set (mem:GPF (plus:P (match_dup 0)
1303 (match_operand:P 5 "const_int_operand" "n")))
1304 (match_operand:GPF 3 "register_operand" "w"))])]
1305 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPF:MODE>mode)"
1306 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1307 [(set_attr "type" "neon_store1_2reg<q>")]
1310 ;; -------------------------------------------------------------------
1311 ;; Sign/Zero extension
1312 ;; -------------------------------------------------------------------
1314 (define_expand "<optab>sidi2"
1315 [(set (match_operand:DI 0 "register_operand")
1316 (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1320 (define_insn "*extendsidi2_aarch64"
1321 [(set (match_operand:DI 0 "register_operand" "=r,r")
1322 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1327 [(set_attr "type" "extend,load1")]
1330 (define_insn "*load_pair_extendsidi2_aarch64"
1331 [(set (match_operand:DI 0 "register_operand" "=r")
1332 (sign_extend:DI (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump")))
1333 (set (match_operand:DI 2 "register_operand" "=r")
1334 (sign_extend:DI (match_operand:SI 3 "memory_operand" "m")))]
1335 "rtx_equal_p (XEXP (operands[3], 0),
1336 plus_constant (Pmode,
1337 XEXP (operands[1], 0),
1338 GET_MODE_SIZE (SImode)))"
1339 "ldpsw\\t%0, %2, %1"
1340 [(set_attr "type" "load2")]
1343 (define_insn "*zero_extendsidi2_aarch64"
1344 [(set (match_operand:DI 0 "register_operand" "=r,r")
1345 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1350 [(set_attr "type" "extend,load1")]
1353 (define_insn "*load_pair_zero_extendsidi2_aarch64"
1354 [(set (match_operand:DI 0 "register_operand" "=r")
1355 (zero_extend:DI (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump")))
1356 (set (match_operand:DI 2 "register_operand" "=r")
1357 (zero_extend:DI (match_operand:SI 3 "memory_operand" "m")))]
1358 "rtx_equal_p (XEXP (operands[3], 0),
1359 plus_constant (Pmode,
1360 XEXP (operands[1], 0),
1361 GET_MODE_SIZE (SImode)))"
1362 "ldp\\t%w0, %w2, %1"
1363 [(set_attr "type" "load2")]
1366 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1367 [(set (match_operand:GPI 0 "register_operand")
1368 (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1372 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1373 [(set (match_operand:GPI 0 "register_operand" "=r,r")
1374 (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1377 sxt<SHORT:size>\t%<GPI:w>0, %w1
1378 ldrs<SHORT:size>\t%<GPI:w>0, %1"
1379 [(set_attr "type" "extend,load1")]
1382 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1383 [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1384 (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1387 uxt<SHORT:size>\t%<GPI:w>0, %w1
1388 ldr<SHORT:size>\t%w0, %1
1389 ldr\t%<SHORT:size>0, %1"
1390 [(set_attr "type" "extend,load1,load1")]
1393 (define_expand "<optab>qihi2"
1394 [(set (match_operand:HI 0 "register_operand")
1395 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1399 (define_insn "*<optab>qihi2_aarch64"
1400 [(set (match_operand:HI 0 "register_operand" "=r,r")
1401 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1406 [(set_attr "type" "extend,load1")]
1409 ;; -------------------------------------------------------------------
1410 ;; Simple arithmetic
1411 ;; -------------------------------------------------------------------
1413 (define_expand "add<mode>3"
1415 (match_operand:GPI 0 "register_operand" "")
1416 (plus:GPI (match_operand:GPI 1 "register_operand" "")
1417 (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1420 if (! aarch64_plus_operand (operands[2], VOIDmode))
1422 HOST_WIDE_INT imm = INTVAL (operands[2]);
1424 if (aarch64_move_imm (imm, <MODE>mode) && can_create_pseudo_p ())
1426 rtx tmp = gen_reg_rtx (<MODE>mode);
1427 emit_move_insn (tmp, operands[2]);
1432 rtx subtarget = ((optimize && can_create_pseudo_p ())
1433 ? gen_reg_rtx (<MODE>mode) : operands[0]);
1436 imm = -(-imm & ~0xfff);
1440 emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1441 operands[1] = subtarget;
1442 operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1448 (define_insn "*addsi3_aarch64"
1450 (match_operand:SI 0 "register_operand" "=rk,rk,w,rk")
1452 (match_operand:SI 1 "register_operand" "%rk,rk,w,rk")
1453 (match_operand:SI 2 "aarch64_plus_operand" "I,r,w,J")))]
1458 add\\t%0.2s, %1.2s, %2.2s
1459 sub\\t%w0, %w1, #%n2"
1460 [(set_attr "type" "alu_imm,alu_sreg,neon_add,alu_imm")
1461 (set_attr "simd" "*,*,yes,*")]
1464 ;; zero_extend version of above
1465 (define_insn "*addsi3_aarch64_uxtw"
1467 (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1469 (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1470 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1475 sub\\t%w0, %w1, #%n2"
1476 [(set_attr "type" "alu_imm,alu_sreg,alu_imm")]
1479 (define_insn "*adddi3_aarch64"
1481 (match_operand:DI 0 "register_operand" "=rk,rk,rk,w")
1483 (match_operand:DI 1 "register_operand" "%rk,rk,rk,w")
1484 (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,w")))]
1489 sub\\t%x0, %x1, #%n2
1490 add\\t%d0, %d1, %d2"
1491 [(set_attr "type" "alu_imm,alu_sreg,alu_imm,neon_add")
1492 (set_attr "simd" "*,*,*,yes")]
1495 (define_expand "addti3"
1496 [(set (match_operand:TI 0 "register_operand" "")
1497 (plus:TI (match_operand:TI 1 "register_operand" "")
1498 (match_operand:TI 2 "register_operand" "")))]
1501 rtx low = gen_reg_rtx (DImode);
1502 emit_insn (gen_adddi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1503 gen_lowpart (DImode, operands[2])));
1505 rtx high = gen_reg_rtx (DImode);
1506 emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]),
1507 gen_highpart (DImode, operands[2])));
1509 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1510 emit_move_insn (gen_highpart (DImode, operands[0]), high);
1514 (define_insn "add<mode>3_compare0"
1515 [(set (reg:CC_NZ CC_REGNUM)
1517 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1518 (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1520 (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1521 (plus:GPI (match_dup 1) (match_dup 2)))]
1524 adds\\t%<w>0, %<w>1, %<w>2
1525 adds\\t%<w>0, %<w>1, %<w>2
1526 subs\\t%<w>0, %<w>1, #%n2"
1527 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1530 ;; zero_extend version of above
1531 (define_insn "*addsi3_compare0_uxtw"
1532 [(set (reg:CC_NZ CC_REGNUM)
1534 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1535 (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1537 (set (match_operand:DI 0 "register_operand" "=r,r,r")
1538 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1541 adds\\t%w0, %w1, %w2
1542 adds\\t%w0, %w1, %w2
1543 subs\\t%w0, %w1, #%n2"
1544 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1547 (define_insn "*adds_shift_imm_<mode>"
1548 [(set (reg:CC_NZ CC_REGNUM)
1550 (plus:GPI (ASHIFT:GPI
1551 (match_operand:GPI 1 "register_operand" "r")
1552 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1553 (match_operand:GPI 3 "register_operand" "r"))
1555 (set (match_operand:GPI 0 "register_operand" "=r")
1556 (plus:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))
1559 "adds\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1560 [(set_attr "type" "alus_shift_imm")]
1563 (define_insn "*subs_shift_imm_<mode>"
1564 [(set (reg:CC_NZ CC_REGNUM)
1566 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1568 (match_operand:GPI 2 "register_operand" "r")
1569 (match_operand:QI 3 "aarch64_shift_imm_<mode>" "n")))
1571 (set (match_operand:GPI 0 "register_operand" "=r")
1572 (minus:GPI (match_dup 1)
1573 (ASHIFT:GPI (match_dup 2) (match_dup 3))))]
1575 "subs\\t%<w>0, %<w>1, %<w>2, <shift> %3"
1576 [(set_attr "type" "alus_shift_imm")]
1579 (define_insn "*adds_mul_imm_<mode>"
1580 [(set (reg:CC_NZ CC_REGNUM)
1583 (match_operand:GPI 1 "register_operand" "r")
1584 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1585 (match_operand:GPI 3 "register_operand" "r"))
1587 (set (match_operand:GPI 0 "register_operand" "=r")
1588 (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1591 "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1592 [(set_attr "type" "alus_shift_imm")]
1595 (define_insn "*subs_mul_imm_<mode>"
1596 [(set (reg:CC_NZ CC_REGNUM)
1598 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1600 (match_operand:GPI 2 "register_operand" "r")
1601 (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1603 (set (match_operand:GPI 0 "register_operand" "=r")
1604 (minus:GPI (match_dup 1)
1605 (mult:GPI (match_dup 2) (match_dup 3))))]
1607 "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1608 [(set_attr "type" "alus_shift_imm")]
1611 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1612 [(set (reg:CC_NZ CC_REGNUM)
1615 (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1616 (match_operand:GPI 2 "register_operand" "r"))
1618 (set (match_operand:GPI 0 "register_operand" "=r")
1619 (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1621 "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1622 [(set_attr "type" "alus_ext")]
1625 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1626 [(set (reg:CC_NZ CC_REGNUM)
1628 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1630 (match_operand:ALLX 2 "register_operand" "r")))
1632 (set (match_operand:GPI 0 "register_operand" "=r")
1633 (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1635 "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1636 [(set_attr "type" "alus_ext")]
1639 (define_insn "*adds_<optab><ALLX:mode>_shift_<GPI:mode>"
1640 [(set (reg:CC_NZ CC_REGNUM)
1642 (plus:GPI (ashift:GPI
1644 (match_operand:ALLX 1 "register_operand" "r"))
1645 (match_operand 2 "aarch64_imm3" "Ui3"))
1646 (match_operand:GPI 3 "register_operand" "r"))
1648 (set (match_operand:GPI 0 "register_operand" "=rk")
1649 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI (match_dup 1))
1653 "adds\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1654 [(set_attr "type" "alus_ext")]
1657 (define_insn "*subs_<optab><ALLX:mode>_shift_<GPI:mode>"
1658 [(set (reg:CC_NZ CC_REGNUM)
1660 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1663 (match_operand:ALLX 2 "register_operand" "r"))
1664 (match_operand 3 "aarch64_imm3" "Ui3")))
1666 (set (match_operand:GPI 0 "register_operand" "=rk")
1667 (minus:GPI (match_dup 1)
1668 (ashift:GPI (ANY_EXTEND:GPI (match_dup 2))
1671 "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1672 [(set_attr "type" "alus_ext")]
1675 (define_insn "*adds_<optab><mode>_multp2"
1676 [(set (reg:CC_NZ CC_REGNUM)
1678 (plus:GPI (ANY_EXTRACT:GPI
1679 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1680 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1681 (match_operand 3 "const_int_operand" "n")
1683 (match_operand:GPI 4 "register_operand" "r"))
1685 (set (match_operand:GPI 0 "register_operand" "=r")
1686 (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1690 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1691 "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1692 [(set_attr "type" "alus_ext")]
1695 (define_insn "*subs_<optab><mode>_multp2"
1696 [(set (reg:CC_NZ CC_REGNUM)
1698 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1700 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1701 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1702 (match_operand 3 "const_int_operand" "n")
1705 (set (match_operand:GPI 0 "register_operand" "=r")
1706 (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1707 (mult:GPI (match_dup 1) (match_dup 2))
1710 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1711 "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1712 [(set_attr "type" "alus_ext")]
1715 (define_insn "*add<mode>3nr_compare0"
1716 [(set (reg:CC_NZ CC_REGNUM)
1718 (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1719 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1726 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1729 (define_insn "*compare_neg<mode>"
1730 [(set (reg:CC_Z CC_REGNUM)
1732 (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1733 (match_operand:GPI 1 "register_operand" "r")))]
1735 "cmn\\t%<w>1, %<w>0"
1736 [(set_attr "type" "alus_sreg")]
1739 (define_insn "*add_<shift>_<mode>"
1740 [(set (match_operand:GPI 0 "register_operand" "=r")
1741 (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1742 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1743 (match_operand:GPI 3 "register_operand" "r")))]
1745 "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1746 [(set_attr "type" "alu_shift_imm")]
1749 ;; zero_extend version of above
1750 (define_insn "*add_<shift>_si_uxtw"
1751 [(set (match_operand:DI 0 "register_operand" "=r")
1753 (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1754 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1755 (match_operand:SI 3 "register_operand" "r"))))]
1757 "add\\t%w0, %w3, %w1, <shift> %2"
1758 [(set_attr "type" "alu_shift_imm")]
1761 (define_insn "*add_mul_imm_<mode>"
1762 [(set (match_operand:GPI 0 "register_operand" "=r")
1763 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1764 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1765 (match_operand:GPI 3 "register_operand" "r")))]
1767 "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1768 [(set_attr "type" "alu_shift_imm")]
1771 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1772 [(set (match_operand:GPI 0 "register_operand" "=rk")
1773 (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1774 (match_operand:GPI 2 "register_operand" "r")))]
1776 "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1777 [(set_attr "type" "alu_ext")]
1780 ;; zero_extend version of above
1781 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1782 [(set (match_operand:DI 0 "register_operand" "=rk")
1784 (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1785 (match_operand:GPI 2 "register_operand" "r"))))]
1787 "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1788 [(set_attr "type" "alu_ext")]
1791 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1792 [(set (match_operand:GPI 0 "register_operand" "=rk")
1793 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1794 (match_operand:ALLX 1 "register_operand" "r"))
1795 (match_operand 2 "aarch64_imm3" "Ui3"))
1796 (match_operand:GPI 3 "register_operand" "r")))]
1798 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1799 [(set_attr "type" "alu_ext")]
1802 ;; zero_extend version of above
1803 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1804 [(set (match_operand:DI 0 "register_operand" "=rk")
1806 (plus:SI (ashift:SI (ANY_EXTEND:SI
1807 (match_operand:SHORT 1 "register_operand" "r"))
1808 (match_operand 2 "aarch64_imm3" "Ui3"))
1809 (match_operand:SI 3 "register_operand" "r"))))]
1811 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1812 [(set_attr "type" "alu_ext")]
1815 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1816 [(set (match_operand:GPI 0 "register_operand" "=rk")
1817 (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1818 (match_operand:ALLX 1 "register_operand" "r"))
1819 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1820 (match_operand:GPI 3 "register_operand" "r")))]
1822 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1823 [(set_attr "type" "alu_ext")]
1826 ;; zero_extend version of above
1827 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1828 [(set (match_operand:DI 0 "register_operand" "=rk")
1829 (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1830 (match_operand:SHORT 1 "register_operand" "r"))
1831 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1832 (match_operand:SI 3 "register_operand" "r"))))]
1834 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1835 [(set_attr "type" "alu_ext")]
1838 (define_insn "*add_<optab><mode>_multp2"
1839 [(set (match_operand:GPI 0 "register_operand" "=rk")
1840 (plus:GPI (ANY_EXTRACT:GPI
1841 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1842 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1843 (match_operand 3 "const_int_operand" "n")
1845 (match_operand:GPI 4 "register_operand" "r")))]
1846 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1847 "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1848 [(set_attr "type" "alu_ext")]
1851 ;; zero_extend version of above
1852 (define_insn "*add_<optab>si_multp2_uxtw"
1853 [(set (match_operand:DI 0 "register_operand" "=rk")
1855 (plus:SI (ANY_EXTRACT:SI
1856 (mult:SI (match_operand:SI 1 "register_operand" "r")
1857 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1858 (match_operand 3 "const_int_operand" "n")
1860 (match_operand:SI 4 "register_operand" "r"))))]
1861 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1862 "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1863 [(set_attr "type" "alu_ext")]
1866 (define_insn "add<mode>3_carryin"
1868 (match_operand:GPI 0 "register_operand" "=r")
1869 (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1871 (match_operand:GPI 1 "register_operand" "r")
1872 (match_operand:GPI 2 "register_operand" "r"))))]
1874 "adc\\t%<w>0, %<w>1, %<w>2"
1875 [(set_attr "type" "adc_reg")]
1878 ;; zero_extend version of above
1879 (define_insn "*addsi3_carryin_uxtw"
1881 (match_operand:DI 0 "register_operand" "=r")
1883 (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1885 (match_operand:SI 1 "register_operand" "r")
1886 (match_operand:SI 2 "register_operand" "r")))))]
1888 "adc\\t%w0, %w1, %w2"
1889 [(set_attr "type" "adc_reg")]
1892 (define_insn "*add<mode>3_carryin_alt1"
1894 (match_operand:GPI 0 "register_operand" "=r")
1896 (match_operand:GPI 1 "register_operand" "r")
1897 (match_operand:GPI 2 "register_operand" "r"))
1898 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1900 "adc\\t%<w>0, %<w>1, %<w>2"
1901 [(set_attr "type" "adc_reg")]
1904 ;; zero_extend version of above
1905 (define_insn "*addsi3_carryin_alt1_uxtw"
1907 (match_operand:DI 0 "register_operand" "=r")
1910 (match_operand:SI 1 "register_operand" "r")
1911 (match_operand:SI 2 "register_operand" "r"))
1912 (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1914 "adc\\t%w0, %w1, %w2"
1915 [(set_attr "type" "adc_reg")]
1918 (define_insn "*add<mode>3_carryin_alt2"
1920 (match_operand:GPI 0 "register_operand" "=r")
1922 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1923 (match_operand:GPI 1 "register_operand" "r"))
1924 (match_operand:GPI 2 "register_operand" "r")))]
1926 "adc\\t%<w>0, %<w>1, %<w>2"
1927 [(set_attr "type" "adc_reg")]
1930 ;; zero_extend version of above
1931 (define_insn "*addsi3_carryin_alt2_uxtw"
1933 (match_operand:DI 0 "register_operand" "=r")
1936 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1937 (match_operand:SI 1 "register_operand" "r"))
1938 (match_operand:SI 2 "register_operand" "r"))))]
1940 "adc\\t%w0, %w1, %w2"
1941 [(set_attr "type" "adc_reg")]
1944 (define_insn "*add<mode>3_carryin_alt3"
1946 (match_operand:GPI 0 "register_operand" "=r")
1948 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1949 (match_operand:GPI 2 "register_operand" "r"))
1950 (match_operand:GPI 1 "register_operand" "r")))]
1952 "adc\\t%<w>0, %<w>1, %<w>2"
1953 [(set_attr "type" "adc_reg")]
1956 ;; zero_extend version of above
1957 (define_insn "*addsi3_carryin_alt3_uxtw"
1959 (match_operand:DI 0 "register_operand" "=r")
1962 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1963 (match_operand:SI 2 "register_operand" "r"))
1964 (match_operand:SI 1 "register_operand" "r"))))]
1966 "adc\\t%w0, %w1, %w2"
1967 [(set_attr "type" "adc_reg")]
1970 (define_insn "*add_uxt<mode>_shift2"
1971 [(set (match_operand:GPI 0 "register_operand" "=rk")
1973 (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
1974 (match_operand 2 "aarch64_imm3" "Ui3"))
1975 (match_operand 3 "const_int_operand" "n"))
1976 (match_operand:GPI 4 "register_operand" "r")))]
1977 "aarch64_uxt_size (INTVAL (operands[2]), INTVAL (operands[3])) != 0"
1979 operands[3] = GEN_INT (aarch64_uxt_size (INTVAL(operands[2]),
1980 INTVAL (operands[3])));
1981 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %2\";"
1982 [(set_attr "type" "alu_ext")]
1985 ;; zero_extend version of above
1986 (define_insn "*add_uxtsi_shift2_uxtw"
1987 [(set (match_operand:DI 0 "register_operand" "=rk")
1990 (ashift:SI (match_operand:SI 1 "register_operand" "r")
1991 (match_operand 2 "aarch64_imm3" "Ui3"))
1992 (match_operand 3 "const_int_operand" "n"))
1993 (match_operand:SI 4 "register_operand" "r"))))]
1994 "aarch64_uxt_size (INTVAL (operands[2]), INTVAL (operands[3])) != 0"
1996 operands[3] = GEN_INT (aarch64_uxt_size (INTVAL (operands[2]),
1997 INTVAL (operands[3])));
1998 return \"add\t%w0, %w4, %w1, uxt%e3 %2\";"
1999 [(set_attr "type" "alu_ext")]
2002 (define_insn "*add_uxt<mode>_multp2"
2003 [(set (match_operand:GPI 0 "register_operand" "=rk")
2005 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2006 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2007 (match_operand 3 "const_int_operand" "n"))
2008 (match_operand:GPI 4 "register_operand" "r")))]
2009 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
2011 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2012 INTVAL (operands[3])));
2013 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
2014 [(set_attr "type" "alu_ext")]
2017 ;; zero_extend version of above
2018 (define_insn "*add_uxtsi_multp2_uxtw"
2019 [(set (match_operand:DI 0 "register_operand" "=rk")
2022 (mult:SI (match_operand:SI 1 "register_operand" "r")
2023 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2024 (match_operand 3 "const_int_operand" "n"))
2025 (match_operand:SI 4 "register_operand" "r"))))]
2026 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
2028 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2029 INTVAL (operands[3])));
2030 return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
2031 [(set_attr "type" "alu_ext")]
2034 (define_insn "subsi3"
2035 [(set (match_operand:SI 0 "register_operand" "=rk")
2036 (minus:SI (match_operand:SI 1 "register_operand" "rk")
2037 (match_operand:SI 2 "register_operand" "r")))]
2039 "sub\\t%w0, %w1, %w2"
2040 [(set_attr "type" "alu_sreg")]
2043 ;; zero_extend version of above
2044 (define_insn "*subsi3_uxtw"
2045 [(set (match_operand:DI 0 "register_operand" "=rk")
2047 (minus:SI (match_operand:SI 1 "register_operand" "rk")
2048 (match_operand:SI 2 "register_operand" "r"))))]
2050 "sub\\t%w0, %w1, %w2"
2051 [(set_attr "type" "alu_sreg")]
2054 (define_insn "subdi3"
2055 [(set (match_operand:DI 0 "register_operand" "=rk,w")
2056 (minus:DI (match_operand:DI 1 "register_operand" "rk,w")
2057 (match_operand:DI 2 "register_operand" "r,w")))]
2061 sub\\t%d0, %d1, %d2"
2062 [(set_attr "type" "alu_sreg, neon_sub")
2063 (set_attr "simd" "*,yes")]
2066 (define_expand "subti3"
2067 [(set (match_operand:TI 0 "register_operand" "")
2068 (minus:TI (match_operand:TI 1 "register_operand" "")
2069 (match_operand:TI 2 "register_operand" "")))]
2072 rtx low = gen_reg_rtx (DImode);
2073 emit_insn (gen_subdi3_compare0 (low, gen_lowpart (DImode, operands[1]),
2074 gen_lowpart (DImode, operands[2])));
2076 rtx high = gen_reg_rtx (DImode);
2077 emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]),
2078 gen_highpart (DImode, operands[2])));
2080 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2081 emit_move_insn (gen_highpart (DImode, operands[0]), high);
2085 (define_insn "sub<mode>3_compare0"
2086 [(set (reg:CC_NZ CC_REGNUM)
2087 (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
2088 (match_operand:GPI 2 "register_operand" "r"))
2090 (set (match_operand:GPI 0 "register_operand" "=r")
2091 (minus:GPI (match_dup 1) (match_dup 2)))]
2093 "subs\\t%<w>0, %<w>1, %<w>2"
2094 [(set_attr "type" "alus_sreg")]
2097 ;; zero_extend version of above
2098 (define_insn "*subsi3_compare0_uxtw"
2099 [(set (reg:CC_NZ CC_REGNUM)
2100 (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
2101 (match_operand:SI 2 "register_operand" "r"))
2103 (set (match_operand:DI 0 "register_operand" "=r")
2104 (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
2106 "subs\\t%w0, %w1, %w2"
2107 [(set_attr "type" "alus_sreg")]
2110 (define_insn "*sub_<shift>_<mode>"
2111 [(set (match_operand:GPI 0 "register_operand" "=r")
2112 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2114 (match_operand:GPI 1 "register_operand" "r")
2115 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2117 "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
2118 [(set_attr "type" "alu_shift_imm")]
2121 ;; zero_extend version of above
2122 (define_insn "*sub_<shift>_si_uxtw"
2123 [(set (match_operand:DI 0 "register_operand" "=r")
2125 (minus:SI (match_operand:SI 3 "register_operand" "r")
2127 (match_operand:SI 1 "register_operand" "r")
2128 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2130 "sub\\t%w0, %w3, %w1, <shift> %2"
2131 [(set_attr "type" "alu_shift_imm")]
2134 (define_insn "*sub_mul_imm_<mode>"
2135 [(set (match_operand:GPI 0 "register_operand" "=r")
2136 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2138 (match_operand:GPI 1 "register_operand" "r")
2139 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2141 "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
2142 [(set_attr "type" "alu_shift_imm")]
2145 ;; zero_extend version of above
2146 (define_insn "*sub_mul_imm_si_uxtw"
2147 [(set (match_operand:DI 0 "register_operand" "=r")
2149 (minus:SI (match_operand:SI 3 "register_operand" "r")
2151 (match_operand:SI 1 "register_operand" "r")
2152 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2154 "sub\\t%w0, %w3, %w1, lsl %p2"
2155 [(set_attr "type" "alu_shift_imm")]
2158 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
2159 [(set (match_operand:GPI 0 "register_operand" "=rk")
2160 (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
2162 (match_operand:ALLX 2 "register_operand" "r"))))]
2164 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
2165 [(set_attr "type" "alu_ext")]
2168 ;; zero_extend version of above
2169 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
2170 [(set (match_operand:DI 0 "register_operand" "=rk")
2172 (minus:SI (match_operand:SI 1 "register_operand" "rk")
2174 (match_operand:SHORT 2 "register_operand" "r")))))]
2176 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
2177 [(set_attr "type" "alu_ext")]
2180 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
2181 [(set (match_operand:GPI 0 "register_operand" "=rk")
2182 (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
2183 (ashift:GPI (ANY_EXTEND:GPI
2184 (match_operand:ALLX 2 "register_operand" "r"))
2185 (match_operand 3 "aarch64_imm3" "Ui3"))))]
2187 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
2188 [(set_attr "type" "alu_ext")]
2191 ;; zero_extend version of above
2192 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
2193 [(set (match_operand:DI 0 "register_operand" "=rk")
2195 (minus:SI (match_operand:SI 1 "register_operand" "rk")
2196 (ashift:SI (ANY_EXTEND:SI
2197 (match_operand:SHORT 2 "register_operand" "r"))
2198 (match_operand 3 "aarch64_imm3" "Ui3")))))]
2200 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
2201 [(set_attr "type" "alu_ext")]
2204 (define_insn "*sub_<optab><mode>_multp2"
2205 [(set (match_operand:GPI 0 "register_operand" "=rk")
2206 (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
2208 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2209 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2210 (match_operand 3 "const_int_operand" "n")
2212 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
2213 "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
2214 [(set_attr "type" "alu_ext")]
2217 ;; zero_extend version of above
2218 (define_insn "*sub_<optab>si_multp2_uxtw"
2219 [(set (match_operand:DI 0 "register_operand" "=rk")
2221 (minus:SI (match_operand:SI 4 "register_operand" "rk")
2223 (mult:SI (match_operand:SI 1 "register_operand" "r")
2224 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2225 (match_operand 3 "const_int_operand" "n")
2227 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
2228 "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
2229 [(set_attr "type" "alu_ext")]
2232 (define_insn "sub<mode>3_carryin"
2234 (match_operand:GPI 0 "register_operand" "=r")
2235 (minus:GPI (minus:GPI
2236 (match_operand:GPI 1 "register_operand" "r")
2237 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2238 (match_operand:GPI 2 "register_operand" "r")))]
2240 "sbc\\t%<w>0, %<w>1, %<w>2"
2241 [(set_attr "type" "adc_reg")]
2244 ;; zero_extend version of the above
2245 (define_insn "*subsi3_carryin_uxtw"
2247 (match_operand:DI 0 "register_operand" "=r")
2250 (match_operand:SI 1 "register_operand" "r")
2251 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2252 (match_operand:SI 2 "register_operand" "r"))))]
2254 "sbc\\t%w0, %w1, %w2"
2255 [(set_attr "type" "adc_reg")]
2258 (define_insn "*sub_uxt<mode>_shift2"
2259 [(set (match_operand:GPI 0 "register_operand" "=rk")
2260 (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
2262 (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
2263 (match_operand 2 "aarch64_imm3" "Ui3"))
2264 (match_operand 3 "const_int_operand" "n"))))]
2265 "aarch64_uxt_size (INTVAL (operands[2]),INTVAL (operands[3])) != 0"
2267 operands[3] = GEN_INT (aarch64_uxt_size (INTVAL (operands[2]),
2268 INTVAL (operands[3])));
2269 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %2\";"
2270 [(set_attr "type" "alu_ext")]
2273 ;; zero_extend version of above
2274 (define_insn "*sub_uxtsi_shift2_uxtw"
2275 [(set (match_operand:DI 0 "register_operand" "=rk")
2277 (minus:SI (match_operand:SI 4 "register_operand" "rk")
2279 (ashift:SI (match_operand:SI 1 "register_operand" "r")
2280 (match_operand 2 "aarch64_imm3" "Ui3"))
2281 (match_operand 3 "const_int_operand" "n")))))]
2282 "aarch64_uxt_size (INTVAL (operands[2]),INTVAL (operands[3])) != 0"
2284 operands[3] = GEN_INT (aarch64_uxt_size (INTVAL (operands[2]),
2285 INTVAL (operands[3])));
2286 return \"sub\t%w0, %w4, %w1, uxt%e3 %2\";"
2287 [(set_attr "type" "alu_ext")]
2290 (define_insn "*sub_uxt<mode>_multp2"
2291 [(set (match_operand:GPI 0 "register_operand" "=rk")
2292 (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
2294 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2295 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2296 (match_operand 3 "const_int_operand" "n"))))]
2297 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2299 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2300 INTVAL (operands[3])));
2301 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
2302 [(set_attr "type" "alu_ext")]
2305 ;; zero_extend version of above
2306 (define_insn "*sub_uxtsi_multp2_uxtw"
2307 [(set (match_operand:DI 0 "register_operand" "=rk")
2309 (minus:SI (match_operand:SI 4 "register_operand" "rk")
2311 (mult:SI (match_operand:SI 1 "register_operand" "r")
2312 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2313 (match_operand 3 "const_int_operand" "n")))))]
2314 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2316 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2317 INTVAL (operands[3])));
2318 return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
2319 [(set_attr "type" "alu_ext")]
2322 (define_expand "abs<mode>2"
2323 [(match_operand:GPI 0 "register_operand" "")
2324 (match_operand:GPI 1 "register_operand" "")]
2327 rtx ccreg = aarch64_gen_compare_reg (LT, operands[1], const0_rtx);
2328 rtx x = gen_rtx_LT (VOIDmode, ccreg, const0_rtx);
2329 emit_insn (gen_csneg3<mode>_insn (operands[0], x, operands[1], operands[1]));
2334 (define_insn "neg<mode>2"
2335 [(set (match_operand:GPI 0 "register_operand" "=r,w")
2336 (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
2340 neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
2341 [(set_attr "type" "alu_sreg, neon_neg<q>")
2342 (set_attr "simd" "*,yes")]
2345 ;; zero_extend version of above
2346 (define_insn "*negsi2_uxtw"
2347 [(set (match_operand:DI 0 "register_operand" "=r")
2348 (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
2351 [(set_attr "type" "alu_sreg")]
2354 (define_insn "*ngc<mode>"
2355 [(set (match_operand:GPI 0 "register_operand" "=r")
2356 (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2357 (match_operand:GPI 1 "register_operand" "r")))]
2359 "ngc\\t%<w>0, %<w>1"
2360 [(set_attr "type" "adc_reg")]
2363 (define_insn "*ngcsi_uxtw"
2364 [(set (match_operand:DI 0 "register_operand" "=r")
2366 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2367 (match_operand:SI 1 "register_operand" "r"))))]
2370 [(set_attr "type" "adc_reg")]
2373 (define_insn "*neg<mode>2_compare0"
2374 [(set (reg:CC_NZ CC_REGNUM)
2375 (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2377 (set (match_operand:GPI 0 "register_operand" "=r")
2378 (neg:GPI (match_dup 1)))]
2380 "negs\\t%<w>0, %<w>1"
2381 [(set_attr "type" "alus_sreg")]
2384 ;; zero_extend version of above
2385 (define_insn "*negsi2_compare0_uxtw"
2386 [(set (reg:CC_NZ CC_REGNUM)
2387 (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
2389 (set (match_operand:DI 0 "register_operand" "=r")
2390 (zero_extend:DI (neg:SI (match_dup 1))))]
2393 [(set_attr "type" "alus_sreg")]
2396 (define_insn "*neg_<shift><mode>3_compare0"
2397 [(set (reg:CC_NZ CC_REGNUM)
2399 (neg:GPI (ASHIFT:GPI
2400 (match_operand:GPI 1 "register_operand" "r")
2401 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2403 (set (match_operand:GPI 0 "register_operand" "=r")
2404 (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2406 "negs\\t%<w>0, %<w>1, <shift> %2"
2407 [(set_attr "type" "alus_shift_imm")]
2410 (define_insn "*neg_<shift>_<mode>2"
2411 [(set (match_operand:GPI 0 "register_operand" "=r")
2412 (neg:GPI (ASHIFT:GPI
2413 (match_operand:GPI 1 "register_operand" "r")
2414 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2416 "neg\\t%<w>0, %<w>1, <shift> %2"
2417 [(set_attr "type" "alu_shift_imm")]
2420 ;; zero_extend version of above
2421 (define_insn "*neg_<shift>_si2_uxtw"
2422 [(set (match_operand:DI 0 "register_operand" "=r")
2425 (match_operand:SI 1 "register_operand" "r")
2426 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2428 "neg\\t%w0, %w1, <shift> %2"
2429 [(set_attr "type" "alu_shift_imm")]
2432 (define_insn "*neg_mul_imm_<mode>2"
2433 [(set (match_operand:GPI 0 "register_operand" "=r")
2435 (match_operand:GPI 1 "register_operand" "r")
2436 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2438 "neg\\t%<w>0, %<w>1, lsl %p2"
2439 [(set_attr "type" "alu_shift_imm")]
2442 ;; zero_extend version of above
2443 (define_insn "*neg_mul_imm_si2_uxtw"
2444 [(set (match_operand:DI 0 "register_operand" "=r")
2447 (match_operand:SI 1 "register_operand" "r")
2448 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2450 "neg\\t%w0, %w1, lsl %p2"
2451 [(set_attr "type" "alu_shift_imm")]
2454 (define_insn "mul<mode>3"
2455 [(set (match_operand:GPI 0 "register_operand" "=r")
2456 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2457 (match_operand:GPI 2 "register_operand" "r")))]
2459 "mul\\t%<w>0, %<w>1, %<w>2"
2460 [(set_attr "type" "mul")]
2463 ;; zero_extend version of above
2464 (define_insn "*mulsi3_uxtw"
2465 [(set (match_operand:DI 0 "register_operand" "=r")
2467 (mult:SI (match_operand:SI 1 "register_operand" "r")
2468 (match_operand:SI 2 "register_operand" "r"))))]
2470 "mul\\t%w0, %w1, %w2"
2471 [(set_attr "type" "mul")]
2474 (define_insn "madd<mode>"
2475 [(set (match_operand:GPI 0 "register_operand" "=r")
2476 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2477 (match_operand:GPI 2 "register_operand" "r"))
2478 (match_operand:GPI 3 "register_operand" "r")))]
2480 "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2481 [(set_attr "type" "mla")]
2484 ;; zero_extend version of above
2485 (define_insn "*maddsi_uxtw"
2486 [(set (match_operand:DI 0 "register_operand" "=r")
2488 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2489 (match_operand:SI 2 "register_operand" "r"))
2490 (match_operand:SI 3 "register_operand" "r"))))]
2492 "madd\\t%w0, %w1, %w2, %w3"
2493 [(set_attr "type" "mla")]
2496 (define_insn "*msub<mode>"
2497 [(set (match_operand:GPI 0 "register_operand" "=r")
2498 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2499 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2500 (match_operand:GPI 2 "register_operand" "r"))))]
2503 "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2504 [(set_attr "type" "mla")]
2507 ;; zero_extend version of above
2508 (define_insn "*msubsi_uxtw"
2509 [(set (match_operand:DI 0 "register_operand" "=r")
2511 (minus:SI (match_operand:SI 3 "register_operand" "r")
2512 (mult:SI (match_operand:SI 1 "register_operand" "r")
2513 (match_operand:SI 2 "register_operand" "r")))))]
2516 "msub\\t%w0, %w1, %w2, %w3"
2517 [(set_attr "type" "mla")]
2520 (define_insn "*mul<mode>_neg"
2521 [(set (match_operand:GPI 0 "register_operand" "=r")
2522 (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2523 (match_operand:GPI 2 "register_operand" "r")))]
2526 "mneg\\t%<w>0, %<w>1, %<w>2"
2527 [(set_attr "type" "mul")]
2530 ;; zero_extend version of above
2531 (define_insn "*mulsi_neg_uxtw"
2532 [(set (match_operand:DI 0 "register_operand" "=r")
2534 (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2535 (match_operand:SI 2 "register_operand" "r"))))]
2538 "mneg\\t%w0, %w1, %w2"
2539 [(set_attr "type" "mul")]
2542 (define_insn "<su_optab>mulsidi3"
2543 [(set (match_operand:DI 0 "register_operand" "=r")
2544 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2545 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2547 "<su>mull\\t%0, %w1, %w2"
2548 [(set_attr "type" "<su>mull")]
2551 (define_insn "<su_optab>maddsidi4"
2552 [(set (match_operand:DI 0 "register_operand" "=r")
2554 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2555 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2556 (match_operand:DI 3 "register_operand" "r")))]
2558 "<su>maddl\\t%0, %w1, %w2, %3"
2559 [(set_attr "type" "<su>mlal")]
2562 (define_insn "<su_optab>msubsidi4"
2563 [(set (match_operand:DI 0 "register_operand" "=r")
2565 (match_operand:DI 3 "register_operand" "r")
2566 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2568 (match_operand:SI 2 "register_operand" "r")))))]
2570 "<su>msubl\\t%0, %w1, %w2, %3"
2571 [(set_attr "type" "<su>mlal")]
2574 (define_insn "*<su_optab>mulsidi_neg"
2575 [(set (match_operand:DI 0 "register_operand" "=r")
2577 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2578 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2580 "<su>mnegl\\t%0, %w1, %w2"
2581 [(set_attr "type" "<su>mull")]
2584 (define_expand "<su_optab>mulditi3"
2585 [(set (match_operand:TI 0 "register_operand")
2586 (mult:TI (ANY_EXTEND:TI (match_operand:DI 1 "register_operand"))
2587 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand"))))]
2590 rtx low = gen_reg_rtx (DImode);
2591 emit_insn (gen_muldi3 (low, operands[1], operands[2]));
2593 rtx high = gen_reg_rtx (DImode);
2594 emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2]));
2596 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2597 emit_move_insn (gen_highpart (DImode, operands[0]), high);
2601 ;; The default expansion of multi3 using umuldi3_highpart will perform
2602 ;; the additions in an order that fails to combine into two madd insns.
2603 (define_expand "multi3"
2604 [(set (match_operand:TI 0 "register_operand")
2605 (mult:TI (match_operand:TI 1 "register_operand")
2606 (match_operand:TI 2 "register_operand")))]
2609 rtx l0 = gen_reg_rtx (DImode);
2610 rtx l1 = gen_lowpart (DImode, operands[1]);
2611 rtx l2 = gen_lowpart (DImode, operands[2]);
2612 rtx h0 = gen_reg_rtx (DImode);
2613 rtx h1 = gen_highpart (DImode, operands[1]);
2614 rtx h2 = gen_highpart (DImode, operands[2]);
2616 emit_insn (gen_muldi3 (l0, l1, l2));
2617 emit_insn (gen_umuldi3_highpart (h0, l1, l2));
2618 emit_insn (gen_madddi (h0, h1, l2, h0));
2619 emit_insn (gen_madddi (h0, l1, h2, h0));
2621 emit_move_insn (gen_lowpart (DImode, operands[0]), l0);
2622 emit_move_insn (gen_highpart (DImode, operands[0]), h0);
2626 (define_insn "<su>muldi3_highpart"
2627 [(set (match_operand:DI 0 "register_operand" "=r")
2631 (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2632 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2635 "<su>mulh\\t%0, %1, %2"
2636 [(set_attr "type" "<su>mull")]
2639 (define_insn "<su_optab>div<mode>3"
2640 [(set (match_operand:GPI 0 "register_operand" "=r")
2641 (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2642 (match_operand:GPI 2 "register_operand" "r")))]
2644 "<su>div\\t%<w>0, %<w>1, %<w>2"
2645 [(set_attr "type" "<su>div")]
2648 ;; zero_extend version of above
2649 (define_insn "*<su_optab>divsi3_uxtw"
2650 [(set (match_operand:DI 0 "register_operand" "=r")
2652 (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2653 (match_operand:SI 2 "register_operand" "r"))))]
2655 "<su>div\\t%w0, %w1, %w2"
2656 [(set_attr "type" "<su>div")]
2659 ;; -------------------------------------------------------------------
2661 ;; -------------------------------------------------------------------
2663 (define_insn "*cmp<mode>"
2664 [(set (reg:CC CC_REGNUM)
2665 (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2666 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2672 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
2675 (define_insn "*cmp<mode>"
2676 [(set (reg:CCFP CC_REGNUM)
2677 (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2678 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2682 fcmp\\t%<s>0, %<s>1"
2683 [(set_attr "type" "fcmp<s>")]
2686 (define_insn "*cmpe<mode>"
2687 [(set (reg:CCFPE CC_REGNUM)
2688 (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2689 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2693 fcmpe\\t%<s>0, %<s>1"
2694 [(set_attr "type" "fcmp<s>")]
2697 (define_insn "*cmp_swp_<shift>_reg<mode>"
2698 [(set (reg:CC_SWP CC_REGNUM)
2699 (compare:CC_SWP (ASHIFT:GPI
2700 (match_operand:GPI 0 "register_operand" "r")
2701 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2702 (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2704 "cmp\\t%<w>2, %<w>0, <shift> %1"
2705 [(set_attr "type" "alus_shift_imm")]
2708 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2709 [(set (reg:CC_SWP CC_REGNUM)
2710 (compare:CC_SWP (ANY_EXTEND:GPI
2711 (match_operand:ALLX 0 "register_operand" "r"))
2712 (match_operand:GPI 1 "register_operand" "r")))]
2714 "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2715 [(set_attr "type" "alus_ext")]
2718 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2719 [(set (reg:CC_SWP CC_REGNUM)
2720 (compare:CC_SWP (ashift:GPI
2722 (match_operand:ALLX 0 "register_operand" "r"))
2723 (match_operand 1 "aarch64_imm3" "Ui3"))
2724 (match_operand:GPI 2 "register_operand" "r")))]
2726 "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2727 [(set_attr "type" "alus_ext")]
2730 ;; -------------------------------------------------------------------
2731 ;; Store-flag and conditional select insns
2732 ;; -------------------------------------------------------------------
2734 (define_expand "cstore<mode>4"
2735 [(set (match_operand:SI 0 "register_operand" "")
2736 (match_operator:SI 1 "aarch64_comparison_operator"
2737 [(match_operand:GPI 2 "register_operand" "")
2738 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2741 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2743 operands[3] = const0_rtx;
2747 (define_expand "cstorecc4"
2748 [(set (match_operand:SI 0 "register_operand")
2749 (match_operator 1 "aarch64_comparison_operator"
2750 [(match_operand 2 "ccmp_cc_register")
2751 (match_operand 3 "const0_operand")]))]
2754 emit_insn (gen_rtx_SET (operands[0], operands[1]));
2759 (define_expand "cstore<mode>4"
2760 [(set (match_operand:SI 0 "register_operand" "")
2761 (match_operator:SI 1 "aarch64_comparison_operator"
2762 [(match_operand:GPF 2 "register_operand" "")
2763 (match_operand:GPF 3 "register_operand" "")]))]
2766 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2768 operands[3] = const0_rtx;
2772 (define_insn "*cstore<mode>_insn"
2773 [(set (match_operand:ALLI 0 "register_operand" "=r")
2774 (match_operator:ALLI 1 "aarch64_comparison_operator"
2775 [(match_operand 2 "cc_register" "") (const_int 0)]))]
2778 [(set_attr "type" "csel")]
2781 ;; zero_extend version of the above
2782 (define_insn "*cstoresi_insn_uxtw"
2783 [(set (match_operand:DI 0 "register_operand" "=r")
2785 (match_operator:SI 1 "aarch64_comparison_operator"
2786 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2789 [(set_attr "type" "csel")]
2792 (define_insn "cstore<mode>_neg"
2793 [(set (match_operand:ALLI 0 "register_operand" "=r")
2794 (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2795 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2797 "csetm\\t%<w>0, %m1"
2798 [(set_attr "type" "csel")]
2801 ;; zero_extend version of the above
2802 (define_insn "*cstoresi_neg_uxtw"
2803 [(set (match_operand:DI 0 "register_operand" "=r")
2805 (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2806 [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2809 [(set_attr "type" "csel")]
2812 (define_expand "cmov<mode>6"
2813 [(set (match_operand:GPI 0 "register_operand" "")
2815 (match_operator 1 "aarch64_comparison_operator"
2816 [(match_operand:GPI 2 "register_operand" "")
2817 (match_operand:GPI 3 "aarch64_plus_operand" "")])
2818 (match_operand:GPI 4 "register_operand" "")
2819 (match_operand:GPI 5 "register_operand" "")))]
2822 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2824 operands[3] = const0_rtx;
2828 (define_expand "cmov<mode>6"
2829 [(set (match_operand:GPF 0 "register_operand" "")
2831 (match_operator 1 "aarch64_comparison_operator"
2832 [(match_operand:GPF 2 "register_operand" "")
2833 (match_operand:GPF 3 "register_operand" "")])
2834 (match_operand:GPF 4 "register_operand" "")
2835 (match_operand:GPF 5 "register_operand" "")))]
2838 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2840 operands[3] = const0_rtx;
2844 (define_insn "*cmov<mode>_insn"
2845 [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2847 (match_operator 1 "aarch64_comparison_operator"
2848 [(match_operand 2 "cc_register" "") (const_int 0)])
2849 (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2850 (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2851 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2852 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2853 ;; Final two alternatives should be unreachable, but included for completeness
2855 csel\\t%<w>0, %<w>3, %<w>4, %m1
2856 csinv\\t%<w>0, %<w>3, <w>zr, %m1
2857 csinv\\t%<w>0, %<w>4, <w>zr, %M1
2858 csinc\\t%<w>0, %<w>3, <w>zr, %m1
2859 csinc\\t%<w>0, %<w>4, <w>zr, %M1
2862 [(set_attr "type" "csel")]
2865 ;; zero_extend version of above
2866 (define_insn "*cmovsi_insn_uxtw"
2867 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2870 (match_operator 1 "aarch64_comparison_operator"
2871 [(match_operand 2 "cc_register" "") (const_int 0)])
2872 (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2873 (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2874 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2875 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2876 ;; Final two alternatives should be unreachable, but included for completeness
2878 csel\\t%w0, %w3, %w4, %m1
2879 csinv\\t%w0, %w3, wzr, %m1
2880 csinv\\t%w0, %w4, wzr, %M1
2881 csinc\\t%w0, %w3, wzr, %m1
2882 csinc\\t%w0, %w4, wzr, %M1
2885 [(set_attr "type" "csel")]
2888 (define_insn "*cmov<mode>_insn"
2889 [(set (match_operand:GPF 0 "register_operand" "=w")
2891 (match_operator 1 "aarch64_comparison_operator"
2892 [(match_operand 2 "cc_register" "") (const_int 0)])
2893 (match_operand:GPF 3 "register_operand" "w")
2894 (match_operand:GPF 4 "register_operand" "w")))]
2896 "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2897 [(set_attr "type" "fcsel")]
2900 (define_expand "mov<mode>cc"
2901 [(set (match_operand:ALLI 0 "register_operand" "")
2902 (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2903 (match_operand:ALLI 2 "register_operand" "")
2904 (match_operand:ALLI 3 "register_operand" "")))]
2907 enum rtx_code code = GET_CODE (operands[1]);
2909 if (code == UNEQ || code == LTGT)
2912 if (!ccmp_cc_register (XEXP (operands[1], 0),
2913 GET_MODE (XEXP (operands[1], 0))))
2916 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2917 XEXP (operands[1], 1));
2918 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2923 (define_expand "mov<GPF:mode><GPI:mode>cc"
2924 [(set (match_operand:GPI 0 "register_operand" "")
2925 (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2926 (match_operand:GPF 2 "register_operand" "")
2927 (match_operand:GPF 3 "register_operand" "")))]
2931 enum rtx_code code = GET_CODE (operands[1]);
2933 if (code == UNEQ || code == LTGT)
2936 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2937 XEXP (operands[1], 1));
2938 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2942 (define_expand "mov<mode>cc"
2943 [(set (match_operand:GPF 0 "register_operand" "")
2944 (if_then_else:GPF (match_operand 1 "aarch64_comparison_operator" "")
2945 (match_operand:GPF 2 "register_operand" "")
2946 (match_operand:GPF 3 "register_operand" "")))]
2950 enum rtx_code code = GET_CODE (operands[1]);
2952 if (code == UNEQ || code == LTGT)
2955 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2956 XEXP (operands[1], 1));
2957 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2962 ;; CRC32 instructions.
2963 (define_insn "aarch64_<crc_variant>"
2964 [(set (match_operand:SI 0 "register_operand" "=r")
2965 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2966 (match_operand:<crc_mode> 2 "register_operand" "r")]
2970 if (GET_MODE_BITSIZE (GET_MODE (operands[2])) >= 64)
2971 return "<crc_variant>\\t%w0, %w1, %x2";
2973 return "<crc_variant>\\t%w0, %w1, %w2";
2975 [(set_attr "type" "crc")]
2978 (define_insn "*csinc2<mode>_insn"
2979 [(set (match_operand:GPI 0 "register_operand" "=r")
2980 (plus:GPI (match_operand 2 "aarch64_comparison_operation" "")
2981 (match_operand:GPI 1 "register_operand" "r")))]
2983 "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2984 [(set_attr "type" "csel")]
2987 (define_insn "csinc3<mode>_insn"
2988 [(set (match_operand:GPI 0 "register_operand" "=r")
2990 (match_operand 1 "aarch64_comparison_operation" "")
2991 (plus:GPI (match_operand:GPI 2 "register_operand" "r")
2993 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2995 "csinc\\t%<w>0, %<w>3, %<w>2, %M1"
2996 [(set_attr "type" "csel")]
2999 (define_insn "*csinv3<mode>_insn"
3000 [(set (match_operand:GPI 0 "register_operand" "=r")
3002 (match_operand 1 "aarch64_comparison_operation" "")
3003 (not:GPI (match_operand:GPI 2 "register_operand" "r"))
3004 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
3006 "csinv\\t%<w>0, %<w>3, %<w>2, %M1"
3007 [(set_attr "type" "csel")]
3010 (define_insn "csneg3<mode>_insn"
3011 [(set (match_operand:GPI 0 "register_operand" "=r")
3013 (match_operand 1 "aarch64_comparison_operation" "")
3014 (neg:GPI (match_operand:GPI 2 "register_operand" "r"))
3015 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
3017 "csneg\\t%<w>0, %<w>3, %<w>2, %M1"
3018 [(set_attr "type" "csel")]
3021 ;; -------------------------------------------------------------------
3022 ;; Logical operations
3023 ;; -------------------------------------------------------------------
3025 (define_insn "<optab><mode>3"
3026 [(set (match_operand:GPI 0 "register_operand" "=r,rk,w")
3027 (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r,w")
3028 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>,w")))]
3031 <logical>\\t%<w>0, %<w>1, %<w>2
3032 <logical>\\t%<w>0, %<w>1, %<w>2
3033 <logical>\\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
3034 [(set_attr "type" "logic_reg,logic_imm,neon_logic")
3035 (set_attr "simd" "*,*,yes")]
3038 ;; zero_extend version of above
3039 (define_insn "*<optab>si3_uxtw"
3040 [(set (match_operand:DI 0 "register_operand" "=r,rk")
3042 (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
3043 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
3045 "<logical>\\t%w0, %w1, %w2"
3046 [(set_attr "type" "logic_reg,logic_imm")]
3049 (define_insn "*and<mode>3_compare0"
3050 [(set (reg:CC_NZ CC_REGNUM)
3052 (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
3053 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
3055 (set (match_operand:GPI 0 "register_operand" "=r,r")
3056 (and:GPI (match_dup 1) (match_dup 2)))]
3058 "ands\\t%<w>0, %<w>1, %<w>2"
3059 [(set_attr "type" "logics_reg,logics_imm")]
3062 ;; zero_extend version of above
3063 (define_insn "*andsi3_compare0_uxtw"
3064 [(set (reg:CC_NZ CC_REGNUM)
3066 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
3067 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
3069 (set (match_operand:DI 0 "register_operand" "=r,r")
3070 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
3072 "ands\\t%w0, %w1, %w2"
3073 [(set_attr "type" "logics_reg,logics_imm")]
3076 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
3077 [(set (reg:CC_NZ CC_REGNUM)
3080 (match_operand:GPI 1 "register_operand" "r")
3081 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3082 (match_operand:GPI 3 "register_operand" "r"))
3084 (set (match_operand:GPI 0 "register_operand" "=r")
3085 (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
3087 "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3088 [(set_attr "type" "logics_shift_imm")]
3091 ;; zero_extend version of above
3092 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
3093 [(set (reg:CC_NZ CC_REGNUM)
3096 (match_operand:SI 1 "register_operand" "r")
3097 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3098 (match_operand:SI 3 "register_operand" "r"))
3100 (set (match_operand:DI 0 "register_operand" "=r")
3101 (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
3104 "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3105 [(set_attr "type" "logics_shift_imm")]
3108 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
3109 [(set (match_operand:GPI 0 "register_operand" "=r")
3110 (LOGICAL:GPI (SHIFT:GPI
3111 (match_operand:GPI 1 "register_operand" "r")
3112 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3113 (match_operand:GPI 3 "register_operand" "r")))]
3115 "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3116 [(set_attr "type" "logic_shift_imm")]
3119 (define_insn "*<optab>_rol<mode>3"
3120 [(set (match_operand:GPI 0 "register_operand" "=r")
3121 (LOGICAL:GPI (rotate:GPI
3122 (match_operand:GPI 1 "register_operand" "r")
3123 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3124 (match_operand:GPI 3 "register_operand" "r")))]
3126 "<logical>\\t%<w>0, %<w>3, %<w>1, ror (<sizen> - %2)"
3127 [(set_attr "type" "logic_shift_imm")]
3130 ;; zero_extend versions of above
3131 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
3132 [(set (match_operand:DI 0 "register_operand" "=r")
3134 (LOGICAL:SI (SHIFT:SI
3135 (match_operand:SI 1 "register_operand" "r")
3136 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3137 (match_operand:SI 3 "register_operand" "r"))))]
3139 "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3140 [(set_attr "type" "logic_shift_imm")]
3143 (define_insn "*<optab>_rolsi3_uxtw"
3144 [(set (match_operand:DI 0 "register_operand" "=r")
3146 (LOGICAL:SI (rotate:SI
3147 (match_operand:SI 1 "register_operand" "r")
3148 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3149 (match_operand:SI 3 "register_operand" "r"))))]
3151 "<logical>\\t%w0, %w3, %w1, ror (32 - %2)"
3152 [(set_attr "type" "logic_shift_imm")]
3155 (define_insn "one_cmpl<mode>2"
3156 [(set (match_operand:GPI 0 "register_operand" "=r,w")
3157 (not:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
3162 [(set_attr "type" "logic_reg,neon_logic")
3163 (set_attr "simd" "*,yes")]
3166 (define_insn "*one_cmpl_<optab><mode>2"
3167 [(set (match_operand:GPI 0 "register_operand" "=r")
3168 (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
3169 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
3171 "mvn\\t%<w>0, %<w>1, <shift> %2"
3172 [(set_attr "type" "logic_shift_imm")]
3175 ;; Binary logical operators negating one operand, i.e. (a & !b), (a | !b).
3177 (define_insn "*<NLOGICAL:optab>_one_cmpl<mode>3"
3178 [(set (match_operand:GPI 0 "register_operand" "=r,w")
3179 (NLOGICAL:GPI (not:GPI (match_operand:GPI 1 "register_operand" "r,w"))
3180 (match_operand:GPI 2 "register_operand" "r,w")))]
3183 <NLOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1
3184 <NLOGICAL:nlogical>\\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>"
3185 [(set_attr "type" "logic_reg,neon_logic")
3186 (set_attr "simd" "*,yes")]
3189 (define_insn "*<NLOGICAL:optab>_one_cmplsidi3_ze"
3190 [(set (match_operand:DI 0 "register_operand" "=r")
3192 (NLOGICAL:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3193 (match_operand:SI 2 "register_operand" "r"))))]
3195 "<NLOGICAL:nlogical>\\t%w0, %w2, %w1"
3196 [(set_attr "type" "logic_reg")]
3199 (define_insn "*xor_one_cmplsidi3_ze"
3200 [(set (match_operand:DI 0 "register_operand" "=r")
3202 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "r")
3203 (match_operand:SI 2 "register_operand" "r")))))]
3205 "eon\\t%w0, %w1, %w2"
3206 [(set_attr "type" "logic_reg")]
3209 ;; (xor (not a) b) is simplify_rtx-ed down to (not (xor a b)).
3210 ;; eon does not operate on SIMD registers so the vector variant must be split.
3211 (define_insn_and_split "*xor_one_cmpl<mode>3"
3212 [(set (match_operand:GPI 0 "register_operand" "=r,w")
3213 (not:GPI (xor:GPI (match_operand:GPI 1 "register_operand" "r,?w")
3214 (match_operand:GPI 2 "register_operand" "r,w"))))]
3217 eon\\t%<w>0, %<w>1, %<w>2
3219 "reload_completed && FP_REGNUM_P (REGNO (operands[0]))" ;; For SIMD registers.
3220 [(set (match_operand:GPI 0 "register_operand" "=w")
3221 (xor:GPI (match_operand:GPI 1 "register_operand" "w")
3222 (match_operand:GPI 2 "register_operand" "w")))
3223 (set (match_dup 0) (not:GPI (match_dup 0)))]
3225 [(set_attr "type" "logic_reg,multiple")
3226 (set_attr "simd" "*,yes")]
3229 (define_insn "*and_one_cmpl<mode>3_compare0"
3230 [(set (reg:CC_NZ CC_REGNUM)
3233 (match_operand:GPI 1 "register_operand" "r"))
3234 (match_operand:GPI 2 "register_operand" "r"))
3236 (set (match_operand:GPI 0 "register_operand" "=r")
3237 (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
3239 "bics\\t%<w>0, %<w>2, %<w>1"
3240 [(set_attr "type" "logics_reg")]
3243 ;; zero_extend version of above
3244 (define_insn "*and_one_cmplsi3_compare0_uxtw"
3245 [(set (reg:CC_NZ CC_REGNUM)
3248 (match_operand:SI 1 "register_operand" "r"))
3249 (match_operand:SI 2 "register_operand" "r"))
3251 (set (match_operand:DI 0 "register_operand" "=r")
3252 (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
3254 "bics\\t%w0, %w2, %w1"
3255 [(set_attr "type" "logics_reg")]
3258 (define_insn "*and_one_cmpl<mode>3_compare0_no_reuse"
3259 [(set (reg:CC_NZ CC_REGNUM)
3262 (match_operand:GPI 0 "register_operand" "r"))
3263 (match_operand:GPI 1 "register_operand" "r"))
3266 "bics\\t<w>zr, %<w>1, %<w>0"
3267 [(set_attr "type" "logics_reg")]
3270 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
3271 [(set (match_operand:GPI 0 "register_operand" "=r")
3272 (LOGICAL:GPI (not:GPI
3274 (match_operand:GPI 1 "register_operand" "r")
3275 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
3276 (match_operand:GPI 3 "register_operand" "r")))]
3278 "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3279 [(set_attr "type" "logic_shift_imm")]
3282 (define_insn "*eor_one_cmpl_<SHIFT:optab><mode>3_alt"
3283 [(set (match_operand:GPI 0 "register_operand" "=r")
3286 (match_operand:GPI 1 "register_operand" "r")
3287 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3288 (match_operand:GPI 3 "register_operand" "r"))))]
3290 "eon\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3291 [(set_attr "type" "logic_shift_imm")]
3294 ;; Zero-extend version of the above.
3295 (define_insn "*eor_one_cmpl_<SHIFT:optab>sidi3_alt_ze"
3296 [(set (match_operand:DI 0 "register_operand" "=r")
3300 (match_operand:SI 1 "register_operand" "r")
3301 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3302 (match_operand:SI 3 "register_operand" "r")))))]
3304 "eon\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3305 [(set_attr "type" "logic_shift_imm")]
3308 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
3309 [(set (reg:CC_NZ CC_REGNUM)
3313 (match_operand:GPI 1 "register_operand" "r")
3314 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
3315 (match_operand:GPI 3 "register_operand" "r"))
3317 (set (match_operand:GPI 0 "register_operand" "=r")
3320 (match_dup 1) (match_dup 2))) (match_dup 3)))]
3322 "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3323 [(set_attr "type" "logics_shift_imm")]
3326 ;; zero_extend version of above
3327 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
3328 [(set (reg:CC_NZ CC_REGNUM)
3332 (match_operand:SI 1 "register_operand" "r")
3333 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
3334 (match_operand:SI 3 "register_operand" "r"))
3336 (set (match_operand:DI 0 "register_operand" "=r")
3337 (zero_extend:DI (and:SI
3339 (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
3341 "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3342 [(set_attr "type" "logics_shift_imm")]
3345 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0_no_reuse"
3346 [(set (reg:CC_NZ CC_REGNUM)
3350 (match_operand:GPI 0 "register_operand" "r")
3351 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n")))
3352 (match_operand:GPI 2 "register_operand" "r"))
3355 "bics\\t<w>zr, %<w>2, %<w>0, <SHIFT:shift> %1"
3356 [(set_attr "type" "logics_shift_imm")]
3359 (define_insn "clz<mode>2"
3360 [(set (match_operand:GPI 0 "register_operand" "=r")
3361 (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
3363 "clz\\t%<w>0, %<w>1"
3364 [(set_attr "type" "clz")]
3367 (define_expand "ffs<mode>2"
3368 [(match_operand:GPI 0 "register_operand")
3369 (match_operand:GPI 1 "register_operand")]
3372 rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
3373 rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
3375 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3376 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3377 emit_insn (gen_csinc3<mode>_insn (operands[0], x, operands[0], const0_rtx));
3382 (define_insn "clrsb<mode>2"
3383 [(set (match_operand:GPI 0 "register_operand" "=r")
3384 (clrsb:GPI (match_operand:GPI 1 "register_operand" "r")))]
3386 "cls\\t%<w>0, %<w>1"
3387 [(set_attr "type" "clz")]
3390 (define_insn "rbit<mode>2"
3391 [(set (match_operand:GPI 0 "register_operand" "=r")
3392 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
3394 "rbit\\t%<w>0, %<w>1"
3395 [(set_attr "type" "rbit")]
3398 (define_expand "ctz<mode>2"
3399 [(match_operand:GPI 0 "register_operand")
3400 (match_operand:GPI 1 "register_operand")]
3403 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3404 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3409 (define_insn "*and<mode>3nr_compare0"
3410 [(set (reg:CC_NZ CC_REGNUM)
3412 (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
3413 (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
3416 "tst\\t%<w>0, %<w>1"
3417 [(set_attr "type" "logics_reg")]
3420 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
3421 [(set (reg:CC_NZ CC_REGNUM)
3424 (match_operand:GPI 0 "register_operand" "r")
3425 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
3426 (match_operand:GPI 2 "register_operand" "r"))
3429 "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
3430 [(set_attr "type" "logics_shift_imm")]
3433 ;; -------------------------------------------------------------------
3435 ;; -------------------------------------------------------------------
3437 (define_expand "<optab><mode>3"
3438 [(set (match_operand:GPI 0 "register_operand")
3439 (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
3440 (match_operand:QI 2 "nonmemory_operand")))]
3443 if (CONST_INT_P (operands[2]))
3445 operands[2] = GEN_INT (INTVAL (operands[2])
3446 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3448 if (operands[2] == const0_rtx)
3450 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3457 (define_expand "ashl<mode>3"
3458 [(set (match_operand:SHORT 0 "register_operand")
3459 (ashift:SHORT (match_operand:SHORT 1 "register_operand")
3460 (match_operand:QI 2 "nonmemory_operand")))]
3463 if (CONST_INT_P (operands[2]))
3465 operands[2] = GEN_INT (INTVAL (operands[2])
3466 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3468 if (operands[2] == const0_rtx)
3470 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3479 (define_expand "rotr<mode>3"
3480 [(set (match_operand:GPI 0 "register_operand")
3481 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3482 (match_operand:QI 2 "nonmemory_operand")))]
3485 if (CONST_INT_P (operands[2]))
3487 operands[2] = GEN_INT (INTVAL (operands[2])
3488 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3490 if (operands[2] == const0_rtx)
3492 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3499 (define_expand "rotl<mode>3"
3500 [(set (match_operand:GPI 0 "register_operand")
3501 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3502 (match_operand:QI 2 "nonmemory_operand")))]
3505 /* (SZ - cnt) % SZ == -cnt % SZ */
3506 if (CONST_INT_P (operands[2]))
3508 operands[2] = GEN_INT ((-INTVAL (operands[2]))
3509 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3510 if (operands[2] == const0_rtx)
3512 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3517 operands[2] = expand_simple_unop (QImode, NEG, operands[2],
3522 ;; Logical left shift using SISD or Integer instruction
3523 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
3524 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3526 (match_operand:GPI 1 "register_operand" "w,w,r")
3527 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3530 shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3531 ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
3532 lsl\t%<w>0, %<w>1, %<w>2"
3533 [(set_attr "simd" "yes,yes,no")
3534 (set_attr "type" "neon_shift_imm<q>, neon_shift_reg<q>,shift_reg")]
3537 ;; Logical right shift using SISD or Integer instruction
3538 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3539 [(set (match_operand:GPI 0 "register_operand" "=w,&w,r")
3541 (match_operand:GPI 1 "register_operand" "w,w,r")
3542 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3545 ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3547 lsr\t%<w>0, %<w>1, %<w>2"
3548 [(set_attr "simd" "yes,yes,no")
3549 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")]
3553 [(set (match_operand:DI 0 "aarch64_simd_register")
3555 (match_operand:DI 1 "aarch64_simd_register")
3556 (match_operand:QI 2 "aarch64_simd_register")))]
3557 "TARGET_SIMD && reload_completed"
3559 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3561 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_USHL))]
3563 operands[3] = gen_lowpart (QImode, operands[0]);
3568 [(set (match_operand:SI 0 "aarch64_simd_register")
3570 (match_operand:SI 1 "aarch64_simd_register")
3571 (match_operand:QI 2 "aarch64_simd_register")))]
3572 "TARGET_SIMD && reload_completed"
3574 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3576 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_USHL_2S))]
3578 operands[3] = gen_lowpart (QImode, operands[0]);
3582 ;; Arithmetic right shift using SISD or Integer instruction
3583 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3584 [(set (match_operand:GPI 0 "register_operand" "=w,&w,&w,r")
3586 (match_operand:GPI 1 "register_operand" "w,w,w,r")
3587 (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,0,rUs<cmode>")))]
3590 sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3593 asr\t%<w>0, %<w>1, %<w>2"
3594 [(set_attr "simd" "yes,yes,yes,no")
3595 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>,shift_reg")]
3599 [(set (match_operand:DI 0 "aarch64_simd_register")
3601 (match_operand:DI 1 "aarch64_simd_register")
3602 (match_operand:QI 2 "aarch64_simd_register")))]
3603 "TARGET_SIMD && reload_completed"
3605 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3607 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_SSHL))]
3609 operands[3] = gen_lowpart (QImode, operands[0]);
3614 [(set (match_operand:SI 0 "aarch64_simd_register")
3616 (match_operand:SI 1 "aarch64_simd_register")
3617 (match_operand:QI 2 "aarch64_simd_register")))]
3618 "TARGET_SIMD && reload_completed"
3620 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3622 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_SSHL_2S))]
3624 operands[3] = gen_lowpart (QImode, operands[0]);
3628 (define_insn "*aarch64_sisd_ushl"
3629 [(set (match_operand:DI 0 "register_operand" "=w")
3630 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3631 (match_operand:QI 2 "register_operand" "w")]
3634 "ushl\t%d0, %d1, %d2"
3635 [(set_attr "simd" "yes")
3636 (set_attr "type" "neon_shift_reg")]
3639 (define_insn "*aarch64_ushl_2s"
3640 [(set (match_operand:SI 0 "register_operand" "=w")
3641 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3642 (match_operand:QI 2 "register_operand" "w")]
3645 "ushl\t%0.2s, %1.2s, %2.2s"
3646 [(set_attr "simd" "yes")
3647 (set_attr "type" "neon_shift_reg")]
3650 (define_insn "*aarch64_sisd_sshl"
3651 [(set (match_operand:DI 0 "register_operand" "=w")
3652 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3653 (match_operand:QI 2 "register_operand" "w")]
3656 "sshl\t%d0, %d1, %d2"
3657 [(set_attr "simd" "yes")
3658 (set_attr "type" "neon_shift_reg")]
3661 (define_insn "*aarch64_sshl_2s"
3662 [(set (match_operand:SI 0 "register_operand" "=w")
3663 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3664 (match_operand:QI 2 "register_operand" "w")]
3667 "sshl\t%0.2s, %1.2s, %2.2s"
3668 [(set_attr "simd" "yes")
3669 (set_attr "type" "neon_shift_reg")]
3672 (define_insn "*aarch64_sisd_neg_qi"
3673 [(set (match_operand:QI 0 "register_operand" "=w")
3674 (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3678 [(set_attr "simd" "yes")
3679 (set_attr "type" "neon_neg")]
3683 (define_insn "*ror<mode>3_insn"
3684 [(set (match_operand:GPI 0 "register_operand" "=r")
3686 (match_operand:GPI 1 "register_operand" "r")
3687 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3689 "ror\\t%<w>0, %<w>1, %<w>2"
3690 [(set_attr "type" "shift_reg")]
3693 ;; zero_extend version of above
3694 (define_insn "*<optab>si3_insn_uxtw"
3695 [(set (match_operand:DI 0 "register_operand" "=r")
3696 (zero_extend:DI (SHIFT:SI
3697 (match_operand:SI 1 "register_operand" "r")
3698 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3700 "<shift>\\t%w0, %w1, %w2"
3701 [(set_attr "type" "shift_reg")]
3704 (define_insn "*<optab><mode>3_insn"
3705 [(set (match_operand:SHORT 0 "register_operand" "=r")
3706 (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3707 (match_operand 2 "const_int_operand" "n")))]
3708 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3710 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3711 return "<bfshift>\t%w0, %w1, %2, %3";
3713 [(set_attr "type" "bfm")]
3716 (define_insn "*extr<mode>5_insn"
3717 [(set (match_operand:GPI 0 "register_operand" "=r")
3718 (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3719 (match_operand 3 "const_int_operand" "n"))
3720 (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3721 (match_operand 4 "const_int_operand" "n"))))]
3722 "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3723 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3724 "extr\\t%<w>0, %<w>1, %<w>2, %4"
3725 [(set_attr "type" "shift_imm")]
3728 ;; There are no canonicalisation rules for ashift and lshiftrt inside an ior
3729 ;; so we have to match both orderings.
3730 (define_insn "*extr<mode>5_insn_alt"
3731 [(set (match_operand:GPI 0 "register_operand" "=r")
3732 (ior:GPI (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3733 (match_operand 4 "const_int_operand" "n"))
3734 (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3735 (match_operand 3 "const_int_operand" "n"))))]
3736 "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode)
3737 && (UINTVAL (operands[3]) + UINTVAL (operands[4])
3738 == GET_MODE_BITSIZE (<MODE>mode))"
3739 "extr\\t%<w>0, %<w>1, %<w>2, %4"
3740 [(set_attr "type" "shift_imm")]
3743 ;; zero_extend version of the above
3744 (define_insn "*extrsi5_insn_uxtw"
3745 [(set (match_operand:DI 0 "register_operand" "=r")
3747 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3748 (match_operand 3 "const_int_operand" "n"))
3749 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3750 (match_operand 4 "const_int_operand" "n")))))]
3751 "UINTVAL (operands[3]) < 32 &&
3752 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3753 "extr\\t%w0, %w1, %w2, %4"
3754 [(set_attr "type" "shift_imm")]
3757 (define_insn "*extrsi5_insn_uxtw_alt"
3758 [(set (match_operand:DI 0 "register_operand" "=r")
3760 (ior:SI (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3761 (match_operand 4 "const_int_operand" "n"))
3762 (ashift:SI (match_operand:SI 1 "register_operand" "r")
3763 (match_operand 3 "const_int_operand" "n")))))]
3764 "UINTVAL (operands[3]) < 32 &&
3765 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3766 "extr\\t%w0, %w1, %w2, %4"
3767 [(set_attr "type" "shift_imm")]
3770 (define_insn "*ror<mode>3_insn"
3771 [(set (match_operand:GPI 0 "register_operand" "=r")
3772 (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3773 (match_operand 2 "const_int_operand" "n")))]
3774 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3776 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3777 return "ror\\t%<w>0, %<w>1, %3";
3779 [(set_attr "type" "shift_imm")]
3782 ;; zero_extend version of the above
3783 (define_insn "*rorsi3_insn_uxtw"
3784 [(set (match_operand:DI 0 "register_operand" "=r")
3786 (rotate:SI (match_operand:SI 1 "register_operand" "r")
3787 (match_operand 2 "const_int_operand" "n"))))]
3788 "UINTVAL (operands[2]) < 32"
3790 operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3791 return "ror\\t%w0, %w1, %3";
3793 [(set_attr "type" "shift_imm")]
3796 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3797 [(set (match_operand:GPI 0 "register_operand" "=r")
3799 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3800 (match_operand 2 "const_int_operand" "n"))))]
3801 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3803 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3804 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3806 [(set_attr "type" "bfm")]
3809 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3810 [(set (match_operand:GPI 0 "register_operand" "=r")
3812 (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3813 (match_operand 2 "const_int_operand" "n"))))]
3814 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3816 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3817 return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3819 [(set_attr "type" "bfm")]
3822 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3823 [(set (match_operand:GPI 0 "register_operand" "=r")
3825 (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3826 (match_operand 2 "const_int_operand" "n"))))]
3827 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3829 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3830 return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3832 [(set_attr "type" "bfm")]
3835 ;; -------------------------------------------------------------------
3837 ;; -------------------------------------------------------------------
3839 (define_expand "<optab>"
3840 [(set (match_operand:DI 0 "register_operand" "=r")
3841 (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3842 (match_operand 2 "const_int_operand" "n")
3843 (match_operand 3 "const_int_operand" "n")))]
3848 (define_insn "*<optab><mode>"
3849 [(set (match_operand:GPI 0 "register_operand" "=r")
3850 (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3851 (match_operand 2 "const_int_operand" "n")
3852 (match_operand 3 "const_int_operand" "n")))]
3854 "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3855 [(set_attr "type" "bfm")]
3858 ;; Bitfield Insert (insv)
3859 (define_expand "insv<mode>"
3860 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3861 (match_operand 1 "const_int_operand")
3862 (match_operand 2 "const_int_operand"))
3863 (match_operand:GPI 3 "general_operand"))]
3866 unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3867 unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3868 rtx value = operands[3];
3870 if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3873 if (CONST_INT_P (value))
3875 unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3877 /* Prefer AND/OR for inserting all zeros or all ones. */
3878 if ((UINTVAL (value) & mask) == 0
3879 || (UINTVAL (value) & mask) == mask)
3882 /* 16-bit aligned 16-bit wide insert is handled by insv_imm. */
3883 if (width == 16 && (pos % 16) == 0)
3886 operands[3] = force_reg (<MODE>mode, value);
3889 (define_insn "*insv_reg<mode>"
3890 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3891 (match_operand 1 "const_int_operand" "n")
3892 (match_operand 2 "const_int_operand" "n"))
3893 (match_operand:GPI 3 "register_operand" "r"))]
3894 "!(UINTVAL (operands[1]) == 0
3895 || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3896 > GET_MODE_BITSIZE (<MODE>mode)))"
3897 "bfi\\t%<w>0, %<w>3, %2, %1"
3898 [(set_attr "type" "bfm")]
3901 (define_insn "*extr_insv_lower_reg<mode>"
3902 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3903 (match_operand 1 "const_int_operand" "n")
3905 (zero_extract:GPI (match_operand:GPI 2 "register_operand" "r")
3907 (match_operand 3 "const_int_operand" "n")))]
3908 "!(UINTVAL (operands[1]) == 0
3909 || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3910 > GET_MODE_BITSIZE (<MODE>mode)))"
3911 "bfxil\\t%<w>0, %<w>2, %3, %1"
3912 [(set_attr "type" "bfm")]
3915 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3916 [(set (match_operand:GPI 0 "register_operand" "=r")
3917 (ashift:GPI (ANY_EXTEND:GPI
3918 (match_operand:ALLX 1 "register_operand" "r"))
3919 (match_operand 2 "const_int_operand" "n")))]
3920 "UINTVAL (operands[2]) < <GPI:sizen>"
3922 operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3923 ? GEN_INT (<ALLX:sizen>)
3924 : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3925 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3927 [(set_attr "type" "bfm")]
3930 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3932 (define_insn "*andim_ashift<mode>_bfiz"
3933 [(set (match_operand:GPI 0 "register_operand" "=r")
3934 (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3935 (match_operand 2 "const_int_operand" "n"))
3936 (match_operand 3 "const_int_operand" "n")))]
3937 "(INTVAL (operands[2]) < (<GPI:sizen>))
3938 && exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3939 && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3940 "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3941 [(set_attr "type" "bfm")]
3944 (define_insn "bswap<mode>2"
3945 [(set (match_operand:GPI 0 "register_operand" "=r")
3946 (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3948 "rev\\t%<w>0, %<w>1"
3949 [(set_attr "type" "rev")]
3952 (define_insn "bswaphi2"
3953 [(set (match_operand:HI 0 "register_operand" "=r")
3954 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3957 [(set_attr "type" "rev")]
3960 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
3961 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
3962 ;; each valid permutation.
3964 (define_insn "rev16<mode>2"
3965 [(set (match_operand:GPI 0 "register_operand" "=r")
3966 (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3968 (match_operand:GPI 3 "const_int_operand" "n"))
3969 (and:GPI (lshiftrt:GPI (match_dup 1)
3971 (match_operand:GPI 2 "const_int_operand" "n"))))]
3972 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3973 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3974 "rev16\\t%<w>0, %<w>1"
3975 [(set_attr "type" "rev")]
3978 (define_insn "rev16<mode>2_alt"
3979 [(set (match_operand:GPI 0 "register_operand" "=r")
3980 (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r")
3982 (match_operand:GPI 2 "const_int_operand" "n"))
3983 (and:GPI (ashift:GPI (match_dup 1)
3985 (match_operand:GPI 3 "const_int_operand" "n"))))]
3986 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3987 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3988 "rev16\\t%<w>0, %<w>1"
3989 [(set_attr "type" "rev")]
3992 ;; zero_extend version of above
3993 (define_insn "*bswapsi2_uxtw"
3994 [(set (match_operand:DI 0 "register_operand" "=r")
3995 (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3998 [(set_attr "type" "rev")]
4001 ;; -------------------------------------------------------------------
4002 ;; Floating-point intrinsics
4003 ;; -------------------------------------------------------------------
4005 ;; frint floating-point round to integral standard patterns.
4006 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round, frintn.
4008 (define_insn "<frint_pattern><mode>2"
4009 [(set (match_operand:GPF 0 "register_operand" "=w")
4010 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
4013 "frint<frint_suffix>\\t%<s>0, %<s>1"
4014 [(set_attr "type" "f_rint<s>")]
4017 ;; frcvt floating-point round to integer and convert standard patterns.
4018 ;; Expands to lbtrunc, lceil, lfloor, lround.
4019 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
4020 [(set (match_operand:GPI 0 "register_operand" "=r")
4021 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
4024 "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
4025 [(set_attr "type" "f_cvtf2i")]
4030 (define_insn "fma<mode>4"
4031 [(set (match_operand:GPF 0 "register_operand" "=w")
4032 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
4033 (match_operand:GPF 2 "register_operand" "w")
4034 (match_operand:GPF 3 "register_operand" "w")))]
4036 "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
4037 [(set_attr "type" "fmac<s>")]
4040 (define_insn "fnma<mode>4"
4041 [(set (match_operand:GPF 0 "register_operand" "=w")
4042 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
4043 (match_operand:GPF 2 "register_operand" "w")
4044 (match_operand:GPF 3 "register_operand" "w")))]
4046 "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
4047 [(set_attr "type" "fmac<s>")]
4050 (define_insn "fms<mode>4"
4051 [(set (match_operand:GPF 0 "register_operand" "=w")
4052 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
4053 (match_operand:GPF 2 "register_operand" "w")
4054 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
4056 "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
4057 [(set_attr "type" "fmac<s>")]
4060 (define_insn "fnms<mode>4"
4061 [(set (match_operand:GPF 0 "register_operand" "=w")
4062 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
4063 (match_operand:GPF 2 "register_operand" "w")
4064 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
4066 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
4067 [(set_attr "type" "fmac<s>")]
4070 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
4071 (define_insn "*fnmadd<mode>4"
4072 [(set (match_operand:GPF 0 "register_operand" "=w")
4073 (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
4074 (match_operand:GPF 2 "register_operand" "w")
4075 (match_operand:GPF 3 "register_operand" "w"))))]
4076 "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
4077 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
4078 [(set_attr "type" "fmac<s>")]
4081 ;; -------------------------------------------------------------------
4082 ;; Floating-point conversions
4083 ;; -------------------------------------------------------------------
4085 (define_insn "extendsfdf2"
4086 [(set (match_operand:DF 0 "register_operand" "=w")
4087 (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
4090 [(set_attr "type" "f_cvt")]
4093 (define_insn "truncdfsf2"
4094 [(set (match_operand:SF 0 "register_operand" "=w")
4095 (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
4098 [(set_attr "type" "f_cvt")]
4101 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
4102 [(set (match_operand:GPI 0 "register_operand" "=r")
4103 (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
4105 "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
4106 [(set_attr "type" "f_cvtf2i")]
4109 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
4110 [(set (match_operand:GPI 0 "register_operand" "=r")
4111 (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
4113 "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
4114 [(set_attr "type" "f_cvtf2i")]
4117 (define_insn "<optab><fcvt_target><GPF:mode>2"
4118 [(set (match_operand:GPF 0 "register_operand" "=w,w")
4119 (FLOATUORS:GPF (match_operand:<FCVT_TARGET> 1 "register_operand" "w,r")))]
4122 <su_optab>cvtf\t%<GPF:s>0, %<s>1
4123 <su_optab>cvtf\t%<GPF:s>0, %<w1>1"
4124 [(set_attr "simd" "yes,no")
4125 (set_attr "fp" "no,yes")
4126 (set_attr "type" "neon_int_to_fp_<Vetype>,f_cvti2f")]
4129 (define_insn "<optab><fcvt_iesize><GPF:mode>2"
4130 [(set (match_operand:GPF 0 "register_operand" "=w")
4131 (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand" "r")))]
4133 "<su_optab>cvtf\t%<GPF:s>0, %<w2>1"
4134 [(set_attr "type" "f_cvti2f")]
4137 ;; -------------------------------------------------------------------
4138 ;; Floating-point arithmetic
4139 ;; -------------------------------------------------------------------
4141 (define_insn "add<mode>3"
4142 [(set (match_operand:GPF 0 "register_operand" "=w")
4144 (match_operand:GPF 1 "register_operand" "w")
4145 (match_operand:GPF 2 "register_operand" "w")))]
4147 "fadd\\t%<s>0, %<s>1, %<s>2"
4148 [(set_attr "type" "fadd<s>")]
4151 (define_insn "sub<mode>3"
4152 [(set (match_operand:GPF 0 "register_operand" "=w")
4154 (match_operand:GPF 1 "register_operand" "w")
4155 (match_operand:GPF 2 "register_operand" "w")))]
4157 "fsub\\t%<s>0, %<s>1, %<s>2"
4158 [(set_attr "type" "fadd<s>")]
4161 (define_insn "mul<mode>3"
4162 [(set (match_operand:GPF 0 "register_operand" "=w")
4164 (match_operand:GPF 1 "register_operand" "w")
4165 (match_operand:GPF 2 "register_operand" "w")))]
4167 "fmul\\t%<s>0, %<s>1, %<s>2"
4168 [(set_attr "type" "fmul<s>")]
4171 (define_insn "*fnmul<mode>3"
4172 [(set (match_operand:GPF 0 "register_operand" "=w")
4174 (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
4175 (match_operand:GPF 2 "register_operand" "w")))]
4177 "fnmul\\t%<s>0, %<s>1, %<s>2"
4178 [(set_attr "type" "fmul<s>")]
4181 (define_insn "div<mode>3"
4182 [(set (match_operand:GPF 0 "register_operand" "=w")
4184 (match_operand:GPF 1 "register_operand" "w")
4185 (match_operand:GPF 2 "register_operand" "w")))]
4187 "fdiv\\t%<s>0, %<s>1, %<s>2"
4188 [(set_attr "type" "fdiv<s>")]
4191 (define_insn "neg<mode>2"
4192 [(set (match_operand:GPF 0 "register_operand" "=w")
4193 (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
4195 "fneg\\t%<s>0, %<s>1"
4196 [(set_attr "type" "ffarith<s>")]
4199 (define_insn "sqrt<mode>2"
4200 [(set (match_operand:GPF 0 "register_operand" "=w")
4201 (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
4203 "fsqrt\\t%<s>0, %<s>1"
4204 [(set_attr "type" "fsqrt<s>")]
4207 (define_insn "abs<mode>2"
4208 [(set (match_operand:GPF 0 "register_operand" "=w")
4209 (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
4211 "fabs\\t%<s>0, %<s>1"
4212 [(set_attr "type" "ffarith<s>")]
4215 ;; Given that smax/smin do not specify the result when either input is NaN,
4216 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
4219 (define_insn "smax<mode>3"
4220 [(set (match_operand:GPF 0 "register_operand" "=w")
4221 (smax:GPF (match_operand:GPF 1 "register_operand" "w")
4222 (match_operand:GPF 2 "register_operand" "w")))]
4224 "fmaxnm\\t%<s>0, %<s>1, %<s>2"
4225 [(set_attr "type" "f_minmax<s>")]
4228 (define_insn "smin<mode>3"
4229 [(set (match_operand:GPF 0 "register_operand" "=w")
4230 (smin:GPF (match_operand:GPF 1 "register_operand" "w")
4231 (match_operand:GPF 2 "register_operand" "w")))]
4233 "fminnm\\t%<s>0, %<s>1, %<s>2"
4234 [(set_attr "type" "f_minmax<s>")]
4237 ;; -------------------------------------------------------------------
4239 ;; -------------------------------------------------------------------
4241 (define_expand "aarch64_reload_mov<mode>"
4242 [(set (match_operand:TX 0 "register_operand" "=w")
4243 (match_operand:TX 1 "register_operand" "w"))
4244 (clobber (match_operand:DI 2 "register_operand" "=&r"))
4248 rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
4249 rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
4250 gen_aarch64_movtilow_tilow (op0, op1);
4251 gen_aarch64_movdi_tihigh (operands[2], op1);
4252 gen_aarch64_movtihigh_di (op0, operands[2]);
4257 ;; The following secondary reload helpers patterns are invoked
4258 ;; after or during reload as we don't want these patterns to start
4259 ;; kicking in during the combiner.
4261 (define_insn "aarch64_movdi_<mode>low"
4262 [(set (match_operand:DI 0 "register_operand" "=r")
4263 (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
4264 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4266 [(set_attr "type" "f_mrc")
4267 (set_attr "length" "4")
4270 (define_insn "aarch64_movdi_<mode>high"
4271 [(set (match_operand:DI 0 "register_operand" "=r")
4273 (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
4275 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4276 "fmov\\t%x0, %1.d[1]"
4277 [(set_attr "type" "f_mrc")
4278 (set_attr "length" "4")
4281 (define_insn "aarch64_mov<mode>high_di"
4282 [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
4283 (const_int 64) (const_int 64))
4284 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4285 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4286 "fmov\\t%0.d[1], %x1"
4287 [(set_attr "type" "f_mcr")
4288 (set_attr "length" "4")
4291 (define_insn "aarch64_mov<mode>low_di"
4292 [(set (match_operand:TX 0 "register_operand" "=w")
4293 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4294 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4296 [(set_attr "type" "f_mcr")
4297 (set_attr "length" "4")
4300 (define_insn "aarch64_movtilow_tilow"
4301 [(set (match_operand:TI 0 "register_operand" "=w")
4303 (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
4304 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4306 [(set_attr "type" "fmov")
4307 (set_attr "length" "4")
4310 ;; There is a deliberate reason why the parameters of high and lo_sum's
4311 ;; don't have modes for ADRP and ADD instructions. This is to allow high
4312 ;; and lo_sum's to be used with the labels defining the jump tables in
4315 (define_expand "add_losym"
4316 [(set (match_operand 0 "register_operand" "=r")
4317 (lo_sum (match_operand 1 "register_operand" "r")
4318 (match_operand 2 "aarch64_valid_symref" "S")))]
4321 machine_mode mode = GET_MODE (operands[0]);
4323 emit_insn ((mode == DImode
4325 : gen_add_losym_si) (operands[0],
4331 (define_insn "add_losym_<mode>"
4332 [(set (match_operand:P 0 "register_operand" "=r")
4333 (lo_sum:P (match_operand:P 1 "register_operand" "r")
4334 (match_operand 2 "aarch64_valid_symref" "S")))]
4336 "add\\t%<w>0, %<w>1, :lo12:%a2"
4337 [(set_attr "type" "alu_imm")]
4340 (define_insn "ldr_got_small_<mode>"
4341 [(set (match_operand:PTR 0 "register_operand" "=r")
4342 (unspec:PTR [(mem:PTR (lo_sum:PTR
4343 (match_operand:PTR 1 "register_operand" "r")
4344 (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
4345 UNSPEC_GOTSMALLPIC))]
4347 "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
4348 [(set_attr "type" "load1")]
4351 (define_insn "ldr_got_small_sidi"
4352 [(set (match_operand:DI 0 "register_operand" "=r")
4354 (unspec:SI [(mem:SI (lo_sum:DI
4355 (match_operand:DI 1 "register_operand" "r")
4356 (match_operand:DI 2 "aarch64_valid_symref" "S")))]
4357 UNSPEC_GOTSMALLPIC)))]
4359 "ldr\\t%w0, [%1, #:got_lo12:%a2]"
4360 [(set_attr "type" "load1")]
4363 (define_insn "ldr_got_tiny"
4364 [(set (match_operand:DI 0 "register_operand" "=r")
4365 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
4366 UNSPEC_GOTTINYPIC))]
4369 [(set_attr "type" "load1")]
4372 (define_insn "aarch64_load_tp_hard"
4373 [(set (match_operand:DI 0 "register_operand" "=r")
4374 (unspec:DI [(const_int 0)] UNSPEC_TLS))]
4376 "mrs\\t%0, tpidr_el0"
4377 [(set_attr "type" "mrs")]
4380 ;; The TLS ABI specifically requires that the compiler does not schedule
4381 ;; instructions in the TLS stubs, in order to enable linker relaxation.
4382 ;; Therefore we treat the stubs as an atomic sequence.
4383 (define_expand "tlsgd_small"
4384 [(parallel [(set (match_operand 0 "register_operand" "")
4385 (call (mem:DI (match_dup 2)) (const_int 1)))
4386 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
4387 (clobber (reg:DI LR_REGNUM))])]
4390 operands[2] = aarch64_tls_get_addr ();
4393 (define_insn "*tlsgd_small"
4394 [(set (match_operand 0 "register_operand" "")
4395 (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
4396 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
4397 (clobber (reg:DI LR_REGNUM))
4400 "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
4401 [(set_attr "type" "call")
4402 (set_attr "length" "16")])
4404 (define_insn "tlsie_small_<mode>"
4405 [(set (match_operand:PTR 0 "register_operand" "=r")
4406 (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
4407 UNSPEC_GOTSMALLTLS))]
4409 "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
4410 [(set_attr "type" "load1")
4411 (set_attr "length" "8")]
4414 (define_insn "tlsie_small_sidi"
4415 [(set (match_operand:DI 0 "register_operand" "=r")
4417 (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")]
4418 UNSPEC_GOTSMALLTLS)))]
4420 "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
4421 [(set_attr "type" "load1")
4422 (set_attr "length" "8")]
4425 (define_expand "tlsle_small"
4426 [(set (match_operand 0 "register_operand" "=r")
4427 (unspec [(match_operand 1 "register_operand" "r")
4428 (match_operand 2 "aarch64_tls_le_symref" "S")]
4429 UNSPEC_GOTSMALLTLS))]
4432 machine_mode mode = GET_MODE (operands[0]);
4433 emit_insn ((mode == DImode
4434 ? gen_tlsle_small_di
4435 : gen_tlsle_small_si) (operands[0],
4441 (define_insn "tlsle_small_<mode>"
4442 [(set (match_operand:P 0 "register_operand" "=r")
4443 (unspec:P [(match_operand:P 1 "register_operand" "r")
4444 (match_operand 2 "aarch64_tls_le_symref" "S")]
4445 UNSPEC_GOTSMALLTLS))]
4447 "add\\t%<w>0, %<w>1, #%G2, lsl #12\;add\\t%<w>0, %<w>0, #%L2"
4448 [(set_attr "type" "alu_sreg")
4449 (set_attr "length" "8")]
4452 (define_insn "tlsdesc_small_<mode>"
4453 [(set (reg:PTR R0_REGNUM)
4454 (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
4456 (clobber (reg:DI LR_REGNUM))
4457 (clobber (reg:CC CC_REGNUM))
4458 (clobber (match_scratch:DI 1 "=r"))]
4460 "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
4461 [(set_attr "type" "call")
4462 (set_attr "length" "16")])
4464 (define_insn "stack_tie"
4465 [(set (mem:BLK (scratch))
4466 (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
4467 (match_operand:DI 1 "register_operand" "rk")]
4471 [(set_attr "length" "0")]
4474 ;; Named pattern for expanding thread pointer reference.
4475 (define_expand "get_thread_pointerdi"
4476 [(match_operand:DI 0 "register_operand" "=r")]
4479 rtx tmp = aarch64_load_tp (operands[0]);
4480 if (tmp != operands[0])
4481 emit_move_insn (operands[0], tmp);
4485 ;; Named patterns for stack smashing protection.
4486 (define_expand "stack_protect_set"
4487 [(match_operand 0 "memory_operand")
4488 (match_operand 1 "memory_operand")]
4491 machine_mode mode = GET_MODE (operands[0]);
4493 emit_insn ((mode == DImode
4494 ? gen_stack_protect_set_di
4495 : gen_stack_protect_set_si) (operands[0], operands[1]));
4499 (define_insn "stack_protect_set_<mode>"
4500 [(set (match_operand:PTR 0 "memory_operand" "=m")
4501 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
4503 (set (match_scratch:PTR 2 "=&r") (const_int 0))]
4505 "ldr\\t%<w>2, %1\;str\\t%<w>2, %0\;mov\t%<w>2,0"
4506 [(set_attr "length" "12")
4507 (set_attr "type" "multiple")])
4509 (define_expand "stack_protect_test"
4510 [(match_operand 0 "memory_operand")
4511 (match_operand 1 "memory_operand")
4516 machine_mode mode = GET_MODE (operands[0]);
4518 result = gen_reg_rtx(mode);
4520 emit_insn ((mode == DImode
4521 ? gen_stack_protect_test_di
4522 : gen_stack_protect_test_si) (result,
4527 emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4528 result, const0_rtx, operands[2]));
4530 emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4531 result, const0_rtx, operands[2]));
4535 (define_insn "stack_protect_test_<mode>"
4536 [(set (match_operand:PTR 0 "register_operand" "=r")
4537 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
4538 (match_operand:PTR 2 "memory_operand" "m")]
4540 (clobber (match_scratch:PTR 3 "=&r"))]
4542 "ldr\t%<w>3, %x1\;ldr\t%<w>0, %x2\;eor\t%<w>0, %<w>3, %<w>0"
4543 [(set_attr "length" "12")
4544 (set_attr "type" "multiple")])
4546 ;; Write Floating-point Control Register.
4547 (define_insn "set_fpcr"
4548 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
4551 [(set_attr "type" "mrs")])
4553 ;; Read Floating-point Control Register.
4554 (define_insn "get_fpcr"
4555 [(set (match_operand:SI 0 "register_operand" "=r")
4556 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
4559 [(set_attr "type" "mrs")])
4561 ;; Write Floating-point Status Register.
4562 (define_insn "set_fpsr"
4563 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
4566 [(set_attr "type" "mrs")])
4568 ;; Read Floating-point Status Register.
4569 (define_insn "get_fpsr"
4570 [(set (match_operand:SI 0 "register_operand" "=r")
4571 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
4574 [(set_attr "type" "mrs")])
4577 ;; Define the subtract-one-and-jump insns so loop.c
4578 ;; knows what to generate.
4579 (define_expand "doloop_end"
4580 [(use (match_operand 0 "" "")) ; loop pseudo
4581 (use (match_operand 1 "" ""))] ; label
4582 "optimize > 0 && flag_modulo_sched"
4591 /* Currently SMS relies on the do-loop pattern to recognize loops
4592 where (1) the control part consists of all insns defining and/or
4593 using a certain 'count' register and (2) the loop count can be
4594 adjusted by modifying this register prior to the loop.
4595 ??? The possible introduction of a new block to initialize the
4596 new IV can potentially affect branch optimizations. */
4598 if (GET_MODE (operands[0]) != DImode)
4602 insn = emit_insn (gen_adddi3_compare0 (s0, s0, GEN_INT (-1)));
4604 cmp = XVECEXP (PATTERN (insn), 0, 0);
4605 cc_reg = SET_DEST (cmp);
4606 bcomp = gen_rtx_NE (VOIDmode, cc_reg, const0_rtx);
4607 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
4608 emit_jump_insn (gen_rtx_SET (pc_rtx,
4609 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
4615 (include "aarch64-simd.md")
4617 ;; Atomic Operations
4618 (include "atomics.md")
4620 ;; ldp/stp peephole patterns
4621 (include "aarch64-ldpstp.md")