1 ;; Machine description for AArch64 architecture.
2 ;; Copyright (C) 2009-2015 Free Software Foundation, Inc.
3 ;; Contributed by ARM Ltd.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; GCC is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ;; General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
68 (define_c_enum "unspec" [
125 (define_c_enum "unspecv" [
126 UNSPECV_EH_RETURN ; Represent EH_RETURN
127 UNSPECV_GET_FPCR ; Represent fetch of FPCR content.
128 UNSPECV_SET_FPCR ; Represent assign of FPCR content.
129 UNSPECV_GET_FPSR ; Represent fetch of FPSR content.
130 UNSPECV_SET_FPSR ; Represent assign of FPSR content.
134 ;; If further include files are added the defintion of MD_INCLUDES
137 (include "constraints.md")
138 (include "predicates.md")
139 (include "iterators.md")
141 ;; -------------------------------------------------------------------
142 ;; Instruction types and attributes
143 ;; -------------------------------------------------------------------
145 ; The "type" attribute is is included here from AArch32 backend to be able
146 ; to share pipeline descriptions.
147 (include "../arm/types.md")
149 ;; It is important to set the fp or simd attributes to yes when a pattern
150 ;; alternative uses the FP or SIMD register files, usually signified by use of
151 ;; the 'w' constraint. This will ensure that the alternative will be
152 ;; disabled when compiling with -mgeneral-regs-only or with the +nofp/+nosimd
153 ;; architecture extensions. If all the alternatives in a pattern use the
154 ;; FP or SIMD registers then the pattern predicate should include TARGET_FLOAT
157 ;; Attribute that specifies whether or not the instruction touches fp
158 ;; registers. When this is set to yes for an alternative, that alternative
159 ;; will be disabled when !TARGET_FLOAT.
160 (define_attr "fp" "no,yes" (const_string "no"))
162 ;; Attribute that specifies whether or not the instruction touches simd
163 ;; registers. When this is set to yes for an alternative, that alternative
164 ;; will be disabled when !TARGET_SIMD.
165 (define_attr "simd" "no,yes" (const_string "no"))
167 (define_attr "length" ""
170 ;; Attribute that controls whether an alternative is enabled or not.
171 ;; Currently it is only used to disable alternatives which touch fp or simd
172 ;; registers when -mgeneral-regs-only is specified.
173 (define_attr "enabled" "no,yes"
175 (and (eq_attr "fp" "yes")
176 (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
177 (and (eq_attr "simd" "yes")
178 (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
180 ] (const_string "yes")))
182 ;; -------------------------------------------------------------------
183 ;; Pipeline descriptions and scheduling
184 ;; -------------------------------------------------------------------
187 (include "aarch64-tune.md")
190 (include "../arm/cortex-a53.md")
191 (include "../arm/cortex-a57.md")
192 (include "thunderx.md")
193 (include "../arm/xgene1.md")
195 ;; -------------------------------------------------------------------
196 ;; Jumps and other miscellaneous insns
197 ;; -------------------------------------------------------------------
199 (define_insn "indirect_jump"
200 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
203 [(set_attr "type" "branch")]
207 [(set (pc) (label_ref (match_operand 0 "" "")))]
210 [(set_attr "type" "branch")]
213 (define_expand "cbranch<mode>4"
214 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
215 [(match_operand:GPI 1 "register_operand" "")
216 (match_operand:GPI 2 "aarch64_plus_operand" "")])
217 (label_ref (match_operand 3 "" ""))
221 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
223 operands[2] = const0_rtx;
227 (define_expand "cbranch<mode>4"
228 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
229 [(match_operand:GPF 1 "register_operand" "")
230 (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
231 (label_ref (match_operand 3 "" ""))
235 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
237 operands[2] = const0_rtx;
241 (define_expand "cbranchcc4"
242 [(set (pc) (if_then_else
243 (match_operator 0 "aarch64_comparison_operator"
244 [(match_operand 1 "cc_register" "")
245 (match_operand 2 "const0_operand")])
246 (label_ref (match_operand 3 "" ""))
251 (define_insn "ccmp_and<mode>"
252 [(set (match_operand 1 "ccmp_cc_register" "")
255 (match_operator 4 "aarch64_comparison_operator"
256 [(match_operand 0 "ccmp_cc_register" "")
258 (match_operator 5 "aarch64_comparison_operator"
259 [(match_operand:GPI 2 "register_operand" "r,r,r")
260 (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")]))
262 "aarch64_ccmp_mode_to_code (GET_MODE (operands[1])) == GET_CODE (operands[5])"
264 ccmp\\t%<w>2, %<w>3, %k5, %m4
265 ccmp\\t%<w>2, %<w>3, %k5, %m4
266 ccmn\\t%<w>2, #%n3, %k5, %m4"
267 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
270 (define_insn "ccmp_ior<mode>"
271 [(set (match_operand 1 "ccmp_cc_register" "")
274 (match_operator 4 "aarch64_comparison_operator"
275 [(match_operand 0 "ccmp_cc_register" "")
277 (match_operator 5 "aarch64_comparison_operator"
278 [(match_operand:GPI 2 "register_operand" "r,r,r")
279 (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")]))
281 "aarch64_ccmp_mode_to_code (GET_MODE (operands[1])) == GET_CODE (operands[5])"
283 ccmp\\t%<w>2, %<w>3, %K5, %M4
284 ccmp\\t%<w>2, %<w>3, %K5, %M4
285 ccmn\\t%<w>2, #%n3, %K5, %M4"
286 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
289 (define_expand "cmp<mode>"
290 [(set (match_operand 0 "cc_register" "")
291 (match_operator:CC 1 "aarch64_comparison_operator"
292 [(match_operand:GPI 2 "register_operand" "")
293 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
296 operands[1] = gen_rtx_fmt_ee (COMPARE,
297 SELECT_CC_MODE (GET_CODE (operands[1]),
298 operands[2], operands[3]),
299 operands[2], operands[3]);
303 (define_insn "*condjump"
304 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
305 [(match_operand 1 "cc_register" "") (const_int 0)])
306 (label_ref (match_operand 2 "" ""))
310 [(set_attr "type" "branch")]
313 (define_expand "casesi"
314 [(match_operand:SI 0 "register_operand" "") ; Index
315 (match_operand:SI 1 "const_int_operand" "") ; Lower bound
316 (match_operand:SI 2 "const_int_operand" "") ; Total range
317 (match_operand:DI 3 "" "") ; Table label
318 (match_operand:DI 4 "" "")] ; Out of range label
321 if (operands[1] != const0_rtx)
323 rtx reg = gen_reg_rtx (SImode);
325 /* Canonical RTL says that if you have:
329 then this should be emitted as:
333 The use of trunc_int_for_mode ensures that the resulting
334 constant can be represented in SImode, this is important
335 for the corner case where operand[1] is INT_MIN. */
337 operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
339 if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
340 (operands[1], SImode))
341 operands[1] = force_reg (SImode, operands[1]);
342 emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
346 if (!aarch64_plus_operand (operands[2], SImode))
347 operands[2] = force_reg (SImode, operands[2]);
348 emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
350 operands[0], operands[2], operands[4]));
352 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
353 emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
359 (define_insn "casesi_dispatch"
362 (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
363 (match_operand:SI 1 "register_operand" "r")]
365 (clobber (reg:CC CC_REGNUM))
366 (clobber (match_scratch:DI 3 "=r"))
367 (clobber (match_scratch:DI 4 "=r"))
368 (use (label_ref (match_operand 2 "" "")))])]
371 return aarch64_output_casesi (operands);
373 [(set_attr "length" "16")
374 (set_attr "type" "branch")]
378 [(unspec[(const_int 0)] UNSPEC_NOP)]
381 [(set_attr "type" "no_insn")]
384 (define_insn "prefetch"
385 [(prefetch (match_operand:DI 0 "address_operand" "r")
386 (match_operand:QI 1 "const_int_operand" "")
387 (match_operand:QI 2 "const_int_operand" ""))]
390 const char * pftype[2][4] =
392 {"prfm\\tPLDL1STRM, %a0",
393 "prfm\\tPLDL3KEEP, %a0",
394 "prfm\\tPLDL2KEEP, %a0",
395 "prfm\\tPLDL1KEEP, %a0"},
396 {"prfm\\tPSTL1STRM, %a0",
397 "prfm\\tPSTL3KEEP, %a0",
398 "prfm\\tPSTL2KEEP, %a0",
399 "prfm\\tPSTL1KEEP, %a0"},
402 int locality = INTVAL (operands[2]);
404 gcc_assert (IN_RANGE (locality, 0, 3));
406 return pftype[INTVAL(operands[1])][locality];
408 [(set_attr "type" "load1")]
412 [(trap_if (const_int 1) (const_int 8))]
415 [(set_attr "type" "trap")])
417 (define_expand "prologue"
418 [(clobber (const_int 0))]
421 aarch64_expand_prologue ();
426 (define_expand "epilogue"
427 [(clobber (const_int 0))]
430 aarch64_expand_epilogue (false);
435 (define_expand "sibcall_epilogue"
436 [(clobber (const_int 0))]
439 aarch64_expand_epilogue (true);
444 (define_insn "*do_return"
448 [(set_attr "type" "branch")]
451 (define_expand "return"
453 "aarch64_use_return_insn_p ()"
457 (define_insn "simple_return"
461 [(set_attr "type" "branch")]
464 (define_insn "eh_return"
465 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
469 [(set_attr "type" "branch")]
474 [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
477 [(set (match_dup 1) (match_dup 0))]
479 operands[1] = aarch64_final_eh_return_addr ();
483 (define_insn "*cb<optab><mode>1"
484 [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
486 (label_ref (match_operand 1 "" ""))
490 [(set_attr "type" "branch")]
494 (define_insn "*tb<optab><mode>1"
495 [(set (pc) (if_then_else
496 (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
498 (match_operand 1 "const_int_operand" "n"))
500 (label_ref (match_operand 2 "" ""))
502 (clobber (reg:CC CC_REGNUM))]
505 if (get_attr_length (insn) == 8)
507 operands[1] = GEN_INT (HOST_WIDE_INT_1U << UINTVAL (operands[1]));
508 return "tst\t%<w>0, %1\;<bcond>\t%l2";
511 return "<tbz>\t%<w>0, %1, %l2";
513 [(set_attr "type" "branch")
515 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
516 (lt (minus (match_dup 2) (pc)) (const_int 32764)))
521 (define_insn "*cb<optab><mode>1"
522 [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
524 (label_ref (match_operand 1 "" ""))
526 (clobber (reg:CC CC_REGNUM))]
529 if (get_attr_length (insn) == 8)
532 uint64_t val = ((uint64_t ) 1)
533 << (GET_MODE_SIZE (<MODE>mode) * BITS_PER_UNIT - 1);
534 sprintf (buf, "tst\t%%<w>0, %"PRId64, val);
535 output_asm_insn (buf, operands);
536 return "<bcond>\t%l1";
539 return "<tbz>\t%<w>0, <sizem1>, %l1";
541 [(set_attr "type" "branch")
543 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
544 (lt (minus (match_dup 1) (pc)) (const_int 32764)))
549 ;; -------------------------------------------------------------------
550 ;; Subroutine calls and sibcalls
551 ;; -------------------------------------------------------------------
553 (define_expand "call_internal"
554 [(parallel [(call (match_operand 0 "memory_operand" "")
555 (match_operand 1 "general_operand" ""))
556 (use (match_operand 2 "" ""))
557 (clobber (reg:DI LR_REGNUM))])])
559 (define_expand "call"
560 [(parallel [(call (match_operand 0 "memory_operand" "")
561 (match_operand 1 "general_operand" ""))
562 (use (match_operand 2 "" ""))
563 (clobber (reg:DI LR_REGNUM))])]
569 /* In an untyped call, we can get NULL for operand 2. */
570 if (operands[2] == NULL)
571 operands[2] = const0_rtx;
573 /* Decide if we should generate indirect calls by loading the
574 64-bit address of the callee into a register before performing
575 the branch-and-link. */
576 callee = XEXP (operands[0], 0);
577 if (GET_CODE (callee) == SYMBOL_REF
578 ? aarch64_is_long_call_p (callee)
580 XEXP (operands[0], 0) = force_reg (Pmode, callee);
582 pat = gen_call_internal (operands[0], operands[1], operands[2]);
583 aarch64_emit_call_insn (pat);
588 (define_insn "*call_reg"
589 [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
590 (match_operand 1 "" ""))
591 (use (match_operand 2 "" ""))
592 (clobber (reg:DI LR_REGNUM))]
595 [(set_attr "type" "call")]
598 (define_insn "*call_symbol"
599 [(call (mem:DI (match_operand:DI 0 "" ""))
600 (match_operand 1 "" ""))
601 (use (match_operand 2 "" ""))
602 (clobber (reg:DI LR_REGNUM))]
603 "GET_CODE (operands[0]) == SYMBOL_REF
604 && !aarch64_is_long_call_p (operands[0])"
606 [(set_attr "type" "call")]
609 (define_expand "call_value_internal"
610 [(parallel [(set (match_operand 0 "" "")
611 (call (match_operand 1 "memory_operand" "")
612 (match_operand 2 "general_operand" "")))
613 (use (match_operand 3 "" ""))
614 (clobber (reg:DI LR_REGNUM))])])
616 (define_expand "call_value"
617 [(parallel [(set (match_operand 0 "" "")
618 (call (match_operand 1 "memory_operand" "")
619 (match_operand 2 "general_operand" "")))
620 (use (match_operand 3 "" ""))
621 (clobber (reg:DI LR_REGNUM))])]
627 /* In an untyped call, we can get NULL for operand 3. */
628 if (operands[3] == NULL)
629 operands[3] = const0_rtx;
631 /* Decide if we should generate indirect calls by loading the
632 64-bit address of the callee into a register before performing
633 the branch-and-link. */
634 callee = XEXP (operands[1], 0);
635 if (GET_CODE (callee) == SYMBOL_REF
636 ? aarch64_is_long_call_p (callee)
638 XEXP (operands[1], 0) = force_reg (Pmode, callee);
640 pat = gen_call_value_internal (operands[0], operands[1], operands[2],
642 aarch64_emit_call_insn (pat);
647 (define_insn "*call_value_reg"
648 [(set (match_operand 0 "" "")
649 (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
650 (match_operand 2 "" "")))
651 (use (match_operand 3 "" ""))
652 (clobber (reg:DI LR_REGNUM))]
655 [(set_attr "type" "call")]
659 (define_insn "*call_value_symbol"
660 [(set (match_operand 0 "" "")
661 (call (mem:DI (match_operand:DI 1 "" ""))
662 (match_operand 2 "" "")))
663 (use (match_operand 3 "" ""))
664 (clobber (reg:DI LR_REGNUM))]
665 "GET_CODE (operands[1]) == SYMBOL_REF
666 && !aarch64_is_long_call_p (operands[1])"
668 [(set_attr "type" "call")]
671 (define_expand "sibcall_internal"
672 [(parallel [(call (match_operand 0 "memory_operand" "")
673 (match_operand 1 "general_operand" ""))
675 (use (match_operand 2 "" ""))])])
677 (define_expand "sibcall"
678 [(parallel [(call (match_operand 0 "memory_operand" "")
679 (match_operand 1 "general_operand" ""))
681 (use (match_operand 2 "" ""))])]
686 if (!REG_P (XEXP (operands[0], 0))
687 && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
688 XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
690 if (operands[2] == NULL_RTX)
691 operands[2] = const0_rtx;
693 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
694 aarch64_emit_call_insn (pat);
699 (define_expand "sibcall_value_internal"
700 [(parallel [(set (match_operand 0 "" "")
701 (call (match_operand 1 "memory_operand" "")
702 (match_operand 2 "general_operand" "")))
704 (use (match_operand 3 "" ""))])])
706 (define_expand "sibcall_value"
707 [(parallel [(set (match_operand 0 "" "")
708 (call (match_operand 1 "memory_operand" "")
709 (match_operand 2 "general_operand" "")))
711 (use (match_operand 3 "" ""))])]
716 if (!REG_P (XEXP (operands[1], 0))
717 && (GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF))
718 XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
720 if (operands[3] == NULL_RTX)
721 operands[3] = const0_rtx;
723 pat = gen_sibcall_value_internal (operands[0], operands[1], operands[2],
725 aarch64_emit_call_insn (pat);
730 (define_insn "*sibcall_insn"
731 [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucs, Usf"))
732 (match_operand 1 "" ""))
734 (use (match_operand 2 "" ""))]
735 "SIBLING_CALL_P (insn)"
739 [(set_attr "type" "branch, branch")]
742 (define_insn "*sibcall_value_insn"
743 [(set (match_operand 0 "" "")
745 (match_operand:DI 1 "aarch64_call_insn_operand" "Ucs, Usf"))
746 (match_operand 2 "" "")))
748 (use (match_operand 3 "" ""))]
749 "SIBLING_CALL_P (insn)"
753 [(set_attr "type" "branch, branch")]
756 ;; Call subroutine returning any type.
758 (define_expand "untyped_call"
759 [(parallel [(call (match_operand 0 "")
762 (match_operand 2 "")])]
767 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
769 for (i = 0; i < XVECLEN (operands[2], 0); i++)
771 rtx set = XVECEXP (operands[2], 0, i);
772 emit_move_insn (SET_DEST (set), SET_SRC (set));
775 /* The optimizer does not know that the call sets the function value
776 registers we stored in the result block. We avoid problems by
777 claiming that all hard registers are used and clobbered at this
779 emit_insn (gen_blockage ());
783 ;; -------------------------------------------------------------------
785 ;; -------------------------------------------------------------------
787 (define_expand "mov<mode>"
788 [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
789 (match_operand:SHORT 1 "general_operand" ""))]
792 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
793 operands[1] = force_reg (<MODE>mode, operands[1]);
797 (define_insn "*mov<mode>_aarch64"
798 [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r, *w,r,*w, m, m, r,*w,*w")
799 (match_operand:SHORT 1 "general_operand" " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
800 "(register_operand (operands[0], <MODE>mode)
801 || aarch64_reg_or_zero (operands[1], <MODE>mode))"
803 switch (which_alternative)
806 return "mov\t%w0, %w1";
808 return "mov\t%w0, %1";
810 return aarch64_output_scalar_simd_mov_immediate (operands[1],
813 return "ldr<size>\t%w0, %1";
815 return "ldr\t%<size>0, %1";
817 return "str<size>\t%w1, %0";
819 return "str\t%<size>1, %0";
821 return "umov\t%w0, %1.<v>[0]";
823 return "dup\t%0.<Vallxd>, %w1";
825 return "dup\t%<Vetype>0, %1.<v>[0]";
830 [(set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
831 neon_to_gp<q>,neon_from_gp<q>,neon_dup")
832 (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")]
835 (define_expand "mov<mode>"
836 [(set (match_operand:GPI 0 "nonimmediate_operand" "")
837 (match_operand:GPI 1 "general_operand" ""))]
840 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
841 operands[1] = force_reg (<MODE>mode, operands[1]);
843 /* FIXME: RR we still need to fix up what we are doing with
844 symbol_refs and other types of constants. */
845 if (CONSTANT_P (operands[1])
846 && !CONST_INT_P (operands[1]))
848 aarch64_expand_mov_immediate (operands[0], operands[1]);
854 (define_insn_and_split "*movsi_aarch64"
855 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,r,*w,m, m,r,r ,*w, r,*w")
856 (match_operand:SI 1 "aarch64_mov_operand" " r,r,k,M,n,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
857 "(register_operand (operands[0], SImode)
858 || aarch64_reg_or_zero (operands[1], SImode))"
874 "CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), SImode)
875 && GP_REGNUM_P (REGNO (operands[0]))"
878 aarch64_expand_mov_immediate (operands[0], operands[1]);
881 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
882 adr,adr,f_mcr,f_mrc,fmov")
883 (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
886 (define_insn_and_split "*movdi_aarch64"
887 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,r,*w,m, m,r,r, *w, r,*w,w")
888 (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,n,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))]
889 "(register_operand (operands[0], DImode)
890 || aarch64_reg_or_zero (operands[1], DImode))"
907 "(CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), DImode))
908 && GP_REGNUM_P (REGNO (operands[0]))"
911 aarch64_expand_mov_immediate (operands[0], operands[1]);
914 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
915 adr,adr,f_mcr,f_mrc,fmov,fmov")
916 (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
917 (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
920 (define_insn "insv_imm<mode>"
921 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
923 (match_operand:GPI 1 "const_int_operand" "n"))
924 (match_operand:GPI 2 "const_int_operand" "n"))]
925 "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
926 && UINTVAL (operands[1]) % 16 == 0"
927 "movk\\t%<w>0, %X2, lsl %1"
928 [(set_attr "type" "mov_imm")]
931 (define_expand "movti"
932 [(set (match_operand:TI 0 "nonimmediate_operand" "")
933 (match_operand:TI 1 "general_operand" ""))]
936 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
937 operands[1] = force_reg (TImode, operands[1]);
941 (define_insn "*movti_aarch64"
942 [(set (match_operand:TI 0
943 "nonimmediate_operand" "=r, *w,r ,*w,r ,Ump,Ump,*w,m")
945 "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r ,Z , m,*w"))]
946 "(register_operand (operands[0], TImode)
947 || aarch64_reg_or_zero (operands[1], TImode))"
952 orr\\t%0.16b, %1.16b, %1.16b
958 [(set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \
959 load2,store2,store2,f_loadd,f_stored")
960 (set_attr "length" "8,8,8,4,4,4,4,4,4")
961 (set_attr "simd" "*,*,*,yes,*,*,*,*,*")
962 (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
965 ;; Split a TImode register-register or register-immediate move into
966 ;; its component DImode pieces, taking care to handle overlapping
967 ;; source and dest registers.
969 [(set (match_operand:TI 0 "register_operand" "")
970 (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
971 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
974 aarch64_split_128bit_move (operands[0], operands[1]);
978 (define_expand "mov<mode>"
979 [(set (match_operand:GPF 0 "nonimmediate_operand" "")
980 (match_operand:GPF 1 "general_operand" ""))]
985 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
989 if (GET_CODE (operands[0]) == MEM)
990 operands[1] = force_reg (<MODE>mode, operands[1]);
994 (define_insn "*movsf_aarch64"
995 [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
996 (match_operand:SF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
997 "TARGET_FLOAT && (register_operand (operands[0], SFmode)
998 || register_operand (operands[1], SFmode))"
1009 [(set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
1010 f_loads,f_stores,f_loads,f_stores,mov_reg")]
1013 (define_insn "*movdf_aarch64"
1014 [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
1015 (match_operand:DF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
1016 "TARGET_FLOAT && (register_operand (operands[0], DFmode)
1017 || register_operand (operands[1], DFmode))"
1028 [(set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
1029 f_loadd,f_stored,f_loadd,f_stored,mov_reg")]
1032 (define_expand "movtf"
1033 [(set (match_operand:TF 0 "nonimmediate_operand" "")
1034 (match_operand:TF 1 "general_operand" ""))]
1039 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
1043 if (GET_CODE (operands[0]) == MEM)
1044 operands[1] = force_reg (TFmode, operands[1]);
1048 (define_insn "*movtf_aarch64"
1049 [(set (match_operand:TF 0
1050 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
1052 "general_operand" " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
1053 "TARGET_FLOAT && (register_operand (operands[0], TFmode)
1054 || register_operand (operands[1], TFmode))"
1056 orr\\t%0.16b, %1.16b, %1.16b
1066 [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,fconstd,fconstd,\
1067 f_loadd,f_stored,neon_load1_2reg,neon_store1_2reg")
1068 (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
1069 (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
1070 (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
1074 [(set (match_operand:TF 0 "register_operand" "")
1075 (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
1076 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
1079 aarch64_split_128bit_move (operands[0], operands[1]);
1086 ;; 2 is size of move in bytes
1089 (define_expand "movmemdi"
1090 [(match_operand:BLK 0 "memory_operand")
1091 (match_operand:BLK 1 "memory_operand")
1092 (match_operand:DI 2 "immediate_operand")
1093 (match_operand:DI 3 "immediate_operand")]
1096 if (aarch64_expand_movmem (operands))
1102 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1103 ;; fairly lax checking on the second memory operation.
1104 (define_insn "load_pairsi"
1105 [(set (match_operand:SI 0 "register_operand" "=r,*w")
1106 (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1107 (set (match_operand:SI 2 "register_operand" "=r,*w")
1108 (match_operand:SI 3 "memory_operand" "m,m"))]
1109 "rtx_equal_p (XEXP (operands[3], 0),
1110 plus_constant (Pmode,
1111 XEXP (operands[1], 0),
1112 GET_MODE_SIZE (SImode)))"
1116 [(set_attr "type" "load2,neon_load1_2reg")
1117 (set_attr "fp" "*,yes")]
1120 (define_insn "load_pairdi"
1121 [(set (match_operand:DI 0 "register_operand" "=r,*w")
1122 (match_operand:DI 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1123 (set (match_operand:DI 2 "register_operand" "=r,*w")
1124 (match_operand:DI 3 "memory_operand" "m,m"))]
1125 "rtx_equal_p (XEXP (operands[3], 0),
1126 plus_constant (Pmode,
1127 XEXP (operands[1], 0),
1128 GET_MODE_SIZE (DImode)))"
1132 [(set_attr "type" "load2,neon_load1_2reg")
1133 (set_attr "fp" "*,yes")]
1137 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1138 ;; fairly lax checking on the second memory operation.
1139 (define_insn "store_pairsi"
1140 [(set (match_operand:SI 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1141 (match_operand:SI 1 "aarch64_reg_or_zero" "rZ,*w"))
1142 (set (match_operand:SI 2 "memory_operand" "=m,m")
1143 (match_operand:SI 3 "aarch64_reg_or_zero" "rZ,*w"))]
1144 "rtx_equal_p (XEXP (operands[2], 0),
1145 plus_constant (Pmode,
1146 XEXP (operands[0], 0),
1147 GET_MODE_SIZE (SImode)))"
1151 [(set_attr "type" "store2,neon_store1_2reg")
1152 (set_attr "fp" "*,yes")]
1155 (define_insn "store_pairdi"
1156 [(set (match_operand:DI 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1157 (match_operand:DI 1 "aarch64_reg_or_zero" "rZ,*w"))
1158 (set (match_operand:DI 2 "memory_operand" "=m,m")
1159 (match_operand:DI 3 "aarch64_reg_or_zero" "rZ,*w"))]
1160 "rtx_equal_p (XEXP (operands[2], 0),
1161 plus_constant (Pmode,
1162 XEXP (operands[0], 0),
1163 GET_MODE_SIZE (DImode)))"
1167 [(set_attr "type" "store2,neon_store1_2reg")
1168 (set_attr "fp" "*,yes")]
1171 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1172 ;; fairly lax checking on the second memory operation.
1173 (define_insn "load_pairsf"
1174 [(set (match_operand:SF 0 "register_operand" "=w,*r")
1175 (match_operand:SF 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1176 (set (match_operand:SF 2 "register_operand" "=w,*r")
1177 (match_operand:SF 3 "memory_operand" "m,m"))]
1178 "rtx_equal_p (XEXP (operands[3], 0),
1179 plus_constant (Pmode,
1180 XEXP (operands[1], 0),
1181 GET_MODE_SIZE (SFmode)))"
1185 [(set_attr "type" "neon_load1_2reg,load2")
1186 (set_attr "fp" "yes,*")]
1189 (define_insn "load_pairdf"
1190 [(set (match_operand:DF 0 "register_operand" "=w,*r")
1191 (match_operand:DF 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1192 (set (match_operand:DF 2 "register_operand" "=w,*r")
1193 (match_operand:DF 3 "memory_operand" "m,m"))]
1194 "rtx_equal_p (XEXP (operands[3], 0),
1195 plus_constant (Pmode,
1196 XEXP (operands[1], 0),
1197 GET_MODE_SIZE (DFmode)))"
1201 [(set_attr "type" "neon_load1_2reg,load2")
1202 (set_attr "fp" "yes,*")]
1205 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1206 ;; fairly lax checking on the second memory operation.
1207 (define_insn "store_pairsf"
1208 [(set (match_operand:SF 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1209 (match_operand:SF 1 "register_operand" "w,*r"))
1210 (set (match_operand:SF 2 "memory_operand" "=m,m")
1211 (match_operand:SF 3 "register_operand" "w,*r"))]
1212 "rtx_equal_p (XEXP (operands[2], 0),
1213 plus_constant (Pmode,
1214 XEXP (operands[0], 0),
1215 GET_MODE_SIZE (SFmode)))"
1219 [(set_attr "type" "neon_store1_2reg,store2")
1220 (set_attr "fp" "yes,*")]
1223 (define_insn "store_pairdf"
1224 [(set (match_operand:DF 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1225 (match_operand:DF 1 "register_operand" "w,*r"))
1226 (set (match_operand:DF 2 "memory_operand" "=m,m")
1227 (match_operand:DF 3 "register_operand" "w,*r"))]
1228 "rtx_equal_p (XEXP (operands[2], 0),
1229 plus_constant (Pmode,
1230 XEXP (operands[0], 0),
1231 GET_MODE_SIZE (DFmode)))"
1235 [(set_attr "type" "neon_store1_2reg,store2")
1236 (set_attr "fp" "yes,*")]
1239 ;; Load pair with post-index writeback. This is primarily used in function
1241 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
1243 [(set (match_operand:P 0 "register_operand" "=k")
1244 (plus:P (match_operand:P 1 "register_operand" "0")
1245 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1246 (set (match_operand:GPI 2 "register_operand" "=r")
1247 (mem:GPI (match_dup 1)))
1248 (set (match_operand:GPI 3 "register_operand" "=r")
1249 (mem:GPI (plus:P (match_dup 1)
1250 (match_operand:P 5 "const_int_operand" "n"))))])]
1251 "INTVAL (operands[5]) == GET_MODE_SIZE (<GPI:MODE>mode)"
1252 "ldp\\t%<w>2, %<w>3, [%1], %4"
1253 [(set_attr "type" "load2")]
1256 (define_insn "loadwb_pair<GPF:mode>_<P:mode>"
1258 [(set (match_operand:P 0 "register_operand" "=k")
1259 (plus:P (match_operand:P 1 "register_operand" "0")
1260 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1261 (set (match_operand:GPF 2 "register_operand" "=w")
1262 (mem:GPF (match_dup 1)))
1263 (set (match_operand:GPF 3 "register_operand" "=w")
1264 (mem:GPF (plus:P (match_dup 1)
1265 (match_operand:P 5 "const_int_operand" "n"))))])]
1266 "INTVAL (operands[5]) == GET_MODE_SIZE (<GPF:MODE>mode)"
1267 "ldp\\t%<w>2, %<w>3, [%1], %4"
1268 [(set_attr "type" "neon_load1_2reg")]
1271 ;; Store pair with pre-index writeback. This is primarily used in function
1273 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
1275 [(set (match_operand:P 0 "register_operand" "=&k")
1276 (plus:P (match_operand:P 1 "register_operand" "0")
1277 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1278 (set (mem:GPI (plus:P (match_dup 0)
1280 (match_operand:GPI 2 "register_operand" "r"))
1281 (set (mem:GPI (plus:P (match_dup 0)
1282 (match_operand:P 5 "const_int_operand" "n")))
1283 (match_operand:GPI 3 "register_operand" "r"))])]
1284 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1285 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1286 [(set_attr "type" "store2")]
1289 (define_insn "storewb_pair<GPF:mode>_<P:mode>"
1291 [(set (match_operand:P 0 "register_operand" "=&k")
1292 (plus:P (match_operand:P 1 "register_operand" "0")
1293 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1294 (set (mem:GPF (plus:P (match_dup 0)
1296 (match_operand:GPF 2 "register_operand" "w"))
1297 (set (mem:GPF (plus:P (match_dup 0)
1298 (match_operand:P 5 "const_int_operand" "n")))
1299 (match_operand:GPF 3 "register_operand" "w"))])]
1300 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPF:MODE>mode)"
1301 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1302 [(set_attr "type" "neon_store1_2reg<q>")]
1305 ;; -------------------------------------------------------------------
1306 ;; Sign/Zero extension
1307 ;; -------------------------------------------------------------------
1309 (define_expand "<optab>sidi2"
1310 [(set (match_operand:DI 0 "register_operand")
1311 (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1315 (define_insn "*extendsidi2_aarch64"
1316 [(set (match_operand:DI 0 "register_operand" "=r,r")
1317 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1322 [(set_attr "type" "extend,load1")]
1325 (define_insn "*load_pair_extendsidi2_aarch64"
1326 [(set (match_operand:DI 0 "register_operand" "=r")
1327 (sign_extend:DI (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump")))
1328 (set (match_operand:DI 2 "register_operand" "=r")
1329 (sign_extend:DI (match_operand:SI 3 "memory_operand" "m")))]
1330 "rtx_equal_p (XEXP (operands[3], 0),
1331 plus_constant (Pmode,
1332 XEXP (operands[1], 0),
1333 GET_MODE_SIZE (SImode)))"
1334 "ldpsw\\t%0, %2, %1"
1335 [(set_attr "type" "load2")]
1338 (define_insn "*zero_extendsidi2_aarch64"
1339 [(set (match_operand:DI 0 "register_operand" "=r,r")
1340 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1345 [(set_attr "type" "extend,load1")]
1348 (define_insn "*load_pair_zero_extendsidi2_aarch64"
1349 [(set (match_operand:DI 0 "register_operand" "=r")
1350 (zero_extend:DI (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump")))
1351 (set (match_operand:DI 2 "register_operand" "=r")
1352 (zero_extend:DI (match_operand:SI 3 "memory_operand" "m")))]
1353 "rtx_equal_p (XEXP (operands[3], 0),
1354 plus_constant (Pmode,
1355 XEXP (operands[1], 0),
1356 GET_MODE_SIZE (SImode)))"
1357 "ldp\\t%w0, %w2, %1"
1358 [(set_attr "type" "load2")]
1361 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1362 [(set (match_operand:GPI 0 "register_operand")
1363 (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1367 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1368 [(set (match_operand:GPI 0 "register_operand" "=r,r")
1369 (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1372 sxt<SHORT:size>\t%<GPI:w>0, %w1
1373 ldrs<SHORT:size>\t%<GPI:w>0, %1"
1374 [(set_attr "type" "extend,load1")]
1377 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1378 [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1379 (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1382 uxt<SHORT:size>\t%<GPI:w>0, %w1
1383 ldr<SHORT:size>\t%w0, %1
1384 ldr\t%<SHORT:size>0, %1"
1385 [(set_attr "type" "extend,load1,load1")]
1388 (define_expand "<optab>qihi2"
1389 [(set (match_operand:HI 0 "register_operand")
1390 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1394 (define_insn "*<optab>qihi2_aarch64"
1395 [(set (match_operand:HI 0 "register_operand" "=r,r")
1396 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1401 [(set_attr "type" "extend,load1")]
1404 ;; -------------------------------------------------------------------
1405 ;; Simple arithmetic
1406 ;; -------------------------------------------------------------------
1408 (define_expand "add<mode>3"
1410 (match_operand:GPI 0 "register_operand" "")
1411 (plus:GPI (match_operand:GPI 1 "register_operand" "")
1412 (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1415 if (! aarch64_plus_operand (operands[2], VOIDmode))
1417 HOST_WIDE_INT imm = INTVAL (operands[2]);
1419 if (aarch64_move_imm (imm, <MODE>mode) && can_create_pseudo_p ())
1421 rtx tmp = gen_reg_rtx (<MODE>mode);
1422 emit_move_insn (tmp, operands[2]);
1427 rtx subtarget = ((optimize && can_create_pseudo_p ())
1428 ? gen_reg_rtx (<MODE>mode) : operands[0]);
1431 imm = -(-imm & ~0xfff);
1435 emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1436 operands[1] = subtarget;
1437 operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1443 (define_insn "*addsi3_aarch64"
1445 (match_operand:SI 0 "register_operand" "=rk,rk,w,rk")
1447 (match_operand:SI 1 "register_operand" "%rk,rk,w,rk")
1448 (match_operand:SI 2 "aarch64_plus_operand" "I,r,w,J")))]
1453 add\\t%0.2s, %1.2s, %2.2s
1454 sub\\t%w0, %w1, #%n2"
1455 [(set_attr "type" "alu_imm,alu_sreg,neon_add,alu_imm")
1456 (set_attr "simd" "*,*,yes,*")]
1459 ;; zero_extend version of above
1460 (define_insn "*addsi3_aarch64_uxtw"
1462 (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1464 (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1465 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1470 sub\\t%w0, %w1, #%n2"
1471 [(set_attr "type" "alu_imm,alu_sreg,alu_imm")]
1474 (define_insn "*adddi3_aarch64"
1476 (match_operand:DI 0 "register_operand" "=rk,rk,rk,w")
1478 (match_operand:DI 1 "register_operand" "%rk,rk,rk,w")
1479 (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,w")))]
1484 sub\\t%x0, %x1, #%n2
1485 add\\t%d0, %d1, %d2"
1486 [(set_attr "type" "alu_imm,alu_sreg,alu_imm,neon_add")
1487 (set_attr "simd" "*,*,*,yes")]
1490 (define_expand "addti3"
1491 [(set (match_operand:TI 0 "register_operand" "")
1492 (plus:TI (match_operand:TI 1 "register_operand" "")
1493 (match_operand:TI 2 "register_operand" "")))]
1496 rtx low = gen_reg_rtx (DImode);
1497 emit_insn (gen_adddi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1498 gen_lowpart (DImode, operands[2])));
1500 rtx high = gen_reg_rtx (DImode);
1501 emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]),
1502 gen_highpart (DImode, operands[2])));
1504 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1505 emit_move_insn (gen_highpart (DImode, operands[0]), high);
1509 (define_insn "add<mode>3_compare0"
1510 [(set (reg:CC_NZ CC_REGNUM)
1512 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1513 (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1515 (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1516 (plus:GPI (match_dup 1) (match_dup 2)))]
1519 adds\\t%<w>0, %<w>1, %<w>2
1520 adds\\t%<w>0, %<w>1, %<w>2
1521 subs\\t%<w>0, %<w>1, #%n2"
1522 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1525 ;; zero_extend version of above
1526 (define_insn "*addsi3_compare0_uxtw"
1527 [(set (reg:CC_NZ CC_REGNUM)
1529 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1530 (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1532 (set (match_operand:DI 0 "register_operand" "=r,r,r")
1533 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1536 adds\\t%w0, %w1, %w2
1537 adds\\t%w0, %w1, %w2
1538 subs\\t%w0, %w1, #%n2"
1539 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1542 (define_insn "*adds_mul_imm_<mode>"
1543 [(set (reg:CC_NZ CC_REGNUM)
1546 (match_operand:GPI 1 "register_operand" "r")
1547 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1548 (match_operand:GPI 3 "register_operand" "r"))
1550 (set (match_operand:GPI 0 "register_operand" "=r")
1551 (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1554 "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1555 [(set_attr "type" "alus_shift_imm")]
1558 (define_insn "*subs_mul_imm_<mode>"
1559 [(set (reg:CC_NZ CC_REGNUM)
1561 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1563 (match_operand:GPI 2 "register_operand" "r")
1564 (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1566 (set (match_operand:GPI 0 "register_operand" "=r")
1567 (minus:GPI (match_dup 1)
1568 (mult:GPI (match_dup 2) (match_dup 3))))]
1570 "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1571 [(set_attr "type" "alus_shift_imm")]
1574 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1575 [(set (reg:CC_NZ CC_REGNUM)
1578 (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1579 (match_operand:GPI 2 "register_operand" "r"))
1581 (set (match_operand:GPI 0 "register_operand" "=r")
1582 (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1584 "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1585 [(set_attr "type" "alus_ext")]
1588 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1589 [(set (reg:CC_NZ CC_REGNUM)
1591 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1593 (match_operand:ALLX 2 "register_operand" "r")))
1595 (set (match_operand:GPI 0 "register_operand" "=r")
1596 (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1598 "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1599 [(set_attr "type" "alus_ext")]
1602 (define_insn "*adds_<optab><mode>_multp2"
1603 [(set (reg:CC_NZ CC_REGNUM)
1605 (plus:GPI (ANY_EXTRACT:GPI
1606 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1607 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1608 (match_operand 3 "const_int_operand" "n")
1610 (match_operand:GPI 4 "register_operand" "r"))
1612 (set (match_operand:GPI 0 "register_operand" "=r")
1613 (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1617 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1618 "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1619 [(set_attr "type" "alus_ext")]
1622 (define_insn "*subs_<optab><mode>_multp2"
1623 [(set (reg:CC_NZ CC_REGNUM)
1625 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1627 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1628 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1629 (match_operand 3 "const_int_operand" "n")
1632 (set (match_operand:GPI 0 "register_operand" "=r")
1633 (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1634 (mult:GPI (match_dup 1) (match_dup 2))
1637 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1638 "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1639 [(set_attr "type" "alus_ext")]
1642 (define_insn "*add<mode>3nr_compare0"
1643 [(set (reg:CC_NZ CC_REGNUM)
1645 (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1646 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1653 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1656 (define_insn "*compare_neg<mode>"
1657 [(set (reg:CC_Z CC_REGNUM)
1659 (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1660 (match_operand:GPI 1 "register_operand" "r")))]
1662 "cmn\\t%<w>1, %<w>0"
1663 [(set_attr "type" "alus_sreg")]
1666 (define_insn "*add_<shift>_<mode>"
1667 [(set (match_operand:GPI 0 "register_operand" "=r")
1668 (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1669 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1670 (match_operand:GPI 3 "register_operand" "r")))]
1672 "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1673 [(set_attr "type" "alu_shift_imm")]
1676 ;; zero_extend version of above
1677 (define_insn "*add_<shift>_si_uxtw"
1678 [(set (match_operand:DI 0 "register_operand" "=r")
1680 (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1681 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1682 (match_operand:SI 3 "register_operand" "r"))))]
1684 "add\\t%w0, %w3, %w1, <shift> %2"
1685 [(set_attr "type" "alu_shift_imm")]
1688 (define_insn "*add_mul_imm_<mode>"
1689 [(set (match_operand:GPI 0 "register_operand" "=r")
1690 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1691 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1692 (match_operand:GPI 3 "register_operand" "r")))]
1694 "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1695 [(set_attr "type" "alu_shift_imm")]
1698 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1699 [(set (match_operand:GPI 0 "register_operand" "=rk")
1700 (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1701 (match_operand:GPI 2 "register_operand" "r")))]
1703 "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1704 [(set_attr "type" "alu_ext")]
1707 ;; zero_extend version of above
1708 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1709 [(set (match_operand:DI 0 "register_operand" "=rk")
1711 (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1712 (match_operand:GPI 2 "register_operand" "r"))))]
1714 "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1715 [(set_attr "type" "alu_ext")]
1718 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1719 [(set (match_operand:GPI 0 "register_operand" "=rk")
1720 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1721 (match_operand:ALLX 1 "register_operand" "r"))
1722 (match_operand 2 "aarch64_imm3" "Ui3"))
1723 (match_operand:GPI 3 "register_operand" "r")))]
1725 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1726 [(set_attr "type" "alu_ext")]
1729 ;; zero_extend version of above
1730 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1731 [(set (match_operand:DI 0 "register_operand" "=rk")
1733 (plus:SI (ashift:SI (ANY_EXTEND:SI
1734 (match_operand:SHORT 1 "register_operand" "r"))
1735 (match_operand 2 "aarch64_imm3" "Ui3"))
1736 (match_operand:SI 3 "register_operand" "r"))))]
1738 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1739 [(set_attr "type" "alu_ext")]
1742 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1743 [(set (match_operand:GPI 0 "register_operand" "=rk")
1744 (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1745 (match_operand:ALLX 1 "register_operand" "r"))
1746 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1747 (match_operand:GPI 3 "register_operand" "r")))]
1749 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1750 [(set_attr "type" "alu_ext")]
1753 ;; zero_extend version of above
1754 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1755 [(set (match_operand:DI 0 "register_operand" "=rk")
1756 (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1757 (match_operand:SHORT 1 "register_operand" "r"))
1758 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1759 (match_operand:SI 3 "register_operand" "r"))))]
1761 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1762 [(set_attr "type" "alu_ext")]
1765 (define_insn "*add_<optab><mode>_multp2"
1766 [(set (match_operand:GPI 0 "register_operand" "=rk")
1767 (plus:GPI (ANY_EXTRACT:GPI
1768 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1769 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1770 (match_operand 3 "const_int_operand" "n")
1772 (match_operand:GPI 4 "register_operand" "r")))]
1773 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1774 "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1775 [(set_attr "type" "alu_ext")]
1778 ;; zero_extend version of above
1779 (define_insn "*add_<optab>si_multp2_uxtw"
1780 [(set (match_operand:DI 0 "register_operand" "=rk")
1782 (plus:SI (ANY_EXTRACT:SI
1783 (mult:SI (match_operand:SI 1 "register_operand" "r")
1784 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1785 (match_operand 3 "const_int_operand" "n")
1787 (match_operand:SI 4 "register_operand" "r"))))]
1788 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1789 "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1790 [(set_attr "type" "alu_ext")]
1793 (define_insn "add<mode>3_carryin"
1795 (match_operand:GPI 0 "register_operand" "=r")
1796 (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1798 (match_operand:GPI 1 "register_operand" "r")
1799 (match_operand:GPI 2 "register_operand" "r"))))]
1801 "adc\\t%<w>0, %<w>1, %<w>2"
1802 [(set_attr "type" "adc_reg")]
1805 ;; zero_extend version of above
1806 (define_insn "*addsi3_carryin_uxtw"
1808 (match_operand:DI 0 "register_operand" "=r")
1810 (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1812 (match_operand:SI 1 "register_operand" "r")
1813 (match_operand:SI 2 "register_operand" "r")))))]
1815 "adc\\t%w0, %w1, %w2"
1816 [(set_attr "type" "adc_reg")]
1819 (define_insn "*add<mode>3_carryin_alt1"
1821 (match_operand:GPI 0 "register_operand" "=r")
1823 (match_operand:GPI 1 "register_operand" "r")
1824 (match_operand:GPI 2 "register_operand" "r"))
1825 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1827 "adc\\t%<w>0, %<w>1, %<w>2"
1828 [(set_attr "type" "adc_reg")]
1831 ;; zero_extend version of above
1832 (define_insn "*addsi3_carryin_alt1_uxtw"
1834 (match_operand:DI 0 "register_operand" "=r")
1837 (match_operand:SI 1 "register_operand" "r")
1838 (match_operand:SI 2 "register_operand" "r"))
1839 (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1841 "adc\\t%w0, %w1, %w2"
1842 [(set_attr "type" "adc_reg")]
1845 (define_insn "*add<mode>3_carryin_alt2"
1847 (match_operand:GPI 0 "register_operand" "=r")
1849 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1850 (match_operand:GPI 1 "register_operand" "r"))
1851 (match_operand:GPI 2 "register_operand" "r")))]
1853 "adc\\t%<w>0, %<w>1, %<w>2"
1854 [(set_attr "type" "adc_reg")]
1857 ;; zero_extend version of above
1858 (define_insn "*addsi3_carryin_alt2_uxtw"
1860 (match_operand:DI 0 "register_operand" "=r")
1863 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1864 (match_operand:SI 1 "register_operand" "r"))
1865 (match_operand:SI 2 "register_operand" "r"))))]
1867 "adc\\t%w0, %w1, %w2"
1868 [(set_attr "type" "adc_reg")]
1871 (define_insn "*add<mode>3_carryin_alt3"
1873 (match_operand:GPI 0 "register_operand" "=r")
1875 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1876 (match_operand:GPI 2 "register_operand" "r"))
1877 (match_operand:GPI 1 "register_operand" "r")))]
1879 "adc\\t%<w>0, %<w>1, %<w>2"
1880 [(set_attr "type" "adc_reg")]
1883 ;; zero_extend version of above
1884 (define_insn "*addsi3_carryin_alt3_uxtw"
1886 (match_operand:DI 0 "register_operand" "=r")
1889 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1890 (match_operand:SI 2 "register_operand" "r"))
1891 (match_operand:SI 1 "register_operand" "r"))))]
1893 "adc\\t%w0, %w1, %w2"
1894 [(set_attr "type" "adc_reg")]
1897 (define_insn "*add_uxt<mode>_multp2"
1898 [(set (match_operand:GPI 0 "register_operand" "=rk")
1900 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1901 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1902 (match_operand 3 "const_int_operand" "n"))
1903 (match_operand:GPI 4 "register_operand" "r")))]
1904 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1906 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1907 INTVAL (operands[3])));
1908 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1909 [(set_attr "type" "alu_ext")]
1912 ;; zero_extend version of above
1913 (define_insn "*add_uxtsi_multp2_uxtw"
1914 [(set (match_operand:DI 0 "register_operand" "=rk")
1917 (mult:SI (match_operand:SI 1 "register_operand" "r")
1918 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1919 (match_operand 3 "const_int_operand" "n"))
1920 (match_operand:SI 4 "register_operand" "r"))))]
1921 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1923 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1924 INTVAL (operands[3])));
1925 return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1926 [(set_attr "type" "alu_ext")]
1929 (define_insn "subsi3"
1930 [(set (match_operand:SI 0 "register_operand" "=rk")
1931 (minus:SI (match_operand:SI 1 "register_operand" "rk")
1932 (match_operand:SI 2 "register_operand" "r")))]
1934 "sub\\t%w0, %w1, %w2"
1935 [(set_attr "type" "alu_sreg")]
1938 ;; zero_extend version of above
1939 (define_insn "*subsi3_uxtw"
1940 [(set (match_operand:DI 0 "register_operand" "=rk")
1942 (minus:SI (match_operand:SI 1 "register_operand" "rk")
1943 (match_operand:SI 2 "register_operand" "r"))))]
1945 "sub\\t%w0, %w1, %w2"
1946 [(set_attr "type" "alu_sreg")]
1949 (define_insn "subdi3"
1950 [(set (match_operand:DI 0 "register_operand" "=rk,w")
1951 (minus:DI (match_operand:DI 1 "register_operand" "rk,w")
1952 (match_operand:DI 2 "register_operand" "r,w")))]
1956 sub\\t%d0, %d1, %d2"
1957 [(set_attr "type" "alu_sreg, neon_sub")
1958 (set_attr "simd" "*,yes")]
1961 (define_expand "subti3"
1962 [(set (match_operand:TI 0 "register_operand" "")
1963 (minus:TI (match_operand:TI 1 "register_operand" "")
1964 (match_operand:TI 2 "register_operand" "")))]
1967 rtx low = gen_reg_rtx (DImode);
1968 emit_insn (gen_subdi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1969 gen_lowpart (DImode, operands[2])));
1971 rtx high = gen_reg_rtx (DImode);
1972 emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]),
1973 gen_highpart (DImode, operands[2])));
1975 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1976 emit_move_insn (gen_highpart (DImode, operands[0]), high);
1980 (define_insn "sub<mode>3_compare0"
1981 [(set (reg:CC_NZ CC_REGNUM)
1982 (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1983 (match_operand:GPI 2 "register_operand" "r"))
1985 (set (match_operand:GPI 0 "register_operand" "=r")
1986 (minus:GPI (match_dup 1) (match_dup 2)))]
1988 "subs\\t%<w>0, %<w>1, %<w>2"
1989 [(set_attr "type" "alus_sreg")]
1992 ;; zero_extend version of above
1993 (define_insn "*subsi3_compare0_uxtw"
1994 [(set (reg:CC_NZ CC_REGNUM)
1995 (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1996 (match_operand:SI 2 "register_operand" "r"))
1998 (set (match_operand:DI 0 "register_operand" "=r")
1999 (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
2001 "subs\\t%w0, %w1, %w2"
2002 [(set_attr "type" "alus_sreg")]
2005 (define_insn "*sub_<shift>_<mode>"
2006 [(set (match_operand:GPI 0 "register_operand" "=r")
2007 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2009 (match_operand:GPI 1 "register_operand" "r")
2010 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2012 "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
2013 [(set_attr "type" "alu_shift_imm")]
2016 ;; zero_extend version of above
2017 (define_insn "*sub_<shift>_si_uxtw"
2018 [(set (match_operand:DI 0 "register_operand" "=r")
2020 (minus:SI (match_operand:SI 3 "register_operand" "r")
2022 (match_operand:SI 1 "register_operand" "r")
2023 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2025 "sub\\t%w0, %w3, %w1, <shift> %2"
2026 [(set_attr "type" "alu_shift_imm")]
2029 (define_insn "*sub_mul_imm_<mode>"
2030 [(set (match_operand:GPI 0 "register_operand" "=r")
2031 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2033 (match_operand:GPI 1 "register_operand" "r")
2034 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2036 "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
2037 [(set_attr "type" "alu_shift_imm")]
2040 ;; zero_extend version of above
2041 (define_insn "*sub_mul_imm_si_uxtw"
2042 [(set (match_operand:DI 0 "register_operand" "=r")
2044 (minus:SI (match_operand:SI 3 "register_operand" "r")
2046 (match_operand:SI 1 "register_operand" "r")
2047 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2049 "sub\\t%w0, %w3, %w1, lsl %p2"
2050 [(set_attr "type" "alu_shift_imm")]
2053 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
2054 [(set (match_operand:GPI 0 "register_operand" "=rk")
2055 (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
2057 (match_operand:ALLX 2 "register_operand" "r"))))]
2059 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
2060 [(set_attr "type" "alu_ext")]
2063 ;; zero_extend version of above
2064 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
2065 [(set (match_operand:DI 0 "register_operand" "=rk")
2067 (minus:SI (match_operand:SI 1 "register_operand" "rk")
2069 (match_operand:SHORT 2 "register_operand" "r")))))]
2071 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
2072 [(set_attr "type" "alu_ext")]
2075 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
2076 [(set (match_operand:GPI 0 "register_operand" "=rk")
2077 (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
2078 (ashift:GPI (ANY_EXTEND:GPI
2079 (match_operand:ALLX 2 "register_operand" "r"))
2080 (match_operand 3 "aarch64_imm3" "Ui3"))))]
2082 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
2083 [(set_attr "type" "alu_ext")]
2086 ;; zero_extend version of above
2087 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
2088 [(set (match_operand:DI 0 "register_operand" "=rk")
2090 (minus:SI (match_operand:SI 1 "register_operand" "rk")
2091 (ashift:SI (ANY_EXTEND:SI
2092 (match_operand:SHORT 2 "register_operand" "r"))
2093 (match_operand 3 "aarch64_imm3" "Ui3")))))]
2095 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
2096 [(set_attr "type" "alu_ext")]
2099 (define_insn "*sub_<optab><mode>_multp2"
2100 [(set (match_operand:GPI 0 "register_operand" "=rk")
2101 (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
2103 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2104 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2105 (match_operand 3 "const_int_operand" "n")
2107 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
2108 "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
2109 [(set_attr "type" "alu_ext")]
2112 ;; zero_extend version of above
2113 (define_insn "*sub_<optab>si_multp2_uxtw"
2114 [(set (match_operand:DI 0 "register_operand" "=rk")
2116 (minus:SI (match_operand:SI 4 "register_operand" "rk")
2118 (mult:SI (match_operand:SI 1 "register_operand" "r")
2119 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2120 (match_operand 3 "const_int_operand" "n")
2122 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
2123 "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
2124 [(set_attr "type" "alu_ext")]
2127 (define_insn "sub<mode>3_carryin"
2129 (match_operand:GPI 0 "register_operand" "=r")
2130 (minus:GPI (minus:GPI
2131 (match_operand:GPI 1 "register_operand" "r")
2132 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2133 (match_operand:GPI 2 "register_operand" "r")))]
2135 "sbc\\t%<w>0, %<w>1, %<w>2"
2136 [(set_attr "type" "adc_reg")]
2139 ;; zero_extend version of the above
2140 (define_insn "*subsi3_carryin_uxtw"
2142 (match_operand:DI 0 "register_operand" "=r")
2145 (match_operand:SI 1 "register_operand" "r")
2146 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2147 (match_operand:SI 2 "register_operand" "r"))))]
2149 "sbc\\t%w0, %w1, %w2"
2150 [(set_attr "type" "adc_reg")]
2153 (define_insn "*sub_uxt<mode>_multp2"
2154 [(set (match_operand:GPI 0 "register_operand" "=rk")
2155 (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
2157 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2158 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2159 (match_operand 3 "const_int_operand" "n"))))]
2160 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2162 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2163 INTVAL (operands[3])));
2164 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
2165 [(set_attr "type" "alu_ext")]
2168 ;; zero_extend version of above
2169 (define_insn "*sub_uxtsi_multp2_uxtw"
2170 [(set (match_operand:DI 0 "register_operand" "=rk")
2172 (minus:SI (match_operand:SI 4 "register_operand" "rk")
2174 (mult:SI (match_operand:SI 1 "register_operand" "r")
2175 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2176 (match_operand 3 "const_int_operand" "n")))))]
2177 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2179 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2180 INTVAL (operands[3])));
2181 return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
2182 [(set_attr "type" "alu_ext")]
2185 (define_insn_and_split "absdi2"
2186 [(set (match_operand:DI 0 "register_operand" "=&r,w")
2187 (abs:DI (match_operand:DI 1 "register_operand" "r,w")))]
2193 && GP_REGNUM_P (REGNO (operands[0]))
2194 && GP_REGNUM_P (REGNO (operands[1]))"
2197 emit_insn (gen_rtx_SET (operands[0],
2198 gen_rtx_XOR (DImode,
2199 gen_rtx_ASHIFTRT (DImode,
2203 emit_insn (gen_rtx_SET (operands[0],
2204 gen_rtx_MINUS (DImode,
2206 gen_rtx_ASHIFTRT (DImode,
2211 [(set_attr "type" "alu_sreg")
2212 (set_attr "simd" "no,yes")]
2215 (define_insn "neg<mode>2"
2216 [(set (match_operand:GPI 0 "register_operand" "=r,w")
2217 (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
2221 neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
2222 [(set_attr "type" "alu_sreg, neon_neg<q>")
2223 (set_attr "simd" "*,yes")]
2226 ;; zero_extend version of above
2227 (define_insn "*negsi2_uxtw"
2228 [(set (match_operand:DI 0 "register_operand" "=r")
2229 (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
2232 [(set_attr "type" "alu_sreg")]
2235 (define_insn "*ngc<mode>"
2236 [(set (match_operand:GPI 0 "register_operand" "=r")
2237 (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2238 (match_operand:GPI 1 "register_operand" "r")))]
2240 "ngc\\t%<w>0, %<w>1"
2241 [(set_attr "type" "adc_reg")]
2244 (define_insn "*ngcsi_uxtw"
2245 [(set (match_operand:DI 0 "register_operand" "=r")
2247 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2248 (match_operand:SI 1 "register_operand" "r"))))]
2251 [(set_attr "type" "adc_reg")]
2254 (define_insn "*neg<mode>2_compare0"
2255 [(set (reg:CC_NZ CC_REGNUM)
2256 (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2258 (set (match_operand:GPI 0 "register_operand" "=r")
2259 (neg:GPI (match_dup 1)))]
2261 "negs\\t%<w>0, %<w>1"
2262 [(set_attr "type" "alus_sreg")]
2265 ;; zero_extend version of above
2266 (define_insn "*negsi2_compare0_uxtw"
2267 [(set (reg:CC_NZ CC_REGNUM)
2268 (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
2270 (set (match_operand:DI 0 "register_operand" "=r")
2271 (zero_extend:DI (neg:SI (match_dup 1))))]
2274 [(set_attr "type" "alus_sreg")]
2277 (define_insn "*neg_<shift><mode>3_compare0"
2278 [(set (reg:CC_NZ CC_REGNUM)
2280 (neg:GPI (ASHIFT:GPI
2281 (match_operand:GPI 1 "register_operand" "r")
2282 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2284 (set (match_operand:GPI 0 "register_operand" "=r")
2285 (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2287 "negs\\t%<w>0, %<w>1, <shift> %2"
2288 [(set_attr "type" "alus_shift_imm")]
2291 (define_insn "*neg_<shift>_<mode>2"
2292 [(set (match_operand:GPI 0 "register_operand" "=r")
2293 (neg:GPI (ASHIFT:GPI
2294 (match_operand:GPI 1 "register_operand" "r")
2295 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2297 "neg\\t%<w>0, %<w>1, <shift> %2"
2298 [(set_attr "type" "alu_shift_imm")]
2301 ;; zero_extend version of above
2302 (define_insn "*neg_<shift>_si2_uxtw"
2303 [(set (match_operand:DI 0 "register_operand" "=r")
2306 (match_operand:SI 1 "register_operand" "r")
2307 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2309 "neg\\t%w0, %w1, <shift> %2"
2310 [(set_attr "type" "alu_shift_imm")]
2313 (define_insn "*neg_mul_imm_<mode>2"
2314 [(set (match_operand:GPI 0 "register_operand" "=r")
2316 (match_operand:GPI 1 "register_operand" "r")
2317 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2319 "neg\\t%<w>0, %<w>1, lsl %p2"
2320 [(set_attr "type" "alu_shift_imm")]
2323 ;; zero_extend version of above
2324 (define_insn "*neg_mul_imm_si2_uxtw"
2325 [(set (match_operand:DI 0 "register_operand" "=r")
2328 (match_operand:SI 1 "register_operand" "r")
2329 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2331 "neg\\t%w0, %w1, lsl %p2"
2332 [(set_attr "type" "alu_shift_imm")]
2335 (define_insn "mul<mode>3"
2336 [(set (match_operand:GPI 0 "register_operand" "=r")
2337 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2338 (match_operand:GPI 2 "register_operand" "r")))]
2340 "mul\\t%<w>0, %<w>1, %<w>2"
2341 [(set_attr "type" "mul")]
2344 ;; zero_extend version of above
2345 (define_insn "*mulsi3_uxtw"
2346 [(set (match_operand:DI 0 "register_operand" "=r")
2348 (mult:SI (match_operand:SI 1 "register_operand" "r")
2349 (match_operand:SI 2 "register_operand" "r"))))]
2351 "mul\\t%w0, %w1, %w2"
2352 [(set_attr "type" "mul")]
2355 (define_insn "madd<mode>"
2356 [(set (match_operand:GPI 0 "register_operand" "=r")
2357 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2358 (match_operand:GPI 2 "register_operand" "r"))
2359 (match_operand:GPI 3 "register_operand" "r")))]
2361 "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2362 [(set_attr "type" "mla")]
2365 ;; zero_extend version of above
2366 (define_insn "*maddsi_uxtw"
2367 [(set (match_operand:DI 0 "register_operand" "=r")
2369 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2370 (match_operand:SI 2 "register_operand" "r"))
2371 (match_operand:SI 3 "register_operand" "r"))))]
2373 "madd\\t%w0, %w1, %w2, %w3"
2374 [(set_attr "type" "mla")]
2377 (define_insn "*msub<mode>"
2378 [(set (match_operand:GPI 0 "register_operand" "=r")
2379 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2380 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2381 (match_operand:GPI 2 "register_operand" "r"))))]
2384 "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2385 [(set_attr "type" "mla")]
2388 ;; zero_extend version of above
2389 (define_insn "*msubsi_uxtw"
2390 [(set (match_operand:DI 0 "register_operand" "=r")
2392 (minus:SI (match_operand:SI 3 "register_operand" "r")
2393 (mult:SI (match_operand:SI 1 "register_operand" "r")
2394 (match_operand:SI 2 "register_operand" "r")))))]
2397 "msub\\t%w0, %w1, %w2, %w3"
2398 [(set_attr "type" "mla")]
2401 (define_insn "*mul<mode>_neg"
2402 [(set (match_operand:GPI 0 "register_operand" "=r")
2403 (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2404 (match_operand:GPI 2 "register_operand" "r")))]
2407 "mneg\\t%<w>0, %<w>1, %<w>2"
2408 [(set_attr "type" "mul")]
2411 ;; zero_extend version of above
2412 (define_insn "*mulsi_neg_uxtw"
2413 [(set (match_operand:DI 0 "register_operand" "=r")
2415 (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2416 (match_operand:SI 2 "register_operand" "r"))))]
2419 "mneg\\t%w0, %w1, %w2"
2420 [(set_attr "type" "mul")]
2423 (define_insn "<su_optab>mulsidi3"
2424 [(set (match_operand:DI 0 "register_operand" "=r")
2425 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2426 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2428 "<su>mull\\t%0, %w1, %w2"
2429 [(set_attr "type" "<su>mull")]
2432 (define_insn "<su_optab>maddsidi4"
2433 [(set (match_operand:DI 0 "register_operand" "=r")
2435 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2436 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2437 (match_operand:DI 3 "register_operand" "r")))]
2439 "<su>maddl\\t%0, %w1, %w2, %3"
2440 [(set_attr "type" "<su>mlal")]
2443 (define_insn "<su_optab>msubsidi4"
2444 [(set (match_operand:DI 0 "register_operand" "=r")
2446 (match_operand:DI 3 "register_operand" "r")
2447 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2449 (match_operand:SI 2 "register_operand" "r")))))]
2451 "<su>msubl\\t%0, %w1, %w2, %3"
2452 [(set_attr "type" "<su>mlal")]
2455 (define_insn "*<su_optab>mulsidi_neg"
2456 [(set (match_operand:DI 0 "register_operand" "=r")
2458 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2459 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2461 "<su>mnegl\\t%0, %w1, %w2"
2462 [(set_attr "type" "<su>mull")]
2465 (define_expand "<su_optab>mulditi3"
2466 [(set (match_operand:TI 0 "register_operand")
2467 (mult:TI (ANY_EXTEND:TI (match_operand:DI 1 "register_operand"))
2468 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand"))))]
2471 rtx low = gen_reg_rtx (DImode);
2472 emit_insn (gen_muldi3 (low, operands[1], operands[2]));
2474 rtx high = gen_reg_rtx (DImode);
2475 emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2]));
2477 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2478 emit_move_insn (gen_highpart (DImode, operands[0]), high);
2482 ;; The default expansion of multi3 using umuldi3_highpart will perform
2483 ;; the additions in an order that fails to combine into two madd insns.
2484 (define_expand "multi3"
2485 [(set (match_operand:TI 0 "register_operand")
2486 (mult:TI (match_operand:TI 1 "register_operand")
2487 (match_operand:TI 2 "register_operand")))]
2490 rtx l0 = gen_reg_rtx (DImode);
2491 rtx l1 = gen_lowpart (DImode, operands[1]);
2492 rtx l2 = gen_lowpart (DImode, operands[2]);
2493 rtx h0 = gen_reg_rtx (DImode);
2494 rtx h1 = gen_highpart (DImode, operands[1]);
2495 rtx h2 = gen_highpart (DImode, operands[2]);
2497 emit_insn (gen_muldi3 (l0, l1, l2));
2498 emit_insn (gen_umuldi3_highpart (h0, l1, l2));
2499 emit_insn (gen_madddi (h0, h1, l2, h0));
2500 emit_insn (gen_madddi (h0, l1, h2, h0));
2502 emit_move_insn (gen_lowpart (DImode, operands[0]), l0);
2503 emit_move_insn (gen_highpart (DImode, operands[0]), h0);
2507 (define_insn "<su>muldi3_highpart"
2508 [(set (match_operand:DI 0 "register_operand" "=r")
2512 (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2513 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2516 "<su>mulh\\t%0, %1, %2"
2517 [(set_attr "type" "<su>mull")]
2520 (define_insn "<su_optab>div<mode>3"
2521 [(set (match_operand:GPI 0 "register_operand" "=r")
2522 (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2523 (match_operand:GPI 2 "register_operand" "r")))]
2525 "<su>div\\t%<w>0, %<w>1, %<w>2"
2526 [(set_attr "type" "<su>div")]
2529 ;; zero_extend version of above
2530 (define_insn "*<su_optab>divsi3_uxtw"
2531 [(set (match_operand:DI 0 "register_operand" "=r")
2533 (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2534 (match_operand:SI 2 "register_operand" "r"))))]
2536 "<su>div\\t%w0, %w1, %w2"
2537 [(set_attr "type" "<su>div")]
2540 ;; -------------------------------------------------------------------
2542 ;; -------------------------------------------------------------------
2544 (define_insn "*cmp<mode>"
2545 [(set (reg:CC CC_REGNUM)
2546 (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2547 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2553 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
2556 (define_insn "*cmp<mode>"
2557 [(set (reg:CCFP CC_REGNUM)
2558 (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2559 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2563 fcmp\\t%<s>0, %<s>1"
2564 [(set_attr "type" "fcmp<s>")]
2567 (define_insn "*cmpe<mode>"
2568 [(set (reg:CCFPE CC_REGNUM)
2569 (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2570 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2574 fcmpe\\t%<s>0, %<s>1"
2575 [(set_attr "type" "fcmp<s>")]
2578 (define_insn "*cmp_swp_<shift>_reg<mode>"
2579 [(set (reg:CC_SWP CC_REGNUM)
2580 (compare:CC_SWP (ASHIFT:GPI
2581 (match_operand:GPI 0 "register_operand" "r")
2582 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2583 (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2585 "cmp\\t%<w>2, %<w>0, <shift> %1"
2586 [(set_attr "type" "alus_shift_imm")]
2589 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2590 [(set (reg:CC_SWP CC_REGNUM)
2591 (compare:CC_SWP (ANY_EXTEND:GPI
2592 (match_operand:ALLX 0 "register_operand" "r"))
2593 (match_operand:GPI 1 "register_operand" "r")))]
2595 "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2596 [(set_attr "type" "alus_ext")]
2599 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2600 [(set (reg:CC_SWP CC_REGNUM)
2601 (compare:CC_SWP (ashift:GPI
2603 (match_operand:ALLX 0 "register_operand" "r"))
2604 (match_operand 1 "aarch64_imm3" "Ui3"))
2605 (match_operand:GPI 2 "register_operand" "r")))]
2607 "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2608 [(set_attr "type" "alus_ext")]
2611 ;; -------------------------------------------------------------------
2612 ;; Store-flag and conditional select insns
2613 ;; -------------------------------------------------------------------
2615 (define_expand "cstore<mode>4"
2616 [(set (match_operand:SI 0 "register_operand" "")
2617 (match_operator:SI 1 "aarch64_comparison_operator"
2618 [(match_operand:GPI 2 "register_operand" "")
2619 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2622 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2624 operands[3] = const0_rtx;
2628 (define_expand "cstorecc4"
2629 [(set (match_operand:SI 0 "register_operand")
2630 (match_operator 1 "aarch64_comparison_operator"
2631 [(match_operand 2 "ccmp_cc_register")
2632 (match_operand 3 "const0_operand")]))]
2635 emit_insn (gen_rtx_SET (operands[0], operands[1]));
2640 (define_expand "cstore<mode>4"
2641 [(set (match_operand:SI 0 "register_operand" "")
2642 (match_operator:SI 1 "aarch64_comparison_operator"
2643 [(match_operand:GPF 2 "register_operand" "")
2644 (match_operand:GPF 3 "register_operand" "")]))]
2647 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2649 operands[3] = const0_rtx;
2653 (define_insn "*cstore<mode>_insn"
2654 [(set (match_operand:ALLI 0 "register_operand" "=r")
2655 (match_operator:ALLI 1 "aarch64_comparison_operator"
2656 [(match_operand 2 "cc_register" "") (const_int 0)]))]
2659 [(set_attr "type" "csel")]
2662 ;; zero_extend version of the above
2663 (define_insn "*cstoresi_insn_uxtw"
2664 [(set (match_operand:DI 0 "register_operand" "=r")
2666 (match_operator:SI 1 "aarch64_comparison_operator"
2667 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2670 [(set_attr "type" "csel")]
2673 (define_insn "cstore<mode>_neg"
2674 [(set (match_operand:ALLI 0 "register_operand" "=r")
2675 (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2676 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2678 "csetm\\t%<w>0, %m1"
2679 [(set_attr "type" "csel")]
2682 ;; zero_extend version of the above
2683 (define_insn "*cstoresi_neg_uxtw"
2684 [(set (match_operand:DI 0 "register_operand" "=r")
2686 (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2687 [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2690 [(set_attr "type" "csel")]
2693 (define_expand "cmov<mode>6"
2694 [(set (match_operand:GPI 0 "register_operand" "")
2696 (match_operator 1 "aarch64_comparison_operator"
2697 [(match_operand:GPI 2 "register_operand" "")
2698 (match_operand:GPI 3 "aarch64_plus_operand" "")])
2699 (match_operand:GPI 4 "register_operand" "")
2700 (match_operand:GPI 5 "register_operand" "")))]
2703 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2705 operands[3] = const0_rtx;
2709 (define_expand "cmov<mode>6"
2710 [(set (match_operand:GPF 0 "register_operand" "")
2712 (match_operator 1 "aarch64_comparison_operator"
2713 [(match_operand:GPF 2 "register_operand" "")
2714 (match_operand:GPF 3 "register_operand" "")])
2715 (match_operand:GPF 4 "register_operand" "")
2716 (match_operand:GPF 5 "register_operand" "")))]
2719 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2721 operands[3] = const0_rtx;
2725 (define_insn "*cmov<mode>_insn"
2726 [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2728 (match_operator 1 "aarch64_comparison_operator"
2729 [(match_operand 2 "cc_register" "") (const_int 0)])
2730 (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2731 (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2732 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2733 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2734 ;; Final two alternatives should be unreachable, but included for completeness
2736 csel\\t%<w>0, %<w>3, %<w>4, %m1
2737 csinv\\t%<w>0, %<w>3, <w>zr, %m1
2738 csinv\\t%<w>0, %<w>4, <w>zr, %M1
2739 csinc\\t%<w>0, %<w>3, <w>zr, %m1
2740 csinc\\t%<w>0, %<w>4, <w>zr, %M1
2743 [(set_attr "type" "csel")]
2746 ;; zero_extend version of above
2747 (define_insn "*cmovsi_insn_uxtw"
2748 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2751 (match_operator 1 "aarch64_comparison_operator"
2752 [(match_operand 2 "cc_register" "") (const_int 0)])
2753 (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2754 (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2755 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2756 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2757 ;; Final two alternatives should be unreachable, but included for completeness
2759 csel\\t%w0, %w3, %w4, %m1
2760 csinv\\t%w0, %w3, wzr, %m1
2761 csinv\\t%w0, %w4, wzr, %M1
2762 csinc\\t%w0, %w3, wzr, %m1
2763 csinc\\t%w0, %w4, wzr, %M1
2766 [(set_attr "type" "csel")]
2769 (define_insn "*cmov<mode>_insn"
2770 [(set (match_operand:GPF 0 "register_operand" "=w")
2772 (match_operator 1 "aarch64_comparison_operator"
2773 [(match_operand 2 "cc_register" "") (const_int 0)])
2774 (match_operand:GPF 3 "register_operand" "w")
2775 (match_operand:GPF 4 "register_operand" "w")))]
2777 "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2778 [(set_attr "type" "fcsel")]
2781 (define_expand "mov<mode>cc"
2782 [(set (match_operand:ALLI 0 "register_operand" "")
2783 (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2784 (match_operand:ALLI 2 "register_operand" "")
2785 (match_operand:ALLI 3 "register_operand" "")))]
2788 enum rtx_code code = GET_CODE (operands[1]);
2790 if (code == UNEQ || code == LTGT)
2793 if (!ccmp_cc_register (XEXP (operands[1], 0),
2794 GET_MODE (XEXP (operands[1], 0))))
2797 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2798 XEXP (operands[1], 1));
2799 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2804 (define_expand "mov<GPF:mode><GPI:mode>cc"
2805 [(set (match_operand:GPI 0 "register_operand" "")
2806 (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2807 (match_operand:GPF 2 "register_operand" "")
2808 (match_operand:GPF 3 "register_operand" "")))]
2812 enum rtx_code code = GET_CODE (operands[1]);
2814 if (code == UNEQ || code == LTGT)
2817 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2818 XEXP (operands[1], 1));
2819 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2823 (define_expand "mov<mode>cc"
2824 [(set (match_operand:GPF 0 "register_operand" "")
2825 (if_then_else:GPF (match_operand 1 "aarch64_comparison_operator" "")
2826 (match_operand:GPF 2 "register_operand" "")
2827 (match_operand:GPF 3 "register_operand" "")))]
2831 enum rtx_code code = GET_CODE (operands[1]);
2833 if (code == UNEQ || code == LTGT)
2836 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2837 XEXP (operands[1], 1));
2838 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2843 ;; CRC32 instructions.
2844 (define_insn "aarch64_<crc_variant>"
2845 [(set (match_operand:SI 0 "register_operand" "=r")
2846 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2847 (match_operand:<crc_mode> 2 "register_operand" "r")]
2851 if (GET_MODE_BITSIZE (GET_MODE (operands[2])) >= 64)
2852 return "<crc_variant>\\t%w0, %w1, %x2";
2854 return "<crc_variant>\\t%w0, %w1, %w2";
2856 [(set_attr "type" "crc")]
2859 (define_insn "*csinc2<mode>_insn"
2860 [(set (match_operand:GPI 0 "register_operand" "=r")
2861 (plus:GPI (match_operand 2 "aarch64_comparison_operation" "")
2862 (match_operand:GPI 1 "register_operand" "r")))]
2864 "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2865 [(set_attr "type" "csel")]
2868 (define_insn "csinc3<mode>_insn"
2869 [(set (match_operand:GPI 0 "register_operand" "=r")
2871 (match_operand 1 "aarch64_comparison_operation" "")
2872 (plus:GPI (match_operand:GPI 2 "register_operand" "r")
2874 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2876 "csinc\\t%<w>0, %<w>3, %<w>2, %M1"
2877 [(set_attr "type" "csel")]
2880 (define_insn "*csinv3<mode>_insn"
2881 [(set (match_operand:GPI 0 "register_operand" "=r")
2883 (match_operand 1 "aarch64_comparison_operation" "")
2884 (not:GPI (match_operand:GPI 2 "register_operand" "r"))
2885 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2887 "csinv\\t%<w>0, %<w>3, %<w>2, %M1"
2888 [(set_attr "type" "csel")]
2891 (define_insn "*csneg3<mode>_insn"
2892 [(set (match_operand:GPI 0 "register_operand" "=r")
2894 (match_operand 1 "aarch64_comparison_operation" "")
2895 (neg:GPI (match_operand:GPI 2 "register_operand" "r"))
2896 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2898 "csneg\\t%<w>0, %<w>3, %<w>2, %M1"
2899 [(set_attr "type" "csel")]
2902 ;; -------------------------------------------------------------------
2903 ;; Logical operations
2904 ;; -------------------------------------------------------------------
2906 (define_insn "<optab><mode>3"
2907 [(set (match_operand:GPI 0 "register_operand" "=r,rk,w")
2908 (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r,w")
2909 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>,w")))]
2912 <logical>\\t%<w>0, %<w>1, %<w>2
2913 <logical>\\t%<w>0, %<w>1, %<w>2
2914 <logical>\\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
2915 [(set_attr "type" "logic_reg,logic_imm,neon_logic")
2916 (set_attr "simd" "*,*,yes")]
2919 ;; zero_extend version of above
2920 (define_insn "*<optab>si3_uxtw"
2921 [(set (match_operand:DI 0 "register_operand" "=r,rk")
2923 (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2924 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2926 "<logical>\\t%w0, %w1, %w2"
2927 [(set_attr "type" "logic_reg,logic_imm")]
2930 (define_insn "*and<mode>3_compare0"
2931 [(set (reg:CC_NZ CC_REGNUM)
2933 (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2934 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2936 (set (match_operand:GPI 0 "register_operand" "=r,r")
2937 (and:GPI (match_dup 1) (match_dup 2)))]
2939 "ands\\t%<w>0, %<w>1, %<w>2"
2940 [(set_attr "type" "logics_reg,logics_imm")]
2943 ;; zero_extend version of above
2944 (define_insn "*andsi3_compare0_uxtw"
2945 [(set (reg:CC_NZ CC_REGNUM)
2947 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2948 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2950 (set (match_operand:DI 0 "register_operand" "=r,r")
2951 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2953 "ands\\t%w0, %w1, %w2"
2954 [(set_attr "type" "logics_reg,logics_imm")]
2957 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2958 [(set (reg:CC_NZ CC_REGNUM)
2961 (match_operand:GPI 1 "register_operand" "r")
2962 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2963 (match_operand:GPI 3 "register_operand" "r"))
2965 (set (match_operand:GPI 0 "register_operand" "=r")
2966 (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2968 "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2969 [(set_attr "type" "logics_shift_imm")]
2972 ;; zero_extend version of above
2973 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2974 [(set (reg:CC_NZ CC_REGNUM)
2977 (match_operand:SI 1 "register_operand" "r")
2978 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2979 (match_operand:SI 3 "register_operand" "r"))
2981 (set (match_operand:DI 0 "register_operand" "=r")
2982 (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2985 "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2986 [(set_attr "type" "logics_shift_imm")]
2989 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2990 [(set (match_operand:GPI 0 "register_operand" "=r")
2991 (LOGICAL:GPI (SHIFT:GPI
2992 (match_operand:GPI 1 "register_operand" "r")
2993 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2994 (match_operand:GPI 3 "register_operand" "r")))]
2996 "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2997 [(set_attr "type" "logic_shift_imm")]
3000 (define_insn "*<optab>_rol<mode>3"
3001 [(set (match_operand:GPI 0 "register_operand" "=r")
3002 (LOGICAL:GPI (rotate:GPI
3003 (match_operand:GPI 1 "register_operand" "r")
3004 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3005 (match_operand:GPI 3 "register_operand" "r")))]
3007 "<logical>\\t%<w>0, %<w>3, %<w>1, ror (<sizen> - %2)"
3008 [(set_attr "type" "logic_shift_imm")]
3011 ;; zero_extend versions of above
3012 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
3013 [(set (match_operand:DI 0 "register_operand" "=r")
3015 (LOGICAL:SI (SHIFT:SI
3016 (match_operand:SI 1 "register_operand" "r")
3017 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3018 (match_operand:SI 3 "register_operand" "r"))))]
3020 "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3021 [(set_attr "type" "logic_shift_imm")]
3024 (define_insn "*<optab>_rolsi3_uxtw"
3025 [(set (match_operand:DI 0 "register_operand" "=r")
3027 (LOGICAL:SI (rotate:SI
3028 (match_operand:SI 1 "register_operand" "r")
3029 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3030 (match_operand:SI 3 "register_operand" "r"))))]
3032 "<logical>\\t%w0, %w3, %w1, ror (32 - %2)"
3033 [(set_attr "type" "logic_shift_imm")]
3036 (define_insn "one_cmpl<mode>2"
3037 [(set (match_operand:GPI 0 "register_operand" "=r,w")
3038 (not:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
3043 [(set_attr "type" "logic_reg,neon_logic")
3044 (set_attr "simd" "*,yes")]
3047 (define_insn "*one_cmpl_<optab><mode>2"
3048 [(set (match_operand:GPI 0 "register_operand" "=r")
3049 (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
3050 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
3052 "mvn\\t%<w>0, %<w>1, <shift> %2"
3053 [(set_attr "type" "logic_shift_imm")]
3056 ;; Binary logical operators negating one operand, i.e. (a & !b), (a | !b).
3058 (define_insn "*<NLOGICAL:optab>_one_cmpl<mode>3"
3059 [(set (match_operand:GPI 0 "register_operand" "=r,w")
3060 (NLOGICAL:GPI (not:GPI (match_operand:GPI 1 "register_operand" "r,w"))
3061 (match_operand:GPI 2 "register_operand" "r,w")))]
3064 <NLOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1
3065 <NLOGICAL:nlogical>\\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>"
3066 [(set_attr "type" "logic_reg,neon_logic")
3067 (set_attr "simd" "*,yes")]
3070 (define_insn "*<NLOGICAL:optab>_one_cmplsidi3_ze"
3071 [(set (match_operand:DI 0 "register_operand" "=r")
3073 (NLOGICAL:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3074 (match_operand:SI 2 "register_operand" "r"))))]
3076 "<NLOGICAL:nlogical>\\t%w0, %w2, %w1"
3077 [(set_attr "type" "logic_reg")]
3080 (define_insn "*xor_one_cmplsidi3_ze"
3081 [(set (match_operand:DI 0 "register_operand" "=r")
3083 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "r")
3084 (match_operand:SI 2 "register_operand" "r")))))]
3086 "eon\\t%w0, %w1, %w2"
3087 [(set_attr "type" "logic_reg")]
3090 ;; (xor (not a) b) is simplify_rtx-ed down to (not (xor a b)).
3091 ;; eon does not operate on SIMD registers so the vector variant must be split.
3092 (define_insn_and_split "*xor_one_cmpl<mode>3"
3093 [(set (match_operand:GPI 0 "register_operand" "=r,w")
3094 (not:GPI (xor:GPI (match_operand:GPI 1 "register_operand" "r,?w")
3095 (match_operand:GPI 2 "register_operand" "r,w"))))]
3098 eon\\t%<w>0, %<w>1, %<w>2
3100 "reload_completed && FP_REGNUM_P (REGNO (operands[0]))" ;; For SIMD registers.
3101 [(set (match_operand:GPI 0 "register_operand" "=w")
3102 (xor:GPI (match_operand:GPI 1 "register_operand" "w")
3103 (match_operand:GPI 2 "register_operand" "w")))
3104 (set (match_dup 0) (not:GPI (match_dup 0)))]
3106 [(set_attr "type" "logic_reg,multiple")
3107 (set_attr "simd" "*,yes")]
3110 (define_insn "*and_one_cmpl<mode>3_compare0"
3111 [(set (reg:CC_NZ CC_REGNUM)
3114 (match_operand:GPI 1 "register_operand" "r"))
3115 (match_operand:GPI 2 "register_operand" "r"))
3117 (set (match_operand:GPI 0 "register_operand" "=r")
3118 (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
3120 "bics\\t%<w>0, %<w>2, %<w>1"
3121 [(set_attr "type" "logics_reg")]
3124 ;; zero_extend version of above
3125 (define_insn "*and_one_cmplsi3_compare0_uxtw"
3126 [(set (reg:CC_NZ CC_REGNUM)
3129 (match_operand:SI 1 "register_operand" "r"))
3130 (match_operand:SI 2 "register_operand" "r"))
3132 (set (match_operand:DI 0 "register_operand" "=r")
3133 (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
3135 "bics\\t%w0, %w2, %w1"
3136 [(set_attr "type" "logics_reg")]
3139 (define_insn "*and_one_cmpl<mode>3_compare0_no_reuse"
3140 [(set (reg:CC_NZ CC_REGNUM)
3143 (match_operand:GPI 0 "register_operand" "r"))
3144 (match_operand:GPI 1 "register_operand" "r"))
3147 "bics\\t<w>zr, %<w>1, %<w>0"
3148 [(set_attr "type" "logics_reg")]
3151 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
3152 [(set (match_operand:GPI 0 "register_operand" "=r")
3153 (LOGICAL:GPI (not:GPI
3155 (match_operand:GPI 1 "register_operand" "r")
3156 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
3157 (match_operand:GPI 3 "register_operand" "r")))]
3159 "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3160 [(set_attr "type" "logics_shift_imm")]
3163 (define_insn "*eor_one_cmpl_<SHIFT:optab><mode>3_alt"
3164 [(set (match_operand:GPI 0 "register_operand" "=r")
3167 (match_operand:GPI 1 "register_operand" "r")
3168 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3169 (match_operand:GPI 3 "register_operand" "r"))))]
3171 "eon\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3172 [(set_attr "type" "logic_shift_imm")]
3175 ;; Zero-extend version of the above.
3176 (define_insn "*eor_one_cmpl_<SHIFT:optab>sidi3_alt_ze"
3177 [(set (match_operand:DI 0 "register_operand" "=r")
3181 (match_operand:SI 1 "register_operand" "r")
3182 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3183 (match_operand:SI 3 "register_operand" "r")))))]
3185 "eon\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3186 [(set_attr "type" "logic_shift_imm")]
3189 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
3190 [(set (reg:CC_NZ CC_REGNUM)
3194 (match_operand:GPI 1 "register_operand" "r")
3195 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
3196 (match_operand:GPI 3 "register_operand" "r"))
3198 (set (match_operand:GPI 0 "register_operand" "=r")
3201 (match_dup 1) (match_dup 2))) (match_dup 3)))]
3203 "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3204 [(set_attr "type" "logics_shift_imm")]
3207 ;; zero_extend version of above
3208 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
3209 [(set (reg:CC_NZ CC_REGNUM)
3213 (match_operand:SI 1 "register_operand" "r")
3214 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
3215 (match_operand:SI 3 "register_operand" "r"))
3217 (set (match_operand:DI 0 "register_operand" "=r")
3218 (zero_extend:DI (and:SI
3220 (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
3222 "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3223 [(set_attr "type" "logics_shift_imm")]
3226 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0_no_reuse"
3227 [(set (reg:CC_NZ CC_REGNUM)
3231 (match_operand:GPI 0 "register_operand" "r")
3232 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n")))
3233 (match_operand:GPI 2 "register_operand" "r"))
3236 "bics\\t<w>zr, %<w>2, %<w>0, <SHIFT:shift> %1"
3237 [(set_attr "type" "logics_shift_imm")]
3240 (define_insn "clz<mode>2"
3241 [(set (match_operand:GPI 0 "register_operand" "=r")
3242 (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
3244 "clz\\t%<w>0, %<w>1"
3245 [(set_attr "type" "clz")]
3248 (define_expand "ffs<mode>2"
3249 [(match_operand:GPI 0 "register_operand")
3250 (match_operand:GPI 1 "register_operand")]
3253 rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
3254 rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
3256 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3257 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3258 emit_insn (gen_csinc3<mode>_insn (operands[0], x, operands[0], const0_rtx));
3263 (define_insn "clrsb<mode>2"
3264 [(set (match_operand:GPI 0 "register_operand" "=r")
3265 (clrsb:GPI (match_operand:GPI 1 "register_operand" "r")))]
3267 "cls\\t%<w>0, %<w>1"
3268 [(set_attr "type" "clz")]
3271 (define_insn "rbit<mode>2"
3272 [(set (match_operand:GPI 0 "register_operand" "=r")
3273 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
3275 "rbit\\t%<w>0, %<w>1"
3276 [(set_attr "type" "rbit")]
3279 (define_expand "ctz<mode>2"
3280 [(match_operand:GPI 0 "register_operand")
3281 (match_operand:GPI 1 "register_operand")]
3284 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3285 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3290 (define_insn "*and<mode>3nr_compare0"
3291 [(set (reg:CC_NZ CC_REGNUM)
3293 (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
3294 (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
3297 "tst\\t%<w>0, %<w>1"
3298 [(set_attr "type" "logics_reg")]
3301 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
3302 [(set (reg:CC_NZ CC_REGNUM)
3305 (match_operand:GPI 0 "register_operand" "r")
3306 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
3307 (match_operand:GPI 2 "register_operand" "r"))
3310 "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
3311 [(set_attr "type" "logics_shift_imm")]
3314 ;; -------------------------------------------------------------------
3316 ;; -------------------------------------------------------------------
3318 (define_expand "<optab><mode>3"
3319 [(set (match_operand:GPI 0 "register_operand")
3320 (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
3321 (match_operand:QI 2 "nonmemory_operand")))]
3324 if (CONST_INT_P (operands[2]))
3326 operands[2] = GEN_INT (INTVAL (operands[2])
3327 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3329 if (operands[2] == const0_rtx)
3331 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3338 (define_expand "ashl<mode>3"
3339 [(set (match_operand:SHORT 0 "register_operand")
3340 (ashift:SHORT (match_operand:SHORT 1 "register_operand")
3341 (match_operand:QI 2 "nonmemory_operand")))]
3344 if (CONST_INT_P (operands[2]))
3346 operands[2] = GEN_INT (INTVAL (operands[2])
3347 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3349 if (operands[2] == const0_rtx)
3351 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3360 (define_expand "rotr<mode>3"
3361 [(set (match_operand:GPI 0 "register_operand")
3362 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3363 (match_operand:QI 2 "nonmemory_operand")))]
3366 if (CONST_INT_P (operands[2]))
3368 operands[2] = GEN_INT (INTVAL (operands[2])
3369 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3371 if (operands[2] == const0_rtx)
3373 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3380 (define_expand "rotl<mode>3"
3381 [(set (match_operand:GPI 0 "register_operand")
3382 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3383 (match_operand:QI 2 "nonmemory_operand")))]
3386 /* (SZ - cnt) % SZ == -cnt % SZ */
3387 if (CONST_INT_P (operands[2]))
3389 operands[2] = GEN_INT ((-INTVAL (operands[2]))
3390 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3391 if (operands[2] == const0_rtx)
3393 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3398 operands[2] = expand_simple_unop (QImode, NEG, operands[2],
3403 ;; Logical left shift using SISD or Integer instruction
3404 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
3405 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3407 (match_operand:GPI 1 "register_operand" "w,w,r")
3408 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3411 shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3412 ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
3413 lsl\t%<w>0, %<w>1, %<w>2"
3414 [(set_attr "simd" "yes,yes,no")
3415 (set_attr "type" "neon_shift_imm<q>, neon_shift_reg<q>,shift_reg")]
3418 ;; Logical right shift using SISD or Integer instruction
3419 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3420 [(set (match_operand:GPI 0 "register_operand" "=w,&w,r")
3422 (match_operand:GPI 1 "register_operand" "w,w,r")
3423 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3426 ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3428 lsr\t%<w>0, %<w>1, %<w>2"
3429 [(set_attr "simd" "yes,yes,no")
3430 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")]
3434 [(set (match_operand:DI 0 "aarch64_simd_register")
3436 (match_operand:DI 1 "aarch64_simd_register")
3437 (match_operand:QI 2 "aarch64_simd_register")))]
3438 "TARGET_SIMD && reload_completed"
3440 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3442 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_USHL))]
3444 operands[3] = gen_lowpart (QImode, operands[0]);
3449 [(set (match_operand:SI 0 "aarch64_simd_register")
3451 (match_operand:SI 1 "aarch64_simd_register")
3452 (match_operand:QI 2 "aarch64_simd_register")))]
3453 "TARGET_SIMD && reload_completed"
3455 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3457 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_USHL_2S))]
3459 operands[3] = gen_lowpart (QImode, operands[0]);
3463 ;; Arithmetic right shift using SISD or Integer instruction
3464 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3465 [(set (match_operand:GPI 0 "register_operand" "=w,&w,&w,r")
3467 (match_operand:GPI 1 "register_operand" "w,w,w,r")
3468 (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,0,rUs<cmode>")))]
3471 sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3474 asr\t%<w>0, %<w>1, %<w>2"
3475 [(set_attr "simd" "yes,yes,yes,no")
3476 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>,shift_reg")]
3480 [(set (match_operand:DI 0 "aarch64_simd_register")
3482 (match_operand:DI 1 "aarch64_simd_register")
3483 (match_operand:QI 2 "aarch64_simd_register")))]
3484 "TARGET_SIMD && reload_completed"
3486 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3488 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_SSHL))]
3490 operands[3] = gen_lowpart (QImode, operands[0]);
3495 [(set (match_operand:SI 0 "aarch64_simd_register")
3497 (match_operand:SI 1 "aarch64_simd_register")
3498 (match_operand:QI 2 "aarch64_simd_register")))]
3499 "TARGET_SIMD && reload_completed"
3501 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3503 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_SSHL_2S))]
3505 operands[3] = gen_lowpart (QImode, operands[0]);
3509 (define_insn "*aarch64_sisd_ushl"
3510 [(set (match_operand:DI 0 "register_operand" "=w")
3511 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3512 (match_operand:QI 2 "register_operand" "w")]
3515 "ushl\t%d0, %d1, %d2"
3516 [(set_attr "simd" "yes")
3517 (set_attr "type" "neon_shift_reg")]
3520 (define_insn "*aarch64_ushl_2s"
3521 [(set (match_operand:SI 0 "register_operand" "=w")
3522 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3523 (match_operand:QI 2 "register_operand" "w")]
3526 "ushl\t%0.2s, %1.2s, %2.2s"
3527 [(set_attr "simd" "yes")
3528 (set_attr "type" "neon_shift_reg")]
3531 (define_insn "*aarch64_sisd_sshl"
3532 [(set (match_operand:DI 0 "register_operand" "=w")
3533 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3534 (match_operand:QI 2 "register_operand" "w")]
3537 "sshl\t%d0, %d1, %d2"
3538 [(set_attr "simd" "yes")
3539 (set_attr "type" "neon_shift_reg")]
3542 (define_insn "*aarch64_sshl_2s"
3543 [(set (match_operand:SI 0 "register_operand" "=w")
3544 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3545 (match_operand:QI 2 "register_operand" "w")]
3548 "sshl\t%0.2s, %1.2s, %2.2s"
3549 [(set_attr "simd" "yes")
3550 (set_attr "type" "neon_shift_reg")]
3553 (define_insn "*aarch64_sisd_neg_qi"
3554 [(set (match_operand:QI 0 "register_operand" "=w")
3555 (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3559 [(set_attr "simd" "yes")
3560 (set_attr "type" "neon_neg")]
3564 (define_insn "*ror<mode>3_insn"
3565 [(set (match_operand:GPI 0 "register_operand" "=r")
3567 (match_operand:GPI 1 "register_operand" "r")
3568 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3570 "ror\\t%<w>0, %<w>1, %<w>2"
3571 [(set_attr "type" "shift_reg")]
3574 ;; zero_extend version of above
3575 (define_insn "*<optab>si3_insn_uxtw"
3576 [(set (match_operand:DI 0 "register_operand" "=r")
3577 (zero_extend:DI (SHIFT:SI
3578 (match_operand:SI 1 "register_operand" "r")
3579 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3581 "<shift>\\t%w0, %w1, %w2"
3582 [(set_attr "type" "shift_reg")]
3585 (define_insn "*<optab><mode>3_insn"
3586 [(set (match_operand:SHORT 0 "register_operand" "=r")
3587 (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3588 (match_operand 2 "const_int_operand" "n")))]
3589 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3591 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3592 return "<bfshift>\t%w0, %w1, %2, %3";
3594 [(set_attr "type" "bfm")]
3597 (define_insn "*extr<mode>5_insn"
3598 [(set (match_operand:GPI 0 "register_operand" "=r")
3599 (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3600 (match_operand 3 "const_int_operand" "n"))
3601 (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3602 (match_operand 4 "const_int_operand" "n"))))]
3603 "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3604 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3605 "extr\\t%<w>0, %<w>1, %<w>2, %4"
3606 [(set_attr "type" "shift_imm")]
3609 ;; There are no canonicalisation rules for ashift and lshiftrt inside an ior
3610 ;; so we have to match both orderings.
3611 (define_insn "*extr<mode>5_insn_alt"
3612 [(set (match_operand:GPI 0 "register_operand" "=r")
3613 (ior:GPI (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3614 (match_operand 4 "const_int_operand" "n"))
3615 (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3616 (match_operand 3 "const_int_operand" "n"))))]
3617 "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode)
3618 && (UINTVAL (operands[3]) + UINTVAL (operands[4])
3619 == GET_MODE_BITSIZE (<MODE>mode))"
3620 "extr\\t%<w>0, %<w>1, %<w>2, %4"
3621 [(set_attr "type" "shift_imm")]
3624 ;; zero_extend version of the above
3625 (define_insn "*extrsi5_insn_uxtw"
3626 [(set (match_operand:DI 0 "register_operand" "=r")
3628 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3629 (match_operand 3 "const_int_operand" "n"))
3630 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3631 (match_operand 4 "const_int_operand" "n")))))]
3632 "UINTVAL (operands[3]) < 32 &&
3633 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3634 "extr\\t%w0, %w1, %w2, %4"
3635 [(set_attr "type" "shift_imm")]
3638 (define_insn "*extrsi5_insn_uxtw_alt"
3639 [(set (match_operand:DI 0 "register_operand" "=r")
3641 (ior:SI (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3642 (match_operand 4 "const_int_operand" "n"))
3643 (ashift:SI (match_operand:SI 1 "register_operand" "r")
3644 (match_operand 3 "const_int_operand" "n")))))]
3645 "UINTVAL (operands[3]) < 32 &&
3646 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3647 "extr\\t%w0, %w1, %w2, %4"
3648 [(set_attr "type" "shift_imm")]
3651 (define_insn "*ror<mode>3_insn"
3652 [(set (match_operand:GPI 0 "register_operand" "=r")
3653 (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3654 (match_operand 2 "const_int_operand" "n")))]
3655 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3657 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3658 return "ror\\t%<w>0, %<w>1, %3";
3660 [(set_attr "type" "shift_imm")]
3663 ;; zero_extend version of the above
3664 (define_insn "*rorsi3_insn_uxtw"
3665 [(set (match_operand:DI 0 "register_operand" "=r")
3667 (rotate:SI (match_operand:SI 1 "register_operand" "r")
3668 (match_operand 2 "const_int_operand" "n"))))]
3669 "UINTVAL (operands[2]) < 32"
3671 operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3672 return "ror\\t%w0, %w1, %3";
3674 [(set_attr "type" "shift_imm")]
3677 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3678 [(set (match_operand:GPI 0 "register_operand" "=r")
3680 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3681 (match_operand 2 "const_int_operand" "n"))))]
3682 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3684 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3685 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3687 [(set_attr "type" "bfm")]
3690 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3691 [(set (match_operand:GPI 0 "register_operand" "=r")
3693 (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3694 (match_operand 2 "const_int_operand" "n"))))]
3695 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3697 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3698 return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3700 [(set_attr "type" "bfm")]
3703 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3704 [(set (match_operand:GPI 0 "register_operand" "=r")
3706 (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3707 (match_operand 2 "const_int_operand" "n"))))]
3708 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3710 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3711 return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3713 [(set_attr "type" "bfm")]
3716 ;; -------------------------------------------------------------------
3718 ;; -------------------------------------------------------------------
3720 (define_expand "<optab>"
3721 [(set (match_operand:DI 0 "register_operand" "=r")
3722 (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3723 (match_operand 2 "const_int_operand" "n")
3724 (match_operand 3 "const_int_operand" "n")))]
3729 (define_insn "*<optab><mode>"
3730 [(set (match_operand:GPI 0 "register_operand" "=r")
3731 (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3732 (match_operand 2 "const_int_operand" "n")
3733 (match_operand 3 "const_int_operand" "n")))]
3735 "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3736 [(set_attr "type" "bfm")]
3739 ;; Bitfield Insert (insv)
3740 (define_expand "insv<mode>"
3741 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3742 (match_operand 1 "const_int_operand")
3743 (match_operand 2 "const_int_operand"))
3744 (match_operand:GPI 3 "general_operand"))]
3747 unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3748 unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3749 rtx value = operands[3];
3751 if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3754 if (CONST_INT_P (value))
3756 unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3758 /* Prefer AND/OR for inserting all zeros or all ones. */
3759 if ((UINTVAL (value) & mask) == 0
3760 || (UINTVAL (value) & mask) == mask)
3763 /* 16-bit aligned 16-bit wide insert is handled by insv_imm. */
3764 if (width == 16 && (pos % 16) == 0)
3767 operands[3] = force_reg (<MODE>mode, value);
3770 (define_insn "*insv_reg<mode>"
3771 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3772 (match_operand 1 "const_int_operand" "n")
3773 (match_operand 2 "const_int_operand" "n"))
3774 (match_operand:GPI 3 "register_operand" "r"))]
3775 "!(UINTVAL (operands[1]) == 0
3776 || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3777 > GET_MODE_BITSIZE (<MODE>mode)))"
3778 "bfi\\t%<w>0, %<w>3, %2, %1"
3779 [(set_attr "type" "bfm")]
3782 (define_insn "*extr_insv_lower_reg<mode>"
3783 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3784 (match_operand 1 "const_int_operand" "n")
3786 (zero_extract:GPI (match_operand:GPI 2 "register_operand" "r")
3788 (match_operand 3 "const_int_operand" "n")))]
3789 "!(UINTVAL (operands[1]) == 0
3790 || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3791 > GET_MODE_BITSIZE (<MODE>mode)))"
3792 "bfxil\\t%<w>0, %<w>2, %3, %1"
3793 [(set_attr "type" "bfm")]
3796 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3797 [(set (match_operand:GPI 0 "register_operand" "=r")
3798 (ashift:GPI (ANY_EXTEND:GPI
3799 (match_operand:ALLX 1 "register_operand" "r"))
3800 (match_operand 2 "const_int_operand" "n")))]
3801 "UINTVAL (operands[2]) < <GPI:sizen>"
3803 operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3804 ? GEN_INT (<ALLX:sizen>)
3805 : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3806 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3808 [(set_attr "type" "bfm")]
3811 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3813 (define_insn "*andim_ashift<mode>_bfiz"
3814 [(set (match_operand:GPI 0 "register_operand" "=r")
3815 (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3816 (match_operand 2 "const_int_operand" "n"))
3817 (match_operand 3 "const_int_operand" "n")))]
3818 "(INTVAL (operands[2]) < (<GPI:sizen>))
3819 && exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3820 && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3821 "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3822 [(set_attr "type" "bfm")]
3825 (define_insn "bswap<mode>2"
3826 [(set (match_operand:GPI 0 "register_operand" "=r")
3827 (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3829 "rev\\t%<w>0, %<w>1"
3830 [(set_attr "type" "rev")]
3833 (define_insn "bswaphi2"
3834 [(set (match_operand:HI 0 "register_operand" "=r")
3835 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3838 [(set_attr "type" "rev")]
3841 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
3842 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
3843 ;; each valid permutation.
3845 (define_insn "rev16<mode>2"
3846 [(set (match_operand:GPI 0 "register_operand" "=r")
3847 (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3849 (match_operand:GPI 3 "const_int_operand" "n"))
3850 (and:GPI (lshiftrt:GPI (match_dup 1)
3852 (match_operand:GPI 2 "const_int_operand" "n"))))]
3853 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3854 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3855 "rev16\\t%<w>0, %<w>1"
3856 [(set_attr "type" "rev")]
3859 (define_insn "rev16<mode>2_alt"
3860 [(set (match_operand:GPI 0 "register_operand" "=r")
3861 (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r")
3863 (match_operand:GPI 2 "const_int_operand" "n"))
3864 (and:GPI (ashift:GPI (match_dup 1)
3866 (match_operand:GPI 3 "const_int_operand" "n"))))]
3867 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3868 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3869 "rev16\\t%<w>0, %<w>1"
3870 [(set_attr "type" "rev")]
3873 ;; zero_extend version of above
3874 (define_insn "*bswapsi2_uxtw"
3875 [(set (match_operand:DI 0 "register_operand" "=r")
3876 (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3879 [(set_attr "type" "rev")]
3882 ;; -------------------------------------------------------------------
3883 ;; Floating-point intrinsics
3884 ;; -------------------------------------------------------------------
3886 ;; frint floating-point round to integral standard patterns.
3887 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round, frintn.
3889 (define_insn "<frint_pattern><mode>2"
3890 [(set (match_operand:GPF 0 "register_operand" "=w")
3891 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3894 "frint<frint_suffix>\\t%<s>0, %<s>1"
3895 [(set_attr "type" "f_rint<s>")]
3898 ;; frcvt floating-point round to integer and convert standard patterns.
3899 ;; Expands to lbtrunc, lceil, lfloor, lround.
3900 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3901 [(set (match_operand:GPI 0 "register_operand" "=r")
3902 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3905 "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3906 [(set_attr "type" "f_cvtf2i")]
3911 (define_insn "fma<mode>4"
3912 [(set (match_operand:GPF 0 "register_operand" "=w")
3913 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3914 (match_operand:GPF 2 "register_operand" "w")
3915 (match_operand:GPF 3 "register_operand" "w")))]
3917 "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3918 [(set_attr "type" "fmac<s>")]
3921 (define_insn "fnma<mode>4"
3922 [(set (match_operand:GPF 0 "register_operand" "=w")
3923 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3924 (match_operand:GPF 2 "register_operand" "w")
3925 (match_operand:GPF 3 "register_operand" "w")))]
3927 "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3928 [(set_attr "type" "fmac<s>")]
3931 (define_insn "fms<mode>4"
3932 [(set (match_operand:GPF 0 "register_operand" "=w")
3933 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3934 (match_operand:GPF 2 "register_operand" "w")
3935 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3937 "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3938 [(set_attr "type" "fmac<s>")]
3941 (define_insn "fnms<mode>4"
3942 [(set (match_operand:GPF 0 "register_operand" "=w")
3943 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3944 (match_operand:GPF 2 "register_operand" "w")
3945 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3947 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3948 [(set_attr "type" "fmac<s>")]
3951 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3952 (define_insn "*fnmadd<mode>4"
3953 [(set (match_operand:GPF 0 "register_operand" "=w")
3954 (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3955 (match_operand:GPF 2 "register_operand" "w")
3956 (match_operand:GPF 3 "register_operand" "w"))))]
3957 "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3958 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3959 [(set_attr "type" "fmac<s>")]
3962 ;; -------------------------------------------------------------------
3963 ;; Floating-point conversions
3964 ;; -------------------------------------------------------------------
3966 (define_insn "extendsfdf2"
3967 [(set (match_operand:DF 0 "register_operand" "=w")
3968 (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3971 [(set_attr "type" "f_cvt")]
3974 (define_insn "truncdfsf2"
3975 [(set (match_operand:SF 0 "register_operand" "=w")
3976 (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3979 [(set_attr "type" "f_cvt")]
3982 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3983 [(set (match_operand:GPI 0 "register_operand" "=r")
3984 (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3986 "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3987 [(set_attr "type" "f_cvtf2i")]
3990 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3991 [(set (match_operand:GPI 0 "register_operand" "=r")
3992 (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3994 "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3995 [(set_attr "type" "f_cvtf2i")]
3998 (define_insn "<optab><fcvt_target><GPF:mode>2"
3999 [(set (match_operand:GPF 0 "register_operand" "=w,w")
4000 (FLOATUORS:GPF (match_operand:<FCVT_TARGET> 1 "register_operand" "w,r")))]
4003 <su_optab>cvtf\t%<GPF:s>0, %<s>1
4004 <su_optab>cvtf\t%<GPF:s>0, %<w1>1"
4005 [(set_attr "simd" "yes,no")
4006 (set_attr "fp" "no,yes")
4007 (set_attr "type" "neon_int_to_fp_<Vetype>,f_cvti2f")]
4010 (define_insn "<optab><fcvt_iesize><GPF:mode>2"
4011 [(set (match_operand:GPF 0 "register_operand" "=w")
4012 (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand" "r")))]
4014 "<su_optab>cvtf\t%<GPF:s>0, %<w2>1"
4015 [(set_attr "type" "f_cvti2f")]
4018 ;; -------------------------------------------------------------------
4019 ;; Floating-point arithmetic
4020 ;; -------------------------------------------------------------------
4022 (define_insn "add<mode>3"
4023 [(set (match_operand:GPF 0 "register_operand" "=w")
4025 (match_operand:GPF 1 "register_operand" "w")
4026 (match_operand:GPF 2 "register_operand" "w")))]
4028 "fadd\\t%<s>0, %<s>1, %<s>2"
4029 [(set_attr "type" "fadd<s>")]
4032 (define_insn "sub<mode>3"
4033 [(set (match_operand:GPF 0 "register_operand" "=w")
4035 (match_operand:GPF 1 "register_operand" "w")
4036 (match_operand:GPF 2 "register_operand" "w")))]
4038 "fsub\\t%<s>0, %<s>1, %<s>2"
4039 [(set_attr "type" "fadd<s>")]
4042 (define_insn "mul<mode>3"
4043 [(set (match_operand:GPF 0 "register_operand" "=w")
4045 (match_operand:GPF 1 "register_operand" "w")
4046 (match_operand:GPF 2 "register_operand" "w")))]
4048 "fmul\\t%<s>0, %<s>1, %<s>2"
4049 [(set_attr "type" "fmul<s>")]
4052 (define_insn "*fnmul<mode>3"
4053 [(set (match_operand:GPF 0 "register_operand" "=w")
4055 (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
4056 (match_operand:GPF 2 "register_operand" "w")))]
4058 "fnmul\\t%<s>0, %<s>1, %<s>2"
4059 [(set_attr "type" "fmul<s>")]
4062 (define_insn "div<mode>3"
4063 [(set (match_operand:GPF 0 "register_operand" "=w")
4065 (match_operand:GPF 1 "register_operand" "w")
4066 (match_operand:GPF 2 "register_operand" "w")))]
4068 "fdiv\\t%<s>0, %<s>1, %<s>2"
4069 [(set_attr "type" "fdiv<s>")]
4072 (define_insn "neg<mode>2"
4073 [(set (match_operand:GPF 0 "register_operand" "=w")
4074 (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
4076 "fneg\\t%<s>0, %<s>1"
4077 [(set_attr "type" "ffarith<s>")]
4080 (define_insn "sqrt<mode>2"
4081 [(set (match_operand:GPF 0 "register_operand" "=w")
4082 (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
4084 "fsqrt\\t%<s>0, %<s>1"
4085 [(set_attr "type" "fsqrt<s>")]
4088 (define_insn "abs<mode>2"
4089 [(set (match_operand:GPF 0 "register_operand" "=w")
4090 (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
4092 "fabs\\t%<s>0, %<s>1"
4093 [(set_attr "type" "ffarith<s>")]
4096 ;; Given that smax/smin do not specify the result when either input is NaN,
4097 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
4100 (define_insn "smax<mode>3"
4101 [(set (match_operand:GPF 0 "register_operand" "=w")
4102 (smax:GPF (match_operand:GPF 1 "register_operand" "w")
4103 (match_operand:GPF 2 "register_operand" "w")))]
4105 "fmaxnm\\t%<s>0, %<s>1, %<s>2"
4106 [(set_attr "type" "f_minmax<s>")]
4109 (define_insn "smin<mode>3"
4110 [(set (match_operand:GPF 0 "register_operand" "=w")
4111 (smin:GPF (match_operand:GPF 1 "register_operand" "w")
4112 (match_operand:GPF 2 "register_operand" "w")))]
4114 "fminnm\\t%<s>0, %<s>1, %<s>2"
4115 [(set_attr "type" "f_minmax<s>")]
4118 ;; -------------------------------------------------------------------
4120 ;; -------------------------------------------------------------------
4122 (define_expand "aarch64_reload_mov<mode>"
4123 [(set (match_operand:TX 0 "register_operand" "=w")
4124 (match_operand:TX 1 "register_operand" "w"))
4125 (clobber (match_operand:DI 2 "register_operand" "=&r"))
4129 rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
4130 rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
4131 gen_aarch64_movtilow_tilow (op0, op1);
4132 gen_aarch64_movdi_tihigh (operands[2], op1);
4133 gen_aarch64_movtihigh_di (op0, operands[2]);
4138 ;; The following secondary reload helpers patterns are invoked
4139 ;; after or during reload as we don't want these patterns to start
4140 ;; kicking in during the combiner.
4142 (define_insn "aarch64_movdi_<mode>low"
4143 [(set (match_operand:DI 0 "register_operand" "=r")
4144 (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
4145 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4147 [(set_attr "type" "f_mrc")
4148 (set_attr "length" "4")
4151 (define_insn "aarch64_movdi_<mode>high"
4152 [(set (match_operand:DI 0 "register_operand" "=r")
4154 (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
4156 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4157 "fmov\\t%x0, %1.d[1]"
4158 [(set_attr "type" "f_mrc")
4159 (set_attr "length" "4")
4162 (define_insn "aarch64_mov<mode>high_di"
4163 [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
4164 (const_int 64) (const_int 64))
4165 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4166 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4167 "fmov\\t%0.d[1], %x1"
4168 [(set_attr "type" "f_mcr")
4169 (set_attr "length" "4")
4172 (define_insn "aarch64_mov<mode>low_di"
4173 [(set (match_operand:TX 0 "register_operand" "=w")
4174 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4175 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4177 [(set_attr "type" "f_mcr")
4178 (set_attr "length" "4")
4181 (define_insn "aarch64_movtilow_tilow"
4182 [(set (match_operand:TI 0 "register_operand" "=w")
4184 (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
4185 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4187 [(set_attr "type" "fmov")
4188 (set_attr "length" "4")
4191 ;; There is a deliberate reason why the parameters of high and lo_sum's
4192 ;; don't have modes for ADRP and ADD instructions. This is to allow high
4193 ;; and lo_sum's to be used with the labels defining the jump tables in
4196 (define_expand "add_losym"
4197 [(set (match_operand 0 "register_operand" "=r")
4198 (lo_sum (match_operand 1 "register_operand" "r")
4199 (match_operand 2 "aarch64_valid_symref" "S")))]
4202 machine_mode mode = GET_MODE (operands[0]);
4204 emit_insn ((mode == DImode
4206 : gen_add_losym_si) (operands[0],
4212 (define_insn "add_losym_<mode>"
4213 [(set (match_operand:P 0 "register_operand" "=r")
4214 (lo_sum:P (match_operand:P 1 "register_operand" "r")
4215 (match_operand 2 "aarch64_valid_symref" "S")))]
4217 "add\\t%<w>0, %<w>1, :lo12:%a2"
4218 [(set_attr "type" "alu_imm")]
4221 (define_insn "ldr_got_small_<mode>"
4222 [(set (match_operand:PTR 0 "register_operand" "=r")
4223 (unspec:PTR [(mem:PTR (lo_sum:PTR
4224 (match_operand:PTR 1 "register_operand" "r")
4225 (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
4226 UNSPEC_GOTSMALLPIC))]
4228 "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
4229 [(set_attr "type" "load1")]
4232 (define_insn "ldr_got_small_sidi"
4233 [(set (match_operand:DI 0 "register_operand" "=r")
4235 (unspec:SI [(mem:SI (lo_sum:DI
4236 (match_operand:DI 1 "register_operand" "r")
4237 (match_operand:DI 2 "aarch64_valid_symref" "S")))]
4238 UNSPEC_GOTSMALLPIC)))]
4240 "ldr\\t%w0, [%1, #:got_lo12:%a2]"
4241 [(set_attr "type" "load1")]
4244 (define_insn "ldr_got_tiny"
4245 [(set (match_operand:DI 0 "register_operand" "=r")
4246 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
4247 UNSPEC_GOTTINYPIC))]
4250 [(set_attr "type" "load1")]
4253 (define_insn "aarch64_load_tp_hard"
4254 [(set (match_operand:DI 0 "register_operand" "=r")
4255 (unspec:DI [(const_int 0)] UNSPEC_TLS))]
4257 "mrs\\t%0, tpidr_el0"
4258 [(set_attr "type" "mrs")]
4261 ;; The TLS ABI specifically requires that the compiler does not schedule
4262 ;; instructions in the TLS stubs, in order to enable linker relaxation.
4263 ;; Therefore we treat the stubs as an atomic sequence.
4264 (define_expand "tlsgd_small"
4265 [(parallel [(set (match_operand 0 "register_operand" "")
4266 (call (mem:DI (match_dup 2)) (const_int 1)))
4267 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
4268 (clobber (reg:DI LR_REGNUM))])]
4271 operands[2] = aarch64_tls_get_addr ();
4274 (define_insn "*tlsgd_small"
4275 [(set (match_operand 0 "register_operand" "")
4276 (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
4277 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
4278 (clobber (reg:DI LR_REGNUM))
4281 "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
4282 [(set_attr "type" "call")
4283 (set_attr "length" "16")])
4285 (define_insn "tlsie_small_<mode>"
4286 [(set (match_operand:PTR 0 "register_operand" "=r")
4287 (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
4288 UNSPEC_GOTSMALLTLS))]
4290 "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
4291 [(set_attr "type" "load1")
4292 (set_attr "length" "8")]
4295 (define_insn "tlsie_small_sidi"
4296 [(set (match_operand:DI 0 "register_operand" "=r")
4298 (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")]
4299 UNSPEC_GOTSMALLTLS)))]
4301 "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
4302 [(set_attr "type" "load1")
4303 (set_attr "length" "8")]
4306 (define_expand "tlsle_small"
4307 [(set (match_operand 0 "register_operand" "=r")
4308 (unspec [(match_operand 1 "register_operand" "r")
4309 (match_operand 2 "aarch64_tls_le_symref" "S")]
4310 UNSPEC_GOTSMALLTLS))]
4313 machine_mode mode = GET_MODE (operands[0]);
4314 emit_insn ((mode == DImode
4315 ? gen_tlsle_small_di
4316 : gen_tlsle_small_si) (operands[0],
4322 (define_insn "tlsle_small_<mode>"
4323 [(set (match_operand:P 0 "register_operand" "=r")
4324 (unspec:P [(match_operand:P 1 "register_operand" "r")
4325 (match_operand 2 "aarch64_tls_le_symref" "S")]
4326 UNSPEC_GOTSMALLTLS))]
4328 "add\\t%<w>0, %<w>1, #%G2, lsl #12\;add\\t%<w>0, %<w>0, #%L2"
4329 [(set_attr "type" "alu_sreg")
4330 (set_attr "length" "8")]
4333 (define_insn "tlsdesc_small_<mode>"
4334 [(set (reg:PTR R0_REGNUM)
4335 (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
4337 (clobber (reg:DI LR_REGNUM))
4338 (clobber (reg:CC CC_REGNUM))
4339 (clobber (match_scratch:DI 1 "=r"))]
4341 "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
4342 [(set_attr "type" "call")
4343 (set_attr "length" "16")])
4345 (define_insn "stack_tie"
4346 [(set (mem:BLK (scratch))
4347 (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
4348 (match_operand:DI 1 "register_operand" "rk")]
4352 [(set_attr "length" "0")]
4355 ;; Named pattern for expanding thread pointer reference.
4356 (define_expand "get_thread_pointerdi"
4357 [(match_operand:DI 0 "register_operand" "=r")]
4360 rtx tmp = aarch64_load_tp (operands[0]);
4361 if (tmp != operands[0])
4362 emit_move_insn (operands[0], tmp);
4366 ;; Named patterns for stack smashing protection.
4367 (define_expand "stack_protect_set"
4368 [(match_operand 0 "memory_operand")
4369 (match_operand 1 "memory_operand")]
4372 machine_mode mode = GET_MODE (operands[0]);
4374 emit_insn ((mode == DImode
4375 ? gen_stack_protect_set_di
4376 : gen_stack_protect_set_si) (operands[0], operands[1]));
4380 (define_insn "stack_protect_set_<mode>"
4381 [(set (match_operand:PTR 0 "memory_operand" "=m")
4382 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
4384 (set (match_scratch:PTR 2 "=&r") (const_int 0))]
4386 "ldr\\t%<w>2, %1\;str\\t%<w>2, %0\;mov\t%<w>2,0"
4387 [(set_attr "length" "12")
4388 (set_attr "type" "multiple")])
4390 (define_expand "stack_protect_test"
4391 [(match_operand 0 "memory_operand")
4392 (match_operand 1 "memory_operand")
4397 machine_mode mode = GET_MODE (operands[0]);
4399 result = gen_reg_rtx(mode);
4401 emit_insn ((mode == DImode
4402 ? gen_stack_protect_test_di
4403 : gen_stack_protect_test_si) (result,
4408 emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4409 result, const0_rtx, operands[2]));
4411 emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4412 result, const0_rtx, operands[2]));
4416 (define_insn "stack_protect_test_<mode>"
4417 [(set (match_operand:PTR 0 "register_operand" "=r")
4418 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
4419 (match_operand:PTR 2 "memory_operand" "m")]
4421 (clobber (match_scratch:PTR 3 "=&r"))]
4423 "ldr\t%<w>3, %x1\;ldr\t%<w>0, %x2\;eor\t%<w>0, %<w>3, %<w>0"
4424 [(set_attr "length" "12")
4425 (set_attr "type" "multiple")])
4427 ;; Write Floating-point Control Register.
4428 (define_insn "set_fpcr"
4429 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
4432 [(set_attr "type" "mrs")])
4434 ;; Read Floating-point Control Register.
4435 (define_insn "get_fpcr"
4436 [(set (match_operand:SI 0 "register_operand" "=r")
4437 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
4440 [(set_attr "type" "mrs")])
4442 ;; Write Floating-point Status Register.
4443 (define_insn "set_fpsr"
4444 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
4447 [(set_attr "type" "mrs")])
4449 ;; Read Floating-point Status Register.
4450 (define_insn "get_fpsr"
4451 [(set (match_operand:SI 0 "register_operand" "=r")
4452 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
4455 [(set_attr "type" "mrs")])
4458 ;; Define the subtract-one-and-jump insns so loop.c
4459 ;; knows what to generate.
4460 (define_expand "doloop_end"
4461 [(use (match_operand 0 "" "")) ; loop pseudo
4462 (use (match_operand 1 "" ""))] ; label
4463 "optimize > 0 && flag_modulo_sched"
4472 /* Currently SMS relies on the do-loop pattern to recognize loops
4473 where (1) the control part consists of all insns defining and/or
4474 using a certain 'count' register and (2) the loop count can be
4475 adjusted by modifying this register prior to the loop.
4476 ??? The possible introduction of a new block to initialize the
4477 new IV can potentially affect branch optimizations. */
4479 if (GET_MODE (operands[0]) != DImode)
4483 insn = emit_insn (gen_adddi3_compare0 (s0, s0, GEN_INT (-1)));
4485 cmp = XVECEXP (PATTERN (insn), 0, 0);
4486 cc_reg = SET_DEST (cmp);
4487 bcomp = gen_rtx_NE (VOIDmode, cc_reg, const0_rtx);
4488 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
4489 emit_jump_insn (gen_rtx_SET (pc_rtx,
4490 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
4496 (include "aarch64-simd.md")
4498 ;; Atomic Operations
4499 (include "atomics.md")
4501 ;; ldp/stp peephole patterns
4502 (include "aarch64-ldpstp.md")