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 rtx subtarget = ((optimize && can_create_pseudo_p ())
1418 ? gen_reg_rtx (<MODE>mode) : operands[0]);
1419 HOST_WIDE_INT imm = INTVAL (operands[2]);
1422 imm = -(-imm & ~0xfff);
1426 emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1427 operands[1] = subtarget;
1428 operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1433 (define_insn "*addsi3_aarch64"
1435 (match_operand:SI 0 "register_operand" "=rk,rk,w,rk")
1437 (match_operand:SI 1 "register_operand" "%rk,rk,w,rk")
1438 (match_operand:SI 2 "aarch64_plus_operand" "I,r,w,J")))]
1443 add\\t%0.2s, %1.2s, %2.2s
1444 sub\\t%w0, %w1, #%n2"
1445 [(set_attr "type" "alu_imm,alu_sreg,neon_add,alu_imm")
1446 (set_attr "simd" "*,*,yes,*")]
1449 ;; zero_extend version of above
1450 (define_insn "*addsi3_aarch64_uxtw"
1452 (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1454 (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1455 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1460 sub\\t%w0, %w1, #%n2"
1461 [(set_attr "type" "alu_imm,alu_sreg,alu_imm")]
1464 (define_insn "*adddi3_aarch64"
1466 (match_operand:DI 0 "register_operand" "=rk,rk,rk,w")
1468 (match_operand:DI 1 "register_operand" "%rk,rk,rk,w")
1469 (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,w")))]
1474 sub\\t%x0, %x1, #%n2
1475 add\\t%d0, %d1, %d2"
1476 [(set_attr "type" "alu_imm,alu_sreg,alu_imm,neon_add")
1477 (set_attr "simd" "*,*,*,yes")]
1480 (define_expand "addti3"
1481 [(set (match_operand:TI 0 "register_operand" "")
1482 (plus:TI (match_operand:TI 1 "register_operand" "")
1483 (match_operand:TI 2 "register_operand" "")))]
1486 rtx low = gen_reg_rtx (DImode);
1487 emit_insn (gen_adddi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1488 gen_lowpart (DImode, operands[2])));
1490 rtx high = gen_reg_rtx (DImode);
1491 emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]),
1492 gen_highpart (DImode, operands[2])));
1494 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1495 emit_move_insn (gen_highpart (DImode, operands[0]), high);
1499 (define_insn "add<mode>3_compare0"
1500 [(set (reg:CC_NZ CC_REGNUM)
1502 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1503 (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1505 (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1506 (plus:GPI (match_dup 1) (match_dup 2)))]
1509 adds\\t%<w>0, %<w>1, %<w>2
1510 adds\\t%<w>0, %<w>1, %<w>2
1511 subs\\t%<w>0, %<w>1, #%n2"
1512 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1515 ;; zero_extend version of above
1516 (define_insn "*addsi3_compare0_uxtw"
1517 [(set (reg:CC_NZ CC_REGNUM)
1519 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1520 (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1522 (set (match_operand:DI 0 "register_operand" "=r,r,r")
1523 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1526 adds\\t%w0, %w1, %w2
1527 adds\\t%w0, %w1, %w2
1528 subs\\t%w0, %w1, #%n2"
1529 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1532 (define_insn "*adds_mul_imm_<mode>"
1533 [(set (reg:CC_NZ CC_REGNUM)
1536 (match_operand:GPI 1 "register_operand" "r")
1537 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1538 (match_operand:GPI 3 "register_operand" "r"))
1540 (set (match_operand:GPI 0 "register_operand" "=r")
1541 (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1544 "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1545 [(set_attr "type" "alus_shift_imm")]
1548 (define_insn "*subs_mul_imm_<mode>"
1549 [(set (reg:CC_NZ CC_REGNUM)
1551 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1553 (match_operand:GPI 2 "register_operand" "r")
1554 (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1556 (set (match_operand:GPI 0 "register_operand" "=r")
1557 (minus:GPI (match_dup 1)
1558 (mult:GPI (match_dup 2) (match_dup 3))))]
1560 "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1561 [(set_attr "type" "alus_shift_imm")]
1564 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1565 [(set (reg:CC_NZ CC_REGNUM)
1568 (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1569 (match_operand:GPI 2 "register_operand" "r"))
1571 (set (match_operand:GPI 0 "register_operand" "=r")
1572 (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1574 "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1575 [(set_attr "type" "alus_ext")]
1578 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1579 [(set (reg:CC_NZ CC_REGNUM)
1581 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1583 (match_operand:ALLX 2 "register_operand" "r")))
1585 (set (match_operand:GPI 0 "register_operand" "=r")
1586 (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1588 "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1589 [(set_attr "type" "alus_ext")]
1592 (define_insn "*adds_<optab><mode>_multp2"
1593 [(set (reg:CC_NZ CC_REGNUM)
1595 (plus:GPI (ANY_EXTRACT:GPI
1596 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1597 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1598 (match_operand 3 "const_int_operand" "n")
1600 (match_operand:GPI 4 "register_operand" "r"))
1602 (set (match_operand:GPI 0 "register_operand" "=r")
1603 (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1607 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1608 "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1609 [(set_attr "type" "alus_ext")]
1612 (define_insn "*subs_<optab><mode>_multp2"
1613 [(set (reg:CC_NZ CC_REGNUM)
1615 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1617 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1618 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1619 (match_operand 3 "const_int_operand" "n")
1622 (set (match_operand:GPI 0 "register_operand" "=r")
1623 (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1624 (mult:GPI (match_dup 1) (match_dup 2))
1627 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1628 "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1629 [(set_attr "type" "alus_ext")]
1632 (define_insn "*add<mode>3nr_compare0"
1633 [(set (reg:CC_NZ CC_REGNUM)
1635 (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1636 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1643 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1646 (define_insn "*compare_neg<mode>"
1647 [(set (reg:CC_Z CC_REGNUM)
1649 (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1650 (match_operand:GPI 1 "register_operand" "r")))]
1652 "cmn\\t%<w>1, %<w>0"
1653 [(set_attr "type" "alus_sreg")]
1656 (define_insn "*add_<shift>_<mode>"
1657 [(set (match_operand:GPI 0 "register_operand" "=r")
1658 (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1659 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1660 (match_operand:GPI 3 "register_operand" "r")))]
1662 "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1663 [(set_attr "type" "alu_shift_imm")]
1666 ;; zero_extend version of above
1667 (define_insn "*add_<shift>_si_uxtw"
1668 [(set (match_operand:DI 0 "register_operand" "=r")
1670 (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1671 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1672 (match_operand:SI 3 "register_operand" "r"))))]
1674 "add\\t%w0, %w3, %w1, <shift> %2"
1675 [(set_attr "type" "alu_shift_imm")]
1678 (define_insn "*add_mul_imm_<mode>"
1679 [(set (match_operand:GPI 0 "register_operand" "=r")
1680 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1681 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1682 (match_operand:GPI 3 "register_operand" "r")))]
1684 "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1685 [(set_attr "type" "alu_shift_imm")]
1688 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1689 [(set (match_operand:GPI 0 "register_operand" "=rk")
1690 (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1691 (match_operand:GPI 2 "register_operand" "r")))]
1693 "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1694 [(set_attr "type" "alu_ext")]
1697 ;; zero_extend version of above
1698 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1699 [(set (match_operand:DI 0 "register_operand" "=rk")
1701 (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1702 (match_operand:GPI 2 "register_operand" "r"))))]
1704 "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1705 [(set_attr "type" "alu_ext")]
1708 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1709 [(set (match_operand:GPI 0 "register_operand" "=rk")
1710 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1711 (match_operand:ALLX 1 "register_operand" "r"))
1712 (match_operand 2 "aarch64_imm3" "Ui3"))
1713 (match_operand:GPI 3 "register_operand" "r")))]
1715 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1716 [(set_attr "type" "alu_ext")]
1719 ;; zero_extend version of above
1720 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1721 [(set (match_operand:DI 0 "register_operand" "=rk")
1723 (plus:SI (ashift:SI (ANY_EXTEND:SI
1724 (match_operand:SHORT 1 "register_operand" "r"))
1725 (match_operand 2 "aarch64_imm3" "Ui3"))
1726 (match_operand:SI 3 "register_operand" "r"))))]
1728 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1729 [(set_attr "type" "alu_ext")]
1732 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1733 [(set (match_operand:GPI 0 "register_operand" "=rk")
1734 (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1735 (match_operand:ALLX 1 "register_operand" "r"))
1736 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1737 (match_operand:GPI 3 "register_operand" "r")))]
1739 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1740 [(set_attr "type" "alu_ext")]
1743 ;; zero_extend version of above
1744 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1745 [(set (match_operand:DI 0 "register_operand" "=rk")
1746 (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1747 (match_operand:SHORT 1 "register_operand" "r"))
1748 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1749 (match_operand:SI 3 "register_operand" "r"))))]
1751 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1752 [(set_attr "type" "alu_ext")]
1755 (define_insn "*add_<optab><mode>_multp2"
1756 [(set (match_operand:GPI 0 "register_operand" "=rk")
1757 (plus:GPI (ANY_EXTRACT:GPI
1758 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1759 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1760 (match_operand 3 "const_int_operand" "n")
1762 (match_operand:GPI 4 "register_operand" "r")))]
1763 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1764 "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1765 [(set_attr "type" "alu_ext")]
1768 ;; zero_extend version of above
1769 (define_insn "*add_<optab>si_multp2_uxtw"
1770 [(set (match_operand:DI 0 "register_operand" "=rk")
1772 (plus:SI (ANY_EXTRACT:SI
1773 (mult:SI (match_operand:SI 1 "register_operand" "r")
1774 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1775 (match_operand 3 "const_int_operand" "n")
1777 (match_operand:SI 4 "register_operand" "r"))))]
1778 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1779 "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1780 [(set_attr "type" "alu_ext")]
1783 (define_insn "add<mode>3_carryin"
1785 (match_operand:GPI 0 "register_operand" "=r")
1786 (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1788 (match_operand:GPI 1 "register_operand" "r")
1789 (match_operand:GPI 2 "register_operand" "r"))))]
1791 "adc\\t%<w>0, %<w>1, %<w>2"
1792 [(set_attr "type" "adc_reg")]
1795 ;; zero_extend version of above
1796 (define_insn "*addsi3_carryin_uxtw"
1798 (match_operand:DI 0 "register_operand" "=r")
1800 (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1802 (match_operand:SI 1 "register_operand" "r")
1803 (match_operand:SI 2 "register_operand" "r")))))]
1805 "adc\\t%w0, %w1, %w2"
1806 [(set_attr "type" "adc_reg")]
1809 (define_insn "*add<mode>3_carryin_alt1"
1811 (match_operand:GPI 0 "register_operand" "=r")
1813 (match_operand:GPI 1 "register_operand" "r")
1814 (match_operand:GPI 2 "register_operand" "r"))
1815 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1817 "adc\\t%<w>0, %<w>1, %<w>2"
1818 [(set_attr "type" "adc_reg")]
1821 ;; zero_extend version of above
1822 (define_insn "*addsi3_carryin_alt1_uxtw"
1824 (match_operand:DI 0 "register_operand" "=r")
1827 (match_operand:SI 1 "register_operand" "r")
1828 (match_operand:SI 2 "register_operand" "r"))
1829 (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1831 "adc\\t%w0, %w1, %w2"
1832 [(set_attr "type" "adc_reg")]
1835 (define_insn "*add<mode>3_carryin_alt2"
1837 (match_operand:GPI 0 "register_operand" "=r")
1839 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1840 (match_operand:GPI 1 "register_operand" "r"))
1841 (match_operand:GPI 2 "register_operand" "r")))]
1843 "adc\\t%<w>0, %<w>1, %<w>2"
1844 [(set_attr "type" "adc_reg")]
1847 ;; zero_extend version of above
1848 (define_insn "*addsi3_carryin_alt2_uxtw"
1850 (match_operand:DI 0 "register_operand" "=r")
1853 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1854 (match_operand:SI 1 "register_operand" "r"))
1855 (match_operand:SI 2 "register_operand" "r"))))]
1857 "adc\\t%w0, %w1, %w2"
1858 [(set_attr "type" "adc_reg")]
1861 (define_insn "*add<mode>3_carryin_alt3"
1863 (match_operand:GPI 0 "register_operand" "=r")
1865 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1866 (match_operand:GPI 2 "register_operand" "r"))
1867 (match_operand:GPI 1 "register_operand" "r")))]
1869 "adc\\t%<w>0, %<w>1, %<w>2"
1870 [(set_attr "type" "adc_reg")]
1873 ;; zero_extend version of above
1874 (define_insn "*addsi3_carryin_alt3_uxtw"
1876 (match_operand:DI 0 "register_operand" "=r")
1879 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1880 (match_operand:SI 2 "register_operand" "r"))
1881 (match_operand:SI 1 "register_operand" "r"))))]
1883 "adc\\t%w0, %w1, %w2"
1884 [(set_attr "type" "adc_reg")]
1887 (define_insn "*add_uxt<mode>_multp2"
1888 [(set (match_operand:GPI 0 "register_operand" "=rk")
1890 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1891 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1892 (match_operand 3 "const_int_operand" "n"))
1893 (match_operand:GPI 4 "register_operand" "r")))]
1894 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1896 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1897 INTVAL (operands[3])));
1898 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1899 [(set_attr "type" "alu_ext")]
1902 ;; zero_extend version of above
1903 (define_insn "*add_uxtsi_multp2_uxtw"
1904 [(set (match_operand:DI 0 "register_operand" "=rk")
1907 (mult:SI (match_operand:SI 1 "register_operand" "r")
1908 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1909 (match_operand 3 "const_int_operand" "n"))
1910 (match_operand:SI 4 "register_operand" "r"))))]
1911 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1913 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1914 INTVAL (operands[3])));
1915 return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1916 [(set_attr "type" "alu_ext")]
1919 (define_insn "subsi3"
1920 [(set (match_operand:SI 0 "register_operand" "=rk")
1921 (minus:SI (match_operand:SI 1 "register_operand" "rk")
1922 (match_operand:SI 2 "register_operand" "r")))]
1924 "sub\\t%w0, %w1, %w2"
1925 [(set_attr "type" "alu_sreg")]
1928 ;; zero_extend version of above
1929 (define_insn "*subsi3_uxtw"
1930 [(set (match_operand:DI 0 "register_operand" "=rk")
1932 (minus:SI (match_operand:SI 1 "register_operand" "rk")
1933 (match_operand:SI 2 "register_operand" "r"))))]
1935 "sub\\t%w0, %w1, %w2"
1936 [(set_attr "type" "alu_sreg")]
1939 (define_insn "subdi3"
1940 [(set (match_operand:DI 0 "register_operand" "=rk,w")
1941 (minus:DI (match_operand:DI 1 "register_operand" "rk,w")
1942 (match_operand:DI 2 "register_operand" "r,w")))]
1946 sub\\t%d0, %d1, %d2"
1947 [(set_attr "type" "alu_sreg, neon_sub")
1948 (set_attr "simd" "*,yes")]
1951 (define_expand "subti3"
1952 [(set (match_operand:TI 0 "register_operand" "")
1953 (minus:TI (match_operand:TI 1 "register_operand" "")
1954 (match_operand:TI 2 "register_operand" "")))]
1957 rtx low = gen_reg_rtx (DImode);
1958 emit_insn (gen_subdi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1959 gen_lowpart (DImode, operands[2])));
1961 rtx high = gen_reg_rtx (DImode);
1962 emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]),
1963 gen_highpart (DImode, operands[2])));
1965 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1966 emit_move_insn (gen_highpart (DImode, operands[0]), high);
1970 (define_insn "sub<mode>3_compare0"
1971 [(set (reg:CC_NZ CC_REGNUM)
1972 (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1973 (match_operand:GPI 2 "register_operand" "r"))
1975 (set (match_operand:GPI 0 "register_operand" "=r")
1976 (minus:GPI (match_dup 1) (match_dup 2)))]
1978 "subs\\t%<w>0, %<w>1, %<w>2"
1979 [(set_attr "type" "alus_sreg")]
1982 ;; zero_extend version of above
1983 (define_insn "*subsi3_compare0_uxtw"
1984 [(set (reg:CC_NZ CC_REGNUM)
1985 (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1986 (match_operand:SI 2 "register_operand" "r"))
1988 (set (match_operand:DI 0 "register_operand" "=r")
1989 (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1991 "subs\\t%w0, %w1, %w2"
1992 [(set_attr "type" "alus_sreg")]
1995 (define_insn "*sub_<shift>_<mode>"
1996 [(set (match_operand:GPI 0 "register_operand" "=r")
1997 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1999 (match_operand:GPI 1 "register_operand" "r")
2000 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2002 "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
2003 [(set_attr "type" "alu_shift_imm")]
2006 ;; zero_extend version of above
2007 (define_insn "*sub_<shift>_si_uxtw"
2008 [(set (match_operand:DI 0 "register_operand" "=r")
2010 (minus:SI (match_operand:SI 3 "register_operand" "r")
2012 (match_operand:SI 1 "register_operand" "r")
2013 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2015 "sub\\t%w0, %w3, %w1, <shift> %2"
2016 [(set_attr "type" "alu_shift_imm")]
2019 (define_insn "*sub_mul_imm_<mode>"
2020 [(set (match_operand:GPI 0 "register_operand" "=r")
2021 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2023 (match_operand:GPI 1 "register_operand" "r")
2024 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2026 "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
2027 [(set_attr "type" "alu_shift_imm")]
2030 ;; zero_extend version of above
2031 (define_insn "*sub_mul_imm_si_uxtw"
2032 [(set (match_operand:DI 0 "register_operand" "=r")
2034 (minus:SI (match_operand:SI 3 "register_operand" "r")
2036 (match_operand:SI 1 "register_operand" "r")
2037 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2039 "sub\\t%w0, %w3, %w1, lsl %p2"
2040 [(set_attr "type" "alu_shift_imm")]
2043 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
2044 [(set (match_operand:GPI 0 "register_operand" "=rk")
2045 (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
2047 (match_operand:ALLX 2 "register_operand" "r"))))]
2049 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
2050 [(set_attr "type" "alu_ext")]
2053 ;; zero_extend version of above
2054 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
2055 [(set (match_operand:DI 0 "register_operand" "=rk")
2057 (minus:SI (match_operand:SI 1 "register_operand" "rk")
2059 (match_operand:SHORT 2 "register_operand" "r")))))]
2061 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
2062 [(set_attr "type" "alu_ext")]
2065 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
2066 [(set (match_operand:GPI 0 "register_operand" "=rk")
2067 (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
2068 (ashift:GPI (ANY_EXTEND:GPI
2069 (match_operand:ALLX 2 "register_operand" "r"))
2070 (match_operand 3 "aarch64_imm3" "Ui3"))))]
2072 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
2073 [(set_attr "type" "alu_ext")]
2076 ;; zero_extend version of above
2077 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
2078 [(set (match_operand:DI 0 "register_operand" "=rk")
2080 (minus:SI (match_operand:SI 1 "register_operand" "rk")
2081 (ashift:SI (ANY_EXTEND:SI
2082 (match_operand:SHORT 2 "register_operand" "r"))
2083 (match_operand 3 "aarch64_imm3" "Ui3")))))]
2085 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
2086 [(set_attr "type" "alu_ext")]
2089 (define_insn "*sub_<optab><mode>_multp2"
2090 [(set (match_operand:GPI 0 "register_operand" "=rk")
2091 (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
2093 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2094 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2095 (match_operand 3 "const_int_operand" "n")
2097 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
2098 "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
2099 [(set_attr "type" "alu_ext")]
2102 ;; zero_extend version of above
2103 (define_insn "*sub_<optab>si_multp2_uxtw"
2104 [(set (match_operand:DI 0 "register_operand" "=rk")
2106 (minus:SI (match_operand:SI 4 "register_operand" "rk")
2108 (mult:SI (match_operand:SI 1 "register_operand" "r")
2109 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2110 (match_operand 3 "const_int_operand" "n")
2112 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
2113 "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
2114 [(set_attr "type" "alu_ext")]
2117 (define_insn "sub<mode>3_carryin"
2119 (match_operand:GPI 0 "register_operand" "=r")
2120 (minus:GPI (minus:GPI
2121 (match_operand:GPI 1 "register_operand" "r")
2122 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2123 (match_operand:GPI 2 "register_operand" "r")))]
2125 "sbc\\t%<w>0, %<w>1, %<w>2"
2126 [(set_attr "type" "adc_reg")]
2129 ;; zero_extend version of the above
2130 (define_insn "*subsi3_carryin_uxtw"
2132 (match_operand:DI 0 "register_operand" "=r")
2135 (match_operand:SI 1 "register_operand" "r")
2136 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2137 (match_operand:SI 2 "register_operand" "r"))))]
2139 "sbc\\t%w0, %w1, %w2"
2140 [(set_attr "type" "adc_reg")]
2143 (define_insn "*sub_uxt<mode>_multp2"
2144 [(set (match_operand:GPI 0 "register_operand" "=rk")
2145 (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
2147 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2148 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2149 (match_operand 3 "const_int_operand" "n"))))]
2150 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2152 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2153 INTVAL (operands[3])));
2154 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
2155 [(set_attr "type" "alu_ext")]
2158 ;; zero_extend version of above
2159 (define_insn "*sub_uxtsi_multp2_uxtw"
2160 [(set (match_operand:DI 0 "register_operand" "=rk")
2162 (minus:SI (match_operand:SI 4 "register_operand" "rk")
2164 (mult:SI (match_operand:SI 1 "register_operand" "r")
2165 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2166 (match_operand 3 "const_int_operand" "n")))))]
2167 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2169 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2170 INTVAL (operands[3])));
2171 return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
2172 [(set_attr "type" "alu_ext")]
2175 (define_insn_and_split "absdi2"
2176 [(set (match_operand:DI 0 "register_operand" "=&r,w")
2177 (abs:DI (match_operand:DI 1 "register_operand" "r,w")))]
2183 && GP_REGNUM_P (REGNO (operands[0]))
2184 && GP_REGNUM_P (REGNO (operands[1]))"
2187 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2188 gen_rtx_XOR (DImode,
2189 gen_rtx_ASHIFTRT (DImode,
2193 emit_insn (gen_rtx_SET (VOIDmode,
2195 gen_rtx_MINUS (DImode,
2197 gen_rtx_ASHIFTRT (DImode,
2202 [(set_attr "type" "alu_sreg")
2203 (set_attr "simd" "no,yes")]
2206 (define_insn "neg<mode>2"
2207 [(set (match_operand:GPI 0 "register_operand" "=r,w")
2208 (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
2212 neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
2213 [(set_attr "type" "alu_sreg, neon_neg<q>")
2214 (set_attr "simd" "*,yes")]
2217 ;; zero_extend version of above
2218 (define_insn "*negsi2_uxtw"
2219 [(set (match_operand:DI 0 "register_operand" "=r")
2220 (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
2223 [(set_attr "type" "alu_sreg")]
2226 (define_insn "*ngc<mode>"
2227 [(set (match_operand:GPI 0 "register_operand" "=r")
2228 (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2229 (match_operand:GPI 1 "register_operand" "r")))]
2231 "ngc\\t%<w>0, %<w>1"
2232 [(set_attr "type" "adc_reg")]
2235 (define_insn "*ngcsi_uxtw"
2236 [(set (match_operand:DI 0 "register_operand" "=r")
2238 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2239 (match_operand:SI 1 "register_operand" "r"))))]
2242 [(set_attr "type" "adc_reg")]
2245 (define_insn "*neg<mode>2_compare0"
2246 [(set (reg:CC_NZ CC_REGNUM)
2247 (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2249 (set (match_operand:GPI 0 "register_operand" "=r")
2250 (neg:GPI (match_dup 1)))]
2252 "negs\\t%<w>0, %<w>1"
2253 [(set_attr "type" "alus_sreg")]
2256 ;; zero_extend version of above
2257 (define_insn "*negsi2_compare0_uxtw"
2258 [(set (reg:CC_NZ CC_REGNUM)
2259 (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
2261 (set (match_operand:DI 0 "register_operand" "=r")
2262 (zero_extend:DI (neg:SI (match_dup 1))))]
2265 [(set_attr "type" "alus_sreg")]
2268 (define_insn "*neg_<shift><mode>3_compare0"
2269 [(set (reg:CC_NZ CC_REGNUM)
2271 (neg:GPI (ASHIFT:GPI
2272 (match_operand:GPI 1 "register_operand" "r")
2273 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2275 (set (match_operand:GPI 0 "register_operand" "=r")
2276 (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2278 "negs\\t%<w>0, %<w>1, <shift> %2"
2279 [(set_attr "type" "alus_shift_imm")]
2282 (define_insn "*neg_<shift>_<mode>2"
2283 [(set (match_operand:GPI 0 "register_operand" "=r")
2284 (neg:GPI (ASHIFT:GPI
2285 (match_operand:GPI 1 "register_operand" "r")
2286 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2288 "neg\\t%<w>0, %<w>1, <shift> %2"
2289 [(set_attr "type" "alu_shift_imm")]
2292 ;; zero_extend version of above
2293 (define_insn "*neg_<shift>_si2_uxtw"
2294 [(set (match_operand:DI 0 "register_operand" "=r")
2297 (match_operand:SI 1 "register_operand" "r")
2298 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2300 "neg\\t%w0, %w1, <shift> %2"
2301 [(set_attr "type" "alu_shift_imm")]
2304 (define_insn "*neg_mul_imm_<mode>2"
2305 [(set (match_operand:GPI 0 "register_operand" "=r")
2307 (match_operand:GPI 1 "register_operand" "r")
2308 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2310 "neg\\t%<w>0, %<w>1, lsl %p2"
2311 [(set_attr "type" "alu_shift_imm")]
2314 ;; zero_extend version of above
2315 (define_insn "*neg_mul_imm_si2_uxtw"
2316 [(set (match_operand:DI 0 "register_operand" "=r")
2319 (match_operand:SI 1 "register_operand" "r")
2320 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2322 "neg\\t%w0, %w1, lsl %p2"
2323 [(set_attr "type" "alu_shift_imm")]
2326 (define_insn "mul<mode>3"
2327 [(set (match_operand:GPI 0 "register_operand" "=r")
2328 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2329 (match_operand:GPI 2 "register_operand" "r")))]
2331 "mul\\t%<w>0, %<w>1, %<w>2"
2332 [(set_attr "type" "mul")]
2335 ;; zero_extend version of above
2336 (define_insn "*mulsi3_uxtw"
2337 [(set (match_operand:DI 0 "register_operand" "=r")
2339 (mult:SI (match_operand:SI 1 "register_operand" "r")
2340 (match_operand:SI 2 "register_operand" "r"))))]
2342 "mul\\t%w0, %w1, %w2"
2343 [(set_attr "type" "mul")]
2346 (define_insn "madd<mode>"
2347 [(set (match_operand:GPI 0 "register_operand" "=r")
2348 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2349 (match_operand:GPI 2 "register_operand" "r"))
2350 (match_operand:GPI 3 "register_operand" "r")))]
2352 "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2353 [(set_attr "type" "mla")]
2356 ;; zero_extend version of above
2357 (define_insn "*maddsi_uxtw"
2358 [(set (match_operand:DI 0 "register_operand" "=r")
2360 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2361 (match_operand:SI 2 "register_operand" "r"))
2362 (match_operand:SI 3 "register_operand" "r"))))]
2364 "madd\\t%w0, %w1, %w2, %w3"
2365 [(set_attr "type" "mla")]
2368 (define_insn "*msub<mode>"
2369 [(set (match_operand:GPI 0 "register_operand" "=r")
2370 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2371 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2372 (match_operand:GPI 2 "register_operand" "r"))))]
2375 "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2376 [(set_attr "type" "mla")]
2379 ;; zero_extend version of above
2380 (define_insn "*msubsi_uxtw"
2381 [(set (match_operand:DI 0 "register_operand" "=r")
2383 (minus:SI (match_operand:SI 3 "register_operand" "r")
2384 (mult:SI (match_operand:SI 1 "register_operand" "r")
2385 (match_operand:SI 2 "register_operand" "r")))))]
2388 "msub\\t%w0, %w1, %w2, %w3"
2389 [(set_attr "type" "mla")]
2392 (define_insn "*mul<mode>_neg"
2393 [(set (match_operand:GPI 0 "register_operand" "=r")
2394 (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2395 (match_operand:GPI 2 "register_operand" "r")))]
2398 "mneg\\t%<w>0, %<w>1, %<w>2"
2399 [(set_attr "type" "mul")]
2402 ;; zero_extend version of above
2403 (define_insn "*mulsi_neg_uxtw"
2404 [(set (match_operand:DI 0 "register_operand" "=r")
2406 (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2407 (match_operand:SI 2 "register_operand" "r"))))]
2410 "mneg\\t%w0, %w1, %w2"
2411 [(set_attr "type" "mul")]
2414 (define_insn "<su_optab>mulsidi3"
2415 [(set (match_operand:DI 0 "register_operand" "=r")
2416 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2417 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2419 "<su>mull\\t%0, %w1, %w2"
2420 [(set_attr "type" "<su>mull")]
2423 (define_insn "<su_optab>maddsidi4"
2424 [(set (match_operand:DI 0 "register_operand" "=r")
2426 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2427 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2428 (match_operand:DI 3 "register_operand" "r")))]
2430 "<su>maddl\\t%0, %w1, %w2, %3"
2431 [(set_attr "type" "<su>mlal")]
2434 (define_insn "<su_optab>msubsidi4"
2435 [(set (match_operand:DI 0 "register_operand" "=r")
2437 (match_operand:DI 3 "register_operand" "r")
2438 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2440 (match_operand:SI 2 "register_operand" "r")))))]
2442 "<su>msubl\\t%0, %w1, %w2, %3"
2443 [(set_attr "type" "<su>mlal")]
2446 (define_insn "*<su_optab>mulsidi_neg"
2447 [(set (match_operand:DI 0 "register_operand" "=r")
2449 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2450 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2452 "<su>mnegl\\t%0, %w1, %w2"
2453 [(set_attr "type" "<su>mull")]
2456 (define_expand "<su_optab>mulditi3"
2457 [(set (match_operand:TI 0 "register_operand")
2458 (mult:TI (ANY_EXTEND:TI (match_operand:DI 1 "register_operand"))
2459 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand"))))]
2462 rtx low = gen_reg_rtx (DImode);
2463 emit_insn (gen_muldi3 (low, operands[1], operands[2]));
2465 rtx high = gen_reg_rtx (DImode);
2466 emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2]));
2468 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2469 emit_move_insn (gen_highpart (DImode, operands[0]), high);
2473 ;; The default expansion of multi3 using umuldi3_highpart will perform
2474 ;; the additions in an order that fails to combine into two madd insns.
2475 (define_expand "multi3"
2476 [(set (match_operand:TI 0 "register_operand")
2477 (mult:TI (match_operand:TI 1 "register_operand")
2478 (match_operand:TI 2 "register_operand")))]
2481 rtx l0 = gen_reg_rtx (DImode);
2482 rtx l1 = gen_lowpart (DImode, operands[1]);
2483 rtx l2 = gen_lowpart (DImode, operands[2]);
2484 rtx h0 = gen_reg_rtx (DImode);
2485 rtx h1 = gen_highpart (DImode, operands[1]);
2486 rtx h2 = gen_highpart (DImode, operands[2]);
2488 emit_insn (gen_muldi3 (l0, l1, l2));
2489 emit_insn (gen_umuldi3_highpart (h0, l1, l2));
2490 emit_insn (gen_madddi (h0, h1, l2, h0));
2491 emit_insn (gen_madddi (h0, l1, h2, h0));
2493 emit_move_insn (gen_lowpart (DImode, operands[0]), l0);
2494 emit_move_insn (gen_highpart (DImode, operands[0]), h0);
2498 (define_insn "<su>muldi3_highpart"
2499 [(set (match_operand:DI 0 "register_operand" "=r")
2503 (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2504 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2507 "<su>mulh\\t%0, %1, %2"
2508 [(set_attr "type" "<su>mull")]
2511 (define_insn "<su_optab>div<mode>3"
2512 [(set (match_operand:GPI 0 "register_operand" "=r")
2513 (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2514 (match_operand:GPI 2 "register_operand" "r")))]
2516 "<su>div\\t%<w>0, %<w>1, %<w>2"
2517 [(set_attr "type" "<su>div")]
2520 ;; zero_extend version of above
2521 (define_insn "*<su_optab>divsi3_uxtw"
2522 [(set (match_operand:DI 0 "register_operand" "=r")
2524 (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2525 (match_operand:SI 2 "register_operand" "r"))))]
2527 "<su>div\\t%w0, %w1, %w2"
2528 [(set_attr "type" "<su>div")]
2531 ;; -------------------------------------------------------------------
2533 ;; -------------------------------------------------------------------
2535 (define_insn "*cmp<mode>"
2536 [(set (reg:CC CC_REGNUM)
2537 (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2538 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2544 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
2547 (define_insn "*cmp<mode>"
2548 [(set (reg:CCFP CC_REGNUM)
2549 (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2550 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2554 fcmp\\t%<s>0, %<s>1"
2555 [(set_attr "type" "fcmp<s>")]
2558 (define_insn "*cmpe<mode>"
2559 [(set (reg:CCFPE CC_REGNUM)
2560 (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2561 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2565 fcmpe\\t%<s>0, %<s>1"
2566 [(set_attr "type" "fcmp<s>")]
2569 (define_insn "*cmp_swp_<shift>_reg<mode>"
2570 [(set (reg:CC_SWP CC_REGNUM)
2571 (compare:CC_SWP (ASHIFT:GPI
2572 (match_operand:GPI 0 "register_operand" "r")
2573 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2574 (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2576 "cmp\\t%<w>2, %<w>0, <shift> %1"
2577 [(set_attr "type" "alus_shift_imm")]
2580 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2581 [(set (reg:CC_SWP CC_REGNUM)
2582 (compare:CC_SWP (ANY_EXTEND:GPI
2583 (match_operand:ALLX 0 "register_operand" "r"))
2584 (match_operand:GPI 1 "register_operand" "r")))]
2586 "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2587 [(set_attr "type" "alus_ext")]
2590 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2591 [(set (reg:CC_SWP CC_REGNUM)
2592 (compare:CC_SWP (ashift:GPI
2594 (match_operand:ALLX 0 "register_operand" "r"))
2595 (match_operand 1 "aarch64_imm3" "Ui3"))
2596 (match_operand:GPI 2 "register_operand" "r")))]
2598 "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2599 [(set_attr "type" "alus_ext")]
2602 ;; -------------------------------------------------------------------
2603 ;; Store-flag and conditional select insns
2604 ;; -------------------------------------------------------------------
2606 (define_expand "cstore<mode>4"
2607 [(set (match_operand:SI 0 "register_operand" "")
2608 (match_operator:SI 1 "aarch64_comparison_operator"
2609 [(match_operand:GPI 2 "register_operand" "")
2610 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2613 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2615 operands[3] = const0_rtx;
2619 (define_expand "cstorecc4"
2620 [(set (match_operand:SI 0 "register_operand")
2621 (match_operator 1 "aarch64_comparison_operator"
2622 [(match_operand 2 "ccmp_cc_register")
2623 (match_operand 3 "const0_operand")]))]
2626 emit_insn (gen_rtx_SET (SImode, operands[0], operands[1]));
2631 (define_expand "cstore<mode>4"
2632 [(set (match_operand:SI 0 "register_operand" "")
2633 (match_operator:SI 1 "aarch64_comparison_operator"
2634 [(match_operand:GPF 2 "register_operand" "")
2635 (match_operand:GPF 3 "register_operand" "")]))]
2638 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2640 operands[3] = const0_rtx;
2644 (define_insn "*cstore<mode>_insn"
2645 [(set (match_operand:ALLI 0 "register_operand" "=r")
2646 (match_operator:ALLI 1 "aarch64_comparison_operator"
2647 [(match_operand 2 "cc_register" "") (const_int 0)]))]
2650 [(set_attr "type" "csel")]
2653 ;; zero_extend version of the above
2654 (define_insn "*cstoresi_insn_uxtw"
2655 [(set (match_operand:DI 0 "register_operand" "=r")
2657 (match_operator:SI 1 "aarch64_comparison_operator"
2658 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2661 [(set_attr "type" "csel")]
2664 (define_insn "cstore<mode>_neg"
2665 [(set (match_operand:ALLI 0 "register_operand" "=r")
2666 (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2667 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2669 "csetm\\t%<w>0, %m1"
2670 [(set_attr "type" "csel")]
2673 ;; zero_extend version of the above
2674 (define_insn "*cstoresi_neg_uxtw"
2675 [(set (match_operand:DI 0 "register_operand" "=r")
2677 (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2678 [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2681 [(set_attr "type" "csel")]
2684 (define_expand "cmov<mode>6"
2685 [(set (match_operand:GPI 0 "register_operand" "")
2687 (match_operator 1 "aarch64_comparison_operator"
2688 [(match_operand:GPI 2 "register_operand" "")
2689 (match_operand:GPI 3 "aarch64_plus_operand" "")])
2690 (match_operand:GPI 4 "register_operand" "")
2691 (match_operand:GPI 5 "register_operand" "")))]
2694 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2696 operands[3] = const0_rtx;
2700 (define_expand "cmov<mode>6"
2701 [(set (match_operand:GPF 0 "register_operand" "")
2703 (match_operator 1 "aarch64_comparison_operator"
2704 [(match_operand:GPF 2 "register_operand" "")
2705 (match_operand:GPF 3 "register_operand" "")])
2706 (match_operand:GPF 4 "register_operand" "")
2707 (match_operand:GPF 5 "register_operand" "")))]
2710 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2712 operands[3] = const0_rtx;
2716 (define_insn "*cmov<mode>_insn"
2717 [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2719 (match_operator 1 "aarch64_comparison_operator"
2720 [(match_operand 2 "cc_register" "") (const_int 0)])
2721 (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2722 (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2723 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2724 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2725 ;; Final two alternatives should be unreachable, but included for completeness
2727 csel\\t%<w>0, %<w>3, %<w>4, %m1
2728 csinv\\t%<w>0, %<w>3, <w>zr, %m1
2729 csinv\\t%<w>0, %<w>4, <w>zr, %M1
2730 csinc\\t%<w>0, %<w>3, <w>zr, %m1
2731 csinc\\t%<w>0, %<w>4, <w>zr, %M1
2734 [(set_attr "type" "csel")]
2737 ;; zero_extend version of above
2738 (define_insn "*cmovsi_insn_uxtw"
2739 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2742 (match_operator 1 "aarch64_comparison_operator"
2743 [(match_operand 2 "cc_register" "") (const_int 0)])
2744 (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2745 (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2746 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2747 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2748 ;; Final two alternatives should be unreachable, but included for completeness
2750 csel\\t%w0, %w3, %w4, %m1
2751 csinv\\t%w0, %w3, wzr, %m1
2752 csinv\\t%w0, %w4, wzr, %M1
2753 csinc\\t%w0, %w3, wzr, %m1
2754 csinc\\t%w0, %w4, wzr, %M1
2757 [(set_attr "type" "csel")]
2760 (define_insn "*cmov<mode>_insn"
2761 [(set (match_operand:GPF 0 "register_operand" "=w")
2763 (match_operator 1 "aarch64_comparison_operator"
2764 [(match_operand 2 "cc_register" "") (const_int 0)])
2765 (match_operand:GPF 3 "register_operand" "w")
2766 (match_operand:GPF 4 "register_operand" "w")))]
2768 "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2769 [(set_attr "type" "fcsel")]
2772 (define_expand "mov<mode>cc"
2773 [(set (match_operand:ALLI 0 "register_operand" "")
2774 (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2775 (match_operand:ALLI 2 "register_operand" "")
2776 (match_operand:ALLI 3 "register_operand" "")))]
2779 enum rtx_code code = GET_CODE (operands[1]);
2781 if (code == UNEQ || code == LTGT)
2784 if (!ccmp_cc_register (XEXP (operands[1], 0),
2785 GET_MODE (XEXP (operands[1], 0))))
2788 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2789 XEXP (operands[1], 1));
2790 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2795 (define_expand "mov<GPF:mode><GPI:mode>cc"
2796 [(set (match_operand:GPI 0 "register_operand" "")
2797 (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2798 (match_operand:GPF 2 "register_operand" "")
2799 (match_operand:GPF 3 "register_operand" "")))]
2803 enum rtx_code code = GET_CODE (operands[1]);
2805 if (code == UNEQ || code == LTGT)
2808 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2809 XEXP (operands[1], 1));
2810 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2814 (define_expand "mov<mode>cc"
2815 [(set (match_operand:GPF 0 "register_operand" "")
2816 (if_then_else:GPF (match_operand 1 "aarch64_comparison_operator" "")
2817 (match_operand:GPF 2 "register_operand" "")
2818 (match_operand:GPF 3 "register_operand" "")))]
2822 enum rtx_code code = GET_CODE (operands[1]);
2824 if (code == UNEQ || code == LTGT)
2827 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2828 XEXP (operands[1], 1));
2829 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2834 ;; CRC32 instructions.
2835 (define_insn "aarch64_<crc_variant>"
2836 [(set (match_operand:SI 0 "register_operand" "=r")
2837 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2838 (match_operand:<crc_mode> 2 "register_operand" "r")]
2842 if (GET_MODE_BITSIZE (GET_MODE (operands[2])) >= 64)
2843 return "<crc_variant>\\t%w0, %w1, %x2";
2845 return "<crc_variant>\\t%w0, %w1, %w2";
2847 [(set_attr "type" "crc")]
2850 (define_insn "*csinc2<mode>_insn"
2851 [(set (match_operand:GPI 0 "register_operand" "=r")
2852 (plus:GPI (match_operand 2 "aarch64_comparison_operation" "")
2853 (match_operand:GPI 1 "register_operand" "r")))]
2855 "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2856 [(set_attr "type" "csel")]
2859 (define_insn "csinc3<mode>_insn"
2860 [(set (match_operand:GPI 0 "register_operand" "=r")
2862 (match_operand 1 "aarch64_comparison_operation" "")
2863 (plus:GPI (match_operand:GPI 2 "register_operand" "r")
2865 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2867 "csinc\\t%<w>0, %<w>3, %<w>2, %M1"
2868 [(set_attr "type" "csel")]
2871 (define_insn "*csinv3<mode>_insn"
2872 [(set (match_operand:GPI 0 "register_operand" "=r")
2874 (match_operand 1 "aarch64_comparison_operation" "")
2875 (not:GPI (match_operand:GPI 2 "register_operand" "r"))
2876 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2878 "csinv\\t%<w>0, %<w>3, %<w>2, %M1"
2879 [(set_attr "type" "csel")]
2882 (define_insn "*csneg3<mode>_insn"
2883 [(set (match_operand:GPI 0 "register_operand" "=r")
2885 (match_operand 1 "aarch64_comparison_operation" "")
2886 (neg:GPI (match_operand:GPI 2 "register_operand" "r"))
2887 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2889 "csneg\\t%<w>0, %<w>3, %<w>2, %M1"
2890 [(set_attr "type" "csel")]
2893 ;; -------------------------------------------------------------------
2894 ;; Logical operations
2895 ;; -------------------------------------------------------------------
2897 (define_insn "<optab><mode>3"
2898 [(set (match_operand:GPI 0 "register_operand" "=r,rk,w")
2899 (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r,w")
2900 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>,w")))]
2903 <logical>\\t%<w>0, %<w>1, %<w>2
2904 <logical>\\t%<w>0, %<w>1, %<w>2
2905 <logical>\\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
2906 [(set_attr "type" "logic_reg,logic_imm,neon_logic")
2907 (set_attr "simd" "*,*,yes")]
2910 ;; zero_extend version of above
2911 (define_insn "*<optab>si3_uxtw"
2912 [(set (match_operand:DI 0 "register_operand" "=r,rk")
2914 (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2915 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2917 "<logical>\\t%w0, %w1, %w2"
2918 [(set_attr "type" "logic_reg,logic_imm")]
2921 (define_insn "*and<mode>3_compare0"
2922 [(set (reg:CC_NZ CC_REGNUM)
2924 (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2925 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2927 (set (match_operand:GPI 0 "register_operand" "=r,r")
2928 (and:GPI (match_dup 1) (match_dup 2)))]
2930 "ands\\t%<w>0, %<w>1, %<w>2"
2931 [(set_attr "type" "logics_reg,logics_imm")]
2934 ;; zero_extend version of above
2935 (define_insn "*andsi3_compare0_uxtw"
2936 [(set (reg:CC_NZ CC_REGNUM)
2938 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2939 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2941 (set (match_operand:DI 0 "register_operand" "=r,r")
2942 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2944 "ands\\t%w0, %w1, %w2"
2945 [(set_attr "type" "logics_reg,logics_imm")]
2948 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2949 [(set (reg:CC_NZ CC_REGNUM)
2952 (match_operand:GPI 1 "register_operand" "r")
2953 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2954 (match_operand:GPI 3 "register_operand" "r"))
2956 (set (match_operand:GPI 0 "register_operand" "=r")
2957 (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2959 "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2960 [(set_attr "type" "logics_shift_imm")]
2963 ;; zero_extend version of above
2964 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2965 [(set (reg:CC_NZ CC_REGNUM)
2968 (match_operand:SI 1 "register_operand" "r")
2969 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2970 (match_operand:SI 3 "register_operand" "r"))
2972 (set (match_operand:DI 0 "register_operand" "=r")
2973 (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2976 "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2977 [(set_attr "type" "logics_shift_imm")]
2980 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2981 [(set (match_operand:GPI 0 "register_operand" "=r")
2982 (LOGICAL:GPI (SHIFT:GPI
2983 (match_operand:GPI 1 "register_operand" "r")
2984 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2985 (match_operand:GPI 3 "register_operand" "r")))]
2987 "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2988 [(set_attr "type" "logic_shift_imm")]
2991 (define_insn "*<optab>_rol<mode>3"
2992 [(set (match_operand:GPI 0 "register_operand" "=r")
2993 (LOGICAL:GPI (rotate:GPI
2994 (match_operand:GPI 1 "register_operand" "r")
2995 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2996 (match_operand:GPI 3 "register_operand" "r")))]
2998 "<logical>\\t%<w>0, %<w>3, %<w>1, ror (<sizen> - %2)"
2999 [(set_attr "type" "logic_shift_imm")]
3002 ;; zero_extend versions of above
3003 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
3004 [(set (match_operand:DI 0 "register_operand" "=r")
3006 (LOGICAL:SI (SHIFT:SI
3007 (match_operand:SI 1 "register_operand" "r")
3008 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3009 (match_operand:SI 3 "register_operand" "r"))))]
3011 "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3012 [(set_attr "type" "logic_shift_imm")]
3015 (define_insn "*<optab>_rolsi3_uxtw"
3016 [(set (match_operand:DI 0 "register_operand" "=r")
3018 (LOGICAL:SI (rotate:SI
3019 (match_operand:SI 1 "register_operand" "r")
3020 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3021 (match_operand:SI 3 "register_operand" "r"))))]
3023 "<logical>\\t%w0, %w3, %w1, ror (32 - %2)"
3024 [(set_attr "type" "logic_shift_imm")]
3027 (define_insn "one_cmpl<mode>2"
3028 [(set (match_operand:GPI 0 "register_operand" "=r,w")
3029 (not:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
3034 [(set_attr "type" "logic_reg,neon_logic")
3035 (set_attr "simd" "*,yes")]
3038 (define_insn "*one_cmpl_<optab><mode>2"
3039 [(set (match_operand:GPI 0 "register_operand" "=r")
3040 (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
3041 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
3043 "mvn\\t%<w>0, %<w>1, <shift> %2"
3044 [(set_attr "type" "logic_shift_imm")]
3047 ;; Binary logical operators negating one operand, i.e. (a & !b), (a | !b).
3049 (define_insn "*<NLOGICAL:optab>_one_cmpl<mode>3"
3050 [(set (match_operand:GPI 0 "register_operand" "=r,w")
3051 (NLOGICAL:GPI (not:GPI (match_operand:GPI 1 "register_operand" "r,w"))
3052 (match_operand:GPI 2 "register_operand" "r,w")))]
3055 <NLOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1
3056 <NLOGICAL:nlogical>\\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>"
3057 [(set_attr "type" "logic_reg,neon_logic")
3058 (set_attr "simd" "*,yes")]
3061 (define_insn "*<NLOGICAL:optab>_one_cmplsidi3_ze"
3062 [(set (match_operand:DI 0 "register_operand" "=r")
3064 (NLOGICAL:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3065 (match_operand:SI 2 "register_operand" "r"))))]
3067 "<NLOGICAL:nlogical>\\t%w0, %w2, %w1"
3068 [(set_attr "type" "logic_reg")]
3071 (define_insn "*xor_one_cmplsidi3_ze"
3072 [(set (match_operand:DI 0 "register_operand" "=r")
3074 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "r")
3075 (match_operand:SI 2 "register_operand" "r")))))]
3077 "eon\\t%w0, %w1, %w2"
3078 [(set_attr "type" "logic_reg")]
3081 ;; (xor (not a) b) is simplify_rtx-ed down to (not (xor a b)).
3082 ;; eon does not operate on SIMD registers so the vector variant must be split.
3083 (define_insn_and_split "*xor_one_cmpl<mode>3"
3084 [(set (match_operand:GPI 0 "register_operand" "=r,w")
3085 (not:GPI (xor:GPI (match_operand:GPI 1 "register_operand" "r,?w")
3086 (match_operand:GPI 2 "register_operand" "r,w"))))]
3089 eon\\t%<w>0, %<w>1, %<w>2
3091 "reload_completed && FP_REGNUM_P (REGNO (operands[0]))" ;; For SIMD registers.
3092 [(set (match_operand:GPI 0 "register_operand" "=w")
3093 (xor:GPI (match_operand:GPI 1 "register_operand" "w")
3094 (match_operand:GPI 2 "register_operand" "w")))
3095 (set (match_dup 0) (not:GPI (match_dup 0)))]
3097 [(set_attr "type" "logic_reg,multiple")
3098 (set_attr "simd" "*,yes")]
3101 (define_insn "*and_one_cmpl<mode>3_compare0"
3102 [(set (reg:CC_NZ CC_REGNUM)
3105 (match_operand:GPI 1 "register_operand" "r"))
3106 (match_operand:GPI 2 "register_operand" "r"))
3108 (set (match_operand:GPI 0 "register_operand" "=r")
3109 (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
3111 "bics\\t%<w>0, %<w>2, %<w>1"
3112 [(set_attr "type" "logics_reg")]
3115 ;; zero_extend version of above
3116 (define_insn "*and_one_cmplsi3_compare0_uxtw"
3117 [(set (reg:CC_NZ CC_REGNUM)
3120 (match_operand:SI 1 "register_operand" "r"))
3121 (match_operand:SI 2 "register_operand" "r"))
3123 (set (match_operand:DI 0 "register_operand" "=r")
3124 (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
3126 "bics\\t%w0, %w2, %w1"
3127 [(set_attr "type" "logics_reg")]
3130 (define_insn "*and_one_cmpl<mode>3_compare0_no_reuse"
3131 [(set (reg:CC_NZ CC_REGNUM)
3134 (match_operand:GPI 0 "register_operand" "r"))
3135 (match_operand:GPI 1 "register_operand" "r"))
3138 "bics\\t<w>zr, %<w>1, %<w>0"
3139 [(set_attr "type" "logics_reg")]
3142 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
3143 [(set (match_operand:GPI 0 "register_operand" "=r")
3144 (LOGICAL:GPI (not:GPI
3146 (match_operand:GPI 1 "register_operand" "r")
3147 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
3148 (match_operand:GPI 3 "register_operand" "r")))]
3150 "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3151 [(set_attr "type" "logics_shift_imm")]
3154 (define_insn "*eor_one_cmpl_<SHIFT:optab><mode>3_alt"
3155 [(set (match_operand:GPI 0 "register_operand" "=r")
3158 (match_operand:GPI 1 "register_operand" "r")
3159 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3160 (match_operand:GPI 3 "register_operand" "r"))))]
3162 "eon\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3163 [(set_attr "type" "logic_shift_imm")]
3166 ;; Zero-extend version of the above.
3167 (define_insn "*eor_one_cmpl_<SHIFT:optab>sidi3_alt_ze"
3168 [(set (match_operand:DI 0 "register_operand" "=r")
3172 (match_operand:SI 1 "register_operand" "r")
3173 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3174 (match_operand:SI 3 "register_operand" "r")))))]
3176 "eon\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3177 [(set_attr "type" "logic_shift_imm")]
3180 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
3181 [(set (reg:CC_NZ CC_REGNUM)
3185 (match_operand:GPI 1 "register_operand" "r")
3186 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
3187 (match_operand:GPI 3 "register_operand" "r"))
3189 (set (match_operand:GPI 0 "register_operand" "=r")
3192 (match_dup 1) (match_dup 2))) (match_dup 3)))]
3194 "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3195 [(set_attr "type" "logics_shift_imm")]
3198 ;; zero_extend version of above
3199 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
3200 [(set (reg:CC_NZ CC_REGNUM)
3204 (match_operand:SI 1 "register_operand" "r")
3205 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
3206 (match_operand:SI 3 "register_operand" "r"))
3208 (set (match_operand:DI 0 "register_operand" "=r")
3209 (zero_extend:DI (and:SI
3211 (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
3213 "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3214 [(set_attr "type" "logics_shift_imm")]
3217 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0_no_reuse"
3218 [(set (reg:CC_NZ CC_REGNUM)
3222 (match_operand:GPI 0 "register_operand" "r")
3223 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n")))
3224 (match_operand:GPI 2 "register_operand" "r"))
3227 "bics\\t<w>zr, %<w>2, %<w>0, <SHIFT:shift> %1"
3228 [(set_attr "type" "logics_shift_imm")]
3231 (define_insn "clz<mode>2"
3232 [(set (match_operand:GPI 0 "register_operand" "=r")
3233 (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
3235 "clz\\t%<w>0, %<w>1"
3236 [(set_attr "type" "clz")]
3239 (define_expand "ffs<mode>2"
3240 [(match_operand:GPI 0 "register_operand")
3241 (match_operand:GPI 1 "register_operand")]
3244 rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
3245 rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
3247 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3248 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3249 emit_insn (gen_csinc3<mode>_insn (operands[0], x, operands[0], const0_rtx));
3254 (define_insn "clrsb<mode>2"
3255 [(set (match_operand:GPI 0 "register_operand" "=r")
3256 (clrsb:GPI (match_operand:GPI 1 "register_operand" "r")))]
3258 "cls\\t%<w>0, %<w>1"
3259 [(set_attr "type" "clz")]
3262 (define_insn "rbit<mode>2"
3263 [(set (match_operand:GPI 0 "register_operand" "=r")
3264 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
3266 "rbit\\t%<w>0, %<w>1"
3267 [(set_attr "type" "rbit")]
3270 (define_expand "ctz<mode>2"
3271 [(match_operand:GPI 0 "register_operand")
3272 (match_operand:GPI 1 "register_operand")]
3275 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3276 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3281 (define_insn "*and<mode>3nr_compare0"
3282 [(set (reg:CC_NZ CC_REGNUM)
3284 (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
3285 (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
3288 "tst\\t%<w>0, %<w>1"
3289 [(set_attr "type" "logics_reg")]
3292 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
3293 [(set (reg:CC_NZ CC_REGNUM)
3296 (match_operand:GPI 0 "register_operand" "r")
3297 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
3298 (match_operand:GPI 2 "register_operand" "r"))
3301 "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
3302 [(set_attr "type" "logics_shift_imm")]
3305 ;; -------------------------------------------------------------------
3307 ;; -------------------------------------------------------------------
3309 (define_expand "<optab><mode>3"
3310 [(set (match_operand:GPI 0 "register_operand")
3311 (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
3312 (match_operand:QI 2 "nonmemory_operand")))]
3315 if (CONST_INT_P (operands[2]))
3317 operands[2] = GEN_INT (INTVAL (operands[2])
3318 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3320 if (operands[2] == const0_rtx)
3322 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3329 (define_expand "ashl<mode>3"
3330 [(set (match_operand:SHORT 0 "register_operand")
3331 (ashift:SHORT (match_operand:SHORT 1 "register_operand")
3332 (match_operand:QI 2 "nonmemory_operand")))]
3335 if (CONST_INT_P (operands[2]))
3337 operands[2] = GEN_INT (INTVAL (operands[2])
3338 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3340 if (operands[2] == const0_rtx)
3342 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3351 (define_expand "rotr<mode>3"
3352 [(set (match_operand:GPI 0 "register_operand")
3353 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3354 (match_operand:QI 2 "nonmemory_operand")))]
3357 if (CONST_INT_P (operands[2]))
3359 operands[2] = GEN_INT (INTVAL (operands[2])
3360 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3362 if (operands[2] == const0_rtx)
3364 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3371 (define_expand "rotl<mode>3"
3372 [(set (match_operand:GPI 0 "register_operand")
3373 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3374 (match_operand:QI 2 "nonmemory_operand")))]
3377 /* (SZ - cnt) % SZ == -cnt % SZ */
3378 if (CONST_INT_P (operands[2]))
3380 operands[2] = GEN_INT ((-INTVAL (operands[2]))
3381 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3382 if (operands[2] == const0_rtx)
3384 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3389 operands[2] = expand_simple_unop (QImode, NEG, operands[2],
3394 ;; Logical left shift using SISD or Integer instruction
3395 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
3396 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3398 (match_operand:GPI 1 "register_operand" "w,w,r")
3399 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3402 shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3403 ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
3404 lsl\t%<w>0, %<w>1, %<w>2"
3405 [(set_attr "simd" "yes,yes,no")
3406 (set_attr "type" "neon_shift_imm<q>, neon_shift_reg<q>,shift_reg")]
3409 ;; Logical right shift using SISD or Integer instruction
3410 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3411 [(set (match_operand:GPI 0 "register_operand" "=w,&w,r")
3413 (match_operand:GPI 1 "register_operand" "w,w,r")
3414 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3417 ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3419 lsr\t%<w>0, %<w>1, %<w>2"
3420 [(set_attr "simd" "yes,yes,no")
3421 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")]
3425 [(set (match_operand:DI 0 "aarch64_simd_register")
3427 (match_operand:DI 1 "aarch64_simd_register")
3428 (match_operand:QI 2 "aarch64_simd_register")))]
3429 "TARGET_SIMD && reload_completed"
3431 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3433 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_USHL))]
3435 operands[3] = gen_lowpart (QImode, operands[0]);
3440 [(set (match_operand:SI 0 "aarch64_simd_register")
3442 (match_operand:SI 1 "aarch64_simd_register")
3443 (match_operand:QI 2 "aarch64_simd_register")))]
3444 "TARGET_SIMD && reload_completed"
3446 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3448 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_USHL_2S))]
3450 operands[3] = gen_lowpart (QImode, operands[0]);
3454 ;; Arithmetic right shift using SISD or Integer instruction
3455 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3456 [(set (match_operand:GPI 0 "register_operand" "=w,&w,&w,r")
3458 (match_operand:GPI 1 "register_operand" "w,w,w,r")
3459 (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,0,rUs<cmode>")))]
3462 sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3465 asr\t%<w>0, %<w>1, %<w>2"
3466 [(set_attr "simd" "yes,yes,yes,no")
3467 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>,shift_reg")]
3471 [(set (match_operand:DI 0 "aarch64_simd_register")
3473 (match_operand:DI 1 "aarch64_simd_register")
3474 (match_operand:QI 2 "aarch64_simd_register")))]
3475 "TARGET_SIMD && reload_completed"
3477 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3479 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_SSHL))]
3481 operands[3] = gen_lowpart (QImode, operands[0]);
3486 [(set (match_operand:SI 0 "aarch64_simd_register")
3488 (match_operand:SI 1 "aarch64_simd_register")
3489 (match_operand:QI 2 "aarch64_simd_register")))]
3490 "TARGET_SIMD && reload_completed"
3492 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3494 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_SSHL_2S))]
3496 operands[3] = gen_lowpart (QImode, operands[0]);
3500 (define_insn "*aarch64_sisd_ushl"
3501 [(set (match_operand:DI 0 "register_operand" "=w")
3502 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3503 (match_operand:QI 2 "register_operand" "w")]
3506 "ushl\t%d0, %d1, %d2"
3507 [(set_attr "simd" "yes")
3508 (set_attr "type" "neon_shift_reg")]
3511 (define_insn "*aarch64_ushl_2s"
3512 [(set (match_operand:SI 0 "register_operand" "=w")
3513 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3514 (match_operand:QI 2 "register_operand" "w")]
3517 "ushl\t%0.2s, %1.2s, %2.2s"
3518 [(set_attr "simd" "yes")
3519 (set_attr "type" "neon_shift_reg")]
3522 (define_insn "*aarch64_sisd_sshl"
3523 [(set (match_operand:DI 0 "register_operand" "=w")
3524 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3525 (match_operand:QI 2 "register_operand" "w")]
3528 "sshl\t%d0, %d1, %d2"
3529 [(set_attr "simd" "yes")
3530 (set_attr "type" "neon_shift_reg")]
3533 (define_insn "*aarch64_sshl_2s"
3534 [(set (match_operand:SI 0 "register_operand" "=w")
3535 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3536 (match_operand:QI 2 "register_operand" "w")]
3539 "sshl\t%0.2s, %1.2s, %2.2s"
3540 [(set_attr "simd" "yes")
3541 (set_attr "type" "neon_shift_reg")]
3544 (define_insn "*aarch64_sisd_neg_qi"
3545 [(set (match_operand:QI 0 "register_operand" "=w")
3546 (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3550 [(set_attr "simd" "yes")
3551 (set_attr "type" "neon_neg")]
3555 (define_insn "*ror<mode>3_insn"
3556 [(set (match_operand:GPI 0 "register_operand" "=r")
3558 (match_operand:GPI 1 "register_operand" "r")
3559 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3561 "ror\\t%<w>0, %<w>1, %<w>2"
3562 [(set_attr "type" "shift_reg")]
3565 ;; zero_extend version of above
3566 (define_insn "*<optab>si3_insn_uxtw"
3567 [(set (match_operand:DI 0 "register_operand" "=r")
3568 (zero_extend:DI (SHIFT:SI
3569 (match_operand:SI 1 "register_operand" "r")
3570 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3572 "<shift>\\t%w0, %w1, %w2"
3573 [(set_attr "type" "shift_reg")]
3576 (define_insn "*<optab><mode>3_insn"
3577 [(set (match_operand:SHORT 0 "register_operand" "=r")
3578 (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3579 (match_operand 2 "const_int_operand" "n")))]
3580 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3582 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3583 return "<bfshift>\t%w0, %w1, %2, %3";
3585 [(set_attr "type" "bfm")]
3588 (define_insn "*extr<mode>5_insn"
3589 [(set (match_operand:GPI 0 "register_operand" "=r")
3590 (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3591 (match_operand 3 "const_int_operand" "n"))
3592 (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3593 (match_operand 4 "const_int_operand" "n"))))]
3594 "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3595 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3596 "extr\\t%<w>0, %<w>1, %<w>2, %4"
3597 [(set_attr "type" "shift_imm")]
3600 ;; zero_extend version of the above
3601 (define_insn "*extrsi5_insn_uxtw"
3602 [(set (match_operand:DI 0 "register_operand" "=r")
3604 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3605 (match_operand 3 "const_int_operand" "n"))
3606 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3607 (match_operand 4 "const_int_operand" "n")))))]
3608 "UINTVAL (operands[3]) < 32 &&
3609 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3610 "extr\\t%w0, %w1, %w2, %4"
3611 [(set_attr "type" "shift_imm")]
3614 (define_insn "*ror<mode>3_insn"
3615 [(set (match_operand:GPI 0 "register_operand" "=r")
3616 (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3617 (match_operand 2 "const_int_operand" "n")))]
3618 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3620 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3621 return "ror\\t%<w>0, %<w>1, %3";
3623 [(set_attr "type" "shift_imm")]
3626 ;; zero_extend version of the above
3627 (define_insn "*rorsi3_insn_uxtw"
3628 [(set (match_operand:DI 0 "register_operand" "=r")
3630 (rotate:SI (match_operand:SI 1 "register_operand" "r")
3631 (match_operand 2 "const_int_operand" "n"))))]
3632 "UINTVAL (operands[2]) < 32"
3634 operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3635 return "ror\\t%w0, %w1, %3";
3637 [(set_attr "type" "shift_imm")]
3640 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3641 [(set (match_operand:GPI 0 "register_operand" "=r")
3643 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3644 (match_operand 2 "const_int_operand" "n"))))]
3645 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3647 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3648 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3650 [(set_attr "type" "bfm")]
3653 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3654 [(set (match_operand:GPI 0 "register_operand" "=r")
3656 (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3657 (match_operand 2 "const_int_operand" "n"))))]
3658 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3660 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3661 return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3663 [(set_attr "type" "bfm")]
3666 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3667 [(set (match_operand:GPI 0 "register_operand" "=r")
3669 (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3670 (match_operand 2 "const_int_operand" "n"))))]
3671 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3673 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3674 return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3676 [(set_attr "type" "bfm")]
3679 ;; -------------------------------------------------------------------
3681 ;; -------------------------------------------------------------------
3683 (define_expand "<optab>"
3684 [(set (match_operand:DI 0 "register_operand" "=r")
3685 (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3686 (match_operand 2 "const_int_operand" "n")
3687 (match_operand 3 "const_int_operand" "n")))]
3692 (define_insn "*<optab><mode>"
3693 [(set (match_operand:GPI 0 "register_operand" "=r")
3694 (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3695 (match_operand 2 "const_int_operand" "n")
3696 (match_operand 3 "const_int_operand" "n")))]
3698 "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3699 [(set_attr "type" "bfm")]
3702 ;; Bitfield Insert (insv)
3703 (define_expand "insv<mode>"
3704 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3705 (match_operand 1 "const_int_operand")
3706 (match_operand 2 "const_int_operand"))
3707 (match_operand:GPI 3 "general_operand"))]
3710 unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3711 unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3712 rtx value = operands[3];
3714 if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3717 if (CONST_INT_P (value))
3719 unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3721 /* Prefer AND/OR for inserting all zeros or all ones. */
3722 if ((UINTVAL (value) & mask) == 0
3723 || (UINTVAL (value) & mask) == mask)
3726 /* 16-bit aligned 16-bit wide insert is handled by insv_imm. */
3727 if (width == 16 && (pos % 16) == 0)
3730 operands[3] = force_reg (<MODE>mode, value);
3733 (define_insn "*insv_reg<mode>"
3734 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3735 (match_operand 1 "const_int_operand" "n")
3736 (match_operand 2 "const_int_operand" "n"))
3737 (match_operand:GPI 3 "register_operand" "r"))]
3738 "!(UINTVAL (operands[1]) == 0
3739 || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3740 > GET_MODE_BITSIZE (<MODE>mode)))"
3741 "bfi\\t%<w>0, %<w>3, %2, %1"
3742 [(set_attr "type" "bfm")]
3745 (define_insn "*extr_insv_lower_reg<mode>"
3746 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3747 (match_operand 1 "const_int_operand" "n")
3749 (zero_extract:GPI (match_operand:GPI 2 "register_operand" "r")
3751 (match_operand 3 "const_int_operand" "n")))]
3752 "!(UINTVAL (operands[1]) == 0
3753 || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3754 > GET_MODE_BITSIZE (<MODE>mode)))"
3755 "bfxil\\t%<w>0, %<w>2, %3, %1"
3756 [(set_attr "type" "bfm")]
3759 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3760 [(set (match_operand:GPI 0 "register_operand" "=r")
3761 (ashift:GPI (ANY_EXTEND:GPI
3762 (match_operand:ALLX 1 "register_operand" "r"))
3763 (match_operand 2 "const_int_operand" "n")))]
3764 "UINTVAL (operands[2]) < <GPI:sizen>"
3766 operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3767 ? GEN_INT (<ALLX:sizen>)
3768 : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3769 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3771 [(set_attr "type" "bfm")]
3774 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3776 (define_insn "*andim_ashift<mode>_bfiz"
3777 [(set (match_operand:GPI 0 "register_operand" "=r")
3778 (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3779 (match_operand 2 "const_int_operand" "n"))
3780 (match_operand 3 "const_int_operand" "n")))]
3781 "(INTVAL (operands[2]) < (<GPI:sizen>))
3782 && exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3783 && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3784 "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3785 [(set_attr "type" "bfm")]
3788 (define_insn "bswap<mode>2"
3789 [(set (match_operand:GPI 0 "register_operand" "=r")
3790 (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3792 "rev\\t%<w>0, %<w>1"
3793 [(set_attr "type" "rev")]
3796 (define_insn "bswaphi2"
3797 [(set (match_operand:HI 0 "register_operand" "=r")
3798 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3801 [(set_attr "type" "rev")]
3804 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
3805 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
3806 ;; each valid permutation.
3808 (define_insn "rev16<mode>2"
3809 [(set (match_operand:GPI 0 "register_operand" "=r")
3810 (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3812 (match_operand:GPI 3 "const_int_operand" "n"))
3813 (and:GPI (lshiftrt:GPI (match_dup 1)
3815 (match_operand:GPI 2 "const_int_operand" "n"))))]
3816 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3817 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3818 "rev16\\t%<w>0, %<w>1"
3819 [(set_attr "type" "rev")]
3822 (define_insn "rev16<mode>2_alt"
3823 [(set (match_operand:GPI 0 "register_operand" "=r")
3824 (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r")
3826 (match_operand:GPI 2 "const_int_operand" "n"))
3827 (and:GPI (ashift:GPI (match_dup 1)
3829 (match_operand:GPI 3 "const_int_operand" "n"))))]
3830 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3831 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3832 "rev16\\t%<w>0, %<w>1"
3833 [(set_attr "type" "rev")]
3836 ;; zero_extend version of above
3837 (define_insn "*bswapsi2_uxtw"
3838 [(set (match_operand:DI 0 "register_operand" "=r")
3839 (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3842 [(set_attr "type" "rev")]
3845 ;; -------------------------------------------------------------------
3846 ;; Floating-point intrinsics
3847 ;; -------------------------------------------------------------------
3849 ;; frint floating-point round to integral standard patterns.
3850 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round, frintn.
3852 (define_insn "<frint_pattern><mode>2"
3853 [(set (match_operand:GPF 0 "register_operand" "=w")
3854 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3857 "frint<frint_suffix>\\t%<s>0, %<s>1"
3858 [(set_attr "type" "f_rint<s>")]
3861 ;; frcvt floating-point round to integer and convert standard patterns.
3862 ;; Expands to lbtrunc, lceil, lfloor, lround.
3863 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3864 [(set (match_operand:GPI 0 "register_operand" "=r")
3865 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3868 "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3869 [(set_attr "type" "f_cvtf2i")]
3874 (define_insn "fma<mode>4"
3875 [(set (match_operand:GPF 0 "register_operand" "=w")
3876 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3877 (match_operand:GPF 2 "register_operand" "w")
3878 (match_operand:GPF 3 "register_operand" "w")))]
3880 "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3881 [(set_attr "type" "fmac<s>")]
3884 (define_insn "fnma<mode>4"
3885 [(set (match_operand:GPF 0 "register_operand" "=w")
3886 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3887 (match_operand:GPF 2 "register_operand" "w")
3888 (match_operand:GPF 3 "register_operand" "w")))]
3890 "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3891 [(set_attr "type" "fmac<s>")]
3894 (define_insn "fms<mode>4"
3895 [(set (match_operand:GPF 0 "register_operand" "=w")
3896 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3897 (match_operand:GPF 2 "register_operand" "w")
3898 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3900 "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3901 [(set_attr "type" "fmac<s>")]
3904 (define_insn "fnms<mode>4"
3905 [(set (match_operand:GPF 0 "register_operand" "=w")
3906 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3907 (match_operand:GPF 2 "register_operand" "w")
3908 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3910 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3911 [(set_attr "type" "fmac<s>")]
3914 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3915 (define_insn "*fnmadd<mode>4"
3916 [(set (match_operand:GPF 0 "register_operand" "=w")
3917 (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3918 (match_operand:GPF 2 "register_operand" "w")
3919 (match_operand:GPF 3 "register_operand" "w"))))]
3920 "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3921 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3922 [(set_attr "type" "fmac<s>")]
3925 ;; -------------------------------------------------------------------
3926 ;; Floating-point conversions
3927 ;; -------------------------------------------------------------------
3929 (define_insn "extendsfdf2"
3930 [(set (match_operand:DF 0 "register_operand" "=w")
3931 (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3934 [(set_attr "type" "f_cvt")]
3937 (define_insn "truncdfsf2"
3938 [(set (match_operand:SF 0 "register_operand" "=w")
3939 (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3942 [(set_attr "type" "f_cvt")]
3945 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3946 [(set (match_operand:GPI 0 "register_operand" "=r")
3947 (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3949 "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3950 [(set_attr "type" "f_cvtf2i")]
3953 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3954 [(set (match_operand:GPI 0 "register_operand" "=r")
3955 (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3957 "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3958 [(set_attr "type" "f_cvtf2i")]
3961 (define_insn "<optab><fcvt_target><GPF:mode>2"
3962 [(set (match_operand:GPF 0 "register_operand" "=w,w")
3963 (FLOATUORS:GPF (match_operand:<FCVT_TARGET> 1 "register_operand" "w,r")))]
3966 <su_optab>cvtf\t%<GPF:s>0, %<s>1
3967 <su_optab>cvtf\t%<GPF:s>0, %<w1>1"
3968 [(set_attr "simd" "yes,no")
3969 (set_attr "fp" "no,yes")
3970 (set_attr "type" "neon_int_to_fp_<Vetype>,f_cvti2f")]
3973 (define_insn "<optab><fcvt_iesize><GPF:mode>2"
3974 [(set (match_operand:GPF 0 "register_operand" "=w")
3975 (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand" "r")))]
3977 "<su_optab>cvtf\t%<GPF:s>0, %<w2>1"
3978 [(set_attr "type" "f_cvti2f")]
3981 ;; -------------------------------------------------------------------
3982 ;; Floating-point arithmetic
3983 ;; -------------------------------------------------------------------
3985 (define_insn "add<mode>3"
3986 [(set (match_operand:GPF 0 "register_operand" "=w")
3988 (match_operand:GPF 1 "register_operand" "w")
3989 (match_operand:GPF 2 "register_operand" "w")))]
3991 "fadd\\t%<s>0, %<s>1, %<s>2"
3992 [(set_attr "type" "fadd<s>")]
3995 (define_insn "sub<mode>3"
3996 [(set (match_operand:GPF 0 "register_operand" "=w")
3998 (match_operand:GPF 1 "register_operand" "w")
3999 (match_operand:GPF 2 "register_operand" "w")))]
4001 "fsub\\t%<s>0, %<s>1, %<s>2"
4002 [(set_attr "type" "fadd<s>")]
4005 (define_insn "mul<mode>3"
4006 [(set (match_operand:GPF 0 "register_operand" "=w")
4008 (match_operand:GPF 1 "register_operand" "w")
4009 (match_operand:GPF 2 "register_operand" "w")))]
4011 "fmul\\t%<s>0, %<s>1, %<s>2"
4012 [(set_attr "type" "fmul<s>")]
4015 (define_insn "*fnmul<mode>3"
4016 [(set (match_operand:GPF 0 "register_operand" "=w")
4018 (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
4019 (match_operand:GPF 2 "register_operand" "w")))]
4021 "fnmul\\t%<s>0, %<s>1, %<s>2"
4022 [(set_attr "type" "fmul<s>")]
4025 (define_insn "div<mode>3"
4026 [(set (match_operand:GPF 0 "register_operand" "=w")
4028 (match_operand:GPF 1 "register_operand" "w")
4029 (match_operand:GPF 2 "register_operand" "w")))]
4031 "fdiv\\t%<s>0, %<s>1, %<s>2"
4032 [(set_attr "type" "fdiv<s>")]
4035 (define_insn "neg<mode>2"
4036 [(set (match_operand:GPF 0 "register_operand" "=w")
4037 (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
4039 "fneg\\t%<s>0, %<s>1"
4040 [(set_attr "type" "ffarith<s>")]
4043 (define_insn "sqrt<mode>2"
4044 [(set (match_operand:GPF 0 "register_operand" "=w")
4045 (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
4047 "fsqrt\\t%<s>0, %<s>1"
4048 [(set_attr "type" "fsqrt<s>")]
4051 (define_insn "abs<mode>2"
4052 [(set (match_operand:GPF 0 "register_operand" "=w")
4053 (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
4055 "fabs\\t%<s>0, %<s>1"
4056 [(set_attr "type" "ffarith<s>")]
4059 ;; Given that smax/smin do not specify the result when either input is NaN,
4060 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
4063 (define_insn "smax<mode>3"
4064 [(set (match_operand:GPF 0 "register_operand" "=w")
4065 (smax:GPF (match_operand:GPF 1 "register_operand" "w")
4066 (match_operand:GPF 2 "register_operand" "w")))]
4068 "fmaxnm\\t%<s>0, %<s>1, %<s>2"
4069 [(set_attr "type" "f_minmax<s>")]
4072 (define_insn "smin<mode>3"
4073 [(set (match_operand:GPF 0 "register_operand" "=w")
4074 (smin:GPF (match_operand:GPF 1 "register_operand" "w")
4075 (match_operand:GPF 2 "register_operand" "w")))]
4077 "fminnm\\t%<s>0, %<s>1, %<s>2"
4078 [(set_attr "type" "f_minmax<s>")]
4081 ;; -------------------------------------------------------------------
4083 ;; -------------------------------------------------------------------
4085 (define_expand "aarch64_reload_mov<mode>"
4086 [(set (match_operand:TX 0 "register_operand" "=w")
4087 (match_operand:TX 1 "register_operand" "w"))
4088 (clobber (match_operand:DI 2 "register_operand" "=&r"))
4092 rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
4093 rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
4094 gen_aarch64_movtilow_tilow (op0, op1);
4095 gen_aarch64_movdi_tihigh (operands[2], op1);
4096 gen_aarch64_movtihigh_di (op0, operands[2]);
4101 ;; The following secondary reload helpers patterns are invoked
4102 ;; after or during reload as we don't want these patterns to start
4103 ;; kicking in during the combiner.
4105 (define_insn "aarch64_movdi_<mode>low"
4106 [(set (match_operand:DI 0 "register_operand" "=r")
4107 (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
4108 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4110 [(set_attr "type" "f_mrc")
4111 (set_attr "length" "4")
4114 (define_insn "aarch64_movdi_<mode>high"
4115 [(set (match_operand:DI 0 "register_operand" "=r")
4117 (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
4119 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4120 "fmov\\t%x0, %1.d[1]"
4121 [(set_attr "type" "f_mrc")
4122 (set_attr "length" "4")
4125 (define_insn "aarch64_mov<mode>high_di"
4126 [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
4127 (const_int 64) (const_int 64))
4128 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4129 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4130 "fmov\\t%0.d[1], %x1"
4131 [(set_attr "type" "f_mcr")
4132 (set_attr "length" "4")
4135 (define_insn "aarch64_mov<mode>low_di"
4136 [(set (match_operand:TX 0 "register_operand" "=w")
4137 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4138 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4140 [(set_attr "type" "f_mcr")
4141 (set_attr "length" "4")
4144 (define_insn "aarch64_movtilow_tilow"
4145 [(set (match_operand:TI 0 "register_operand" "=w")
4147 (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
4148 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4150 [(set_attr "type" "fmov")
4151 (set_attr "length" "4")
4154 ;; There is a deliberate reason why the parameters of high and lo_sum's
4155 ;; don't have modes for ADRP and ADD instructions. This is to allow high
4156 ;; and lo_sum's to be used with the labels defining the jump tables in
4159 (define_expand "add_losym"
4160 [(set (match_operand 0 "register_operand" "=r")
4161 (lo_sum (match_operand 1 "register_operand" "r")
4162 (match_operand 2 "aarch64_valid_symref" "S")))]
4165 machine_mode mode = GET_MODE (operands[0]);
4167 emit_insn ((mode == DImode
4169 : gen_add_losym_si) (operands[0],
4175 (define_insn "add_losym_<mode>"
4176 [(set (match_operand:P 0 "register_operand" "=r")
4177 (lo_sum:P (match_operand:P 1 "register_operand" "r")
4178 (match_operand 2 "aarch64_valid_symref" "S")))]
4180 "add\\t%<w>0, %<w>1, :lo12:%a2"
4181 [(set_attr "type" "alu_imm")]
4184 (define_insn "ldr_got_small_<mode>"
4185 [(set (match_operand:PTR 0 "register_operand" "=r")
4186 (unspec:PTR [(mem:PTR (lo_sum:PTR
4187 (match_operand:PTR 1 "register_operand" "r")
4188 (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
4189 UNSPEC_GOTSMALLPIC))]
4191 "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
4192 [(set_attr "type" "load1")]
4195 (define_insn "ldr_got_small_sidi"
4196 [(set (match_operand:DI 0 "register_operand" "=r")
4198 (unspec:SI [(mem:SI (lo_sum:DI
4199 (match_operand:DI 1 "register_operand" "r")
4200 (match_operand:DI 2 "aarch64_valid_symref" "S")))]
4201 UNSPEC_GOTSMALLPIC)))]
4203 "ldr\\t%w0, [%1, #:got_lo12:%a2]"
4204 [(set_attr "type" "load1")]
4207 (define_insn "ldr_got_tiny"
4208 [(set (match_operand:DI 0 "register_operand" "=r")
4209 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
4210 UNSPEC_GOTTINYPIC))]
4213 [(set_attr "type" "load1")]
4216 (define_insn "aarch64_load_tp_hard"
4217 [(set (match_operand:DI 0 "register_operand" "=r")
4218 (unspec:DI [(const_int 0)] UNSPEC_TLS))]
4220 "mrs\\t%0, tpidr_el0"
4221 [(set_attr "type" "mrs")]
4224 ;; The TLS ABI specifically requires that the compiler does not schedule
4225 ;; instructions in the TLS stubs, in order to enable linker relaxation.
4226 ;; Therefore we treat the stubs as an atomic sequence.
4227 (define_expand "tlsgd_small"
4228 [(parallel [(set (match_operand 0 "register_operand" "")
4229 (call (mem:DI (match_dup 2)) (const_int 1)))
4230 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
4231 (clobber (reg:DI LR_REGNUM))])]
4234 operands[2] = aarch64_tls_get_addr ();
4237 (define_insn "*tlsgd_small"
4238 [(set (match_operand 0 "register_operand" "")
4239 (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
4240 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
4241 (clobber (reg:DI LR_REGNUM))
4244 "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
4245 [(set_attr "type" "call")
4246 (set_attr "length" "16")])
4248 (define_insn "tlsie_small_<mode>"
4249 [(set (match_operand:PTR 0 "register_operand" "=r")
4250 (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
4251 UNSPEC_GOTSMALLTLS))]
4253 "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
4254 [(set_attr "type" "load1")
4255 (set_attr "length" "8")]
4258 (define_insn "tlsie_small_sidi"
4259 [(set (match_operand:DI 0 "register_operand" "=r")
4261 (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")]
4262 UNSPEC_GOTSMALLTLS)))]
4264 "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
4265 [(set_attr "type" "load1")
4266 (set_attr "length" "8")]
4269 (define_expand "tlsle_small"
4270 [(set (match_operand 0 "register_operand" "=r")
4271 (unspec [(match_operand 1 "register_operand" "r")
4272 (match_operand 2 "aarch64_tls_le_symref" "S")]
4273 UNSPEC_GOTSMALLTLS))]
4276 machine_mode mode = GET_MODE (operands[0]);
4277 emit_insn ((mode == DImode
4278 ? gen_tlsle_small_di
4279 : gen_tlsle_small_si) (operands[0],
4285 (define_insn "tlsle_small_<mode>"
4286 [(set (match_operand:P 0 "register_operand" "=r")
4287 (unspec:P [(match_operand:P 1 "register_operand" "r")
4288 (match_operand 2 "aarch64_tls_le_symref" "S")]
4289 UNSPEC_GOTSMALLTLS))]
4291 "add\\t%<w>0, %<w>1, #%G2, lsl #12\;add\\t%<w>0, %<w>0, #%L2"
4292 [(set_attr "type" "alu_sreg")
4293 (set_attr "length" "8")]
4296 (define_insn "tlsdesc_small_<mode>"
4297 [(set (reg:PTR R0_REGNUM)
4298 (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
4300 (clobber (reg:DI LR_REGNUM))
4301 (clobber (reg:CC CC_REGNUM))
4302 (clobber (match_scratch:DI 1 "=r"))]
4304 "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
4305 [(set_attr "type" "call")
4306 (set_attr "length" "16")])
4308 (define_insn "stack_tie"
4309 [(set (mem:BLK (scratch))
4310 (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
4311 (match_operand:DI 1 "register_operand" "rk")]
4315 [(set_attr "length" "0")]
4318 ;; Named pattern for expanding thread pointer reference.
4319 (define_expand "get_thread_pointerdi"
4320 [(match_operand:DI 0 "register_operand" "=r")]
4323 rtx tmp = aarch64_load_tp (operands[0]);
4324 if (tmp != operands[0])
4325 emit_move_insn (operands[0], tmp);
4329 ;; Named patterns for stack smashing protection.
4330 (define_expand "stack_protect_set"
4331 [(match_operand 0 "memory_operand")
4332 (match_operand 1 "memory_operand")]
4335 machine_mode mode = GET_MODE (operands[0]);
4337 emit_insn ((mode == DImode
4338 ? gen_stack_protect_set_di
4339 : gen_stack_protect_set_si) (operands[0], operands[1]));
4343 (define_insn "stack_protect_set_<mode>"
4344 [(set (match_operand:PTR 0 "memory_operand" "=m")
4345 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
4347 (set (match_scratch:PTR 2 "=&r") (const_int 0))]
4349 "ldr\\t%<w>2, %1\;str\\t%<w>2, %0\;mov\t%<w>2,0"
4350 [(set_attr "length" "12")
4351 (set_attr "type" "multiple")])
4353 (define_expand "stack_protect_test"
4354 [(match_operand 0 "memory_operand")
4355 (match_operand 1 "memory_operand")
4360 machine_mode mode = GET_MODE (operands[0]);
4362 result = gen_reg_rtx(mode);
4364 emit_insn ((mode == DImode
4365 ? gen_stack_protect_test_di
4366 : gen_stack_protect_test_si) (result,
4371 emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4372 result, const0_rtx, operands[2]));
4374 emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4375 result, const0_rtx, operands[2]));
4379 (define_insn "stack_protect_test_<mode>"
4380 [(set (match_operand:PTR 0 "register_operand" "=r")
4381 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
4382 (match_operand:PTR 2 "memory_operand" "m")]
4384 (clobber (match_scratch:PTR 3 "=&r"))]
4386 "ldr\t%<w>3, %x1\;ldr\t%<w>0, %x2\;eor\t%<w>0, %<w>3, %<w>0"
4387 [(set_attr "length" "12")
4388 (set_attr "type" "multiple")])
4390 ;; Write Floating-point Control Register.
4391 (define_insn "set_fpcr"
4392 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
4395 [(set_attr "type" "mrs")])
4397 ;; Read Floating-point Control Register.
4398 (define_insn "get_fpcr"
4399 [(set (match_operand:SI 0 "register_operand" "=r")
4400 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
4403 [(set_attr "type" "mrs")])
4405 ;; Write Floating-point Status Register.
4406 (define_insn "set_fpsr"
4407 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
4410 [(set_attr "type" "mrs")])
4412 ;; Read Floating-point Status Register.
4413 (define_insn "get_fpsr"
4414 [(set (match_operand:SI 0 "register_operand" "=r")
4415 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
4418 [(set_attr "type" "mrs")])
4421 ;; Define the subtract-one-and-jump insns so loop.c
4422 ;; knows what to generate.
4423 (define_expand "doloop_end"
4424 [(use (match_operand 0 "" "")) ; loop pseudo
4425 (use (match_operand 1 "" ""))] ; label
4426 "optimize > 0 && flag_modulo_sched"
4435 /* Currently SMS relies on the do-loop pattern to recognize loops
4436 where (1) the control part consists of all insns defining and/or
4437 using a certain 'count' register and (2) the loop count can be
4438 adjusted by modifying this register prior to the loop.
4439 ??? The possible introduction of a new block to initialize the
4440 new IV can potentially affect branch optimizations. */
4442 if (GET_MODE (operands[0]) != DImode)
4446 insn = emit_insn (gen_adddi3_compare0 (s0, s0, GEN_INT (-1)));
4448 cmp = XVECEXP (PATTERN (insn), 0, 0);
4449 cc_reg = SET_DEST (cmp);
4450 bcomp = gen_rtx_NE (VOIDmode, cc_reg, const0_rtx);
4451 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
4452 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4453 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
4459 (include "aarch64-simd.md")
4461 ;; Atomic Operations
4462 (include "atomics.md")
4464 ;; ldp/stp peephole patterns
4465 (include "aarch64-ldpstp.md")