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" [
131 (define_c_enum "unspecv" [
132 UNSPECV_EH_RETURN ; Represent EH_RETURN
133 UNSPECV_GET_FPCR ; Represent fetch of FPCR content.
134 UNSPECV_SET_FPCR ; Represent assign of FPCR content.
135 UNSPECV_GET_FPSR ; Represent fetch of FPSR content.
136 UNSPECV_SET_FPSR ; Represent assign of FPSR content.
140 ;; If further include files are added the defintion of MD_INCLUDES
143 (include "constraints.md")
144 (include "predicates.md")
145 (include "iterators.md")
147 ;; -------------------------------------------------------------------
148 ;; Instruction types and attributes
149 ;; -------------------------------------------------------------------
151 ; The "type" attribute is included here from AArch32 backend to be able
152 ; to share pipeline descriptions.
153 (include "../arm/types.md")
155 ;; It is important to set the fp or simd attributes to yes when a pattern
156 ;; alternative uses the FP or SIMD register files, usually signified by use of
157 ;; the 'w' constraint. This will ensure that the alternative will be
158 ;; disabled when compiling with -mgeneral-regs-only or with the +nofp/+nosimd
159 ;; architecture extensions. If all the alternatives in a pattern use the
160 ;; FP or SIMD registers then the pattern predicate should include TARGET_FLOAT
163 ;; Attribute that specifies whether or not the instruction touches fp
164 ;; registers. When this is set to yes for an alternative, that alternative
165 ;; will be disabled when !TARGET_FLOAT.
166 (define_attr "fp" "no,yes" (const_string "no"))
168 ;; Attribute that specifies whether or not the instruction touches simd
169 ;; registers. When this is set to yes for an alternative, that alternative
170 ;; will be disabled when !TARGET_SIMD.
171 (define_attr "simd" "no,yes" (const_string "no"))
173 (define_attr "length" ""
176 ;; Attribute that controls whether an alternative is enabled or not.
177 ;; Currently it is only used to disable alternatives which touch fp or simd
178 ;; registers when -mgeneral-regs-only is specified.
179 (define_attr "enabled" "no,yes"
181 (and (eq_attr "fp" "yes")
182 (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
183 (and (eq_attr "simd" "yes")
184 (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
186 ] (const_string "yes")))
188 ;; Attribute that specifies whether we are dealing with a branch to a
189 ;; label that is far away, i.e. further away than the maximum/minimum
190 ;; representable in a signed 21-bits number.
193 (define_attr "far_branch" "" (const_int 0))
195 ;; -------------------------------------------------------------------
196 ;; Pipeline descriptions and scheduling
197 ;; -------------------------------------------------------------------
200 (include "aarch64-tune.md")
203 (include "../arm/cortex-a53.md")
204 (include "../arm/cortex-a57.md")
205 (include "thunderx.md")
206 (include "../arm/xgene1.md")
208 ;; -------------------------------------------------------------------
209 ;; Jumps and other miscellaneous insns
210 ;; -------------------------------------------------------------------
212 (define_insn "indirect_jump"
213 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
216 [(set_attr "type" "branch")]
220 [(set (pc) (label_ref (match_operand 0 "" "")))]
223 [(set_attr "type" "branch")]
226 (define_expand "cbranch<mode>4"
227 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
228 [(match_operand:GPI 1 "register_operand" "")
229 (match_operand:GPI 2 "aarch64_plus_operand" "")])
230 (label_ref (match_operand 3 "" ""))
234 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
236 operands[2] = const0_rtx;
240 (define_expand "cbranch<mode>4"
241 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
242 [(match_operand:GPF 1 "register_operand" "")
243 (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
244 (label_ref (match_operand 3 "" ""))
248 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
250 operands[2] = const0_rtx;
254 (define_expand "cbranchcc4"
255 [(set (pc) (if_then_else
256 (match_operator 0 "aarch64_comparison_operator"
257 [(match_operand 1 "cc_register" "")
258 (match_operand 2 "const0_operand")])
259 (label_ref (match_operand 3 "" ""))
264 (define_insn "ccmp_and<mode>"
265 [(set (match_operand 1 "ccmp_cc_register" "")
268 (match_operator 4 "aarch64_comparison_operator"
269 [(match_operand 0 "ccmp_cc_register" "")
271 (match_operator 5 "aarch64_comparison_operator"
272 [(match_operand:GPI 2 "register_operand" "r,r,r")
273 (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")]))
275 "aarch64_ccmp_mode_to_code (GET_MODE (operands[1])) == GET_CODE (operands[5])"
277 ccmp\\t%<w>2, %<w>3, %k5, %m4
278 ccmp\\t%<w>2, %<w>3, %k5, %m4
279 ccmn\\t%<w>2, #%n3, %k5, %m4"
280 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
283 (define_insn "ccmp_ior<mode>"
284 [(set (match_operand 1 "ccmp_cc_register" "")
287 (match_operator 4 "aarch64_comparison_operator"
288 [(match_operand 0 "ccmp_cc_register" "")
290 (match_operator 5 "aarch64_comparison_operator"
291 [(match_operand:GPI 2 "register_operand" "r,r,r")
292 (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")]))
294 "aarch64_ccmp_mode_to_code (GET_MODE (operands[1])) == GET_CODE (operands[5])"
296 ccmp\\t%<w>2, %<w>3, %K5, %M4
297 ccmp\\t%<w>2, %<w>3, %K5, %M4
298 ccmn\\t%<w>2, #%n3, %K5, %M4"
299 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
302 (define_expand "cmp<mode>"
303 [(set (match_operand 0 "cc_register" "")
304 (match_operator:CC 1 "aarch64_comparison_operator"
305 [(match_operand:GPI 2 "register_operand" "")
306 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
309 operands[1] = gen_rtx_fmt_ee (COMPARE,
310 SELECT_CC_MODE (GET_CODE (operands[1]),
311 operands[2], operands[3]),
312 operands[2], operands[3]);
316 ;; Expansion of signed mod by a power of 2 using CSNEG.
317 ;; For x0 % n where n is a power of 2 produce:
319 ;; and x0, x0, #(n - 1)
320 ;; and x1, x1, #(n - 1)
321 ;; csneg x0, x0, x1, mi
323 (define_expand "mod<mode>3"
324 [(match_operand:GPI 0 "register_operand" "")
325 (match_operand:GPI 1 "register_operand" "")
326 (match_operand:GPI 2 "const_int_operand" "")]
329 HOST_WIDE_INT val = INTVAL (operands[2]);
332 || exact_log2 (val) <= 0
333 || !aarch64_bitmask_imm (val - 1, <MODE>mode))
336 rtx mask = GEN_INT (val - 1);
338 /* In the special case of x0 % 2 we can do the even shorter:
344 rtx masked = gen_reg_rtx (<MODE>mode);
345 rtx ccreg = aarch64_gen_compare_reg (LT, operands[1], const0_rtx);
346 emit_insn (gen_and<mode>3 (masked, operands[1], mask));
347 rtx x = gen_rtx_LT (VOIDmode, ccreg, const0_rtx);
348 emit_insn (gen_csneg3<mode>_insn (operands[0], x, masked, masked));
352 rtx neg_op = gen_reg_rtx (<MODE>mode);
353 rtx_insn *insn = emit_insn (gen_neg<mode>2_compare0 (neg_op, operands[1]));
355 /* Extract the condition register and mode. */
356 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
357 rtx cc_reg = SET_DEST (cmp);
358 rtx cond = gen_rtx_GE (VOIDmode, cc_reg, const0_rtx);
360 rtx masked_pos = gen_reg_rtx (<MODE>mode);
361 emit_insn (gen_and<mode>3 (masked_pos, operands[1], mask));
363 rtx masked_neg = gen_reg_rtx (<MODE>mode);
364 emit_insn (gen_and<mode>3 (masked_neg, neg_op, mask));
366 emit_insn (gen_csneg3<mode>_insn (operands[0], cond,
367 masked_neg, masked_pos));
372 (define_insn "*condjump"
373 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
374 [(match_operand 1 "cc_register" "") (const_int 0)])
375 (label_ref (match_operand 2 "" ""))
379 if (get_attr_length (insn) == 8)
380 return aarch64_gen_far_branch (operands, 2, "Lbcond", "b%M0\\t");
384 [(set_attr "type" "branch")
386 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576))
387 (lt (minus (match_dup 2) (pc)) (const_int 1048572)))
390 (set (attr "far_branch")
391 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576))
392 (lt (minus (match_dup 2) (pc)) (const_int 1048572)))
397 (define_expand "casesi"
398 [(match_operand:SI 0 "register_operand" "") ; Index
399 (match_operand:SI 1 "const_int_operand" "") ; Lower bound
400 (match_operand:SI 2 "const_int_operand" "") ; Total range
401 (match_operand:DI 3 "" "") ; Table label
402 (match_operand:DI 4 "" "")] ; Out of range label
405 if (operands[1] != const0_rtx)
407 rtx reg = gen_reg_rtx (SImode);
409 /* Canonical RTL says that if you have:
413 then this should be emitted as:
417 The use of trunc_int_for_mode ensures that the resulting
418 constant can be represented in SImode, this is important
419 for the corner case where operand[1] is INT_MIN. */
421 operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
423 if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
424 (operands[1], SImode))
425 operands[1] = force_reg (SImode, operands[1]);
426 emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
430 if (!aarch64_plus_operand (operands[2], SImode))
431 operands[2] = force_reg (SImode, operands[2]);
432 emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
434 operands[0], operands[2], operands[4]));
436 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
437 emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
443 (define_insn "casesi_dispatch"
446 (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
447 (match_operand:SI 1 "register_operand" "r")]
449 (clobber (reg:CC CC_REGNUM))
450 (clobber (match_scratch:DI 3 "=r"))
451 (clobber (match_scratch:DI 4 "=r"))
452 (use (label_ref (match_operand 2 "" "")))])]
455 return aarch64_output_casesi (operands);
457 [(set_attr "length" "16")
458 (set_attr "type" "branch")]
462 [(unspec[(const_int 0)] UNSPEC_NOP)]
465 [(set_attr "type" "no_insn")]
468 (define_insn "prefetch"
469 [(prefetch (match_operand:DI 0 "register_operand" "r")
470 (match_operand:QI 1 "const_int_operand" "")
471 (match_operand:QI 2 "const_int_operand" ""))]
474 const char * pftype[2][4] =
476 {"prfm\\tPLDL1STRM, %a0",
477 "prfm\\tPLDL3KEEP, %a0",
478 "prfm\\tPLDL2KEEP, %a0",
479 "prfm\\tPLDL1KEEP, %a0"},
480 {"prfm\\tPSTL1STRM, %a0",
481 "prfm\\tPSTL3KEEP, %a0",
482 "prfm\\tPSTL2KEEP, %a0",
483 "prfm\\tPSTL1KEEP, %a0"},
486 int locality = INTVAL (operands[2]);
488 gcc_assert (IN_RANGE (locality, 0, 3));
490 return pftype[INTVAL(operands[1])][locality];
492 [(set_attr "type" "load1")]
496 [(trap_if (const_int 1) (const_int 8))]
499 [(set_attr "type" "trap")])
501 (define_expand "prologue"
502 [(clobber (const_int 0))]
505 aarch64_expand_prologue ();
510 (define_expand "epilogue"
511 [(clobber (const_int 0))]
514 aarch64_expand_epilogue (false);
519 (define_expand "sibcall_epilogue"
520 [(clobber (const_int 0))]
523 aarch64_expand_epilogue (true);
528 (define_insn "*do_return"
532 [(set_attr "type" "branch")]
535 (define_expand "return"
537 "aarch64_use_return_insn_p ()"
541 (define_insn "simple_return"
545 [(set_attr "type" "branch")]
548 (define_insn "eh_return"
549 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
553 [(set_attr "type" "branch")]
558 [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
561 [(set (match_dup 1) (match_dup 0))]
563 operands[1] = aarch64_final_eh_return_addr ();
567 (define_insn "*cb<optab><mode>1"
568 [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
570 (label_ref (match_operand 1 "" ""))
574 if (get_attr_length (insn) == 8)
575 return aarch64_gen_far_branch (operands, 1, "Lcb", "<inv_cb>\\t%<w>0, ");
577 return "<cbz>\\t%<w>0, %l1";
579 [(set_attr "type" "branch")
581 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -1048576))
582 (lt (minus (match_dup 1) (pc)) (const_int 1048572)))
585 (set (attr "far_branch")
586 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576))
587 (lt (minus (match_dup 2) (pc)) (const_int 1048572)))
592 (define_insn "*tb<optab><mode>1"
593 [(set (pc) (if_then_else
594 (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
596 (match_operand 1 "const_int_operand" "n"))
598 (label_ref (match_operand 2 "" ""))
600 (clobber (reg:CC CC_REGNUM))]
603 if (get_attr_length (insn) == 8)
605 if (get_attr_far_branch (insn) == 1)
606 return aarch64_gen_far_branch (operands, 2, "Ltb",
607 "<inv_tb>\\t%<w>0, %1, ");
610 operands[1] = GEN_INT (HOST_WIDE_INT_1U << UINTVAL (operands[1]));
611 return "tst\t%<w>0, %1\;<bcond>\t%l2";
615 return "<tbz>\t%<w>0, %1, %l2";
617 [(set_attr "type" "branch")
619 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
620 (lt (minus (match_dup 2) (pc)) (const_int 32764)))
623 (set (attr "far_branch")
624 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -1048576))
625 (lt (minus (match_dup 2) (pc)) (const_int 1048572)))
631 (define_insn "*cb<optab><mode>1"
632 [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
634 (label_ref (match_operand 1 "" ""))
636 (clobber (reg:CC CC_REGNUM))]
639 if (get_attr_length (insn) == 8)
641 if (get_attr_far_branch (insn) == 1)
642 return aarch64_gen_far_branch (operands, 1, "Ltb",
643 "<inv_tb>\\t%<w>0, <sizem1>, ");
647 uint64_t val = ((uint64_t) 1)
648 << (GET_MODE_SIZE (<MODE>mode) * BITS_PER_UNIT - 1);
649 sprintf (buf, "tst\t%%<w>0, %" PRId64, val);
650 output_asm_insn (buf, operands);
651 return "<bcond>\t%l1";
655 return "<tbz>\t%<w>0, <sizem1>, %l1";
657 [(set_attr "type" "branch")
659 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
660 (lt (minus (match_dup 1) (pc)) (const_int 32764)))
663 (set (attr "far_branch")
664 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -1048576))
665 (lt (minus (match_dup 1) (pc)) (const_int 1048572)))
670 ;; -------------------------------------------------------------------
671 ;; Subroutine calls and sibcalls
672 ;; -------------------------------------------------------------------
674 (define_expand "call_internal"
675 [(parallel [(call (match_operand 0 "memory_operand" "")
676 (match_operand 1 "general_operand" ""))
677 (use (match_operand 2 "" ""))
678 (clobber (reg:DI LR_REGNUM))])])
680 (define_expand "call"
681 [(parallel [(call (match_operand 0 "memory_operand" "")
682 (match_operand 1 "general_operand" ""))
683 (use (match_operand 2 "" ""))
684 (clobber (reg:DI LR_REGNUM))])]
690 /* In an untyped call, we can get NULL for operand 2. */
691 if (operands[2] == NULL)
692 operands[2] = const0_rtx;
694 /* Decide if we should generate indirect calls by loading the
695 64-bit address of the callee into a register before performing
696 the branch-and-link. */
697 callee = XEXP (operands[0], 0);
698 if (GET_CODE (callee) == SYMBOL_REF
699 ? aarch64_is_long_call_p (callee)
701 XEXP (operands[0], 0) = force_reg (Pmode, callee);
703 pat = gen_call_internal (operands[0], operands[1], operands[2]);
704 aarch64_emit_call_insn (pat);
709 (define_insn "*call_reg"
710 [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
711 (match_operand 1 "" ""))
712 (use (match_operand 2 "" ""))
713 (clobber (reg:DI LR_REGNUM))]
716 [(set_attr "type" "call")]
719 (define_insn "*call_symbol"
720 [(call (mem:DI (match_operand:DI 0 "" ""))
721 (match_operand 1 "" ""))
722 (use (match_operand 2 "" ""))
723 (clobber (reg:DI LR_REGNUM))]
724 "GET_CODE (operands[0]) == SYMBOL_REF
725 && !aarch64_is_long_call_p (operands[0])
726 && !aarch64_is_noplt_call_p (operands[0])"
728 [(set_attr "type" "call")]
731 (define_expand "call_value_internal"
732 [(parallel [(set (match_operand 0 "" "")
733 (call (match_operand 1 "memory_operand" "")
734 (match_operand 2 "general_operand" "")))
735 (use (match_operand 3 "" ""))
736 (clobber (reg:DI LR_REGNUM))])])
738 (define_expand "call_value"
739 [(parallel [(set (match_operand 0 "" "")
740 (call (match_operand 1 "memory_operand" "")
741 (match_operand 2 "general_operand" "")))
742 (use (match_operand 3 "" ""))
743 (clobber (reg:DI LR_REGNUM))])]
749 /* In an untyped call, we can get NULL for operand 3. */
750 if (operands[3] == NULL)
751 operands[3] = const0_rtx;
753 /* Decide if we should generate indirect calls by loading the
754 64-bit address of the callee into a register before performing
755 the branch-and-link. */
756 callee = XEXP (operands[1], 0);
757 if (GET_CODE (callee) == SYMBOL_REF
758 ? aarch64_is_long_call_p (callee)
760 XEXP (operands[1], 0) = force_reg (Pmode, callee);
762 pat = gen_call_value_internal (operands[0], operands[1], operands[2],
764 aarch64_emit_call_insn (pat);
769 (define_insn "*call_value_reg"
770 [(set (match_operand 0 "" "")
771 (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
772 (match_operand 2 "" "")))
773 (use (match_operand 3 "" ""))
774 (clobber (reg:DI LR_REGNUM))]
777 [(set_attr "type" "call")]
781 (define_insn "*call_value_symbol"
782 [(set (match_operand 0 "" "")
783 (call (mem:DI (match_operand:DI 1 "" ""))
784 (match_operand 2 "" "")))
785 (use (match_operand 3 "" ""))
786 (clobber (reg:DI LR_REGNUM))]
787 "GET_CODE (operands[1]) == SYMBOL_REF
788 && !aarch64_is_long_call_p (operands[1])
789 && !aarch64_is_noplt_call_p (operands[1])"
791 [(set_attr "type" "call")]
794 (define_expand "sibcall_internal"
795 [(parallel [(call (match_operand 0 "memory_operand" "")
796 (match_operand 1 "general_operand" ""))
798 (use (match_operand 2 "" ""))])])
800 (define_expand "sibcall"
801 [(parallel [(call (match_operand 0 "memory_operand" "")
802 (match_operand 1 "general_operand" ""))
804 (use (match_operand 2 "" ""))])]
809 if (!REG_P (XEXP (operands[0], 0))
810 && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
811 XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
813 if (operands[2] == NULL_RTX)
814 operands[2] = const0_rtx;
816 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
817 aarch64_emit_call_insn (pat);
822 (define_expand "sibcall_value_internal"
823 [(parallel [(set (match_operand 0 "" "")
824 (call (match_operand 1 "memory_operand" "")
825 (match_operand 2 "general_operand" "")))
827 (use (match_operand 3 "" ""))])])
829 (define_expand "sibcall_value"
830 [(parallel [(set (match_operand 0 "" "")
831 (call (match_operand 1 "memory_operand" "")
832 (match_operand 2 "general_operand" "")))
834 (use (match_operand 3 "" ""))])]
839 if (!REG_P (XEXP (operands[1], 0))
840 && (GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF))
841 XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
843 if (operands[3] == NULL_RTX)
844 operands[3] = const0_rtx;
846 pat = gen_sibcall_value_internal (operands[0], operands[1], operands[2],
848 aarch64_emit_call_insn (pat);
853 (define_insn "*sibcall_insn"
854 [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucs, Usf"))
855 (match_operand 1 "" ""))
857 (use (match_operand 2 "" ""))]
858 "SIBLING_CALL_P (insn)"
862 [(set_attr "type" "branch, branch")]
865 (define_insn "*sibcall_value_insn"
866 [(set (match_operand 0 "" "")
868 (match_operand:DI 1 "aarch64_call_insn_operand" "Ucs, Usf"))
869 (match_operand 2 "" "")))
871 (use (match_operand 3 "" ""))]
872 "SIBLING_CALL_P (insn)"
876 [(set_attr "type" "branch, branch")]
879 ;; Call subroutine returning any type.
881 (define_expand "untyped_call"
882 [(parallel [(call (match_operand 0 "")
885 (match_operand 2 "")])]
890 emit_call_insn (gen_call (operands[0], const0_rtx, NULL));
892 for (i = 0; i < XVECLEN (operands[2], 0); i++)
894 rtx set = XVECEXP (operands[2], 0, i);
895 emit_move_insn (SET_DEST (set), SET_SRC (set));
898 /* The optimizer does not know that the call sets the function value
899 registers we stored in the result block. We avoid problems by
900 claiming that all hard registers are used and clobbered at this
902 emit_insn (gen_blockage ());
906 ;; -------------------------------------------------------------------
908 ;; -------------------------------------------------------------------
910 (define_expand "mov<mode>"
911 [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
912 (match_operand:SHORT 1 "general_operand" ""))]
915 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
916 operands[1] = force_reg (<MODE>mode, operands[1]);
920 (define_insn "*mov<mode>_aarch64"
921 [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r, *w,r,*w, m, m, r,*w,*w")
922 (match_operand:SHORT 1 "general_operand" " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
923 "(register_operand (operands[0], <MODE>mode)
924 || aarch64_reg_or_zero (operands[1], <MODE>mode))"
926 switch (which_alternative)
929 return "mov\t%w0, %w1";
931 return "mov\t%w0, %1";
933 return aarch64_output_scalar_simd_mov_immediate (operands[1],
936 return "ldr<size>\t%w0, %1";
938 return "ldr\t%<size>0, %1";
940 return "str<size>\t%w1, %0";
942 return "str\t%<size>1, %0";
944 return "umov\t%w0, %1.<v>[0]";
946 return "dup\t%0.<Vallxd>, %w1";
948 return "dup\t%<Vetype>0, %1.<v>[0]";
953 [(set_attr "type" "mov_reg,mov_imm,neon_move,load1,load1,store1,store1,\
954 neon_to_gp<q>,neon_from_gp<q>,neon_dup")
955 (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")]
958 (define_expand "mov<mode>"
959 [(set (match_operand:GPI 0 "nonimmediate_operand" "")
960 (match_operand:GPI 1 "general_operand" ""))]
963 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
964 operands[1] = force_reg (<MODE>mode, operands[1]);
966 /* FIXME: RR we still need to fix up what we are doing with
967 symbol_refs and other types of constants. */
968 if (CONSTANT_P (operands[1])
969 && !CONST_INT_P (operands[1]))
971 aarch64_expand_mov_immediate (operands[0], operands[1]);
977 (define_insn_and_split "*movsi_aarch64"
978 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,r,*w,m, m,r,r ,*w, r,*w")
979 (match_operand:SI 1 "aarch64_mov_operand" " r,r,k,M,n,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
980 "(register_operand (operands[0], SImode)
981 || aarch64_reg_or_zero (operands[1], SImode))"
997 "CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), SImode)
998 && GP_REGNUM_P (REGNO (operands[0]))"
1001 aarch64_expand_mov_immediate (operands[0], operands[1]);
1004 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
1005 adr,adr,f_mcr,f_mrc,fmov")
1006 (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
1009 (define_insn_and_split "*movdi_aarch64"
1010 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,r,*w,m, m,r,r, *w, r,*w,w")
1011 (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,n,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))]
1012 "(register_operand (operands[0], DImode)
1013 || aarch64_reg_or_zero (operands[1], DImode))"
1030 "(CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), DImode))
1031 && GP_REGNUM_P (REGNO (operands[0]))"
1034 aarch64_expand_mov_immediate (operands[0], operands[1]);
1037 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
1038 adr,adr,f_mcr,f_mrc,fmov,neon_move")
1039 (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
1040 (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
1043 (define_insn "insv_imm<mode>"
1044 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
1046 (match_operand:GPI 1 "const_int_operand" "n"))
1047 (match_operand:GPI 2 "const_int_operand" "n"))]
1048 "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
1049 && UINTVAL (operands[1]) % 16 == 0"
1050 "movk\\t%<w>0, %X2, lsl %1"
1051 [(set_attr "type" "mov_imm")]
1054 (define_expand "movti"
1055 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1056 (match_operand:TI 1 "general_operand" ""))]
1059 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
1060 operands[1] = force_reg (TImode, operands[1]);
1064 (define_insn "*movti_aarch64"
1065 [(set (match_operand:TI 0
1066 "nonimmediate_operand" "=r, *w,r ,*w,r ,Ump,Ump,*w,m")
1068 "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r ,Z , m,*w"))]
1069 "(register_operand (operands[0], TImode)
1070 || aarch64_reg_or_zero (operands[1], TImode))"
1075 orr\\t%0.16b, %1.16b, %1.16b
1081 [(set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \
1082 load2,store2,store2,f_loadd,f_stored")
1083 (set_attr "length" "8,8,8,4,4,4,4,4,4")
1084 (set_attr "simd" "*,*,*,yes,*,*,*,*,*")
1085 (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
1088 ;; Split a TImode register-register or register-immediate move into
1089 ;; its component DImode pieces, taking care to handle overlapping
1090 ;; source and dest registers.
1092 [(set (match_operand:TI 0 "register_operand" "")
1093 (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
1094 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
1097 aarch64_split_128bit_move (operands[0], operands[1]);
1101 (define_expand "mov<mode>"
1102 [(set (match_operand:GPF_TF_F16 0 "nonimmediate_operand" "")
1103 (match_operand:GPF_TF_F16 1 "general_operand" ""))]
1108 aarch64_err_no_fpadvsimd (<MODE>mode, "code");
1112 if (GET_CODE (operands[0]) == MEM
1113 && ! (GET_CODE (operands[1]) == CONST_DOUBLE
1114 && aarch64_float_const_zero_rtx_p (operands[1])))
1115 operands[1] = force_reg (<MODE>mode, operands[1]);
1119 (define_insn "*movhf_aarch64"
1120 [(set (match_operand:HF 0 "nonimmediate_operand" "=w, ?r,w,w,m,r,m ,r")
1121 (match_operand:HF 1 "general_operand" "?rY, w,w,m,w,m,rY,r"))]
1122 "TARGET_FLOAT && (register_operand (operands[0], HFmode)
1123 || register_operand (operands[1], HFmode))"
1127 mov\\t%0.h[0], %1.h[0]
1133 [(set_attr "type" "neon_from_gp,neon_to_gp,fmov,\
1134 f_loads,f_stores,load1,store1,mov_reg")
1135 (set_attr "simd" "yes,yes,yes,*,*,*,*,*")
1136 (set_attr "fp" "*,*,*,yes,yes,*,*,*")]
1139 (define_insn "*movsf_aarch64"
1140 [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
1141 (match_operand:SF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
1142 "TARGET_FLOAT && (register_operand (operands[0], SFmode)
1143 || aarch64_reg_or_fp_zero (operands[1], SFmode))"
1154 [(set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
1155 f_loads,f_stores,load1,store1,mov_reg")]
1158 (define_insn "*movdf_aarch64"
1159 [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
1160 (match_operand:DF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
1161 "TARGET_FLOAT && (register_operand (operands[0], DFmode)
1162 || aarch64_reg_or_fp_zero (operands[1], DFmode))"
1173 [(set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
1174 f_loadd,f_stored,load1,store1,mov_reg")]
1177 (define_insn "*movtf_aarch64"
1178 [(set (match_operand:TF 0
1179 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump,Ump")
1181 "general_operand" " w,?r, ?r,w ,Y,Y ,m,w,Ump,?r ,Y"))]
1182 "TARGET_FLOAT && (register_operand (operands[0], TFmode)
1183 || aarch64_reg_or_fp_zero (operands[1], TFmode))"
1185 orr\\t%0.16b, %1.16b, %1.16b
1196 [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,neon_move_q,fconstd,\
1197 f_loadd,f_stored,load2,store2,store2")
1198 (set_attr "length" "4,8,8,8,4,4,4,4,4,4,4")
1199 (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*,*")
1200 (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*,*")]
1204 [(set (match_operand:TF 0 "register_operand" "")
1205 (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
1206 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
1209 aarch64_split_128bit_move (operands[0], operands[1]);
1216 ;; 2 is size of move in bytes
1219 (define_expand "movmemdi"
1220 [(match_operand:BLK 0 "memory_operand")
1221 (match_operand:BLK 1 "memory_operand")
1222 (match_operand:DI 2 "immediate_operand")
1223 (match_operand:DI 3 "immediate_operand")]
1226 if (aarch64_expand_movmem (operands))
1232 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1233 ;; fairly lax checking on the second memory operation.
1234 (define_insn "load_pairsi"
1235 [(set (match_operand:SI 0 "register_operand" "=r,*w")
1236 (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1237 (set (match_operand:SI 2 "register_operand" "=r,*w")
1238 (match_operand:SI 3 "memory_operand" "m,m"))]
1239 "rtx_equal_p (XEXP (operands[3], 0),
1240 plus_constant (Pmode,
1241 XEXP (operands[1], 0),
1242 GET_MODE_SIZE (SImode)))"
1246 [(set_attr "type" "load2,neon_load1_2reg")
1247 (set_attr "fp" "*,yes")]
1250 (define_insn "load_pairdi"
1251 [(set (match_operand:DI 0 "register_operand" "=r,*w")
1252 (match_operand:DI 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1253 (set (match_operand:DI 2 "register_operand" "=r,*w")
1254 (match_operand:DI 3 "memory_operand" "m,m"))]
1255 "rtx_equal_p (XEXP (operands[3], 0),
1256 plus_constant (Pmode,
1257 XEXP (operands[1], 0),
1258 GET_MODE_SIZE (DImode)))"
1262 [(set_attr "type" "load2,neon_load1_2reg")
1263 (set_attr "fp" "*,yes")]
1267 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1268 ;; fairly lax checking on the second memory operation.
1269 (define_insn "store_pairsi"
1270 [(set (match_operand:SI 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1271 (match_operand:SI 1 "aarch64_reg_or_zero" "rZ,*w"))
1272 (set (match_operand:SI 2 "memory_operand" "=m,m")
1273 (match_operand:SI 3 "aarch64_reg_or_zero" "rZ,*w"))]
1274 "rtx_equal_p (XEXP (operands[2], 0),
1275 plus_constant (Pmode,
1276 XEXP (operands[0], 0),
1277 GET_MODE_SIZE (SImode)))"
1281 [(set_attr "type" "store2,neon_store1_2reg")
1282 (set_attr "fp" "*,yes")]
1285 (define_insn "store_pairdi"
1286 [(set (match_operand:DI 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1287 (match_operand:DI 1 "aarch64_reg_or_zero" "rZ,*w"))
1288 (set (match_operand:DI 2 "memory_operand" "=m,m")
1289 (match_operand:DI 3 "aarch64_reg_or_zero" "rZ,*w"))]
1290 "rtx_equal_p (XEXP (operands[2], 0),
1291 plus_constant (Pmode,
1292 XEXP (operands[0], 0),
1293 GET_MODE_SIZE (DImode)))"
1297 [(set_attr "type" "store2,neon_store1_2reg")
1298 (set_attr "fp" "*,yes")]
1301 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1302 ;; fairly lax checking on the second memory operation.
1303 (define_insn "load_pairsf"
1304 [(set (match_operand:SF 0 "register_operand" "=w,*r")
1305 (match_operand:SF 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1306 (set (match_operand:SF 2 "register_operand" "=w,*r")
1307 (match_operand:SF 3 "memory_operand" "m,m"))]
1308 "rtx_equal_p (XEXP (operands[3], 0),
1309 plus_constant (Pmode,
1310 XEXP (operands[1], 0),
1311 GET_MODE_SIZE (SFmode)))"
1315 [(set_attr "type" "neon_load1_2reg,load2")
1316 (set_attr "fp" "yes,*")]
1319 (define_insn "load_pairdf"
1320 [(set (match_operand:DF 0 "register_operand" "=w,*r")
1321 (match_operand:DF 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1322 (set (match_operand:DF 2 "register_operand" "=w,*r")
1323 (match_operand:DF 3 "memory_operand" "m,m"))]
1324 "rtx_equal_p (XEXP (operands[3], 0),
1325 plus_constant (Pmode,
1326 XEXP (operands[1], 0),
1327 GET_MODE_SIZE (DFmode)))"
1331 [(set_attr "type" "neon_load1_2reg,load2")
1332 (set_attr "fp" "yes,*")]
1335 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1336 ;; fairly lax checking on the second memory operation.
1337 (define_insn "store_pairsf"
1338 [(set (match_operand:SF 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1339 (match_operand:SF 1 "register_operand" "w,*r"))
1340 (set (match_operand:SF 2 "memory_operand" "=m,m")
1341 (match_operand:SF 3 "register_operand" "w,*r"))]
1342 "rtx_equal_p (XEXP (operands[2], 0),
1343 plus_constant (Pmode,
1344 XEXP (operands[0], 0),
1345 GET_MODE_SIZE (SFmode)))"
1349 [(set_attr "type" "neon_store1_2reg,store2")
1350 (set_attr "fp" "yes,*")]
1353 (define_insn "store_pairdf"
1354 [(set (match_operand:DF 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1355 (match_operand:DF 1 "register_operand" "w,*r"))
1356 (set (match_operand:DF 2 "memory_operand" "=m,m")
1357 (match_operand:DF 3 "register_operand" "w,*r"))]
1358 "rtx_equal_p (XEXP (operands[2], 0),
1359 plus_constant (Pmode,
1360 XEXP (operands[0], 0),
1361 GET_MODE_SIZE (DFmode)))"
1365 [(set_attr "type" "neon_store1_2reg,store2")
1366 (set_attr "fp" "yes,*")]
1369 ;; Load pair with post-index writeback. This is primarily used in function
1371 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
1373 [(set (match_operand:P 0 "register_operand" "=k")
1374 (plus:P (match_operand:P 1 "register_operand" "0")
1375 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1376 (set (match_operand:GPI 2 "register_operand" "=r")
1377 (mem:GPI (match_dup 1)))
1378 (set (match_operand:GPI 3 "register_operand" "=r")
1379 (mem:GPI (plus:P (match_dup 1)
1380 (match_operand:P 5 "const_int_operand" "n"))))])]
1381 "INTVAL (operands[5]) == GET_MODE_SIZE (<GPI:MODE>mode)"
1382 "ldp\\t%<w>2, %<w>3, [%1], %4"
1383 [(set_attr "type" "load2")]
1386 (define_insn "loadwb_pair<GPF:mode>_<P:mode>"
1388 [(set (match_operand:P 0 "register_operand" "=k")
1389 (plus:P (match_operand:P 1 "register_operand" "0")
1390 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1391 (set (match_operand:GPF 2 "register_operand" "=w")
1392 (mem:GPF (match_dup 1)))
1393 (set (match_operand:GPF 3 "register_operand" "=w")
1394 (mem:GPF (plus:P (match_dup 1)
1395 (match_operand:P 5 "const_int_operand" "n"))))])]
1396 "INTVAL (operands[5]) == GET_MODE_SIZE (<GPF:MODE>mode)"
1397 "ldp\\t%<w>2, %<w>3, [%1], %4"
1398 [(set_attr "type" "neon_load1_2reg")]
1401 ;; Store pair with pre-index writeback. This is primarily used in function
1403 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
1405 [(set (match_operand:P 0 "register_operand" "=&k")
1406 (plus:P (match_operand:P 1 "register_operand" "0")
1407 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1408 (set (mem:GPI (plus:P (match_dup 0)
1410 (match_operand:GPI 2 "register_operand" "r"))
1411 (set (mem:GPI (plus:P (match_dup 0)
1412 (match_operand:P 5 "const_int_operand" "n")))
1413 (match_operand:GPI 3 "register_operand" "r"))])]
1414 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1415 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1416 [(set_attr "type" "store2")]
1419 (define_insn "storewb_pair<GPF:mode>_<P:mode>"
1421 [(set (match_operand:P 0 "register_operand" "=&k")
1422 (plus:P (match_operand:P 1 "register_operand" "0")
1423 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1424 (set (mem:GPF (plus:P (match_dup 0)
1426 (match_operand:GPF 2 "register_operand" "w"))
1427 (set (mem:GPF (plus:P (match_dup 0)
1428 (match_operand:P 5 "const_int_operand" "n")))
1429 (match_operand:GPF 3 "register_operand" "w"))])]
1430 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPF:MODE>mode)"
1431 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1432 [(set_attr "type" "neon_store1_2reg<q>")]
1435 ;; -------------------------------------------------------------------
1436 ;; Sign/Zero extension
1437 ;; -------------------------------------------------------------------
1439 (define_expand "<optab>sidi2"
1440 [(set (match_operand:DI 0 "register_operand")
1441 (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1445 (define_insn "*extendsidi2_aarch64"
1446 [(set (match_operand:DI 0 "register_operand" "=r,r")
1447 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1452 [(set_attr "type" "extend,load1")]
1455 (define_insn "*load_pair_extendsidi2_aarch64"
1456 [(set (match_operand:DI 0 "register_operand" "=r")
1457 (sign_extend:DI (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump")))
1458 (set (match_operand:DI 2 "register_operand" "=r")
1459 (sign_extend:DI (match_operand:SI 3 "memory_operand" "m")))]
1460 "rtx_equal_p (XEXP (operands[3], 0),
1461 plus_constant (Pmode,
1462 XEXP (operands[1], 0),
1463 GET_MODE_SIZE (SImode)))"
1464 "ldpsw\\t%0, %2, %1"
1465 [(set_attr "type" "load2")]
1468 (define_insn "*zero_extendsidi2_aarch64"
1469 [(set (match_operand:DI 0 "register_operand" "=r,r")
1470 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1475 [(set_attr "type" "extend,load1")]
1478 (define_insn "*load_pair_zero_extendsidi2_aarch64"
1479 [(set (match_operand:DI 0 "register_operand" "=r")
1480 (zero_extend:DI (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump")))
1481 (set (match_operand:DI 2 "register_operand" "=r")
1482 (zero_extend:DI (match_operand:SI 3 "memory_operand" "m")))]
1483 "rtx_equal_p (XEXP (operands[3], 0),
1484 plus_constant (Pmode,
1485 XEXP (operands[1], 0),
1486 GET_MODE_SIZE (SImode)))"
1487 "ldp\\t%w0, %w2, %1"
1488 [(set_attr "type" "load2")]
1491 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1492 [(set (match_operand:GPI 0 "register_operand")
1493 (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1497 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1498 [(set (match_operand:GPI 0 "register_operand" "=r,r")
1499 (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1502 sxt<SHORT:size>\t%<GPI:w>0, %w1
1503 ldrs<SHORT:size>\t%<GPI:w>0, %1"
1504 [(set_attr "type" "extend,load1")]
1507 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1508 [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1509 (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1512 uxt<SHORT:size>\t%<GPI:w>0, %w1
1513 ldr<SHORT:size>\t%w0, %1
1514 ldr\t%<SHORT:size>0, %1"
1515 [(set_attr "type" "extend,load1,load1")]
1518 (define_expand "<optab>qihi2"
1519 [(set (match_operand:HI 0 "register_operand")
1520 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1524 (define_insn "*<optab>qihi2_aarch64"
1525 [(set (match_operand:HI 0 "register_operand" "=r,r")
1526 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1531 [(set_attr "type" "extend,load1")]
1534 ;; -------------------------------------------------------------------
1535 ;; Simple arithmetic
1536 ;; -------------------------------------------------------------------
1538 (define_expand "add<mode>3"
1540 (match_operand:GPI 0 "register_operand" "")
1541 (plus:GPI (match_operand:GPI 1 "register_operand" "")
1542 (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1545 if (! aarch64_plus_operand (operands[2], VOIDmode))
1547 HOST_WIDE_INT imm = INTVAL (operands[2]);
1549 if (aarch64_move_imm (imm, <MODE>mode) && can_create_pseudo_p ())
1551 rtx tmp = gen_reg_rtx (<MODE>mode);
1552 emit_move_insn (tmp, operands[2]);
1557 rtx subtarget = ((optimize && can_create_pseudo_p ())
1558 ? gen_reg_rtx (<MODE>mode) : operands[0]);
1561 imm = -(-imm & ~0xfff);
1565 emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1566 operands[1] = subtarget;
1567 operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1573 (define_insn "*addsi3_aarch64"
1575 (match_operand:SI 0 "register_operand" "=rk,rk,w,rk")
1577 (match_operand:SI 1 "register_operand" "%rk,rk,w,rk")
1578 (match_operand:SI 2 "aarch64_plus_operand" "I,r,w,J")))]
1583 add\\t%0.2s, %1.2s, %2.2s
1584 sub\\t%w0, %w1, #%n2"
1585 [(set_attr "type" "alu_imm,alu_sreg,neon_add,alu_imm")
1586 (set_attr "simd" "*,*,yes,*")]
1589 ;; zero_extend version of above
1590 (define_insn "*addsi3_aarch64_uxtw"
1592 (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1594 (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1595 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1600 sub\\t%w0, %w1, #%n2"
1601 [(set_attr "type" "alu_imm,alu_sreg,alu_imm")]
1604 (define_insn "*adddi3_aarch64"
1606 (match_operand:DI 0 "register_operand" "=rk,rk,rk,w")
1608 (match_operand:DI 1 "register_operand" "%rk,rk,rk,w")
1609 (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,w")))]
1614 sub\\t%x0, %x1, #%n2
1615 add\\t%d0, %d1, %d2"
1616 [(set_attr "type" "alu_imm,alu_sreg,alu_imm,neon_add")
1617 (set_attr "simd" "*,*,*,yes")]
1620 (define_expand "addti3"
1621 [(set (match_operand:TI 0 "register_operand" "")
1622 (plus:TI (match_operand:TI 1 "register_operand" "")
1623 (match_operand:TI 2 "register_operand" "")))]
1626 rtx low = gen_reg_rtx (DImode);
1627 emit_insn (gen_adddi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1628 gen_lowpart (DImode, operands[2])));
1630 rtx high = gen_reg_rtx (DImode);
1631 emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]),
1632 gen_highpart (DImode, operands[2])));
1634 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1635 emit_move_insn (gen_highpart (DImode, operands[0]), high);
1639 (define_insn "add<mode>3_compare0"
1640 [(set (reg:CC_NZ CC_REGNUM)
1642 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1643 (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1645 (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1646 (plus:GPI (match_dup 1) (match_dup 2)))]
1649 adds\\t%<w>0, %<w>1, %<w>2
1650 adds\\t%<w>0, %<w>1, %<w>2
1651 subs\\t%<w>0, %<w>1, #%n2"
1652 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1655 ;; zero_extend version of above
1656 (define_insn "*addsi3_compare0_uxtw"
1657 [(set (reg:CC_NZ CC_REGNUM)
1659 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1660 (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1662 (set (match_operand:DI 0 "register_operand" "=r,r,r")
1663 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1666 adds\\t%w0, %w1, %w2
1667 adds\\t%w0, %w1, %w2
1668 subs\\t%w0, %w1, #%n2"
1669 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1672 (define_insn "*adds_shift_imm_<mode>"
1673 [(set (reg:CC_NZ CC_REGNUM)
1675 (plus:GPI (ASHIFT:GPI
1676 (match_operand:GPI 1 "register_operand" "r")
1677 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1678 (match_operand:GPI 3 "register_operand" "r"))
1680 (set (match_operand:GPI 0 "register_operand" "=r")
1681 (plus:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))
1684 "adds\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1685 [(set_attr "type" "alus_shift_imm")]
1688 (define_insn "*subs_shift_imm_<mode>"
1689 [(set (reg:CC_NZ CC_REGNUM)
1691 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1693 (match_operand:GPI 2 "register_operand" "r")
1694 (match_operand:QI 3 "aarch64_shift_imm_<mode>" "n")))
1696 (set (match_operand:GPI 0 "register_operand" "=r")
1697 (minus:GPI (match_dup 1)
1698 (ASHIFT:GPI (match_dup 2) (match_dup 3))))]
1700 "subs\\t%<w>0, %<w>1, %<w>2, <shift> %3"
1701 [(set_attr "type" "alus_shift_imm")]
1704 (define_insn "*adds_mul_imm_<mode>"
1705 [(set (reg:CC_NZ CC_REGNUM)
1708 (match_operand:GPI 1 "register_operand" "r")
1709 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1710 (match_operand:GPI 3 "register_operand" "r"))
1712 (set (match_operand:GPI 0 "register_operand" "=r")
1713 (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1716 "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1717 [(set_attr "type" "alus_shift_imm")]
1720 (define_insn "*subs_mul_imm_<mode>"
1721 [(set (reg:CC_NZ CC_REGNUM)
1723 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1725 (match_operand:GPI 2 "register_operand" "r")
1726 (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1728 (set (match_operand:GPI 0 "register_operand" "=r")
1729 (minus:GPI (match_dup 1)
1730 (mult:GPI (match_dup 2) (match_dup 3))))]
1732 "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1733 [(set_attr "type" "alus_shift_imm")]
1736 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1737 [(set (reg:CC_NZ CC_REGNUM)
1740 (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1741 (match_operand:GPI 2 "register_operand" "r"))
1743 (set (match_operand:GPI 0 "register_operand" "=r")
1744 (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1746 "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1747 [(set_attr "type" "alus_ext")]
1750 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1751 [(set (reg:CC_NZ CC_REGNUM)
1753 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1755 (match_operand:ALLX 2 "register_operand" "r")))
1757 (set (match_operand:GPI 0 "register_operand" "=r")
1758 (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1760 "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1761 [(set_attr "type" "alus_ext")]
1764 (define_insn "*adds_<optab><ALLX:mode>_shift_<GPI:mode>"
1765 [(set (reg:CC_NZ CC_REGNUM)
1767 (plus:GPI (ashift:GPI
1769 (match_operand:ALLX 1 "register_operand" "r"))
1770 (match_operand 2 "aarch64_imm3" "Ui3"))
1771 (match_operand:GPI 3 "register_operand" "r"))
1773 (set (match_operand:GPI 0 "register_operand" "=rk")
1774 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI (match_dup 1))
1778 "adds\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1779 [(set_attr "type" "alus_ext")]
1782 (define_insn "*subs_<optab><ALLX:mode>_shift_<GPI:mode>"
1783 [(set (reg:CC_NZ CC_REGNUM)
1785 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1788 (match_operand:ALLX 2 "register_operand" "r"))
1789 (match_operand 3 "aarch64_imm3" "Ui3")))
1791 (set (match_operand:GPI 0 "register_operand" "=rk")
1792 (minus:GPI (match_dup 1)
1793 (ashift:GPI (ANY_EXTEND:GPI (match_dup 2))
1796 "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1797 [(set_attr "type" "alus_ext")]
1800 (define_insn "*adds_<optab><mode>_multp2"
1801 [(set (reg:CC_NZ CC_REGNUM)
1803 (plus:GPI (ANY_EXTRACT:GPI
1804 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1805 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1806 (match_operand 3 "const_int_operand" "n")
1808 (match_operand:GPI 4 "register_operand" "r"))
1810 (set (match_operand:GPI 0 "register_operand" "=r")
1811 (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1815 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1816 "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1817 [(set_attr "type" "alus_ext")]
1820 (define_insn "*subs_<optab><mode>_multp2"
1821 [(set (reg:CC_NZ CC_REGNUM)
1823 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1825 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1826 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1827 (match_operand 3 "const_int_operand" "n")
1830 (set (match_operand:GPI 0 "register_operand" "=r")
1831 (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1832 (mult:GPI (match_dup 1) (match_dup 2))
1835 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1836 "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1837 [(set_attr "type" "alus_ext")]
1840 (define_insn "*add<mode>3nr_compare0"
1841 [(set (reg:CC_NZ CC_REGNUM)
1843 (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1844 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1851 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1854 (define_insn "*compare_neg<mode>"
1855 [(set (reg:CC_Z CC_REGNUM)
1857 (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1858 (match_operand:GPI 1 "register_operand" "r")))]
1860 "cmn\\t%<w>1, %<w>0"
1861 [(set_attr "type" "alus_sreg")]
1864 (define_insn "*add_<shift>_<mode>"
1865 [(set (match_operand:GPI 0 "register_operand" "=r")
1866 (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1867 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1868 (match_operand:GPI 3 "register_operand" "r")))]
1870 "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1871 [(set_attr "type" "alu_shift_imm")]
1874 ;; zero_extend version of above
1875 (define_insn "*add_<shift>_si_uxtw"
1876 [(set (match_operand:DI 0 "register_operand" "=r")
1878 (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1879 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1880 (match_operand:SI 3 "register_operand" "r"))))]
1882 "add\\t%w0, %w3, %w1, <shift> %2"
1883 [(set_attr "type" "alu_shift_imm")]
1886 (define_insn "*add_mul_imm_<mode>"
1887 [(set (match_operand:GPI 0 "register_operand" "=r")
1888 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1889 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1890 (match_operand:GPI 3 "register_operand" "r")))]
1892 "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1893 [(set_attr "type" "alu_shift_imm")]
1896 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1897 [(set (match_operand:GPI 0 "register_operand" "=rk")
1898 (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1899 (match_operand:GPI 2 "register_operand" "r")))]
1901 "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1902 [(set_attr "type" "alu_ext")]
1905 ;; zero_extend version of above
1906 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1907 [(set (match_operand:DI 0 "register_operand" "=rk")
1909 (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1910 (match_operand:GPI 2 "register_operand" "r"))))]
1912 "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1913 [(set_attr "type" "alu_ext")]
1916 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1917 [(set (match_operand:GPI 0 "register_operand" "=rk")
1918 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1919 (match_operand:ALLX 1 "register_operand" "r"))
1920 (match_operand 2 "aarch64_imm3" "Ui3"))
1921 (match_operand:GPI 3 "register_operand" "r")))]
1923 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1924 [(set_attr "type" "alu_ext")]
1927 ;; zero_extend version of above
1928 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1929 [(set (match_operand:DI 0 "register_operand" "=rk")
1931 (plus:SI (ashift:SI (ANY_EXTEND:SI
1932 (match_operand:SHORT 1 "register_operand" "r"))
1933 (match_operand 2 "aarch64_imm3" "Ui3"))
1934 (match_operand:SI 3 "register_operand" "r"))))]
1936 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1937 [(set_attr "type" "alu_ext")]
1940 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1941 [(set (match_operand:GPI 0 "register_operand" "=rk")
1942 (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1943 (match_operand:ALLX 1 "register_operand" "r"))
1944 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1945 (match_operand:GPI 3 "register_operand" "r")))]
1947 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1948 [(set_attr "type" "alu_ext")]
1951 ;; zero_extend version of above
1952 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1953 [(set (match_operand:DI 0 "register_operand" "=rk")
1954 (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1955 (match_operand:SHORT 1 "register_operand" "r"))
1956 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1957 (match_operand:SI 3 "register_operand" "r"))))]
1959 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1960 [(set_attr "type" "alu_ext")]
1963 (define_insn "*add_<optab><mode>_multp2"
1964 [(set (match_operand:GPI 0 "register_operand" "=rk")
1965 (plus:GPI (ANY_EXTRACT:GPI
1966 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1967 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1968 (match_operand 3 "const_int_operand" "n")
1970 (match_operand:GPI 4 "register_operand" "r")))]
1971 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1972 "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1973 [(set_attr "type" "alu_ext")]
1976 ;; zero_extend version of above
1977 (define_insn "*add_<optab>si_multp2_uxtw"
1978 [(set (match_operand:DI 0 "register_operand" "=rk")
1980 (plus:SI (ANY_EXTRACT:SI
1981 (mult:SI (match_operand:SI 1 "register_operand" "r")
1982 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1983 (match_operand 3 "const_int_operand" "n")
1985 (match_operand:SI 4 "register_operand" "r"))))]
1986 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1987 "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1988 [(set_attr "type" "alu_ext")]
1991 (define_insn "add<mode>3_carryin"
1993 (match_operand:GPI 0 "register_operand" "=r")
1994 (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1996 (match_operand:GPI 1 "register_operand" "r")
1997 (match_operand:GPI 2 "register_operand" "r"))))]
1999 "adc\\t%<w>0, %<w>1, %<w>2"
2000 [(set_attr "type" "adc_reg")]
2003 ;; zero_extend version of above
2004 (define_insn "*addsi3_carryin_uxtw"
2006 (match_operand:DI 0 "register_operand" "=r")
2008 (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
2010 (match_operand:SI 1 "register_operand" "r")
2011 (match_operand:SI 2 "register_operand" "r")))))]
2013 "adc\\t%w0, %w1, %w2"
2014 [(set_attr "type" "adc_reg")]
2017 (define_insn "*add<mode>3_carryin_alt1"
2019 (match_operand:GPI 0 "register_operand" "=r")
2021 (match_operand:GPI 1 "register_operand" "r")
2022 (match_operand:GPI 2 "register_operand" "r"))
2023 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
2025 "adc\\t%<w>0, %<w>1, %<w>2"
2026 [(set_attr "type" "adc_reg")]
2029 ;; zero_extend version of above
2030 (define_insn "*addsi3_carryin_alt1_uxtw"
2032 (match_operand:DI 0 "register_operand" "=r")
2035 (match_operand:SI 1 "register_operand" "r")
2036 (match_operand:SI 2 "register_operand" "r"))
2037 (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
2039 "adc\\t%w0, %w1, %w2"
2040 [(set_attr "type" "adc_reg")]
2043 (define_insn "*add<mode>3_carryin_alt2"
2045 (match_operand:GPI 0 "register_operand" "=r")
2047 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
2048 (match_operand:GPI 1 "register_operand" "r"))
2049 (match_operand:GPI 2 "register_operand" "r")))]
2051 "adc\\t%<w>0, %<w>1, %<w>2"
2052 [(set_attr "type" "adc_reg")]
2055 ;; zero_extend version of above
2056 (define_insn "*addsi3_carryin_alt2_uxtw"
2058 (match_operand:DI 0 "register_operand" "=r")
2061 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
2062 (match_operand:SI 1 "register_operand" "r"))
2063 (match_operand:SI 2 "register_operand" "r"))))]
2065 "adc\\t%w0, %w1, %w2"
2066 [(set_attr "type" "adc_reg")]
2069 (define_insn "*add<mode>3_carryin_alt3"
2071 (match_operand:GPI 0 "register_operand" "=r")
2073 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
2074 (match_operand:GPI 2 "register_operand" "r"))
2075 (match_operand:GPI 1 "register_operand" "r")))]
2077 "adc\\t%<w>0, %<w>1, %<w>2"
2078 [(set_attr "type" "adc_reg")]
2081 ;; zero_extend version of above
2082 (define_insn "*addsi3_carryin_alt3_uxtw"
2084 (match_operand:DI 0 "register_operand" "=r")
2087 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
2088 (match_operand:SI 2 "register_operand" "r"))
2089 (match_operand:SI 1 "register_operand" "r"))))]
2091 "adc\\t%w0, %w1, %w2"
2092 [(set_attr "type" "adc_reg")]
2095 (define_insn "*add_uxt<mode>_shift2"
2096 [(set (match_operand:GPI 0 "register_operand" "=rk")
2098 (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
2099 (match_operand 2 "aarch64_imm3" "Ui3"))
2100 (match_operand 3 "const_int_operand" "n"))
2101 (match_operand:GPI 4 "register_operand" "r")))]
2102 "aarch64_uxt_size (INTVAL (operands[2]), INTVAL (operands[3])) != 0"
2104 operands[3] = GEN_INT (aarch64_uxt_size (INTVAL(operands[2]),
2105 INTVAL (operands[3])));
2106 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %2\";"
2107 [(set_attr "type" "alu_ext")]
2110 ;; zero_extend version of above
2111 (define_insn "*add_uxtsi_shift2_uxtw"
2112 [(set (match_operand:DI 0 "register_operand" "=rk")
2115 (ashift:SI (match_operand:SI 1 "register_operand" "r")
2116 (match_operand 2 "aarch64_imm3" "Ui3"))
2117 (match_operand 3 "const_int_operand" "n"))
2118 (match_operand:SI 4 "register_operand" "r"))))]
2119 "aarch64_uxt_size (INTVAL (operands[2]), INTVAL (operands[3])) != 0"
2121 operands[3] = GEN_INT (aarch64_uxt_size (INTVAL (operands[2]),
2122 INTVAL (operands[3])));
2123 return \"add\t%w0, %w4, %w1, uxt%e3 %2\";"
2124 [(set_attr "type" "alu_ext")]
2127 (define_insn "*add_uxt<mode>_multp2"
2128 [(set (match_operand:GPI 0 "register_operand" "=rk")
2130 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2131 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2132 (match_operand 3 "const_int_operand" "n"))
2133 (match_operand:GPI 4 "register_operand" "r")))]
2134 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
2136 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2137 INTVAL (operands[3])));
2138 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
2139 [(set_attr "type" "alu_ext")]
2142 ;; zero_extend version of above
2143 (define_insn "*add_uxtsi_multp2_uxtw"
2144 [(set (match_operand:DI 0 "register_operand" "=rk")
2147 (mult:SI (match_operand:SI 1 "register_operand" "r")
2148 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2149 (match_operand 3 "const_int_operand" "n"))
2150 (match_operand:SI 4 "register_operand" "r"))))]
2151 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
2153 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2154 INTVAL (operands[3])));
2155 return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
2156 [(set_attr "type" "alu_ext")]
2159 (define_insn "subsi3"
2160 [(set (match_operand:SI 0 "register_operand" "=rk")
2161 (minus:SI (match_operand:SI 1 "register_operand" "rk")
2162 (match_operand:SI 2 "register_operand" "r")))]
2164 "sub\\t%w0, %w1, %w2"
2165 [(set_attr "type" "alu_sreg")]
2168 ;; zero_extend version of above
2169 (define_insn "*subsi3_uxtw"
2170 [(set (match_operand:DI 0 "register_operand" "=rk")
2172 (minus:SI (match_operand:SI 1 "register_operand" "rk")
2173 (match_operand:SI 2 "register_operand" "r"))))]
2175 "sub\\t%w0, %w1, %w2"
2176 [(set_attr "type" "alu_sreg")]
2179 (define_insn "subdi3"
2180 [(set (match_operand:DI 0 "register_operand" "=rk,w")
2181 (minus:DI (match_operand:DI 1 "register_operand" "rk,w")
2182 (match_operand:DI 2 "register_operand" "r,w")))]
2186 sub\\t%d0, %d1, %d2"
2187 [(set_attr "type" "alu_sreg, neon_sub")
2188 (set_attr "simd" "*,yes")]
2191 (define_expand "subti3"
2192 [(set (match_operand:TI 0 "register_operand" "")
2193 (minus:TI (match_operand:TI 1 "register_operand" "")
2194 (match_operand:TI 2 "register_operand" "")))]
2197 rtx low = gen_reg_rtx (DImode);
2198 emit_insn (gen_subdi3_compare0 (low, gen_lowpart (DImode, operands[1]),
2199 gen_lowpart (DImode, operands[2])));
2201 rtx high = gen_reg_rtx (DImode);
2202 emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]),
2203 gen_highpart (DImode, operands[2])));
2205 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2206 emit_move_insn (gen_highpart (DImode, operands[0]), high);
2210 (define_insn "sub<mode>3_compare0"
2211 [(set (reg:CC_NZ CC_REGNUM)
2212 (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
2213 (match_operand:GPI 2 "register_operand" "r"))
2215 (set (match_operand:GPI 0 "register_operand" "=r")
2216 (minus:GPI (match_dup 1) (match_dup 2)))]
2218 "subs\\t%<w>0, %<w>1, %<w>2"
2219 [(set_attr "type" "alus_sreg")]
2222 ;; zero_extend version of above
2223 (define_insn "*subsi3_compare0_uxtw"
2224 [(set (reg:CC_NZ CC_REGNUM)
2225 (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
2226 (match_operand:SI 2 "register_operand" "r"))
2228 (set (match_operand:DI 0 "register_operand" "=r")
2229 (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
2231 "subs\\t%w0, %w1, %w2"
2232 [(set_attr "type" "alus_sreg")]
2235 (define_insn "*sub_<shift>_<mode>"
2236 [(set (match_operand:GPI 0 "register_operand" "=r")
2237 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2239 (match_operand:GPI 1 "register_operand" "r")
2240 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2242 "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
2243 [(set_attr "type" "alu_shift_imm")]
2246 ;; zero_extend version of above
2247 (define_insn "*sub_<shift>_si_uxtw"
2248 [(set (match_operand:DI 0 "register_operand" "=r")
2250 (minus:SI (match_operand:SI 3 "register_operand" "r")
2252 (match_operand:SI 1 "register_operand" "r")
2253 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2255 "sub\\t%w0, %w3, %w1, <shift> %2"
2256 [(set_attr "type" "alu_shift_imm")]
2259 (define_insn "*sub_mul_imm_<mode>"
2260 [(set (match_operand:GPI 0 "register_operand" "=r")
2261 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2263 (match_operand:GPI 1 "register_operand" "r")
2264 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2266 "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
2267 [(set_attr "type" "alu_shift_imm")]
2270 ;; zero_extend version of above
2271 (define_insn "*sub_mul_imm_si_uxtw"
2272 [(set (match_operand:DI 0 "register_operand" "=r")
2274 (minus:SI (match_operand:SI 3 "register_operand" "r")
2276 (match_operand:SI 1 "register_operand" "r")
2277 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2279 "sub\\t%w0, %w3, %w1, lsl %p2"
2280 [(set_attr "type" "alu_shift_imm")]
2283 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
2284 [(set (match_operand:GPI 0 "register_operand" "=rk")
2285 (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
2287 (match_operand:ALLX 2 "register_operand" "r"))))]
2289 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
2290 [(set_attr "type" "alu_ext")]
2293 ;; zero_extend version of above
2294 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
2295 [(set (match_operand:DI 0 "register_operand" "=rk")
2297 (minus:SI (match_operand:SI 1 "register_operand" "rk")
2299 (match_operand:SHORT 2 "register_operand" "r")))))]
2301 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
2302 [(set_attr "type" "alu_ext")]
2305 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
2306 [(set (match_operand:GPI 0 "register_operand" "=rk")
2307 (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
2308 (ashift:GPI (ANY_EXTEND:GPI
2309 (match_operand:ALLX 2 "register_operand" "r"))
2310 (match_operand 3 "aarch64_imm3" "Ui3"))))]
2312 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
2313 [(set_attr "type" "alu_ext")]
2316 ;; zero_extend version of above
2317 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
2318 [(set (match_operand:DI 0 "register_operand" "=rk")
2320 (minus:SI (match_operand:SI 1 "register_operand" "rk")
2321 (ashift:SI (ANY_EXTEND:SI
2322 (match_operand:SHORT 2 "register_operand" "r"))
2323 (match_operand 3 "aarch64_imm3" "Ui3")))))]
2325 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
2326 [(set_attr "type" "alu_ext")]
2329 (define_insn "*sub_<optab><mode>_multp2"
2330 [(set (match_operand:GPI 0 "register_operand" "=rk")
2331 (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
2333 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2334 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2335 (match_operand 3 "const_int_operand" "n")
2337 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
2338 "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
2339 [(set_attr "type" "alu_ext")]
2342 ;; zero_extend version of above
2343 (define_insn "*sub_<optab>si_multp2_uxtw"
2344 [(set (match_operand:DI 0 "register_operand" "=rk")
2346 (minus:SI (match_operand:SI 4 "register_operand" "rk")
2348 (mult:SI (match_operand:SI 1 "register_operand" "r")
2349 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2350 (match_operand 3 "const_int_operand" "n")
2352 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
2353 "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
2354 [(set_attr "type" "alu_ext")]
2357 (define_insn "sub<mode>3_carryin"
2359 (match_operand:GPI 0 "register_operand" "=r")
2360 (minus:GPI (minus:GPI
2361 (match_operand:GPI 1 "register_operand" "r")
2362 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2363 (match_operand:GPI 2 "register_operand" "r")))]
2365 "sbc\\t%<w>0, %<w>1, %<w>2"
2366 [(set_attr "type" "adc_reg")]
2369 ;; zero_extend version of the above
2370 (define_insn "*subsi3_carryin_uxtw"
2372 (match_operand:DI 0 "register_operand" "=r")
2375 (match_operand:SI 1 "register_operand" "r")
2376 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2377 (match_operand:SI 2 "register_operand" "r"))))]
2379 "sbc\\t%w0, %w1, %w2"
2380 [(set_attr "type" "adc_reg")]
2383 (define_insn "*sub_uxt<mode>_shift2"
2384 [(set (match_operand:GPI 0 "register_operand" "=rk")
2385 (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
2387 (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
2388 (match_operand 2 "aarch64_imm3" "Ui3"))
2389 (match_operand 3 "const_int_operand" "n"))))]
2390 "aarch64_uxt_size (INTVAL (operands[2]),INTVAL (operands[3])) != 0"
2392 operands[3] = GEN_INT (aarch64_uxt_size (INTVAL (operands[2]),
2393 INTVAL (operands[3])));
2394 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %2\";"
2395 [(set_attr "type" "alu_ext")]
2398 ;; zero_extend version of above
2399 (define_insn "*sub_uxtsi_shift2_uxtw"
2400 [(set (match_operand:DI 0 "register_operand" "=rk")
2402 (minus:SI (match_operand:SI 4 "register_operand" "rk")
2404 (ashift:SI (match_operand:SI 1 "register_operand" "r")
2405 (match_operand 2 "aarch64_imm3" "Ui3"))
2406 (match_operand 3 "const_int_operand" "n")))))]
2407 "aarch64_uxt_size (INTVAL (operands[2]),INTVAL (operands[3])) != 0"
2409 operands[3] = GEN_INT (aarch64_uxt_size (INTVAL (operands[2]),
2410 INTVAL (operands[3])));
2411 return \"sub\t%w0, %w4, %w1, uxt%e3 %2\";"
2412 [(set_attr "type" "alu_ext")]
2415 (define_insn "*sub_uxt<mode>_multp2"
2416 [(set (match_operand:GPI 0 "register_operand" "=rk")
2417 (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
2419 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2420 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2421 (match_operand 3 "const_int_operand" "n"))))]
2422 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2424 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2425 INTVAL (operands[3])));
2426 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
2427 [(set_attr "type" "alu_ext")]
2430 ;; zero_extend version of above
2431 (define_insn "*sub_uxtsi_multp2_uxtw"
2432 [(set (match_operand:DI 0 "register_operand" "=rk")
2434 (minus:SI (match_operand:SI 4 "register_operand" "rk")
2436 (mult:SI (match_operand:SI 1 "register_operand" "r")
2437 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2438 (match_operand 3 "const_int_operand" "n")))))]
2439 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2441 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2442 INTVAL (operands[3])));
2443 return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
2444 [(set_attr "type" "alu_ext")]
2447 (define_expand "abs<mode>2"
2448 [(match_operand:GPI 0 "register_operand" "")
2449 (match_operand:GPI 1 "register_operand" "")]
2452 rtx ccreg = aarch64_gen_compare_reg (LT, operands[1], const0_rtx);
2453 rtx x = gen_rtx_LT (VOIDmode, ccreg, const0_rtx);
2454 emit_insn (gen_csneg3<mode>_insn (operands[0], x, operands[1], operands[1]));
2459 (define_insn "neg<mode>2"
2460 [(set (match_operand:GPI 0 "register_operand" "=r,w")
2461 (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
2465 neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
2466 [(set_attr "type" "alu_sreg, neon_neg<q>")
2467 (set_attr "simd" "*,yes")]
2470 ;; zero_extend version of above
2471 (define_insn "*negsi2_uxtw"
2472 [(set (match_operand:DI 0 "register_operand" "=r")
2473 (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
2476 [(set_attr "type" "alu_sreg")]
2479 (define_insn "*ngc<mode>"
2480 [(set (match_operand:GPI 0 "register_operand" "=r")
2481 (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2482 (match_operand:GPI 1 "register_operand" "r")))]
2484 "ngc\\t%<w>0, %<w>1"
2485 [(set_attr "type" "adc_reg")]
2488 (define_insn "*ngcsi_uxtw"
2489 [(set (match_operand:DI 0 "register_operand" "=r")
2491 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2492 (match_operand:SI 1 "register_operand" "r"))))]
2495 [(set_attr "type" "adc_reg")]
2498 (define_insn "neg<mode>2_compare0"
2499 [(set (reg:CC_NZ CC_REGNUM)
2500 (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2502 (set (match_operand:GPI 0 "register_operand" "=r")
2503 (neg:GPI (match_dup 1)))]
2505 "negs\\t%<w>0, %<w>1"
2506 [(set_attr "type" "alus_sreg")]
2509 ;; zero_extend version of above
2510 (define_insn "*negsi2_compare0_uxtw"
2511 [(set (reg:CC_NZ CC_REGNUM)
2512 (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
2514 (set (match_operand:DI 0 "register_operand" "=r")
2515 (zero_extend:DI (neg:SI (match_dup 1))))]
2518 [(set_attr "type" "alus_sreg")]
2521 (define_insn "*neg_<shift><mode>3_compare0"
2522 [(set (reg:CC_NZ CC_REGNUM)
2524 (neg:GPI (ASHIFT:GPI
2525 (match_operand:GPI 1 "register_operand" "r")
2526 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2528 (set (match_operand:GPI 0 "register_operand" "=r")
2529 (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2531 "negs\\t%<w>0, %<w>1, <shift> %2"
2532 [(set_attr "type" "alus_shift_imm")]
2535 (define_insn "*neg_<shift>_<mode>2"
2536 [(set (match_operand:GPI 0 "register_operand" "=r")
2537 (neg:GPI (ASHIFT:GPI
2538 (match_operand:GPI 1 "register_operand" "r")
2539 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2541 "neg\\t%<w>0, %<w>1, <shift> %2"
2542 [(set_attr "type" "alu_shift_imm")]
2545 ;; zero_extend version of above
2546 (define_insn "*neg_<shift>_si2_uxtw"
2547 [(set (match_operand:DI 0 "register_operand" "=r")
2550 (match_operand:SI 1 "register_operand" "r")
2551 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2553 "neg\\t%w0, %w1, <shift> %2"
2554 [(set_attr "type" "alu_shift_imm")]
2557 (define_insn "*neg_mul_imm_<mode>2"
2558 [(set (match_operand:GPI 0 "register_operand" "=r")
2560 (match_operand:GPI 1 "register_operand" "r")
2561 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2563 "neg\\t%<w>0, %<w>1, lsl %p2"
2564 [(set_attr "type" "alu_shift_imm")]
2567 ;; zero_extend version of above
2568 (define_insn "*neg_mul_imm_si2_uxtw"
2569 [(set (match_operand:DI 0 "register_operand" "=r")
2572 (match_operand:SI 1 "register_operand" "r")
2573 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2575 "neg\\t%w0, %w1, lsl %p2"
2576 [(set_attr "type" "alu_shift_imm")]
2579 (define_insn "mul<mode>3"
2580 [(set (match_operand:GPI 0 "register_operand" "=r")
2581 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2582 (match_operand:GPI 2 "register_operand" "r")))]
2584 "mul\\t%<w>0, %<w>1, %<w>2"
2585 [(set_attr "type" "mul")]
2588 ;; zero_extend version of above
2589 (define_insn "*mulsi3_uxtw"
2590 [(set (match_operand:DI 0 "register_operand" "=r")
2592 (mult:SI (match_operand:SI 1 "register_operand" "r")
2593 (match_operand:SI 2 "register_operand" "r"))))]
2595 "mul\\t%w0, %w1, %w2"
2596 [(set_attr "type" "mul")]
2599 (define_insn "madd<mode>"
2600 [(set (match_operand:GPI 0 "register_operand" "=r")
2601 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2602 (match_operand:GPI 2 "register_operand" "r"))
2603 (match_operand:GPI 3 "register_operand" "r")))]
2605 "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2606 [(set_attr "type" "mla")]
2609 ;; zero_extend version of above
2610 (define_insn "*maddsi_uxtw"
2611 [(set (match_operand:DI 0 "register_operand" "=r")
2613 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2614 (match_operand:SI 2 "register_operand" "r"))
2615 (match_operand:SI 3 "register_operand" "r"))))]
2617 "madd\\t%w0, %w1, %w2, %w3"
2618 [(set_attr "type" "mla")]
2621 (define_insn "*msub<mode>"
2622 [(set (match_operand:GPI 0 "register_operand" "=r")
2623 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2624 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2625 (match_operand:GPI 2 "register_operand" "r"))))]
2628 "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2629 [(set_attr "type" "mla")]
2632 ;; zero_extend version of above
2633 (define_insn "*msubsi_uxtw"
2634 [(set (match_operand:DI 0 "register_operand" "=r")
2636 (minus:SI (match_operand:SI 3 "register_operand" "r")
2637 (mult:SI (match_operand:SI 1 "register_operand" "r")
2638 (match_operand:SI 2 "register_operand" "r")))))]
2641 "msub\\t%w0, %w1, %w2, %w3"
2642 [(set_attr "type" "mla")]
2645 (define_insn "*mul<mode>_neg"
2646 [(set (match_operand:GPI 0 "register_operand" "=r")
2647 (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2648 (match_operand:GPI 2 "register_operand" "r")))]
2651 "mneg\\t%<w>0, %<w>1, %<w>2"
2652 [(set_attr "type" "mul")]
2655 ;; zero_extend version of above
2656 (define_insn "*mulsi_neg_uxtw"
2657 [(set (match_operand:DI 0 "register_operand" "=r")
2659 (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2660 (match_operand:SI 2 "register_operand" "r"))))]
2663 "mneg\\t%w0, %w1, %w2"
2664 [(set_attr "type" "mul")]
2667 (define_insn "<su_optab>mulsidi3"
2668 [(set (match_operand:DI 0 "register_operand" "=r")
2669 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2670 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2672 "<su>mull\\t%0, %w1, %w2"
2673 [(set_attr "type" "<su>mull")]
2676 (define_insn "<su_optab>maddsidi4"
2677 [(set (match_operand:DI 0 "register_operand" "=r")
2679 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2680 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2681 (match_operand:DI 3 "register_operand" "r")))]
2683 "<su>maddl\\t%0, %w1, %w2, %3"
2684 [(set_attr "type" "<su>mlal")]
2687 (define_insn "<su_optab>msubsidi4"
2688 [(set (match_operand:DI 0 "register_operand" "=r")
2690 (match_operand:DI 3 "register_operand" "r")
2691 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2693 (match_operand:SI 2 "register_operand" "r")))))]
2695 "<su>msubl\\t%0, %w1, %w2, %3"
2696 [(set_attr "type" "<su>mlal")]
2699 (define_insn "*<su_optab>mulsidi_neg"
2700 [(set (match_operand:DI 0 "register_operand" "=r")
2702 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2703 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2705 "<su>mnegl\\t%0, %w1, %w2"
2706 [(set_attr "type" "<su>mull")]
2709 (define_expand "<su_optab>mulditi3"
2710 [(set (match_operand:TI 0 "register_operand")
2711 (mult:TI (ANY_EXTEND:TI (match_operand:DI 1 "register_operand"))
2712 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand"))))]
2715 rtx low = gen_reg_rtx (DImode);
2716 emit_insn (gen_muldi3 (low, operands[1], operands[2]));
2718 rtx high = gen_reg_rtx (DImode);
2719 emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2]));
2721 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2722 emit_move_insn (gen_highpart (DImode, operands[0]), high);
2726 ;; The default expansion of multi3 using umuldi3_highpart will perform
2727 ;; the additions in an order that fails to combine into two madd insns.
2728 (define_expand "multi3"
2729 [(set (match_operand:TI 0 "register_operand")
2730 (mult:TI (match_operand:TI 1 "register_operand")
2731 (match_operand:TI 2 "register_operand")))]
2734 rtx l0 = gen_reg_rtx (DImode);
2735 rtx l1 = gen_lowpart (DImode, operands[1]);
2736 rtx l2 = gen_lowpart (DImode, operands[2]);
2737 rtx h0 = gen_reg_rtx (DImode);
2738 rtx h1 = gen_highpart (DImode, operands[1]);
2739 rtx h2 = gen_highpart (DImode, operands[2]);
2741 emit_insn (gen_muldi3 (l0, l1, l2));
2742 emit_insn (gen_umuldi3_highpart (h0, l1, l2));
2743 emit_insn (gen_madddi (h0, h1, l2, h0));
2744 emit_insn (gen_madddi (h0, l1, h2, h0));
2746 emit_move_insn (gen_lowpart (DImode, operands[0]), l0);
2747 emit_move_insn (gen_highpart (DImode, operands[0]), h0);
2751 (define_insn "<su>muldi3_highpart"
2752 [(set (match_operand:DI 0 "register_operand" "=r")
2756 (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2757 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2760 "<su>mulh\\t%0, %1, %2"
2761 [(set_attr "type" "<su>mull")]
2764 (define_insn "<su_optab>div<mode>3"
2765 [(set (match_operand:GPI 0 "register_operand" "=r")
2766 (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2767 (match_operand:GPI 2 "register_operand" "r")))]
2769 "<su>div\\t%<w>0, %<w>1, %<w>2"
2770 [(set_attr "type" "<su>div")]
2773 ;; zero_extend version of above
2774 (define_insn "*<su_optab>divsi3_uxtw"
2775 [(set (match_operand:DI 0 "register_operand" "=r")
2777 (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2778 (match_operand:SI 2 "register_operand" "r"))))]
2780 "<su>div\\t%w0, %w1, %w2"
2781 [(set_attr "type" "<su>div")]
2784 ;; -------------------------------------------------------------------
2786 ;; -------------------------------------------------------------------
2788 (define_insn "*cmp<mode>"
2789 [(set (reg:CC CC_REGNUM)
2790 (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2791 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2797 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
2800 (define_insn "*cmp<mode>"
2801 [(set (reg:CCFP CC_REGNUM)
2802 (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2803 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2807 fcmp\\t%<s>0, %<s>1"
2808 [(set_attr "type" "fcmp<s>")]
2811 (define_insn "*cmpe<mode>"
2812 [(set (reg:CCFPE CC_REGNUM)
2813 (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2814 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2818 fcmpe\\t%<s>0, %<s>1"
2819 [(set_attr "type" "fcmp<s>")]
2822 (define_insn "*cmp_swp_<shift>_reg<mode>"
2823 [(set (reg:CC_SWP CC_REGNUM)
2824 (compare:CC_SWP (ASHIFT:GPI
2825 (match_operand:GPI 0 "register_operand" "r")
2826 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2827 (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2829 "cmp\\t%<w>2, %<w>0, <shift> %1"
2830 [(set_attr "type" "alus_shift_imm")]
2833 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2834 [(set (reg:CC_SWP CC_REGNUM)
2835 (compare:CC_SWP (ANY_EXTEND:GPI
2836 (match_operand:ALLX 0 "register_operand" "r"))
2837 (match_operand:GPI 1 "register_operand" "r")))]
2839 "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2840 [(set_attr "type" "alus_ext")]
2843 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2844 [(set (reg:CC_SWP CC_REGNUM)
2845 (compare:CC_SWP (ashift:GPI
2847 (match_operand:ALLX 0 "register_operand" "r"))
2848 (match_operand 1 "aarch64_imm3" "Ui3"))
2849 (match_operand:GPI 2 "register_operand" "r")))]
2851 "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2852 [(set_attr "type" "alus_ext")]
2855 ;; -------------------------------------------------------------------
2856 ;; Store-flag and conditional select insns
2857 ;; -------------------------------------------------------------------
2859 (define_expand "cstore<mode>4"
2860 [(set (match_operand:SI 0 "register_operand" "")
2861 (match_operator:SI 1 "aarch64_comparison_operator"
2862 [(match_operand:GPI 2 "register_operand" "")
2863 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2866 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2868 operands[3] = const0_rtx;
2872 (define_expand "cstorecc4"
2873 [(set (match_operand:SI 0 "register_operand")
2874 (match_operator 1 "aarch64_comparison_operator"
2875 [(match_operand 2 "ccmp_cc_register")
2876 (match_operand 3 "const0_operand")]))]
2879 emit_insn (gen_rtx_SET (operands[0], operands[1]));
2884 (define_expand "cstore<mode>4"
2885 [(set (match_operand:SI 0 "register_operand" "")
2886 (match_operator:SI 1 "aarch64_comparison_operator"
2887 [(match_operand:GPF 2 "register_operand" "")
2888 (match_operand:GPF 3 "register_operand" "")]))]
2891 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2893 operands[3] = const0_rtx;
2897 (define_insn "*cstore<mode>_insn"
2898 [(set (match_operand:ALLI 0 "register_operand" "=r")
2899 (match_operator:ALLI 1 "aarch64_comparison_operator"
2900 [(match_operand 2 "cc_register" "") (const_int 0)]))]
2903 [(set_attr "type" "csel")]
2906 ;; zero_extend version of the above
2907 (define_insn "*cstoresi_insn_uxtw"
2908 [(set (match_operand:DI 0 "register_operand" "=r")
2910 (match_operator:SI 1 "aarch64_comparison_operator"
2911 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2914 [(set_attr "type" "csel")]
2917 (define_insn "cstore<mode>_neg"
2918 [(set (match_operand:ALLI 0 "register_operand" "=r")
2919 (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2920 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2922 "csetm\\t%<w>0, %m1"
2923 [(set_attr "type" "csel")]
2926 ;; zero_extend version of the above
2927 (define_insn "*cstoresi_neg_uxtw"
2928 [(set (match_operand:DI 0 "register_operand" "=r")
2930 (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2931 [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2934 [(set_attr "type" "csel")]
2937 (define_expand "cmov<mode>6"
2938 [(set (match_operand:GPI 0 "register_operand" "")
2940 (match_operator 1 "aarch64_comparison_operator"
2941 [(match_operand:GPI 2 "register_operand" "")
2942 (match_operand:GPI 3 "aarch64_plus_operand" "")])
2943 (match_operand:GPI 4 "register_operand" "")
2944 (match_operand:GPI 5 "register_operand" "")))]
2947 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2949 operands[3] = const0_rtx;
2953 (define_expand "cmov<mode>6"
2954 [(set (match_operand:GPF 0 "register_operand" "")
2956 (match_operator 1 "aarch64_comparison_operator"
2957 [(match_operand:GPF 2 "register_operand" "")
2958 (match_operand:GPF 3 "register_operand" "")])
2959 (match_operand:GPF 4 "register_operand" "")
2960 (match_operand:GPF 5 "register_operand" "")))]
2963 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2965 operands[3] = const0_rtx;
2969 (define_insn "*cmov<mode>_insn"
2970 [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2972 (match_operator 1 "aarch64_comparison_operator"
2973 [(match_operand 2 "cc_register" "") (const_int 0)])
2974 (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2975 (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2976 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2977 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2978 ;; Final two alternatives should be unreachable, but included for completeness
2980 csel\\t%<w>0, %<w>3, %<w>4, %m1
2981 csinv\\t%<w>0, %<w>3, <w>zr, %m1
2982 csinv\\t%<w>0, %<w>4, <w>zr, %M1
2983 csinc\\t%<w>0, %<w>3, <w>zr, %m1
2984 csinc\\t%<w>0, %<w>4, <w>zr, %M1
2987 [(set_attr "type" "csel")]
2990 ;; zero_extend version of above
2991 (define_insn "*cmovsi_insn_uxtw"
2992 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2995 (match_operator 1 "aarch64_comparison_operator"
2996 [(match_operand 2 "cc_register" "") (const_int 0)])
2997 (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2998 (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2999 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
3000 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
3001 ;; Final two alternatives should be unreachable, but included for completeness
3003 csel\\t%w0, %w3, %w4, %m1
3004 csinv\\t%w0, %w3, wzr, %m1
3005 csinv\\t%w0, %w4, wzr, %M1
3006 csinc\\t%w0, %w3, wzr, %m1
3007 csinc\\t%w0, %w4, wzr, %M1
3010 [(set_attr "type" "csel")]
3013 (define_insn "*cmovdi_insn_uxtw"
3014 [(set (match_operand:DI 0 "register_operand" "=r")
3016 (match_operator 1 "aarch64_comparison_operator"
3017 [(match_operand 2 "cc_register" "") (const_int 0)])
3018 (zero_extend:DI (match_operand:SI 3 "register_operand" "r"))
3019 (zero_extend:DI (match_operand:SI 4 "register_operand" "r"))))]
3021 "csel\\t%w0, %w3, %w4, %m1"
3022 [(set_attr "type" "csel")]
3025 (define_insn "*cmov<mode>_insn"
3026 [(set (match_operand:GPF 0 "register_operand" "=w")
3028 (match_operator 1 "aarch64_comparison_operator"
3029 [(match_operand 2 "cc_register" "") (const_int 0)])
3030 (match_operand:GPF 3 "register_operand" "w")
3031 (match_operand:GPF 4 "register_operand" "w")))]
3033 "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
3034 [(set_attr "type" "fcsel")]
3037 (define_expand "mov<mode>cc"
3038 [(set (match_operand:ALLI 0 "register_operand" "")
3039 (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
3040 (match_operand:ALLI 2 "register_operand" "")
3041 (match_operand:ALLI 3 "register_operand" "")))]
3044 enum rtx_code code = GET_CODE (operands[1]);
3046 if (code == UNEQ || code == LTGT)
3049 if (!ccmp_cc_register (XEXP (operands[1], 0),
3050 GET_MODE (XEXP (operands[1], 0))))
3053 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
3054 XEXP (operands[1], 1));
3055 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
3060 (define_expand "mov<GPF:mode><GPI:mode>cc"
3061 [(set (match_operand:GPI 0 "register_operand" "")
3062 (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
3063 (match_operand:GPF 2 "register_operand" "")
3064 (match_operand:GPF 3 "register_operand" "")))]
3068 enum rtx_code code = GET_CODE (operands[1]);
3070 if (code == UNEQ || code == LTGT)
3073 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
3074 XEXP (operands[1], 1));
3075 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
3079 (define_expand "mov<mode>cc"
3080 [(set (match_operand:GPF 0 "register_operand" "")
3081 (if_then_else:GPF (match_operand 1 "aarch64_comparison_operator" "")
3082 (match_operand:GPF 2 "register_operand" "")
3083 (match_operand:GPF 3 "register_operand" "")))]
3087 enum rtx_code code = GET_CODE (operands[1]);
3089 if (code == UNEQ || code == LTGT)
3092 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
3093 XEXP (operands[1], 1));
3094 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
3099 ;; CRC32 instructions.
3100 (define_insn "aarch64_<crc_variant>"
3101 [(set (match_operand:SI 0 "register_operand" "=r")
3102 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
3103 (match_operand:<crc_mode> 2 "register_operand" "r")]
3107 if (GET_MODE_BITSIZE (GET_MODE (operands[2])) >= 64)
3108 return "<crc_variant>\\t%w0, %w1, %x2";
3110 return "<crc_variant>\\t%w0, %w1, %w2";
3112 [(set_attr "type" "crc")]
3115 (define_insn "*csinc2<mode>_insn"
3116 [(set (match_operand:GPI 0 "register_operand" "=r")
3117 (plus:GPI (match_operand 2 "aarch64_comparison_operation" "")
3118 (match_operand:GPI 1 "register_operand" "r")))]
3120 "cinc\\t%<w>0, %<w>1, %m2"
3121 [(set_attr "type" "csel")]
3124 (define_insn "csinc3<mode>_insn"
3125 [(set (match_operand:GPI 0 "register_operand" "=r")
3127 (match_operand 1 "aarch64_comparison_operation" "")
3128 (plus:GPI (match_operand:GPI 2 "register_operand" "r")
3130 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
3132 "csinc\\t%<w>0, %<w>3, %<w>2, %M1"
3133 [(set_attr "type" "csel")]
3136 (define_insn "*csinv3<mode>_insn"
3137 [(set (match_operand:GPI 0 "register_operand" "=r")
3139 (match_operand 1 "aarch64_comparison_operation" "")
3140 (not:GPI (match_operand:GPI 2 "register_operand" "r"))
3141 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
3143 "csinv\\t%<w>0, %<w>3, %<w>2, %M1"
3144 [(set_attr "type" "csel")]
3147 (define_insn "csneg3_uxtw_insn"
3148 [(set (match_operand:DI 0 "register_operand" "=r")
3151 (match_operand 1 "aarch64_comparison_operation" "")
3152 (neg:SI (match_operand:SI 2 "register_operand" "r"))
3153 (match_operand:SI 3 "aarch64_reg_or_zero" "rZ"))))]
3155 "csneg\\t%w0, %w3, %w2, %M1"
3156 [(set_attr "type" "csel")]
3159 (define_insn "csneg3<mode>_insn"
3160 [(set (match_operand:GPI 0 "register_operand" "=r")
3162 (match_operand 1 "aarch64_comparison_operation" "")
3163 (neg:GPI (match_operand:GPI 2 "register_operand" "r"))
3164 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
3166 "csneg\\t%<w>0, %<w>3, %<w>2, %M1"
3167 [(set_attr "type" "csel")]
3170 ;; -------------------------------------------------------------------
3171 ;; Logical operations
3172 ;; -------------------------------------------------------------------
3174 (define_insn "<optab><mode>3"
3175 [(set (match_operand:GPI 0 "register_operand" "=r,rk,w")
3176 (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r,w")
3177 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>,w")))]
3180 <logical>\\t%<w>0, %<w>1, %<w>2
3181 <logical>\\t%<w>0, %<w>1, %<w>2
3182 <logical>\\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
3183 [(set_attr "type" "logic_reg,logic_imm,neon_logic")
3184 (set_attr "simd" "*,*,yes")]
3187 ;; zero_extend version of above
3188 (define_insn "*<optab>si3_uxtw"
3189 [(set (match_operand:DI 0 "register_operand" "=r,rk")
3191 (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
3192 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
3194 "<logical>\\t%w0, %w1, %w2"
3195 [(set_attr "type" "logic_reg,logic_imm")]
3198 (define_insn "*and<mode>3_compare0"
3199 [(set (reg:CC_NZ CC_REGNUM)
3201 (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
3202 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
3204 (set (match_operand:GPI 0 "register_operand" "=r,r")
3205 (and:GPI (match_dup 1) (match_dup 2)))]
3207 "ands\\t%<w>0, %<w>1, %<w>2"
3208 [(set_attr "type" "logics_reg,logics_imm")]
3211 ;; zero_extend version of above
3212 (define_insn "*andsi3_compare0_uxtw"
3213 [(set (reg:CC_NZ CC_REGNUM)
3215 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
3216 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
3218 (set (match_operand:DI 0 "register_operand" "=r,r")
3219 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
3221 "ands\\t%w0, %w1, %w2"
3222 [(set_attr "type" "logics_reg,logics_imm")]
3225 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
3226 [(set (reg:CC_NZ CC_REGNUM)
3229 (match_operand:GPI 1 "register_operand" "r")
3230 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3231 (match_operand:GPI 3 "register_operand" "r"))
3233 (set (match_operand:GPI 0 "register_operand" "=r")
3234 (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
3236 "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3237 [(set_attr "type" "logics_shift_imm")]
3240 ;; zero_extend version of above
3241 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
3242 [(set (reg:CC_NZ CC_REGNUM)
3245 (match_operand:SI 1 "register_operand" "r")
3246 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3247 (match_operand:SI 3 "register_operand" "r"))
3249 (set (match_operand:DI 0 "register_operand" "=r")
3250 (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
3253 "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3254 [(set_attr "type" "logics_shift_imm")]
3257 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
3258 [(set (match_operand:GPI 0 "register_operand" "=r")
3259 (LOGICAL:GPI (SHIFT:GPI
3260 (match_operand:GPI 1 "register_operand" "r")
3261 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3262 (match_operand:GPI 3 "register_operand" "r")))]
3264 "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3265 [(set_attr "type" "logic_shift_imm")]
3268 (define_insn "*<optab>_rol<mode>3"
3269 [(set (match_operand:GPI 0 "register_operand" "=r")
3270 (LOGICAL:GPI (rotate:GPI
3271 (match_operand:GPI 1 "register_operand" "r")
3272 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3273 (match_operand:GPI 3 "register_operand" "r")))]
3275 "<logical>\\t%<w>0, %<w>3, %<w>1, ror (<sizen> - %2)"
3276 [(set_attr "type" "logic_shift_imm")]
3279 ;; zero_extend versions of above
3280 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
3281 [(set (match_operand:DI 0 "register_operand" "=r")
3283 (LOGICAL:SI (SHIFT:SI
3284 (match_operand:SI 1 "register_operand" "r")
3285 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3286 (match_operand:SI 3 "register_operand" "r"))))]
3288 "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3289 [(set_attr "type" "logic_shift_imm")]
3292 (define_insn "*<optab>_rolsi3_uxtw"
3293 [(set (match_operand:DI 0 "register_operand" "=r")
3295 (LOGICAL:SI (rotate:SI
3296 (match_operand:SI 1 "register_operand" "r")
3297 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3298 (match_operand:SI 3 "register_operand" "r"))))]
3300 "<logical>\\t%w0, %w3, %w1, ror (32 - %2)"
3301 [(set_attr "type" "logic_shift_imm")]
3304 (define_insn "one_cmpl<mode>2"
3305 [(set (match_operand:GPI 0 "register_operand" "=r,w")
3306 (not:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
3311 [(set_attr "type" "logic_reg,neon_logic")
3312 (set_attr "simd" "*,yes")]
3315 (define_insn "*one_cmpl_<optab><mode>2"
3316 [(set (match_operand:GPI 0 "register_operand" "=r")
3317 (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
3318 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
3320 "mvn\\t%<w>0, %<w>1, <shift> %2"
3321 [(set_attr "type" "logic_shift_imm")]
3324 ;; Binary logical operators negating one operand, i.e. (a & !b), (a | !b).
3326 (define_insn "*<NLOGICAL:optab>_one_cmpl<mode>3"
3327 [(set (match_operand:GPI 0 "register_operand" "=r,w")
3328 (NLOGICAL:GPI (not:GPI (match_operand:GPI 1 "register_operand" "r,w"))
3329 (match_operand:GPI 2 "register_operand" "r,w")))]
3332 <NLOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1
3333 <NLOGICAL:nlogical>\\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>"
3334 [(set_attr "type" "logic_reg,neon_logic")
3335 (set_attr "simd" "*,yes")]
3338 (define_insn "*<NLOGICAL:optab>_one_cmplsidi3_ze"
3339 [(set (match_operand:DI 0 "register_operand" "=r")
3341 (NLOGICAL:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3342 (match_operand:SI 2 "register_operand" "r"))))]
3344 "<NLOGICAL:nlogical>\\t%w0, %w2, %w1"
3345 [(set_attr "type" "logic_reg")]
3348 (define_insn "*xor_one_cmplsidi3_ze"
3349 [(set (match_operand:DI 0 "register_operand" "=r")
3351 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "r")
3352 (match_operand:SI 2 "register_operand" "r")))))]
3354 "eon\\t%w0, %w1, %w2"
3355 [(set_attr "type" "logic_reg")]
3358 ;; (xor (not a) b) is simplify_rtx-ed down to (not (xor a b)).
3359 ;; eon does not operate on SIMD registers so the vector variant must be split.
3360 (define_insn_and_split "*xor_one_cmpl<mode>3"
3361 [(set (match_operand:GPI 0 "register_operand" "=r,w")
3362 (not:GPI (xor:GPI (match_operand:GPI 1 "register_operand" "r,?w")
3363 (match_operand:GPI 2 "register_operand" "r,w"))))]
3366 eon\\t%<w>0, %<w>1, %<w>2
3368 "reload_completed && FP_REGNUM_P (REGNO (operands[0]))" ;; For SIMD registers.
3369 [(set (match_operand:GPI 0 "register_operand" "=w")
3370 (xor:GPI (match_operand:GPI 1 "register_operand" "w")
3371 (match_operand:GPI 2 "register_operand" "w")))
3372 (set (match_dup 0) (not:GPI (match_dup 0)))]
3374 [(set_attr "type" "logic_reg,multiple")
3375 (set_attr "simd" "*,yes")]
3378 (define_insn "*and_one_cmpl<mode>3_compare0"
3379 [(set (reg:CC_NZ CC_REGNUM)
3382 (match_operand:GPI 1 "register_operand" "r"))
3383 (match_operand:GPI 2 "register_operand" "r"))
3385 (set (match_operand:GPI 0 "register_operand" "=r")
3386 (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
3388 "bics\\t%<w>0, %<w>2, %<w>1"
3389 [(set_attr "type" "logics_reg")]
3392 ;; zero_extend version of above
3393 (define_insn "*and_one_cmplsi3_compare0_uxtw"
3394 [(set (reg:CC_NZ CC_REGNUM)
3397 (match_operand:SI 1 "register_operand" "r"))
3398 (match_operand:SI 2 "register_operand" "r"))
3400 (set (match_operand:DI 0 "register_operand" "=r")
3401 (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
3403 "bics\\t%w0, %w2, %w1"
3404 [(set_attr "type" "logics_reg")]
3407 (define_insn "*and_one_cmpl<mode>3_compare0_no_reuse"
3408 [(set (reg:CC_NZ CC_REGNUM)
3411 (match_operand:GPI 0 "register_operand" "r"))
3412 (match_operand:GPI 1 "register_operand" "r"))
3415 "bics\\t<w>zr, %<w>1, %<w>0"
3416 [(set_attr "type" "logics_reg")]
3419 (define_insn "<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
3420 [(set (match_operand:GPI 0 "register_operand" "=r")
3421 (LOGICAL:GPI (not:GPI
3423 (match_operand:GPI 1 "register_operand" "r")
3424 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
3425 (match_operand:GPI 3 "register_operand" "r")))]
3427 "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3428 [(set_attr "type" "logic_shift_imm")]
3431 (define_insn "*eor_one_cmpl_<SHIFT:optab><mode>3_alt"
3432 [(set (match_operand:GPI 0 "register_operand" "=r")
3435 (match_operand:GPI 1 "register_operand" "r")
3436 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3437 (match_operand:GPI 3 "register_operand" "r"))))]
3439 "eon\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3440 [(set_attr "type" "logic_shift_imm")]
3443 ;; Zero-extend version of the above.
3444 (define_insn "*eor_one_cmpl_<SHIFT:optab>sidi3_alt_ze"
3445 [(set (match_operand:DI 0 "register_operand" "=r")
3449 (match_operand:SI 1 "register_operand" "r")
3450 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3451 (match_operand:SI 3 "register_operand" "r")))))]
3453 "eon\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3454 [(set_attr "type" "logic_shift_imm")]
3457 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
3458 [(set (reg:CC_NZ CC_REGNUM)
3462 (match_operand:GPI 1 "register_operand" "r")
3463 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
3464 (match_operand:GPI 3 "register_operand" "r"))
3466 (set (match_operand:GPI 0 "register_operand" "=r")
3469 (match_dup 1) (match_dup 2))) (match_dup 3)))]
3471 "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3472 [(set_attr "type" "logics_shift_imm")]
3475 ;; zero_extend version of above
3476 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
3477 [(set (reg:CC_NZ CC_REGNUM)
3481 (match_operand:SI 1 "register_operand" "r")
3482 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
3483 (match_operand:SI 3 "register_operand" "r"))
3485 (set (match_operand:DI 0 "register_operand" "=r")
3486 (zero_extend:DI (and:SI
3488 (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
3490 "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3491 [(set_attr "type" "logics_shift_imm")]
3494 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0_no_reuse"
3495 [(set (reg:CC_NZ CC_REGNUM)
3499 (match_operand:GPI 0 "register_operand" "r")
3500 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n")))
3501 (match_operand:GPI 2 "register_operand" "r"))
3504 "bics\\t<w>zr, %<w>2, %<w>0, <SHIFT:shift> %1"
3505 [(set_attr "type" "logics_shift_imm")]
3508 (define_insn "clz<mode>2"
3509 [(set (match_operand:GPI 0 "register_operand" "=r")
3510 (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
3512 "clz\\t%<w>0, %<w>1"
3513 [(set_attr "type" "clz")]
3516 (define_expand "ffs<mode>2"
3517 [(match_operand:GPI 0 "register_operand")
3518 (match_operand:GPI 1 "register_operand")]
3521 rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
3522 rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
3524 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3525 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3526 emit_insn (gen_csinc3<mode>_insn (operands[0], x, operands[0], const0_rtx));
3531 (define_insn "clrsb<mode>2"
3532 [(set (match_operand:GPI 0 "register_operand" "=r")
3533 (clrsb:GPI (match_operand:GPI 1 "register_operand" "r")))]
3535 "cls\\t%<w>0, %<w>1"
3536 [(set_attr "type" "clz")]
3539 (define_insn "rbit<mode>2"
3540 [(set (match_operand:GPI 0 "register_operand" "=r")
3541 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
3543 "rbit\\t%<w>0, %<w>1"
3544 [(set_attr "type" "rbit")]
3547 (define_expand "ctz<mode>2"
3548 [(match_operand:GPI 0 "register_operand")
3549 (match_operand:GPI 1 "register_operand")]
3552 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3553 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3558 (define_insn "*and<mode>3nr_compare0"
3559 [(set (reg:CC_NZ CC_REGNUM)
3561 (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
3562 (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
3565 "tst\\t%<w>0, %<w>1"
3566 [(set_attr "type" "logics_reg,logics_imm")]
3569 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
3570 [(set (reg:CC_NZ CC_REGNUM)
3573 (match_operand:GPI 0 "register_operand" "r")
3574 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
3575 (match_operand:GPI 2 "register_operand" "r"))
3578 "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
3579 [(set_attr "type" "logics_shift_imm")]
3582 ;; -------------------------------------------------------------------
3584 ;; -------------------------------------------------------------------
3586 (define_expand "<optab><mode>3"
3587 [(set (match_operand:GPI 0 "register_operand")
3588 (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
3589 (match_operand:QI 2 "nonmemory_operand")))]
3592 if (CONST_INT_P (operands[2]))
3594 operands[2] = GEN_INT (INTVAL (operands[2])
3595 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3597 if (operands[2] == const0_rtx)
3599 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3606 (define_expand "ashl<mode>3"
3607 [(set (match_operand:SHORT 0 "register_operand")
3608 (ashift:SHORT (match_operand:SHORT 1 "register_operand")
3609 (match_operand:QI 2 "nonmemory_operand")))]
3612 if (CONST_INT_P (operands[2]))
3614 operands[2] = GEN_INT (INTVAL (operands[2])
3615 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3617 if (operands[2] == const0_rtx)
3619 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3628 (define_expand "rotr<mode>3"
3629 [(set (match_operand:GPI 0 "register_operand")
3630 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3631 (match_operand:QI 2 "nonmemory_operand")))]
3634 if (CONST_INT_P (operands[2]))
3636 operands[2] = GEN_INT (INTVAL (operands[2])
3637 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3639 if (operands[2] == const0_rtx)
3641 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3648 (define_expand "rotl<mode>3"
3649 [(set (match_operand:GPI 0 "register_operand")
3650 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3651 (match_operand:QI 2 "nonmemory_operand")))]
3654 /* (SZ - cnt) % SZ == -cnt % SZ */
3655 if (CONST_INT_P (operands[2]))
3657 operands[2] = GEN_INT ((-INTVAL (operands[2]))
3658 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3659 if (operands[2] == const0_rtx)
3661 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3666 operands[2] = expand_simple_unop (QImode, NEG, operands[2],
3671 ;; Logical left shift using SISD or Integer instruction
3672 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
3673 [(set (match_operand:GPI 0 "register_operand" "=r,w,w")
3675 (match_operand:GPI 1 "register_operand" "r,w,w")
3676 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>,Us<cmode>,w")))]
3679 lsl\t%<w>0, %<w>1, %<w>2
3680 shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3681 ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>"
3682 [(set_attr "simd" "no,yes,yes")
3683 (set_attr "type" "shift_reg,neon_shift_imm<q>, neon_shift_reg<q>")]
3686 ;; Logical right shift using SISD or Integer instruction
3687 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3688 [(set (match_operand:GPI 0 "register_operand" "=r,w,&w,&w")
3690 (match_operand:GPI 1 "register_operand" "r,w,w,w")
3691 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>,Us<cmode>,w,0")))]
3694 lsr\t%<w>0, %<w>1, %<w>2
3695 ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3698 [(set_attr "simd" "no,yes,yes,yes")
3699 (set_attr "type" "shift_reg,neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>")]
3703 [(set (match_operand:DI 0 "aarch64_simd_register")
3705 (match_operand:DI 1 "aarch64_simd_register")
3706 (match_operand:QI 2 "aarch64_simd_register")))]
3707 "TARGET_SIMD && reload_completed"
3709 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3711 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_USHL))]
3713 operands[3] = gen_lowpart (QImode, operands[0]);
3718 [(set (match_operand:SI 0 "aarch64_simd_register")
3720 (match_operand:SI 1 "aarch64_simd_register")
3721 (match_operand:QI 2 "aarch64_simd_register")))]
3722 "TARGET_SIMD && reload_completed"
3724 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3726 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_USHL_2S))]
3728 operands[3] = gen_lowpart (QImode, operands[0]);
3732 ;; Arithmetic right shift using SISD or Integer instruction
3733 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3734 [(set (match_operand:GPI 0 "register_operand" "=r,w,&w,&w")
3736 (match_operand:GPI 1 "register_operand" "r,w,w,w")
3737 (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "rUs<cmode>,Us<cmode>,w,0")))]
3740 asr\t%<w>0, %<w>1, %<w>2
3741 sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3744 [(set_attr "simd" "no,yes,yes,yes")
3745 (set_attr "type" "shift_reg,neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>")]
3749 [(set (match_operand:DI 0 "aarch64_simd_register")
3751 (match_operand:DI 1 "aarch64_simd_register")
3752 (match_operand:QI 2 "aarch64_simd_register")))]
3753 "TARGET_SIMD && reload_completed"
3755 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3757 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_SSHL))]
3759 operands[3] = gen_lowpart (QImode, operands[0]);
3764 [(set (match_operand:SI 0 "aarch64_simd_register")
3766 (match_operand:SI 1 "aarch64_simd_register")
3767 (match_operand:QI 2 "aarch64_simd_register")))]
3768 "TARGET_SIMD && reload_completed"
3770 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3772 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_SSHL_2S))]
3774 operands[3] = gen_lowpart (QImode, operands[0]);
3778 (define_insn "*aarch64_sisd_ushl"
3779 [(set (match_operand:DI 0 "register_operand" "=w")
3780 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3781 (match_operand:QI 2 "register_operand" "w")]
3784 "ushl\t%d0, %d1, %d2"
3785 [(set_attr "simd" "yes")
3786 (set_attr "type" "neon_shift_reg")]
3789 (define_insn "*aarch64_ushl_2s"
3790 [(set (match_operand:SI 0 "register_operand" "=w")
3791 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3792 (match_operand:QI 2 "register_operand" "w")]
3795 "ushl\t%0.2s, %1.2s, %2.2s"
3796 [(set_attr "simd" "yes")
3797 (set_attr "type" "neon_shift_reg")]
3800 (define_insn "*aarch64_sisd_sshl"
3801 [(set (match_operand:DI 0 "register_operand" "=w")
3802 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3803 (match_operand:QI 2 "register_operand" "w")]
3806 "sshl\t%d0, %d1, %d2"
3807 [(set_attr "simd" "yes")
3808 (set_attr "type" "neon_shift_reg")]
3811 (define_insn "*aarch64_sshl_2s"
3812 [(set (match_operand:SI 0 "register_operand" "=w")
3813 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3814 (match_operand:QI 2 "register_operand" "w")]
3817 "sshl\t%0.2s, %1.2s, %2.2s"
3818 [(set_attr "simd" "yes")
3819 (set_attr "type" "neon_shift_reg")]
3822 (define_insn "*aarch64_sisd_neg_qi"
3823 [(set (match_operand:QI 0 "register_operand" "=w")
3824 (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3828 [(set_attr "simd" "yes")
3829 (set_attr "type" "neon_neg")]
3833 (define_insn "*ror<mode>3_insn"
3834 [(set (match_operand:GPI 0 "register_operand" "=r,r")
3836 (match_operand:GPI 1 "register_operand" "r,r")
3837 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "r,Us<cmode>")))]
3839 "ror\\t%<w>0, %<w>1, %<w>2"
3840 [(set_attr "type" "shift_reg, rotate_imm")]
3843 ;; zero_extend version of above
3844 (define_insn "*<optab>si3_insn_uxtw"
3845 [(set (match_operand:DI 0 "register_operand" "=r")
3846 (zero_extend:DI (SHIFT:SI
3847 (match_operand:SI 1 "register_operand" "r")
3848 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3850 "<shift>\\t%w0, %w1, %w2"
3851 [(set_attr "type" "shift_reg")]
3854 (define_insn "*<optab><mode>3_insn"
3855 [(set (match_operand:SHORT 0 "register_operand" "=r")
3856 (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3857 (match_operand 2 "const_int_operand" "n")))]
3858 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3860 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3861 return "<bfshift>\t%w0, %w1, %2, %3";
3863 [(set_attr "type" "bfm")]
3866 (define_insn "*extr<mode>5_insn"
3867 [(set (match_operand:GPI 0 "register_operand" "=r")
3868 (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3869 (match_operand 3 "const_int_operand" "n"))
3870 (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3871 (match_operand 4 "const_int_operand" "n"))))]
3872 "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3873 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3874 "extr\\t%<w>0, %<w>1, %<w>2, %4"
3875 [(set_attr "type" "shift_imm")]
3878 ;; There are no canonicalisation rules for ashift and lshiftrt inside an ior
3879 ;; so we have to match both orderings.
3880 (define_insn "*extr<mode>5_insn_alt"
3881 [(set (match_operand:GPI 0 "register_operand" "=r")
3882 (ior:GPI (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3883 (match_operand 4 "const_int_operand" "n"))
3884 (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3885 (match_operand 3 "const_int_operand" "n"))))]
3886 "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode)
3887 && (UINTVAL (operands[3]) + UINTVAL (operands[4])
3888 == GET_MODE_BITSIZE (<MODE>mode))"
3889 "extr\\t%<w>0, %<w>1, %<w>2, %4"
3890 [(set_attr "type" "shift_imm")]
3893 ;; zero_extend version of the above
3894 (define_insn "*extrsi5_insn_uxtw"
3895 [(set (match_operand:DI 0 "register_operand" "=r")
3897 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3898 (match_operand 3 "const_int_operand" "n"))
3899 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3900 (match_operand 4 "const_int_operand" "n")))))]
3901 "UINTVAL (operands[3]) < 32 &&
3902 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3903 "extr\\t%w0, %w1, %w2, %4"
3904 [(set_attr "type" "shift_imm")]
3907 (define_insn "*extrsi5_insn_uxtw_alt"
3908 [(set (match_operand:DI 0 "register_operand" "=r")
3910 (ior:SI (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3911 (match_operand 4 "const_int_operand" "n"))
3912 (ashift:SI (match_operand:SI 1 "register_operand" "r")
3913 (match_operand 3 "const_int_operand" "n")))))]
3914 "UINTVAL (operands[3]) < 32 &&
3915 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3916 "extr\\t%w0, %w1, %w2, %4"
3917 [(set_attr "type" "shift_imm")]
3920 (define_insn "*ror<mode>3_insn"
3921 [(set (match_operand:GPI 0 "register_operand" "=r")
3922 (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3923 (match_operand 2 "const_int_operand" "n")))]
3924 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3926 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3927 return "ror\\t%<w>0, %<w>1, %3";
3929 [(set_attr "type" "rotate_imm")]
3932 ;; zero_extend version of the above
3933 (define_insn "*rorsi3_insn_uxtw"
3934 [(set (match_operand:DI 0 "register_operand" "=r")
3936 (rotate:SI (match_operand:SI 1 "register_operand" "r")
3937 (match_operand 2 "const_int_operand" "n"))))]
3938 "UINTVAL (operands[2]) < 32"
3940 operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3941 return "ror\\t%w0, %w1, %3";
3943 [(set_attr "type" "rotate_imm")]
3946 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3947 [(set (match_operand:GPI 0 "register_operand" "=r")
3949 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3950 (match_operand 2 "const_int_operand" "n"))))]
3951 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3953 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3954 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3956 [(set_attr "type" "bfm")]
3959 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3960 [(set (match_operand:GPI 0 "register_operand" "=r")
3962 (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3963 (match_operand 2 "const_int_operand" "n"))))]
3964 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3966 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3967 return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3969 [(set_attr "type" "bfm")]
3972 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3973 [(set (match_operand:GPI 0 "register_operand" "=r")
3975 (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3976 (match_operand 2 "const_int_operand" "n"))))]
3977 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3979 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3980 return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3982 [(set_attr "type" "bfm")]
3985 ;; -------------------------------------------------------------------
3987 ;; -------------------------------------------------------------------
3989 (define_expand "<optab>"
3990 [(set (match_operand:DI 0 "register_operand" "=r")
3991 (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3992 (match_operand 2 "const_int_operand" "n")
3993 (match_operand 3 "const_int_operand" "n")))]
3998 (define_insn "*<optab><mode>"
3999 [(set (match_operand:GPI 0 "register_operand" "=r")
4000 (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
4001 (match_operand 2 "const_int_operand" "n")
4002 (match_operand 3 "const_int_operand" "n")))]
4004 "<su>bfx\\t%<w>0, %<w>1, %3, %2"
4005 [(set_attr "type" "bfm")]
4008 ;; Bitfield Insert (insv)
4009 (define_expand "insv<mode>"
4010 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
4011 (match_operand 1 "const_int_operand")
4012 (match_operand 2 "const_int_operand"))
4013 (match_operand:GPI 3 "general_operand"))]
4016 unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
4017 unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
4018 rtx value = operands[3];
4020 if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
4023 if (CONST_INT_P (value))
4025 unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
4027 /* Prefer AND/OR for inserting all zeros or all ones. */
4028 if ((UINTVAL (value) & mask) == 0
4029 || (UINTVAL (value) & mask) == mask)
4032 /* 16-bit aligned 16-bit wide insert is handled by insv_imm. */
4033 if (width == 16 && (pos % 16) == 0)
4036 operands[3] = force_reg (<MODE>mode, value);
4039 (define_insn "*insv_reg<mode>"
4040 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
4041 (match_operand 1 "const_int_operand" "n")
4042 (match_operand 2 "const_int_operand" "n"))
4043 (match_operand:GPI 3 "register_operand" "r"))]
4044 "!(UINTVAL (operands[1]) == 0
4045 || (UINTVAL (operands[2]) + UINTVAL (operands[1])
4046 > GET_MODE_BITSIZE (<MODE>mode)))"
4047 "bfi\\t%<w>0, %<w>3, %2, %1"
4048 [(set_attr "type" "bfm")]
4051 (define_insn "*aarch64_bfi<GPI:mode><ALLX:mode>4"
4052 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
4053 (match_operand 1 "const_int_operand" "n")
4054 (match_operand 2 "const_int_operand" "n"))
4055 (zero_extend:GPI (match_operand:ALLX 3 "register_operand" "r")))]
4056 "UINTVAL (operands[1]) <= <ALLX:sizen>"
4057 "bfi\\t%<GPI:w>0, %<GPI:w>3, %2, %1"
4058 [(set_attr "type" "bfm")]
4061 (define_insn "*extr_insv_lower_reg<mode>"
4062 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
4063 (match_operand 1 "const_int_operand" "n")
4065 (zero_extract:GPI (match_operand:GPI 2 "register_operand" "r")
4067 (match_operand 3 "const_int_operand" "n")))]
4068 "!(UINTVAL (operands[1]) == 0
4069 || (UINTVAL (operands[3]) + UINTVAL (operands[1])
4070 > GET_MODE_BITSIZE (<MODE>mode)))"
4071 "bfxil\\t%<w>0, %<w>2, %3, %1"
4072 [(set_attr "type" "bfm")]
4075 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
4076 [(set (match_operand:GPI 0 "register_operand" "=r")
4077 (ashift:GPI (ANY_EXTEND:GPI
4078 (match_operand:ALLX 1 "register_operand" "r"))
4079 (match_operand 2 "const_int_operand" "n")))]
4080 "UINTVAL (operands[2]) < <GPI:sizen>"
4082 operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
4083 ? GEN_INT (<ALLX:sizen>)
4084 : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
4085 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
4087 [(set_attr "type" "bfm")]
4090 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
4092 (define_insn "*andim_ashift<mode>_bfiz"
4093 [(set (match_operand:GPI 0 "register_operand" "=r")
4094 (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
4095 (match_operand 2 "const_int_operand" "n"))
4096 (match_operand 3 "const_int_operand" "n")))]
4097 "(INTVAL (operands[2]) < (<GPI:sizen>))
4098 && exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
4099 && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
4100 "ubfiz\\t%<w>0, %<w>1, %2, %P3"
4101 [(set_attr "type" "bfm")]
4104 (define_insn "bswap<mode>2"
4105 [(set (match_operand:GPI 0 "register_operand" "=r")
4106 (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
4108 "rev\\t%<w>0, %<w>1"
4109 [(set_attr "type" "rev")]
4112 (define_insn "bswaphi2"
4113 [(set (match_operand:HI 0 "register_operand" "=r")
4114 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
4117 [(set_attr "type" "rev")]
4120 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
4121 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
4122 ;; each valid permutation.
4124 (define_insn "rev16<mode>2"
4125 [(set (match_operand:GPI 0 "register_operand" "=r")
4126 (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
4128 (match_operand:GPI 3 "const_int_operand" "n"))
4129 (and:GPI (lshiftrt:GPI (match_dup 1)
4131 (match_operand:GPI 2 "const_int_operand" "n"))))]
4132 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
4133 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
4134 "rev16\\t%<w>0, %<w>1"
4135 [(set_attr "type" "rev")]
4138 (define_insn "rev16<mode>2_alt"
4139 [(set (match_operand:GPI 0 "register_operand" "=r")
4140 (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r")
4142 (match_operand:GPI 2 "const_int_operand" "n"))
4143 (and:GPI (ashift:GPI (match_dup 1)
4145 (match_operand:GPI 3 "const_int_operand" "n"))))]
4146 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
4147 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
4148 "rev16\\t%<w>0, %<w>1"
4149 [(set_attr "type" "rev")]
4152 ;; zero_extend version of above
4153 (define_insn "*bswapsi2_uxtw"
4154 [(set (match_operand:DI 0 "register_operand" "=r")
4155 (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
4158 [(set_attr "type" "rev")]
4161 ;; -------------------------------------------------------------------
4162 ;; Floating-point intrinsics
4163 ;; -------------------------------------------------------------------
4165 ;; frint floating-point round to integral standard patterns.
4166 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round, frintn.
4168 (define_insn "<frint_pattern><mode>2"
4169 [(set (match_operand:GPF 0 "register_operand" "=w")
4170 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
4173 "frint<frint_suffix>\\t%<s>0, %<s>1"
4174 [(set_attr "type" "f_rint<s>")]
4177 ;; frcvt floating-point round to integer and convert standard patterns.
4178 ;; Expands to lbtrunc, lceil, lfloor, lround.
4179 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
4180 [(set (match_operand:GPI 0 "register_operand" "=r")
4181 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
4184 "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
4185 [(set_attr "type" "f_cvtf2i")]
4190 (define_insn "fma<mode>4"
4191 [(set (match_operand:GPF 0 "register_operand" "=w")
4192 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
4193 (match_operand:GPF 2 "register_operand" "w")
4194 (match_operand:GPF 3 "register_operand" "w")))]
4196 "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
4197 [(set_attr "type" "fmac<s>")]
4200 (define_insn "fnma<mode>4"
4201 [(set (match_operand:GPF 0 "register_operand" "=w")
4202 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
4203 (match_operand:GPF 2 "register_operand" "w")
4204 (match_operand:GPF 3 "register_operand" "w")))]
4206 "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
4207 [(set_attr "type" "fmac<s>")]
4210 (define_insn "fms<mode>4"
4211 [(set (match_operand:GPF 0 "register_operand" "=w")
4212 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
4213 (match_operand:GPF 2 "register_operand" "w")
4214 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
4216 "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
4217 [(set_attr "type" "fmac<s>")]
4220 (define_insn "fnms<mode>4"
4221 [(set (match_operand:GPF 0 "register_operand" "=w")
4222 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
4223 (match_operand:GPF 2 "register_operand" "w")
4224 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
4226 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
4227 [(set_attr "type" "fmac<s>")]
4230 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
4231 (define_insn "*fnmadd<mode>4"
4232 [(set (match_operand:GPF 0 "register_operand" "=w")
4233 (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
4234 (match_operand:GPF 2 "register_operand" "w")
4235 (match_operand:GPF 3 "register_operand" "w"))))]
4236 "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
4237 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
4238 [(set_attr "type" "fmac<s>")]
4241 ;; -------------------------------------------------------------------
4242 ;; Floating-point conversions
4243 ;; -------------------------------------------------------------------
4245 (define_insn "extendsfdf2"
4246 [(set (match_operand:DF 0 "register_operand" "=w")
4247 (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
4250 [(set_attr "type" "f_cvt")]
4253 (define_insn "extendhfsf2"
4254 [(set (match_operand:SF 0 "register_operand" "=w")
4255 (float_extend:SF (match_operand:HF 1 "register_operand" "w")))]
4258 [(set_attr "type" "f_cvt")]
4261 (define_insn "extendhfdf2"
4262 [(set (match_operand:DF 0 "register_operand" "=w")
4263 (float_extend:DF (match_operand:HF 1 "register_operand" "w")))]
4266 [(set_attr "type" "f_cvt")]
4269 (define_insn "truncdfsf2"
4270 [(set (match_operand:SF 0 "register_operand" "=w")
4271 (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
4274 [(set_attr "type" "f_cvt")]
4277 (define_insn "truncsfhf2"
4278 [(set (match_operand:HF 0 "register_operand" "=w")
4279 (float_truncate:HF (match_operand:SF 1 "register_operand" "w")))]
4282 [(set_attr "type" "f_cvt")]
4285 (define_insn "truncdfhf2"
4286 [(set (match_operand:HF 0 "register_operand" "=w")
4287 (float_truncate:HF (match_operand:DF 1 "register_operand" "w")))]
4290 [(set_attr "type" "f_cvt")]
4293 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
4294 [(set (match_operand:GPI 0 "register_operand" "=r")
4295 (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
4297 "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
4298 [(set_attr "type" "f_cvtf2i")]
4301 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
4302 [(set (match_operand:GPI 0 "register_operand" "=r")
4303 (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
4305 "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
4306 [(set_attr "type" "f_cvtf2i")]
4309 (define_insn "<optab><fcvt_target><GPF:mode>2"
4310 [(set (match_operand:GPF 0 "register_operand" "=w,w")
4311 (FLOATUORS:GPF (match_operand:<FCVT_TARGET> 1 "register_operand" "w,r")))]
4314 <su_optab>cvtf\t%<GPF:s>0, %<s>1
4315 <su_optab>cvtf\t%<GPF:s>0, %<w1>1"
4316 [(set_attr "simd" "yes,no")
4317 (set_attr "fp" "no,yes")
4318 (set_attr "type" "neon_int_to_fp_<Vetype>,f_cvti2f")]
4321 (define_insn "<optab><fcvt_iesize><GPF:mode>2"
4322 [(set (match_operand:GPF 0 "register_operand" "=w")
4323 (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand" "r")))]
4325 "<su_optab>cvtf\t%<GPF:s>0, %<w2>1"
4326 [(set_attr "type" "f_cvti2f")]
4329 ;; -------------------------------------------------------------------
4330 ;; Floating-point arithmetic
4331 ;; -------------------------------------------------------------------
4333 (define_insn "add<mode>3"
4334 [(set (match_operand:GPF 0 "register_operand" "=w")
4336 (match_operand:GPF 1 "register_operand" "w")
4337 (match_operand:GPF 2 "register_operand" "w")))]
4339 "fadd\\t%<s>0, %<s>1, %<s>2"
4340 [(set_attr "type" "fadd<s>")]
4343 (define_insn "sub<mode>3"
4344 [(set (match_operand:GPF 0 "register_operand" "=w")
4346 (match_operand:GPF 1 "register_operand" "w")
4347 (match_operand:GPF 2 "register_operand" "w")))]
4349 "fsub\\t%<s>0, %<s>1, %<s>2"
4350 [(set_attr "type" "fadd<s>")]
4353 (define_insn "mul<mode>3"
4354 [(set (match_operand:GPF 0 "register_operand" "=w")
4356 (match_operand:GPF 1 "register_operand" "w")
4357 (match_operand:GPF 2 "register_operand" "w")))]
4359 "fmul\\t%<s>0, %<s>1, %<s>2"
4360 [(set_attr "type" "fmul<s>")]
4363 (define_insn "*fnmul<mode>3"
4364 [(set (match_operand:GPF 0 "register_operand" "=w")
4366 (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
4367 (match_operand:GPF 2 "register_operand" "w")))]
4368 "TARGET_FLOAT && !flag_rounding_math"
4369 "fnmul\\t%<s>0, %<s>1, %<s>2"
4370 [(set_attr "type" "fmul<s>")]
4373 (define_insn "*fnmul<mode>3"
4374 [(set (match_operand:GPF 0 "register_operand" "=w")
4376 (match_operand:GPF 1 "register_operand" "w")
4377 (match_operand:GPF 2 "register_operand" "w"))))]
4379 "fnmul\\t%<s>0, %<s>1, %<s>2"
4380 [(set_attr "type" "fmul<s>")]
4383 (define_insn "div<mode>3"
4384 [(set (match_operand:GPF 0 "register_operand" "=w")
4386 (match_operand:GPF 1 "register_operand" "w")
4387 (match_operand:GPF 2 "register_operand" "w")))]
4389 "fdiv\\t%<s>0, %<s>1, %<s>2"
4390 [(set_attr "type" "fdiv<s>")]
4393 (define_insn "neg<mode>2"
4394 [(set (match_operand:GPF 0 "register_operand" "=w")
4395 (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
4397 "fneg\\t%<s>0, %<s>1"
4398 [(set_attr "type" "ffarith<s>")]
4401 (define_insn "sqrt<mode>2"
4402 [(set (match_operand:GPF 0 "register_operand" "=w")
4403 (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
4405 "fsqrt\\t%<s>0, %<s>1"
4406 [(set_attr "type" "fsqrt<s>")]
4409 (define_insn "abs<mode>2"
4410 [(set (match_operand:GPF 0 "register_operand" "=w")
4411 (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
4413 "fabs\\t%<s>0, %<s>1"
4414 [(set_attr "type" "ffarith<s>")]
4417 ;; Given that smax/smin do not specify the result when either input is NaN,
4418 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
4421 (define_insn "smax<mode>3"
4422 [(set (match_operand:GPF 0 "register_operand" "=w")
4423 (smax:GPF (match_operand:GPF 1 "register_operand" "w")
4424 (match_operand:GPF 2 "register_operand" "w")))]
4426 "fmaxnm\\t%<s>0, %<s>1, %<s>2"
4427 [(set_attr "type" "f_minmax<s>")]
4430 (define_insn "smin<mode>3"
4431 [(set (match_operand:GPF 0 "register_operand" "=w")
4432 (smin:GPF (match_operand:GPF 1 "register_operand" "w")
4433 (match_operand:GPF 2 "register_operand" "w")))]
4435 "fminnm\\t%<s>0, %<s>1, %<s>2"
4436 [(set_attr "type" "f_minmax<s>")]
4439 ;; For copysign (x, y), we want to generate:
4441 ;; LDR d2, #(1 << 63)
4442 ;; BSL v2.8b, [y], [x]
4444 ;; or another, equivalent, sequence using one of BSL/BIT/BIF.
4445 ;; aarch64_simd_bsldf will select the best suited of these instructions
4446 ;; to generate based on register allocation, and knows how to partially
4447 ;; constant fold based on the values of X and Y, so expand through that.
4449 (define_expand "copysigndf3"
4450 [(match_operand:DF 0 "register_operand")
4451 (match_operand:DF 1 "register_operand")
4452 (match_operand:DF 2 "register_operand")]
4453 "TARGET_FLOAT && TARGET_SIMD"
4455 rtx mask = gen_reg_rtx (DImode);
4456 emit_move_insn (mask, GEN_INT (HOST_WIDE_INT_1U << 63));
4457 emit_insn (gen_aarch64_simd_bsldf (operands[0], mask,
4458 operands[2], operands[1]));
4463 ;; As above, but we must first get to a 64-bit value if we wish to use
4464 ;; aarch64_simd_bslv2sf.
4466 (define_expand "copysignsf3"
4467 [(match_operand:SF 0 "register_operand")
4468 (match_operand:SF 1 "register_operand")
4469 (match_operand:SF 2 "register_operand")]
4470 "TARGET_FLOAT && TARGET_SIMD"
4472 rtx mask = gen_reg_rtx (DImode);
4474 /* Juggle modes to get us in to a vector mode for BSL. */
4475 rtx op1 = lowpart_subreg (V2SFmode, operands[1], SFmode);
4476 rtx op2 = lowpart_subreg (V2SFmode, operands[2], SFmode);
4477 rtx tmp = gen_reg_rtx (V2SFmode);
4478 emit_move_insn (mask, GEN_INT (HOST_WIDE_INT_1U << 31));
4479 emit_insn (gen_aarch64_simd_bslv2sf (tmp, mask, op2, op1));
4480 emit_move_insn (operands[0], lowpart_subreg (SFmode, tmp, V2SFmode));
4485 ;; -------------------------------------------------------------------
4487 ;; -------------------------------------------------------------------
4488 ;; Reload Scalar Floating point modes from constant pool.
4489 ;; The AArch64 port doesn't have __int128 constant move support.
4490 (define_expand "aarch64_reload_movcp<GPF_TF:mode><P:mode>"
4491 [(set (match_operand:GPF_TF 0 "register_operand" "=w")
4492 (mem:GPF_TF (match_operand 1 "aarch64_constant_pool_symref" "S")))
4493 (clobber (match_operand:P 2 "register_operand" "=&r"))]
4494 "TARGET_FLOAT && nopcrelative_literal_loads"
4496 aarch64_expand_mov_immediate (operands[2], XEXP (operands[1], 0));
4497 emit_move_insn (operands[0], gen_rtx_MEM (<GPF_TF:MODE>mode, operands[2]));
4502 ;; Reload Vector modes from constant pool.
4503 (define_expand "aarch64_reload_movcp<VALL:mode><P:mode>"
4504 [(set (match_operand:VALL 0 "register_operand" "=w")
4505 (mem:VALL (match_operand 1 "aarch64_constant_pool_symref" "S")))
4506 (clobber (match_operand:P 2 "register_operand" "=&r"))]
4507 "TARGET_FLOAT && nopcrelative_literal_loads"
4509 aarch64_expand_mov_immediate (operands[2], XEXP (operands[1], 0));
4510 emit_move_insn (operands[0], gen_rtx_MEM (<VALL:MODE>mode, operands[2]));
4515 (define_expand "aarch64_reload_mov<mode>"
4516 [(set (match_operand:TX 0 "register_operand" "=w")
4517 (match_operand:TX 1 "register_operand" "w"))
4518 (clobber (match_operand:DI 2 "register_operand" "=&r"))
4522 rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
4523 rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
4524 gen_aarch64_movtilow_tilow (op0, op1);
4525 gen_aarch64_movdi_tihigh (operands[2], op1);
4526 gen_aarch64_movtihigh_di (op0, operands[2]);
4531 ;; The following secondary reload helpers patterns are invoked
4532 ;; after or during reload as we don't want these patterns to start
4533 ;; kicking in during the combiner.
4535 (define_insn "aarch64_movdi_<mode>low"
4536 [(set (match_operand:DI 0 "register_operand" "=r")
4537 (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
4538 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4540 [(set_attr "type" "f_mrc")
4541 (set_attr "length" "4")
4544 (define_insn "aarch64_movdi_<mode>high"
4545 [(set (match_operand:DI 0 "register_operand" "=r")
4547 (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
4549 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4550 "fmov\\t%x0, %1.d[1]"
4551 [(set_attr "type" "f_mrc")
4552 (set_attr "length" "4")
4555 (define_insn "aarch64_mov<mode>high_di"
4556 [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
4557 (const_int 64) (const_int 64))
4558 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4559 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4560 "fmov\\t%0.d[1], %x1"
4561 [(set_attr "type" "f_mcr")
4562 (set_attr "length" "4")
4565 (define_insn "aarch64_mov<mode>low_di"
4566 [(set (match_operand:TX 0 "register_operand" "=w")
4567 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4568 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4570 [(set_attr "type" "f_mcr")
4571 (set_attr "length" "4")
4574 (define_insn "aarch64_movtilow_tilow"
4575 [(set (match_operand:TI 0 "register_operand" "=w")
4577 (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
4578 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4580 [(set_attr "type" "fmov")
4581 (set_attr "length" "4")
4584 ;; There is a deliberate reason why the parameters of high and lo_sum's
4585 ;; don't have modes for ADRP and ADD instructions. This is to allow high
4586 ;; and lo_sum's to be used with the labels defining the jump tables in
4589 (define_expand "add_losym"
4590 [(set (match_operand 0 "register_operand" "=r")
4591 (lo_sum (match_operand 1 "register_operand" "r")
4592 (match_operand 2 "aarch64_valid_symref" "S")))]
4595 machine_mode mode = GET_MODE (operands[0]);
4597 emit_insn ((mode == DImode
4599 : gen_add_losym_si) (operands[0],
4605 (define_insn "add_losym_<mode>"
4606 [(set (match_operand:P 0 "register_operand" "=r")
4607 (lo_sum:P (match_operand:P 1 "register_operand" "r")
4608 (match_operand 2 "aarch64_valid_symref" "S")))]
4610 "add\\t%<w>0, %<w>1, :lo12:%a2"
4611 [(set_attr "type" "alu_imm")]
4614 (define_insn "ldr_got_small_<mode>"
4615 [(set (match_operand:PTR 0 "register_operand" "=r")
4616 (unspec:PTR [(mem:PTR (lo_sum:PTR
4617 (match_operand:PTR 1 "register_operand" "r")
4618 (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
4619 UNSPEC_GOTSMALLPIC))]
4621 "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
4622 [(set_attr "type" "load1")]
4625 (define_insn "ldr_got_small_sidi"
4626 [(set (match_operand:DI 0 "register_operand" "=r")
4628 (unspec:SI [(mem:SI (lo_sum:DI
4629 (match_operand:DI 1 "register_operand" "r")
4630 (match_operand:DI 2 "aarch64_valid_symref" "S")))]
4631 UNSPEC_GOTSMALLPIC)))]
4633 "ldr\\t%w0, [%1, #:got_lo12:%a2]"
4634 [(set_attr "type" "load1")]
4637 (define_insn "ldr_got_small_28k_<mode>"
4638 [(set (match_operand:PTR 0 "register_operand" "=r")
4639 (unspec:PTR [(mem:PTR (lo_sum:PTR
4640 (match_operand:PTR 1 "register_operand" "r")
4641 (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
4642 UNSPEC_GOTSMALLPIC28K))]
4644 "ldr\\t%<w>0, [%1, #:<got_modifier>:%a2]"
4645 [(set_attr "type" "load1")]
4648 (define_insn "ldr_got_small_28k_sidi"
4649 [(set (match_operand:DI 0 "register_operand" "=r")
4651 (unspec:SI [(mem:SI (lo_sum:DI
4652 (match_operand:DI 1 "register_operand" "r")
4653 (match_operand:DI 2 "aarch64_valid_symref" "S")))]
4654 UNSPEC_GOTSMALLPIC28K)))]
4656 "ldr\\t%w0, [%1, #:gotpage_lo14:%a2]"
4657 [(set_attr "type" "load1")]
4660 (define_insn "ldr_got_tiny"
4661 [(set (match_operand:DI 0 "register_operand" "=r")
4662 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
4663 UNSPEC_GOTTINYPIC))]
4666 [(set_attr "type" "load1")]
4669 (define_insn "aarch64_load_tp_hard"
4670 [(set (match_operand:DI 0 "register_operand" "=r")
4671 (unspec:DI [(const_int 0)] UNSPEC_TLS))]
4673 "mrs\\t%0, tpidr_el0"
4674 [(set_attr "type" "mrs")]
4677 ;; The TLS ABI specifically requires that the compiler does not schedule
4678 ;; instructions in the TLS stubs, in order to enable linker relaxation.
4679 ;; Therefore we treat the stubs as an atomic sequence.
4680 (define_expand "tlsgd_small"
4681 [(parallel [(set (match_operand 0 "register_operand" "")
4682 (call (mem:DI (match_dup 2)) (const_int 1)))
4683 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
4684 (clobber (reg:DI LR_REGNUM))])]
4687 operands[2] = aarch64_tls_get_addr ();
4690 (define_insn "*tlsgd_small"
4691 [(set (match_operand 0 "register_operand" "")
4692 (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
4693 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
4694 (clobber (reg:DI LR_REGNUM))
4697 "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
4698 [(set_attr "type" "call")
4699 (set_attr "length" "16")])
4701 (define_insn "tlsie_small_<mode>"
4702 [(set (match_operand:PTR 0 "register_operand" "=r")
4703 (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
4704 UNSPEC_GOTSMALLTLS))]
4706 "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
4707 [(set_attr "type" "load1")
4708 (set_attr "length" "8")]
4711 (define_insn "tlsie_small_sidi"
4712 [(set (match_operand:DI 0 "register_operand" "=r")
4714 (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")]
4715 UNSPEC_GOTSMALLTLS)))]
4717 "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
4718 [(set_attr "type" "load1")
4719 (set_attr "length" "8")]
4722 (define_insn "tlsie_tiny_<mode>"
4723 [(set (match_operand:PTR 0 "register_operand" "=&r")
4724 (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")
4725 (match_operand:PTR 2 "register_operand" "r")]
4726 UNSPEC_GOTTINYTLS))]
4728 "ldr\\t%<w>0, %L1\;add\\t%<w>0, %<w>0, %<w>2"
4729 [(set_attr "type" "multiple")
4730 (set_attr "length" "8")]
4733 (define_insn "tlsie_tiny_sidi"
4734 [(set (match_operand:DI 0 "register_operand" "=&r")
4736 (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")
4737 (match_operand:DI 2 "register_operand" "r")
4739 UNSPEC_GOTTINYTLS)))]
4741 "ldr\\t%w0, %L1\;add\\t%w0, %w0, %w2"
4742 [(set_attr "type" "multiple")
4743 (set_attr "length" "8")]
4746 (define_insn "tlsle12_<mode>"
4747 [(set (match_operand:P 0 "register_operand" "=r")
4748 (unspec:P [(match_operand:P 1 "register_operand" "r")
4749 (match_operand 2 "aarch64_tls_le_symref" "S")]
4752 "add\\t%<w>0, %<w>1, #%L2";
4753 [(set_attr "type" "alu_sreg")
4754 (set_attr "length" "4")]
4757 (define_insn "tlsle24_<mode>"
4758 [(set (match_operand:P 0 "register_operand" "=r")
4759 (unspec:P [(match_operand:P 1 "register_operand" "r")
4760 (match_operand 2 "aarch64_tls_le_symref" "S")]
4763 "add\\t%<w>0, %<w>1, #%G2, lsl #12\;add\\t%<w>0, %<w>0, #%L2"
4764 [(set_attr "type" "multiple")
4765 (set_attr "length" "8")]
4768 (define_insn "tlsle32_<mode>"
4769 [(set (match_operand:P 0 "register_operand" "=r")
4770 (unspec:P [(match_operand 1 "aarch64_tls_le_symref" "S")]
4773 "movz\\t%<w>0, #:tprel_g1:%1\;movk\\t%<w>0, #:tprel_g0_nc:%1"
4774 [(set_attr "type" "multiple")
4775 (set_attr "length" "8")]
4778 (define_insn "tlsle48_<mode>"
4779 [(set (match_operand:P 0 "register_operand" "=r")
4780 (unspec:P [(match_operand 1 "aarch64_tls_le_symref" "S")]
4783 "movz\\t%<w>0, #:tprel_g2:%1\;movk\\t%<w>0, #:tprel_g1_nc:%1\;movk\\t%<w>0, #:tprel_g0_nc:%1"
4784 [(set_attr "type" "multiple")
4785 (set_attr "length" "12")]
4788 (define_insn "tlsdesc_small_<mode>"
4789 [(set (reg:PTR R0_REGNUM)
4790 (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
4792 (clobber (reg:DI LR_REGNUM))
4793 (clobber (reg:CC CC_REGNUM))
4794 (clobber (match_scratch:DI 1 "=r"))]
4796 "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
4797 [(set_attr "type" "call")
4798 (set_attr "length" "16")])
4800 (define_insn "stack_tie"
4801 [(set (mem:BLK (scratch))
4802 (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
4803 (match_operand:DI 1 "register_operand" "rk")]
4807 [(set_attr "length" "0")]
4810 ;; Named pattern for expanding thread pointer reference.
4811 (define_expand "get_thread_pointerdi"
4812 [(match_operand:DI 0 "register_operand" "=r")]
4815 rtx tmp = aarch64_load_tp (operands[0]);
4816 if (tmp != operands[0])
4817 emit_move_insn (operands[0], tmp);
4821 ;; Named patterns for stack smashing protection.
4822 (define_expand "stack_protect_set"
4823 [(match_operand 0 "memory_operand")
4824 (match_operand 1 "memory_operand")]
4827 machine_mode mode = GET_MODE (operands[0]);
4829 emit_insn ((mode == DImode
4830 ? gen_stack_protect_set_di
4831 : gen_stack_protect_set_si) (operands[0], operands[1]));
4835 (define_insn "stack_protect_set_<mode>"
4836 [(set (match_operand:PTR 0 "memory_operand" "=m")
4837 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
4839 (set (match_scratch:PTR 2 "=&r") (const_int 0))]
4841 "ldr\\t%<w>2, %1\;str\\t%<w>2, %0\;mov\t%<w>2,0"
4842 [(set_attr "length" "12")
4843 (set_attr "type" "multiple")])
4845 (define_expand "stack_protect_test"
4846 [(match_operand 0 "memory_operand")
4847 (match_operand 1 "memory_operand")
4852 machine_mode mode = GET_MODE (operands[0]);
4854 result = gen_reg_rtx(mode);
4856 emit_insn ((mode == DImode
4857 ? gen_stack_protect_test_di
4858 : gen_stack_protect_test_si) (result,
4863 emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4864 result, const0_rtx, operands[2]));
4866 emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4867 result, const0_rtx, operands[2]));
4871 (define_insn "stack_protect_test_<mode>"
4872 [(set (match_operand:PTR 0 "register_operand" "=r")
4873 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
4874 (match_operand:PTR 2 "memory_operand" "m")]
4876 (clobber (match_scratch:PTR 3 "=&r"))]
4878 "ldr\t%<w>3, %x1\;ldr\t%<w>0, %x2\;eor\t%<w>0, %<w>3, %<w>0"
4879 [(set_attr "length" "12")
4880 (set_attr "type" "multiple")])
4882 ;; Write Floating-point Control Register.
4883 (define_insn "set_fpcr"
4884 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
4887 [(set_attr "type" "mrs")])
4889 ;; Read Floating-point Control Register.
4890 (define_insn "get_fpcr"
4891 [(set (match_operand:SI 0 "register_operand" "=r")
4892 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
4895 [(set_attr "type" "mrs")])
4897 ;; Write Floating-point Status Register.
4898 (define_insn "set_fpsr"
4899 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
4902 [(set_attr "type" "mrs")])
4904 ;; Read Floating-point Status Register.
4905 (define_insn "get_fpsr"
4906 [(set (match_operand:SI 0 "register_operand" "=r")
4907 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
4910 [(set_attr "type" "mrs")])
4913 ;; Define the subtract-one-and-jump insns so loop.c
4914 ;; knows what to generate.
4915 (define_expand "doloop_end"
4916 [(use (match_operand 0 "" "")) ; loop pseudo
4917 (use (match_operand 1 "" ""))] ; label
4918 "optimize > 0 && flag_modulo_sched"
4927 /* Currently SMS relies on the do-loop pattern to recognize loops
4928 where (1) the control part consists of all insns defining and/or
4929 using a certain 'count' register and (2) the loop count can be
4930 adjusted by modifying this register prior to the loop.
4931 ??? The possible introduction of a new block to initialize the
4932 new IV can potentially affect branch optimizations. */
4934 if (GET_MODE (operands[0]) != DImode)
4938 insn = emit_insn (gen_adddi3_compare0 (s0, s0, GEN_INT (-1)));
4940 cmp = XVECEXP (PATTERN (insn), 0, 0);
4941 cc_reg = SET_DEST (cmp);
4942 bcomp = gen_rtx_NE (VOIDmode, cc_reg, const0_rtx);
4943 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
4944 emit_jump_insn (gen_rtx_SET (pc_rtx,
4945 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
4951 (include "aarch64-simd.md")
4953 ;; Atomic Operations
4954 (include "atomics.md")
4956 ;; ldp/stp peephole patterns
4957 (include "aarch64-ldpstp.md")