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)
700 || aarch64_is_noplt_call_p (callee))
702 XEXP (operands[0], 0) = force_reg (Pmode, callee);
704 pat = gen_call_internal (operands[0], operands[1], operands[2]);
705 aarch64_emit_call_insn (pat);
710 (define_insn "*call_reg"
711 [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
712 (match_operand 1 "" ""))
713 (use (match_operand 2 "" ""))
714 (clobber (reg:DI LR_REGNUM))]
717 [(set_attr "type" "call")]
720 (define_insn "*call_symbol"
721 [(call (mem:DI (match_operand:DI 0 "" ""))
722 (match_operand 1 "" ""))
723 (use (match_operand 2 "" ""))
724 (clobber (reg:DI LR_REGNUM))]
725 "GET_CODE (operands[0]) == SYMBOL_REF
726 && !aarch64_is_long_call_p (operands[0])
727 && !aarch64_is_noplt_call_p (operands[0])"
729 [(set_attr "type" "call")]
732 (define_expand "call_value_internal"
733 [(parallel [(set (match_operand 0 "" "")
734 (call (match_operand 1 "memory_operand" "")
735 (match_operand 2 "general_operand" "")))
736 (use (match_operand 3 "" ""))
737 (clobber (reg:DI LR_REGNUM))])])
739 (define_expand "call_value"
740 [(parallel [(set (match_operand 0 "" "")
741 (call (match_operand 1 "memory_operand" "")
742 (match_operand 2 "general_operand" "")))
743 (use (match_operand 3 "" ""))
744 (clobber (reg:DI LR_REGNUM))])]
750 /* In an untyped call, we can get NULL for operand 3. */
751 if (operands[3] == NULL)
752 operands[3] = const0_rtx;
754 /* Decide if we should generate indirect calls by loading the
755 64-bit address of the callee into a register before performing
756 the branch-and-link. */
757 callee = XEXP (operands[1], 0);
758 if (GET_CODE (callee) == SYMBOL_REF
759 ? (aarch64_is_long_call_p (callee)
760 || aarch64_is_noplt_call_p (callee))
762 XEXP (operands[1], 0) = force_reg (Pmode, callee);
764 pat = gen_call_value_internal (operands[0], operands[1], operands[2],
766 aarch64_emit_call_insn (pat);
771 (define_insn "*call_value_reg"
772 [(set (match_operand 0 "" "")
773 (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
774 (match_operand 2 "" "")))
775 (use (match_operand 3 "" ""))
776 (clobber (reg:DI LR_REGNUM))]
779 [(set_attr "type" "call")]
783 (define_insn "*call_value_symbol"
784 [(set (match_operand 0 "" "")
785 (call (mem:DI (match_operand:DI 1 "" ""))
786 (match_operand 2 "" "")))
787 (use (match_operand 3 "" ""))
788 (clobber (reg:DI LR_REGNUM))]
789 "GET_CODE (operands[1]) == SYMBOL_REF
790 && !aarch64_is_long_call_p (operands[1])
791 && !aarch64_is_noplt_call_p (operands[1])"
793 [(set_attr "type" "call")]
796 (define_expand "sibcall_internal"
797 [(parallel [(call (match_operand 0 "memory_operand" "")
798 (match_operand 1 "general_operand" ""))
800 (use (match_operand 2 "" ""))])])
802 (define_expand "sibcall"
803 [(parallel [(call (match_operand 0 "memory_operand" "")
804 (match_operand 1 "general_operand" ""))
806 (use (match_operand 2 "" ""))])]
810 rtx callee = XEXP (operands[0], 0);
812 && ((GET_CODE (callee) != SYMBOL_REF)
813 || aarch64_is_noplt_call_p (callee)))
814 XEXP (operands[0], 0) = force_reg (Pmode, callee);
816 if (operands[2] == NULL_RTX)
817 operands[2] = const0_rtx;
819 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
820 aarch64_emit_call_insn (pat);
825 (define_expand "sibcall_value_internal"
826 [(parallel [(set (match_operand 0 "" "")
827 (call (match_operand 1 "memory_operand" "")
828 (match_operand 2 "general_operand" "")))
830 (use (match_operand 3 "" ""))])])
832 (define_expand "sibcall_value"
833 [(parallel [(set (match_operand 0 "" "")
834 (call (match_operand 1 "memory_operand" "")
835 (match_operand 2 "general_operand" "")))
837 (use (match_operand 3 "" ""))])]
841 rtx callee = XEXP (operands[1], 0);
843 && ((GET_CODE (callee) != SYMBOL_REF)
844 || aarch64_is_noplt_call_p (callee)))
845 XEXP (operands[1], 0) = force_reg (Pmode, callee);
847 if (operands[3] == NULL_RTX)
848 operands[3] = const0_rtx;
850 pat = gen_sibcall_value_internal (operands[0], operands[1], operands[2],
852 aarch64_emit_call_insn (pat);
857 (define_insn "*sibcall_insn"
858 [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucs, Usf"))
859 (match_operand 1 "" ""))
861 (use (match_operand 2 "" ""))]
862 "SIBLING_CALL_P (insn)"
866 [(set_attr "type" "branch, branch")]
869 (define_insn "*sibcall_value_insn"
870 [(set (match_operand 0 "" "")
872 (match_operand:DI 1 "aarch64_call_insn_operand" "Ucs, Usf"))
873 (match_operand 2 "" "")))
875 (use (match_operand 3 "" ""))]
876 "SIBLING_CALL_P (insn)"
880 [(set_attr "type" "branch, branch")]
883 ;; Call subroutine returning any type.
885 (define_expand "untyped_call"
886 [(parallel [(call (match_operand 0 "")
889 (match_operand 2 "")])]
894 emit_call_insn (gen_call (operands[0], const0_rtx, NULL));
896 for (i = 0; i < XVECLEN (operands[2], 0); i++)
898 rtx set = XVECEXP (operands[2], 0, i);
899 emit_move_insn (SET_DEST (set), SET_SRC (set));
902 /* The optimizer does not know that the call sets the function value
903 registers we stored in the result block. We avoid problems by
904 claiming that all hard registers are used and clobbered at this
906 emit_insn (gen_blockage ());
910 ;; -------------------------------------------------------------------
912 ;; -------------------------------------------------------------------
914 (define_expand "mov<mode>"
915 [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
916 (match_operand:SHORT 1 "general_operand" ""))]
919 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
920 operands[1] = force_reg (<MODE>mode, operands[1]);
924 (define_insn "*mov<mode>_aarch64"
925 [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r, *w,r,*w, m, m, r,*w,*w")
926 (match_operand:SHORT 1 "general_operand" " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
927 "(register_operand (operands[0], <MODE>mode)
928 || aarch64_reg_or_zero (operands[1], <MODE>mode))"
930 switch (which_alternative)
933 return "mov\t%w0, %w1";
935 return "mov\t%w0, %1";
937 return aarch64_output_scalar_simd_mov_immediate (operands[1],
940 return "ldr<size>\t%w0, %1";
942 return "ldr\t%<size>0, %1";
944 return "str<size>\t%w1, %0";
946 return "str\t%<size>1, %0";
948 return "umov\t%w0, %1.<v>[0]";
950 return "dup\t%0.<Vallxd>, %w1";
952 return "dup\t%<Vetype>0, %1.<v>[0]";
957 [(set_attr "type" "mov_reg,mov_imm,neon_move,load1,load1,store1,store1,\
958 neon_to_gp<q>,neon_from_gp<q>,neon_dup")
959 (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")]
962 (define_expand "mov<mode>"
963 [(set (match_operand:GPI 0 "nonimmediate_operand" "")
964 (match_operand:GPI 1 "general_operand" ""))]
967 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
968 operands[1] = force_reg (<MODE>mode, operands[1]);
970 /* FIXME: RR we still need to fix up what we are doing with
971 symbol_refs and other types of constants. */
972 if (CONSTANT_P (operands[1])
973 && !CONST_INT_P (operands[1]))
975 aarch64_expand_mov_immediate (operands[0], operands[1]);
981 (define_insn_and_split "*movsi_aarch64"
982 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,r,*w,m, m,r,r ,*w, r,*w")
983 (match_operand:SI 1 "aarch64_mov_operand" " r,r,k,M,n,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
984 "(register_operand (operands[0], SImode)
985 || aarch64_reg_or_zero (operands[1], SImode))"
1001 "CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), SImode)
1002 && REG_P (operands[0]) && GP_REGNUM_P (REGNO (operands[0]))"
1005 aarch64_expand_mov_immediate (operands[0], operands[1]);
1008 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
1009 adr,adr,f_mcr,f_mrc,fmov")
1010 (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
1013 (define_insn_and_split "*movdi_aarch64"
1014 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,r,*w,m, m,r,r, *w, r,*w,w")
1015 (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,n,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))]
1016 "(register_operand (operands[0], DImode)
1017 || aarch64_reg_or_zero (operands[1], DImode))"
1034 "(CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), DImode))
1035 && REG_P (operands[0]) && GP_REGNUM_P (REGNO (operands[0]))"
1038 aarch64_expand_mov_immediate (operands[0], operands[1]);
1041 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
1042 adr,adr,f_mcr,f_mrc,fmov,neon_move")
1043 (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
1044 (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
1047 (define_insn "insv_imm<mode>"
1048 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
1050 (match_operand:GPI 1 "const_int_operand" "n"))
1051 (match_operand:GPI 2 "const_int_operand" "n"))]
1052 "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
1053 && UINTVAL (operands[1]) % 16 == 0"
1054 "movk\\t%<w>0, %X2, lsl %1"
1055 [(set_attr "type" "mov_imm")]
1058 (define_expand "movti"
1059 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1060 (match_operand:TI 1 "general_operand" ""))]
1063 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
1064 operands[1] = force_reg (TImode, operands[1]);
1068 (define_insn "*movti_aarch64"
1069 [(set (match_operand:TI 0
1070 "nonimmediate_operand" "=r, *w,r ,*w,r ,Ump,Ump,*w,m")
1072 "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r ,Z , m,*w"))]
1073 "(register_operand (operands[0], TImode)
1074 || aarch64_reg_or_zero (operands[1], TImode))"
1079 orr\\t%0.16b, %1.16b, %1.16b
1085 [(set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \
1086 load2,store2,store2,f_loadd,f_stored")
1087 (set_attr "length" "8,8,8,4,4,4,4,4,4")
1088 (set_attr "simd" "*,*,*,yes,*,*,*,*,*")
1089 (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
1092 ;; Split a TImode register-register or register-immediate move into
1093 ;; its component DImode pieces, taking care to handle overlapping
1094 ;; source and dest registers.
1096 [(set (match_operand:TI 0 "register_operand" "")
1097 (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
1098 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
1101 aarch64_split_128bit_move (operands[0], operands[1]);
1105 (define_expand "mov<mode>"
1106 [(set (match_operand:GPF_TF_F16 0 "nonimmediate_operand" "")
1107 (match_operand:GPF_TF_F16 1 "general_operand" ""))]
1112 aarch64_err_no_fpadvsimd (<MODE>mode, "code");
1116 if (GET_CODE (operands[0]) == MEM
1117 && ! (GET_CODE (operands[1]) == CONST_DOUBLE
1118 && aarch64_float_const_zero_rtx_p (operands[1])))
1119 operands[1] = force_reg (<MODE>mode, operands[1]);
1123 (define_insn "*movhf_aarch64"
1124 [(set (match_operand:HF 0 "nonimmediate_operand" "=w, ?r,w,w,m,r,m ,r")
1125 (match_operand:HF 1 "general_operand" "?rY, w,w,m,w,m,rY,r"))]
1126 "TARGET_FLOAT && (register_operand (operands[0], HFmode)
1127 || register_operand (operands[1], HFmode))"
1131 mov\\t%0.h[0], %1.h[0]
1137 [(set_attr "type" "neon_from_gp,neon_to_gp,fmov,\
1138 f_loads,f_stores,load1,store1,mov_reg")
1139 (set_attr "simd" "yes,yes,yes,*,*,*,*,*")
1140 (set_attr "fp" "*,*,*,yes,yes,*,*,*")]
1143 (define_insn "*movsf_aarch64"
1144 [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
1145 (match_operand:SF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
1146 "TARGET_FLOAT && (register_operand (operands[0], SFmode)
1147 || aarch64_reg_or_fp_zero (operands[1], SFmode))"
1158 [(set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
1159 f_loads,f_stores,load1,store1,mov_reg")]
1162 (define_insn "*movdf_aarch64"
1163 [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
1164 (match_operand:DF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
1165 "TARGET_FLOAT && (register_operand (operands[0], DFmode)
1166 || aarch64_reg_or_fp_zero (operands[1], DFmode))"
1177 [(set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
1178 f_loadd,f_stored,load1,store1,mov_reg")]
1181 (define_insn "*movtf_aarch64"
1182 [(set (match_operand:TF 0
1183 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump,Ump")
1185 "general_operand" " w,?r, ?r,w ,Y,Y ,m,w,Ump,?r ,Y"))]
1186 "TARGET_FLOAT && (register_operand (operands[0], TFmode)
1187 || aarch64_reg_or_fp_zero (operands[1], TFmode))"
1189 orr\\t%0.16b, %1.16b, %1.16b
1200 [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,neon_move_q,fconstd,\
1201 f_loadd,f_stored,load2,store2,store2")
1202 (set_attr "length" "4,8,8,8,4,4,4,4,4,4,4")
1203 (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*,*")
1204 (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*,*")]
1208 [(set (match_operand:TF 0 "register_operand" "")
1209 (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
1210 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
1213 aarch64_split_128bit_move (operands[0], operands[1]);
1220 ;; 2 is size of move in bytes
1223 (define_expand "movmemdi"
1224 [(match_operand:BLK 0 "memory_operand")
1225 (match_operand:BLK 1 "memory_operand")
1226 (match_operand:DI 2 "immediate_operand")
1227 (match_operand:DI 3 "immediate_operand")]
1230 if (aarch64_expand_movmem (operands))
1236 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1237 ;; fairly lax checking on the second memory operation.
1238 (define_insn "load_pairsi"
1239 [(set (match_operand:SI 0 "register_operand" "=r,*w")
1240 (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1241 (set (match_operand:SI 2 "register_operand" "=r,*w")
1242 (match_operand:SI 3 "memory_operand" "m,m"))]
1243 "rtx_equal_p (XEXP (operands[3], 0),
1244 plus_constant (Pmode,
1245 XEXP (operands[1], 0),
1246 GET_MODE_SIZE (SImode)))"
1250 [(set_attr "type" "load2,neon_load1_2reg")
1251 (set_attr "fp" "*,yes")]
1254 (define_insn "load_pairdi"
1255 [(set (match_operand:DI 0 "register_operand" "=r,*w")
1256 (match_operand:DI 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1257 (set (match_operand:DI 2 "register_operand" "=r,*w")
1258 (match_operand:DI 3 "memory_operand" "m,m"))]
1259 "rtx_equal_p (XEXP (operands[3], 0),
1260 plus_constant (Pmode,
1261 XEXP (operands[1], 0),
1262 GET_MODE_SIZE (DImode)))"
1266 [(set_attr "type" "load2,neon_load1_2reg")
1267 (set_attr "fp" "*,yes")]
1271 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1272 ;; fairly lax checking on the second memory operation.
1273 (define_insn "store_pairsi"
1274 [(set (match_operand:SI 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1275 (match_operand:SI 1 "aarch64_reg_or_zero" "rZ,*w"))
1276 (set (match_operand:SI 2 "memory_operand" "=m,m")
1277 (match_operand:SI 3 "aarch64_reg_or_zero" "rZ,*w"))]
1278 "rtx_equal_p (XEXP (operands[2], 0),
1279 plus_constant (Pmode,
1280 XEXP (operands[0], 0),
1281 GET_MODE_SIZE (SImode)))"
1285 [(set_attr "type" "store2,neon_store1_2reg")
1286 (set_attr "fp" "*,yes")]
1289 (define_insn "store_pairdi"
1290 [(set (match_operand:DI 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1291 (match_operand:DI 1 "aarch64_reg_or_zero" "rZ,*w"))
1292 (set (match_operand:DI 2 "memory_operand" "=m,m")
1293 (match_operand:DI 3 "aarch64_reg_or_zero" "rZ,*w"))]
1294 "rtx_equal_p (XEXP (operands[2], 0),
1295 plus_constant (Pmode,
1296 XEXP (operands[0], 0),
1297 GET_MODE_SIZE (DImode)))"
1301 [(set_attr "type" "store2,neon_store1_2reg")
1302 (set_attr "fp" "*,yes")]
1305 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1306 ;; fairly lax checking on the second memory operation.
1307 (define_insn "load_pairsf"
1308 [(set (match_operand:SF 0 "register_operand" "=w,*r")
1309 (match_operand:SF 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1310 (set (match_operand:SF 2 "register_operand" "=w,*r")
1311 (match_operand:SF 3 "memory_operand" "m,m"))]
1312 "rtx_equal_p (XEXP (operands[3], 0),
1313 plus_constant (Pmode,
1314 XEXP (operands[1], 0),
1315 GET_MODE_SIZE (SFmode)))"
1319 [(set_attr "type" "neon_load1_2reg,load2")
1320 (set_attr "fp" "yes,*")]
1323 (define_insn "load_pairdf"
1324 [(set (match_operand:DF 0 "register_operand" "=w,*r")
1325 (match_operand:DF 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1326 (set (match_operand:DF 2 "register_operand" "=w,*r")
1327 (match_operand:DF 3 "memory_operand" "m,m"))]
1328 "rtx_equal_p (XEXP (operands[3], 0),
1329 plus_constant (Pmode,
1330 XEXP (operands[1], 0),
1331 GET_MODE_SIZE (DFmode)))"
1335 [(set_attr "type" "neon_load1_2reg,load2")
1336 (set_attr "fp" "yes,*")]
1339 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1340 ;; fairly lax checking on the second memory operation.
1341 (define_insn "store_pairsf"
1342 [(set (match_operand:SF 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1343 (match_operand:SF 1 "register_operand" "w,*r"))
1344 (set (match_operand:SF 2 "memory_operand" "=m,m")
1345 (match_operand:SF 3 "register_operand" "w,*r"))]
1346 "rtx_equal_p (XEXP (operands[2], 0),
1347 plus_constant (Pmode,
1348 XEXP (operands[0], 0),
1349 GET_MODE_SIZE (SFmode)))"
1353 [(set_attr "type" "neon_store1_2reg,store2")
1354 (set_attr "fp" "yes,*")]
1357 (define_insn "store_pairdf"
1358 [(set (match_operand:DF 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1359 (match_operand:DF 1 "register_operand" "w,*r"))
1360 (set (match_operand:DF 2 "memory_operand" "=m,m")
1361 (match_operand:DF 3 "register_operand" "w,*r"))]
1362 "rtx_equal_p (XEXP (operands[2], 0),
1363 plus_constant (Pmode,
1364 XEXP (operands[0], 0),
1365 GET_MODE_SIZE (DFmode)))"
1369 [(set_attr "type" "neon_store1_2reg,store2")
1370 (set_attr "fp" "yes,*")]
1373 ;; Load pair with post-index writeback. This is primarily used in function
1375 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
1377 [(set (match_operand:P 0 "register_operand" "=k")
1378 (plus:P (match_operand:P 1 "register_operand" "0")
1379 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1380 (set (match_operand:GPI 2 "register_operand" "=r")
1381 (mem:GPI (match_dup 1)))
1382 (set (match_operand:GPI 3 "register_operand" "=r")
1383 (mem:GPI (plus:P (match_dup 1)
1384 (match_operand:P 5 "const_int_operand" "n"))))])]
1385 "INTVAL (operands[5]) == GET_MODE_SIZE (<GPI:MODE>mode)"
1386 "ldp\\t%<w>2, %<w>3, [%1], %4"
1387 [(set_attr "type" "load2")]
1390 (define_insn "loadwb_pair<GPF:mode>_<P:mode>"
1392 [(set (match_operand:P 0 "register_operand" "=k")
1393 (plus:P (match_operand:P 1 "register_operand" "0")
1394 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1395 (set (match_operand:GPF 2 "register_operand" "=w")
1396 (mem:GPF (match_dup 1)))
1397 (set (match_operand:GPF 3 "register_operand" "=w")
1398 (mem:GPF (plus:P (match_dup 1)
1399 (match_operand:P 5 "const_int_operand" "n"))))])]
1400 "INTVAL (operands[5]) == GET_MODE_SIZE (<GPF:MODE>mode)"
1401 "ldp\\t%<w>2, %<w>3, [%1], %4"
1402 [(set_attr "type" "neon_load1_2reg")]
1405 ;; Store pair with pre-index writeback. This is primarily used in function
1407 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
1409 [(set (match_operand:P 0 "register_operand" "=&k")
1410 (plus:P (match_operand:P 1 "register_operand" "0")
1411 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1412 (set (mem:GPI (plus:P (match_dup 0)
1414 (match_operand:GPI 2 "register_operand" "r"))
1415 (set (mem:GPI (plus:P (match_dup 0)
1416 (match_operand:P 5 "const_int_operand" "n")))
1417 (match_operand:GPI 3 "register_operand" "r"))])]
1418 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1419 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1420 [(set_attr "type" "store2")]
1423 (define_insn "storewb_pair<GPF:mode>_<P:mode>"
1425 [(set (match_operand:P 0 "register_operand" "=&k")
1426 (plus:P (match_operand:P 1 "register_operand" "0")
1427 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1428 (set (mem:GPF (plus:P (match_dup 0)
1430 (match_operand:GPF 2 "register_operand" "w"))
1431 (set (mem:GPF (plus:P (match_dup 0)
1432 (match_operand:P 5 "const_int_operand" "n")))
1433 (match_operand:GPF 3 "register_operand" "w"))])]
1434 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPF:MODE>mode)"
1435 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1436 [(set_attr "type" "neon_store1_2reg<q>")]
1439 ;; -------------------------------------------------------------------
1440 ;; Sign/Zero extension
1441 ;; -------------------------------------------------------------------
1443 (define_expand "<optab>sidi2"
1444 [(set (match_operand:DI 0 "register_operand")
1445 (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1449 (define_insn "*extendsidi2_aarch64"
1450 [(set (match_operand:DI 0 "register_operand" "=r,r")
1451 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1456 [(set_attr "type" "extend,load1")]
1459 (define_insn "*load_pair_extendsidi2_aarch64"
1460 [(set (match_operand:DI 0 "register_operand" "=r")
1461 (sign_extend:DI (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump")))
1462 (set (match_operand:DI 2 "register_operand" "=r")
1463 (sign_extend:DI (match_operand:SI 3 "memory_operand" "m")))]
1464 "rtx_equal_p (XEXP (operands[3], 0),
1465 plus_constant (Pmode,
1466 XEXP (operands[1], 0),
1467 GET_MODE_SIZE (SImode)))"
1468 "ldpsw\\t%0, %2, %1"
1469 [(set_attr "type" "load2")]
1472 (define_insn "*zero_extendsidi2_aarch64"
1473 [(set (match_operand:DI 0 "register_operand" "=r,r")
1474 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1479 [(set_attr "type" "extend,load1")]
1482 (define_insn "*load_pair_zero_extendsidi2_aarch64"
1483 [(set (match_operand:DI 0 "register_operand" "=r")
1484 (zero_extend:DI (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump")))
1485 (set (match_operand:DI 2 "register_operand" "=r")
1486 (zero_extend:DI (match_operand:SI 3 "memory_operand" "m")))]
1487 "rtx_equal_p (XEXP (operands[3], 0),
1488 plus_constant (Pmode,
1489 XEXP (operands[1], 0),
1490 GET_MODE_SIZE (SImode)))"
1491 "ldp\\t%w0, %w2, %1"
1492 [(set_attr "type" "load2")]
1495 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1496 [(set (match_operand:GPI 0 "register_operand")
1497 (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1501 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1502 [(set (match_operand:GPI 0 "register_operand" "=r,r")
1503 (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1506 sxt<SHORT:size>\t%<GPI:w>0, %w1
1507 ldrs<SHORT:size>\t%<GPI:w>0, %1"
1508 [(set_attr "type" "extend,load1")]
1511 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1512 [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1513 (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1516 uxt<SHORT:size>\t%<GPI:w>0, %w1
1517 ldr<SHORT:size>\t%w0, %1
1518 ldr\t%<SHORT:size>0, %1"
1519 [(set_attr "type" "extend,load1,load1")]
1522 (define_expand "<optab>qihi2"
1523 [(set (match_operand:HI 0 "register_operand")
1524 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1528 (define_insn "*<optab>qihi2_aarch64"
1529 [(set (match_operand:HI 0 "register_operand" "=r,r")
1530 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1535 [(set_attr "type" "extend,load1")]
1538 ;; -------------------------------------------------------------------
1539 ;; Simple arithmetic
1540 ;; -------------------------------------------------------------------
1542 (define_expand "add<mode>3"
1544 (match_operand:GPI 0 "register_operand" "")
1545 (plus:GPI (match_operand:GPI 1 "register_operand" "")
1546 (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1549 if (! aarch64_plus_operand (operands[2], VOIDmode))
1551 HOST_WIDE_INT imm = INTVAL (operands[2]);
1553 if (aarch64_move_imm (imm, <MODE>mode) && can_create_pseudo_p ())
1555 rtx tmp = gen_reg_rtx (<MODE>mode);
1556 emit_move_insn (tmp, operands[2]);
1561 rtx subtarget = ((optimize && can_create_pseudo_p ())
1562 ? gen_reg_rtx (<MODE>mode) : operands[0]);
1565 imm = -(-imm & ~0xfff);
1569 emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1570 operands[1] = subtarget;
1571 operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1577 (define_insn "*addsi3_aarch64"
1579 (match_operand:SI 0 "register_operand" "=rk,rk,w,rk")
1581 (match_operand:SI 1 "register_operand" "%rk,rk,w,rk")
1582 (match_operand:SI 2 "aarch64_plus_operand" "I,r,w,J")))]
1587 add\\t%0.2s, %1.2s, %2.2s
1588 sub\\t%w0, %w1, #%n2"
1589 [(set_attr "type" "alu_imm,alu_sreg,neon_add,alu_imm")
1590 (set_attr "simd" "*,*,yes,*")]
1593 ;; zero_extend version of above
1594 (define_insn "*addsi3_aarch64_uxtw"
1596 (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1598 (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1599 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1604 sub\\t%w0, %w1, #%n2"
1605 [(set_attr "type" "alu_imm,alu_sreg,alu_imm")]
1608 (define_insn "*adddi3_aarch64"
1610 (match_operand:DI 0 "register_operand" "=rk,rk,rk,w")
1612 (match_operand:DI 1 "register_operand" "%rk,rk,rk,w")
1613 (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,w")))]
1618 sub\\t%x0, %x1, #%n2
1619 add\\t%d0, %d1, %d2"
1620 [(set_attr "type" "alu_imm,alu_sreg,alu_imm,neon_add")
1621 (set_attr "simd" "*,*,*,yes")]
1624 (define_expand "addti3"
1625 [(set (match_operand:TI 0 "register_operand" "")
1626 (plus:TI (match_operand:TI 1 "register_operand" "")
1627 (match_operand:TI 2 "register_operand" "")))]
1630 rtx low = gen_reg_rtx (DImode);
1631 emit_insn (gen_adddi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1632 gen_lowpart (DImode, operands[2])));
1634 rtx high = gen_reg_rtx (DImode);
1635 emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]),
1636 gen_highpart (DImode, operands[2])));
1638 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1639 emit_move_insn (gen_highpart (DImode, operands[0]), high);
1643 (define_insn "add<mode>3_compare0"
1644 [(set (reg:CC_NZ CC_REGNUM)
1646 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1647 (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1649 (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1650 (plus:GPI (match_dup 1) (match_dup 2)))]
1653 adds\\t%<w>0, %<w>1, %<w>2
1654 adds\\t%<w>0, %<w>1, %<w>2
1655 subs\\t%<w>0, %<w>1, #%n2"
1656 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1659 ;; zero_extend version of above
1660 (define_insn "*addsi3_compare0_uxtw"
1661 [(set (reg:CC_NZ CC_REGNUM)
1663 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1664 (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1666 (set (match_operand:DI 0 "register_operand" "=r,r,r")
1667 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1670 adds\\t%w0, %w1, %w2
1671 adds\\t%w0, %w1, %w2
1672 subs\\t%w0, %w1, #%n2"
1673 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1676 (define_insn "*adds_shift_imm_<mode>"
1677 [(set (reg:CC_NZ CC_REGNUM)
1679 (plus:GPI (ASHIFT:GPI
1680 (match_operand:GPI 1 "register_operand" "r")
1681 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1682 (match_operand:GPI 3 "register_operand" "r"))
1684 (set (match_operand:GPI 0 "register_operand" "=r")
1685 (plus:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))
1688 "adds\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1689 [(set_attr "type" "alus_shift_imm")]
1692 (define_insn "*subs_shift_imm_<mode>"
1693 [(set (reg:CC_NZ CC_REGNUM)
1695 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1697 (match_operand:GPI 2 "register_operand" "r")
1698 (match_operand:QI 3 "aarch64_shift_imm_<mode>" "n")))
1700 (set (match_operand:GPI 0 "register_operand" "=r")
1701 (minus:GPI (match_dup 1)
1702 (ASHIFT:GPI (match_dup 2) (match_dup 3))))]
1704 "subs\\t%<w>0, %<w>1, %<w>2, <shift> %3"
1705 [(set_attr "type" "alus_shift_imm")]
1708 (define_insn "*adds_mul_imm_<mode>"
1709 [(set (reg:CC_NZ CC_REGNUM)
1712 (match_operand:GPI 1 "register_operand" "r")
1713 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1714 (match_operand:GPI 3 "register_operand" "r"))
1716 (set (match_operand:GPI 0 "register_operand" "=r")
1717 (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1720 "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1721 [(set_attr "type" "alus_shift_imm")]
1724 (define_insn "*subs_mul_imm_<mode>"
1725 [(set (reg:CC_NZ CC_REGNUM)
1727 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1729 (match_operand:GPI 2 "register_operand" "r")
1730 (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1732 (set (match_operand:GPI 0 "register_operand" "=r")
1733 (minus:GPI (match_dup 1)
1734 (mult:GPI (match_dup 2) (match_dup 3))))]
1736 "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1737 [(set_attr "type" "alus_shift_imm")]
1740 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1741 [(set (reg:CC_NZ CC_REGNUM)
1744 (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1745 (match_operand:GPI 2 "register_operand" "r"))
1747 (set (match_operand:GPI 0 "register_operand" "=r")
1748 (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1750 "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1751 [(set_attr "type" "alus_ext")]
1754 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1755 [(set (reg:CC_NZ CC_REGNUM)
1757 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1759 (match_operand:ALLX 2 "register_operand" "r")))
1761 (set (match_operand:GPI 0 "register_operand" "=r")
1762 (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1764 "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1765 [(set_attr "type" "alus_ext")]
1768 (define_insn "*adds_<optab><ALLX:mode>_shift_<GPI:mode>"
1769 [(set (reg:CC_NZ CC_REGNUM)
1771 (plus:GPI (ashift:GPI
1773 (match_operand:ALLX 1 "register_operand" "r"))
1774 (match_operand 2 "aarch64_imm3" "Ui3"))
1775 (match_operand:GPI 3 "register_operand" "r"))
1777 (set (match_operand:GPI 0 "register_operand" "=rk")
1778 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI (match_dup 1))
1782 "adds\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1783 [(set_attr "type" "alus_ext")]
1786 (define_insn "*subs_<optab><ALLX:mode>_shift_<GPI:mode>"
1787 [(set (reg:CC_NZ CC_REGNUM)
1789 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1792 (match_operand:ALLX 2 "register_operand" "r"))
1793 (match_operand 3 "aarch64_imm3" "Ui3")))
1795 (set (match_operand:GPI 0 "register_operand" "=rk")
1796 (minus:GPI (match_dup 1)
1797 (ashift:GPI (ANY_EXTEND:GPI (match_dup 2))
1800 "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1801 [(set_attr "type" "alus_ext")]
1804 (define_insn "*adds_<optab><mode>_multp2"
1805 [(set (reg:CC_NZ CC_REGNUM)
1807 (plus:GPI (ANY_EXTRACT:GPI
1808 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1809 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1810 (match_operand 3 "const_int_operand" "n")
1812 (match_operand:GPI 4 "register_operand" "r"))
1814 (set (match_operand:GPI 0 "register_operand" "=r")
1815 (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1819 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1820 "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1821 [(set_attr "type" "alus_ext")]
1824 (define_insn "*subs_<optab><mode>_multp2"
1825 [(set (reg:CC_NZ CC_REGNUM)
1827 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1829 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1830 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1831 (match_operand 3 "const_int_operand" "n")
1834 (set (match_operand:GPI 0 "register_operand" "=r")
1835 (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1836 (mult:GPI (match_dup 1) (match_dup 2))
1839 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1840 "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1841 [(set_attr "type" "alus_ext")]
1844 (define_insn "*add<mode>3nr_compare0"
1845 [(set (reg:CC_NZ CC_REGNUM)
1847 (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1848 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1855 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1858 (define_insn "*compare_neg<mode>"
1859 [(set (reg:CC_Z CC_REGNUM)
1861 (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1862 (match_operand:GPI 1 "register_operand" "r")))]
1864 "cmn\\t%<w>1, %<w>0"
1865 [(set_attr "type" "alus_sreg")]
1868 (define_insn "*add_<shift>_<mode>"
1869 [(set (match_operand:GPI 0 "register_operand" "=r")
1870 (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1871 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1872 (match_operand:GPI 3 "register_operand" "r")))]
1874 "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1875 [(set_attr "type" "alu_shift_imm")]
1878 ;; zero_extend version of above
1879 (define_insn "*add_<shift>_si_uxtw"
1880 [(set (match_operand:DI 0 "register_operand" "=r")
1882 (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1883 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1884 (match_operand:SI 3 "register_operand" "r"))))]
1886 "add\\t%w0, %w3, %w1, <shift> %2"
1887 [(set_attr "type" "alu_shift_imm")]
1890 (define_insn "*add_mul_imm_<mode>"
1891 [(set (match_operand:GPI 0 "register_operand" "=r")
1892 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1893 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1894 (match_operand:GPI 3 "register_operand" "r")))]
1896 "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1897 [(set_attr "type" "alu_shift_imm")]
1900 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1901 [(set (match_operand:GPI 0 "register_operand" "=rk")
1902 (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1903 (match_operand:GPI 2 "register_operand" "r")))]
1905 "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1906 [(set_attr "type" "alu_ext")]
1909 ;; zero_extend version of above
1910 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1911 [(set (match_operand:DI 0 "register_operand" "=rk")
1913 (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1914 (match_operand:GPI 2 "register_operand" "r"))))]
1916 "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1917 [(set_attr "type" "alu_ext")]
1920 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1921 [(set (match_operand:GPI 0 "register_operand" "=rk")
1922 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1923 (match_operand:ALLX 1 "register_operand" "r"))
1924 (match_operand 2 "aarch64_imm3" "Ui3"))
1925 (match_operand:GPI 3 "register_operand" "r")))]
1927 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1928 [(set_attr "type" "alu_ext")]
1931 ;; zero_extend version of above
1932 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1933 [(set (match_operand:DI 0 "register_operand" "=rk")
1935 (plus:SI (ashift:SI (ANY_EXTEND:SI
1936 (match_operand:SHORT 1 "register_operand" "r"))
1937 (match_operand 2 "aarch64_imm3" "Ui3"))
1938 (match_operand:SI 3 "register_operand" "r"))))]
1940 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1941 [(set_attr "type" "alu_ext")]
1944 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1945 [(set (match_operand:GPI 0 "register_operand" "=rk")
1946 (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1947 (match_operand:ALLX 1 "register_operand" "r"))
1948 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1949 (match_operand:GPI 3 "register_operand" "r")))]
1951 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1952 [(set_attr "type" "alu_ext")]
1955 ;; zero_extend version of above
1956 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1957 [(set (match_operand:DI 0 "register_operand" "=rk")
1958 (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1959 (match_operand:SHORT 1 "register_operand" "r"))
1960 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1961 (match_operand:SI 3 "register_operand" "r"))))]
1963 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1964 [(set_attr "type" "alu_ext")]
1967 (define_insn "*add_<optab><mode>_multp2"
1968 [(set (match_operand:GPI 0 "register_operand" "=rk")
1969 (plus:GPI (ANY_EXTRACT:GPI
1970 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1971 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1972 (match_operand 3 "const_int_operand" "n")
1974 (match_operand:GPI 4 "register_operand" "r")))]
1975 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1976 "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1977 [(set_attr "type" "alu_ext")]
1980 ;; zero_extend version of above
1981 (define_insn "*add_<optab>si_multp2_uxtw"
1982 [(set (match_operand:DI 0 "register_operand" "=rk")
1984 (plus:SI (ANY_EXTRACT:SI
1985 (mult:SI (match_operand:SI 1 "register_operand" "r")
1986 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1987 (match_operand 3 "const_int_operand" "n")
1989 (match_operand:SI 4 "register_operand" "r"))))]
1990 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1991 "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1992 [(set_attr "type" "alu_ext")]
1995 (define_insn "add<mode>3_carryin"
1997 (match_operand:GPI 0 "register_operand" "=r")
1998 (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
2000 (match_operand:GPI 1 "register_operand" "r")
2001 (match_operand:GPI 2 "register_operand" "r"))))]
2003 "adc\\t%<w>0, %<w>1, %<w>2"
2004 [(set_attr "type" "adc_reg")]
2007 ;; zero_extend version of above
2008 (define_insn "*addsi3_carryin_uxtw"
2010 (match_operand:DI 0 "register_operand" "=r")
2012 (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
2014 (match_operand:SI 1 "register_operand" "r")
2015 (match_operand:SI 2 "register_operand" "r")))))]
2017 "adc\\t%w0, %w1, %w2"
2018 [(set_attr "type" "adc_reg")]
2021 (define_insn "*add<mode>3_carryin_alt1"
2023 (match_operand:GPI 0 "register_operand" "=r")
2025 (match_operand:GPI 1 "register_operand" "r")
2026 (match_operand:GPI 2 "register_operand" "r"))
2027 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
2029 "adc\\t%<w>0, %<w>1, %<w>2"
2030 [(set_attr "type" "adc_reg")]
2033 ;; zero_extend version of above
2034 (define_insn "*addsi3_carryin_alt1_uxtw"
2036 (match_operand:DI 0 "register_operand" "=r")
2039 (match_operand:SI 1 "register_operand" "r")
2040 (match_operand:SI 2 "register_operand" "r"))
2041 (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
2043 "adc\\t%w0, %w1, %w2"
2044 [(set_attr "type" "adc_reg")]
2047 (define_insn "*add<mode>3_carryin_alt2"
2049 (match_operand:GPI 0 "register_operand" "=r")
2051 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
2052 (match_operand:GPI 1 "register_operand" "r"))
2053 (match_operand:GPI 2 "register_operand" "r")))]
2055 "adc\\t%<w>0, %<w>1, %<w>2"
2056 [(set_attr "type" "adc_reg")]
2059 ;; zero_extend version of above
2060 (define_insn "*addsi3_carryin_alt2_uxtw"
2062 (match_operand:DI 0 "register_operand" "=r")
2065 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
2066 (match_operand:SI 1 "register_operand" "r"))
2067 (match_operand:SI 2 "register_operand" "r"))))]
2069 "adc\\t%w0, %w1, %w2"
2070 [(set_attr "type" "adc_reg")]
2073 (define_insn "*add<mode>3_carryin_alt3"
2075 (match_operand:GPI 0 "register_operand" "=r")
2077 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
2078 (match_operand:GPI 2 "register_operand" "r"))
2079 (match_operand:GPI 1 "register_operand" "r")))]
2081 "adc\\t%<w>0, %<w>1, %<w>2"
2082 [(set_attr "type" "adc_reg")]
2085 ;; zero_extend version of above
2086 (define_insn "*addsi3_carryin_alt3_uxtw"
2088 (match_operand:DI 0 "register_operand" "=r")
2091 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
2092 (match_operand:SI 2 "register_operand" "r"))
2093 (match_operand:SI 1 "register_operand" "r"))))]
2095 "adc\\t%w0, %w1, %w2"
2096 [(set_attr "type" "adc_reg")]
2099 (define_insn "*add_uxt<mode>_shift2"
2100 [(set (match_operand:GPI 0 "register_operand" "=rk")
2102 (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
2103 (match_operand 2 "aarch64_imm3" "Ui3"))
2104 (match_operand 3 "const_int_operand" "n"))
2105 (match_operand:GPI 4 "register_operand" "r")))]
2106 "aarch64_uxt_size (INTVAL (operands[2]), INTVAL (operands[3])) != 0"
2108 operands[3] = GEN_INT (aarch64_uxt_size (INTVAL(operands[2]),
2109 INTVAL (operands[3])));
2110 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %2\";"
2111 [(set_attr "type" "alu_ext")]
2114 ;; zero_extend version of above
2115 (define_insn "*add_uxtsi_shift2_uxtw"
2116 [(set (match_operand:DI 0 "register_operand" "=rk")
2119 (ashift:SI (match_operand:SI 1 "register_operand" "r")
2120 (match_operand 2 "aarch64_imm3" "Ui3"))
2121 (match_operand 3 "const_int_operand" "n"))
2122 (match_operand:SI 4 "register_operand" "r"))))]
2123 "aarch64_uxt_size (INTVAL (operands[2]), INTVAL (operands[3])) != 0"
2125 operands[3] = GEN_INT (aarch64_uxt_size (INTVAL (operands[2]),
2126 INTVAL (operands[3])));
2127 return \"add\t%w0, %w4, %w1, uxt%e3 %2\";"
2128 [(set_attr "type" "alu_ext")]
2131 (define_insn "*add_uxt<mode>_multp2"
2132 [(set (match_operand:GPI 0 "register_operand" "=rk")
2134 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2135 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2136 (match_operand 3 "const_int_operand" "n"))
2137 (match_operand:GPI 4 "register_operand" "r")))]
2138 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
2140 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2141 INTVAL (operands[3])));
2142 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
2143 [(set_attr "type" "alu_ext")]
2146 ;; zero_extend version of above
2147 (define_insn "*add_uxtsi_multp2_uxtw"
2148 [(set (match_operand:DI 0 "register_operand" "=rk")
2151 (mult:SI (match_operand:SI 1 "register_operand" "r")
2152 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2153 (match_operand 3 "const_int_operand" "n"))
2154 (match_operand:SI 4 "register_operand" "r"))))]
2155 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
2157 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2158 INTVAL (operands[3])));
2159 return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
2160 [(set_attr "type" "alu_ext")]
2163 (define_insn "subsi3"
2164 [(set (match_operand:SI 0 "register_operand" "=rk")
2165 (minus:SI (match_operand:SI 1 "register_operand" "rk")
2166 (match_operand:SI 2 "register_operand" "r")))]
2168 "sub\\t%w0, %w1, %w2"
2169 [(set_attr "type" "alu_sreg")]
2172 ;; zero_extend version of above
2173 (define_insn "*subsi3_uxtw"
2174 [(set (match_operand:DI 0 "register_operand" "=rk")
2176 (minus:SI (match_operand:SI 1 "register_operand" "rk")
2177 (match_operand:SI 2 "register_operand" "r"))))]
2179 "sub\\t%w0, %w1, %w2"
2180 [(set_attr "type" "alu_sreg")]
2183 (define_insn "subdi3"
2184 [(set (match_operand:DI 0 "register_operand" "=rk,w")
2185 (minus:DI (match_operand:DI 1 "register_operand" "rk,w")
2186 (match_operand:DI 2 "register_operand" "r,w")))]
2190 sub\\t%d0, %d1, %d2"
2191 [(set_attr "type" "alu_sreg, neon_sub")
2192 (set_attr "simd" "*,yes")]
2195 (define_expand "subti3"
2196 [(set (match_operand:TI 0 "register_operand" "")
2197 (minus:TI (match_operand:TI 1 "register_operand" "")
2198 (match_operand:TI 2 "register_operand" "")))]
2201 rtx low = gen_reg_rtx (DImode);
2202 emit_insn (gen_subdi3_compare0 (low, gen_lowpart (DImode, operands[1]),
2203 gen_lowpart (DImode, operands[2])));
2205 rtx high = gen_reg_rtx (DImode);
2206 emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]),
2207 gen_highpart (DImode, operands[2])));
2209 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2210 emit_move_insn (gen_highpart (DImode, operands[0]), high);
2214 (define_insn "sub<mode>3_compare0"
2215 [(set (reg:CC_NZ CC_REGNUM)
2216 (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
2217 (match_operand:GPI 2 "register_operand" "r"))
2219 (set (match_operand:GPI 0 "register_operand" "=r")
2220 (minus:GPI (match_dup 1) (match_dup 2)))]
2222 "subs\\t%<w>0, %<w>1, %<w>2"
2223 [(set_attr "type" "alus_sreg")]
2226 ;; zero_extend version of above
2227 (define_insn "*subsi3_compare0_uxtw"
2228 [(set (reg:CC_NZ CC_REGNUM)
2229 (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
2230 (match_operand:SI 2 "register_operand" "r"))
2232 (set (match_operand:DI 0 "register_operand" "=r")
2233 (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
2235 "subs\\t%w0, %w1, %w2"
2236 [(set_attr "type" "alus_sreg")]
2239 (define_insn "*sub_<shift>_<mode>"
2240 [(set (match_operand:GPI 0 "register_operand" "=r")
2241 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2243 (match_operand:GPI 1 "register_operand" "r")
2244 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2246 "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
2247 [(set_attr "type" "alu_shift_imm")]
2250 ;; zero_extend version of above
2251 (define_insn "*sub_<shift>_si_uxtw"
2252 [(set (match_operand:DI 0 "register_operand" "=r")
2254 (minus:SI (match_operand:SI 3 "register_operand" "r")
2256 (match_operand:SI 1 "register_operand" "r")
2257 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2259 "sub\\t%w0, %w3, %w1, <shift> %2"
2260 [(set_attr "type" "alu_shift_imm")]
2263 (define_insn "*sub_mul_imm_<mode>"
2264 [(set (match_operand:GPI 0 "register_operand" "=r")
2265 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2267 (match_operand:GPI 1 "register_operand" "r")
2268 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2270 "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
2271 [(set_attr "type" "alu_shift_imm")]
2274 ;; zero_extend version of above
2275 (define_insn "*sub_mul_imm_si_uxtw"
2276 [(set (match_operand:DI 0 "register_operand" "=r")
2278 (minus:SI (match_operand:SI 3 "register_operand" "r")
2280 (match_operand:SI 1 "register_operand" "r")
2281 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2283 "sub\\t%w0, %w3, %w1, lsl %p2"
2284 [(set_attr "type" "alu_shift_imm")]
2287 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
2288 [(set (match_operand:GPI 0 "register_operand" "=rk")
2289 (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
2291 (match_operand:ALLX 2 "register_operand" "r"))))]
2293 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
2294 [(set_attr "type" "alu_ext")]
2297 ;; zero_extend version of above
2298 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
2299 [(set (match_operand:DI 0 "register_operand" "=rk")
2301 (minus:SI (match_operand:SI 1 "register_operand" "rk")
2303 (match_operand:SHORT 2 "register_operand" "r")))))]
2305 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
2306 [(set_attr "type" "alu_ext")]
2309 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
2310 [(set (match_operand:GPI 0 "register_operand" "=rk")
2311 (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
2312 (ashift:GPI (ANY_EXTEND:GPI
2313 (match_operand:ALLX 2 "register_operand" "r"))
2314 (match_operand 3 "aarch64_imm3" "Ui3"))))]
2316 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
2317 [(set_attr "type" "alu_ext")]
2320 ;; zero_extend version of above
2321 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
2322 [(set (match_operand:DI 0 "register_operand" "=rk")
2324 (minus:SI (match_operand:SI 1 "register_operand" "rk")
2325 (ashift:SI (ANY_EXTEND:SI
2326 (match_operand:SHORT 2 "register_operand" "r"))
2327 (match_operand 3 "aarch64_imm3" "Ui3")))))]
2329 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
2330 [(set_attr "type" "alu_ext")]
2333 (define_insn "*sub_<optab><mode>_multp2"
2334 [(set (match_operand:GPI 0 "register_operand" "=rk")
2335 (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
2337 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2338 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2339 (match_operand 3 "const_int_operand" "n")
2341 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
2342 "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
2343 [(set_attr "type" "alu_ext")]
2346 ;; zero_extend version of above
2347 (define_insn "*sub_<optab>si_multp2_uxtw"
2348 [(set (match_operand:DI 0 "register_operand" "=rk")
2350 (minus:SI (match_operand:SI 4 "register_operand" "rk")
2352 (mult:SI (match_operand:SI 1 "register_operand" "r")
2353 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2354 (match_operand 3 "const_int_operand" "n")
2356 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
2357 "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
2358 [(set_attr "type" "alu_ext")]
2361 (define_insn "sub<mode>3_carryin"
2363 (match_operand:GPI 0 "register_operand" "=r")
2364 (minus:GPI (minus:GPI
2365 (match_operand:GPI 1 "register_operand" "r")
2366 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2367 (match_operand:GPI 2 "register_operand" "r")))]
2369 "sbc\\t%<w>0, %<w>1, %<w>2"
2370 [(set_attr "type" "adc_reg")]
2373 ;; zero_extend version of the above
2374 (define_insn "*subsi3_carryin_uxtw"
2376 (match_operand:DI 0 "register_operand" "=r")
2379 (match_operand:SI 1 "register_operand" "r")
2380 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2381 (match_operand:SI 2 "register_operand" "r"))))]
2383 "sbc\\t%w0, %w1, %w2"
2384 [(set_attr "type" "adc_reg")]
2387 (define_insn "*sub_uxt<mode>_shift2"
2388 [(set (match_operand:GPI 0 "register_operand" "=rk")
2389 (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
2391 (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
2392 (match_operand 2 "aarch64_imm3" "Ui3"))
2393 (match_operand 3 "const_int_operand" "n"))))]
2394 "aarch64_uxt_size (INTVAL (operands[2]),INTVAL (operands[3])) != 0"
2396 operands[3] = GEN_INT (aarch64_uxt_size (INTVAL (operands[2]),
2397 INTVAL (operands[3])));
2398 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %2\";"
2399 [(set_attr "type" "alu_ext")]
2402 ;; zero_extend version of above
2403 (define_insn "*sub_uxtsi_shift2_uxtw"
2404 [(set (match_operand:DI 0 "register_operand" "=rk")
2406 (minus:SI (match_operand:SI 4 "register_operand" "rk")
2408 (ashift:SI (match_operand:SI 1 "register_operand" "r")
2409 (match_operand 2 "aarch64_imm3" "Ui3"))
2410 (match_operand 3 "const_int_operand" "n")))))]
2411 "aarch64_uxt_size (INTVAL (operands[2]),INTVAL (operands[3])) != 0"
2413 operands[3] = GEN_INT (aarch64_uxt_size (INTVAL (operands[2]),
2414 INTVAL (operands[3])));
2415 return \"sub\t%w0, %w4, %w1, uxt%e3 %2\";"
2416 [(set_attr "type" "alu_ext")]
2419 (define_insn "*sub_uxt<mode>_multp2"
2420 [(set (match_operand:GPI 0 "register_operand" "=rk")
2421 (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
2423 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2424 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2425 (match_operand 3 "const_int_operand" "n"))))]
2426 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2428 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2429 INTVAL (operands[3])));
2430 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
2431 [(set_attr "type" "alu_ext")]
2434 ;; zero_extend version of above
2435 (define_insn "*sub_uxtsi_multp2_uxtw"
2436 [(set (match_operand:DI 0 "register_operand" "=rk")
2438 (minus:SI (match_operand:SI 4 "register_operand" "rk")
2440 (mult:SI (match_operand:SI 1 "register_operand" "r")
2441 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2442 (match_operand 3 "const_int_operand" "n")))))]
2443 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2445 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2446 INTVAL (operands[3])));
2447 return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
2448 [(set_attr "type" "alu_ext")]
2451 (define_expand "abs<mode>2"
2452 [(match_operand:GPI 0 "register_operand" "")
2453 (match_operand:GPI 1 "register_operand" "")]
2456 rtx ccreg = aarch64_gen_compare_reg (LT, operands[1], const0_rtx);
2457 rtx x = gen_rtx_LT (VOIDmode, ccreg, const0_rtx);
2458 emit_insn (gen_csneg3<mode>_insn (operands[0], x, operands[1], operands[1]));
2463 (define_insn "neg<mode>2"
2464 [(set (match_operand:GPI 0 "register_operand" "=r,w")
2465 (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
2469 neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
2470 [(set_attr "type" "alu_sreg, neon_neg<q>")
2471 (set_attr "simd" "*,yes")]
2474 ;; zero_extend version of above
2475 (define_insn "*negsi2_uxtw"
2476 [(set (match_operand:DI 0 "register_operand" "=r")
2477 (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
2480 [(set_attr "type" "alu_sreg")]
2483 (define_insn "*ngc<mode>"
2484 [(set (match_operand:GPI 0 "register_operand" "=r")
2485 (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2486 (match_operand:GPI 1 "register_operand" "r")))]
2488 "ngc\\t%<w>0, %<w>1"
2489 [(set_attr "type" "adc_reg")]
2492 (define_insn "*ngcsi_uxtw"
2493 [(set (match_operand:DI 0 "register_operand" "=r")
2495 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2496 (match_operand:SI 1 "register_operand" "r"))))]
2499 [(set_attr "type" "adc_reg")]
2502 (define_insn "neg<mode>2_compare0"
2503 [(set (reg:CC_NZ CC_REGNUM)
2504 (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2506 (set (match_operand:GPI 0 "register_operand" "=r")
2507 (neg:GPI (match_dup 1)))]
2509 "negs\\t%<w>0, %<w>1"
2510 [(set_attr "type" "alus_sreg")]
2513 ;; zero_extend version of above
2514 (define_insn "*negsi2_compare0_uxtw"
2515 [(set (reg:CC_NZ CC_REGNUM)
2516 (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
2518 (set (match_operand:DI 0 "register_operand" "=r")
2519 (zero_extend:DI (neg:SI (match_dup 1))))]
2522 [(set_attr "type" "alus_sreg")]
2525 (define_insn "*neg_<shift><mode>3_compare0"
2526 [(set (reg:CC_NZ CC_REGNUM)
2528 (neg:GPI (ASHIFT:GPI
2529 (match_operand:GPI 1 "register_operand" "r")
2530 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2532 (set (match_operand:GPI 0 "register_operand" "=r")
2533 (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2535 "negs\\t%<w>0, %<w>1, <shift> %2"
2536 [(set_attr "type" "alus_shift_imm")]
2539 (define_insn "*neg_<shift>_<mode>2"
2540 [(set (match_operand:GPI 0 "register_operand" "=r")
2541 (neg:GPI (ASHIFT:GPI
2542 (match_operand:GPI 1 "register_operand" "r")
2543 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2545 "neg\\t%<w>0, %<w>1, <shift> %2"
2546 [(set_attr "type" "alu_shift_imm")]
2549 ;; zero_extend version of above
2550 (define_insn "*neg_<shift>_si2_uxtw"
2551 [(set (match_operand:DI 0 "register_operand" "=r")
2554 (match_operand:SI 1 "register_operand" "r")
2555 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2557 "neg\\t%w0, %w1, <shift> %2"
2558 [(set_attr "type" "alu_shift_imm")]
2561 (define_insn "*neg_mul_imm_<mode>2"
2562 [(set (match_operand:GPI 0 "register_operand" "=r")
2564 (match_operand:GPI 1 "register_operand" "r")
2565 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2567 "neg\\t%<w>0, %<w>1, lsl %p2"
2568 [(set_attr "type" "alu_shift_imm")]
2571 ;; zero_extend version of above
2572 (define_insn "*neg_mul_imm_si2_uxtw"
2573 [(set (match_operand:DI 0 "register_operand" "=r")
2576 (match_operand:SI 1 "register_operand" "r")
2577 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2579 "neg\\t%w0, %w1, lsl %p2"
2580 [(set_attr "type" "alu_shift_imm")]
2583 (define_insn "mul<mode>3"
2584 [(set (match_operand:GPI 0 "register_operand" "=r")
2585 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2586 (match_operand:GPI 2 "register_operand" "r")))]
2588 "mul\\t%<w>0, %<w>1, %<w>2"
2589 [(set_attr "type" "mul")]
2592 ;; zero_extend version of above
2593 (define_insn "*mulsi3_uxtw"
2594 [(set (match_operand:DI 0 "register_operand" "=r")
2596 (mult:SI (match_operand:SI 1 "register_operand" "r")
2597 (match_operand:SI 2 "register_operand" "r"))))]
2599 "mul\\t%w0, %w1, %w2"
2600 [(set_attr "type" "mul")]
2603 (define_insn "madd<mode>"
2604 [(set (match_operand:GPI 0 "register_operand" "=r")
2605 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2606 (match_operand:GPI 2 "register_operand" "r"))
2607 (match_operand:GPI 3 "register_operand" "r")))]
2609 "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2610 [(set_attr "type" "mla")]
2613 ;; zero_extend version of above
2614 (define_insn "*maddsi_uxtw"
2615 [(set (match_operand:DI 0 "register_operand" "=r")
2617 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2618 (match_operand:SI 2 "register_operand" "r"))
2619 (match_operand:SI 3 "register_operand" "r"))))]
2621 "madd\\t%w0, %w1, %w2, %w3"
2622 [(set_attr "type" "mla")]
2625 (define_insn "*msub<mode>"
2626 [(set (match_operand:GPI 0 "register_operand" "=r")
2627 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2628 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2629 (match_operand:GPI 2 "register_operand" "r"))))]
2632 "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2633 [(set_attr "type" "mla")]
2636 ;; zero_extend version of above
2637 (define_insn "*msubsi_uxtw"
2638 [(set (match_operand:DI 0 "register_operand" "=r")
2640 (minus:SI (match_operand:SI 3 "register_operand" "r")
2641 (mult:SI (match_operand:SI 1 "register_operand" "r")
2642 (match_operand:SI 2 "register_operand" "r")))))]
2645 "msub\\t%w0, %w1, %w2, %w3"
2646 [(set_attr "type" "mla")]
2649 (define_insn "*mul<mode>_neg"
2650 [(set (match_operand:GPI 0 "register_operand" "=r")
2651 (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2652 (match_operand:GPI 2 "register_operand" "r")))]
2655 "mneg\\t%<w>0, %<w>1, %<w>2"
2656 [(set_attr "type" "mul")]
2659 ;; zero_extend version of above
2660 (define_insn "*mulsi_neg_uxtw"
2661 [(set (match_operand:DI 0 "register_operand" "=r")
2663 (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2664 (match_operand:SI 2 "register_operand" "r"))))]
2667 "mneg\\t%w0, %w1, %w2"
2668 [(set_attr "type" "mul")]
2671 (define_insn "<su_optab>mulsidi3"
2672 [(set (match_operand:DI 0 "register_operand" "=r")
2673 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2674 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2676 "<su>mull\\t%0, %w1, %w2"
2677 [(set_attr "type" "<su>mull")]
2680 (define_insn "<su_optab>maddsidi4"
2681 [(set (match_operand:DI 0 "register_operand" "=r")
2683 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2684 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2685 (match_operand:DI 3 "register_operand" "r")))]
2687 "<su>maddl\\t%0, %w1, %w2, %3"
2688 [(set_attr "type" "<su>mlal")]
2691 (define_insn "<su_optab>msubsidi4"
2692 [(set (match_operand:DI 0 "register_operand" "=r")
2694 (match_operand:DI 3 "register_operand" "r")
2695 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2697 (match_operand:SI 2 "register_operand" "r")))))]
2699 "<su>msubl\\t%0, %w1, %w2, %3"
2700 [(set_attr "type" "<su>mlal")]
2703 (define_insn "*<su_optab>mulsidi_neg"
2704 [(set (match_operand:DI 0 "register_operand" "=r")
2706 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2707 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2709 "<su>mnegl\\t%0, %w1, %w2"
2710 [(set_attr "type" "<su>mull")]
2713 (define_expand "<su_optab>mulditi3"
2714 [(set (match_operand:TI 0 "register_operand")
2715 (mult:TI (ANY_EXTEND:TI (match_operand:DI 1 "register_operand"))
2716 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand"))))]
2719 rtx low = gen_reg_rtx (DImode);
2720 emit_insn (gen_muldi3 (low, operands[1], operands[2]));
2722 rtx high = gen_reg_rtx (DImode);
2723 emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2]));
2725 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2726 emit_move_insn (gen_highpart (DImode, operands[0]), high);
2730 ;; The default expansion of multi3 using umuldi3_highpart will perform
2731 ;; the additions in an order that fails to combine into two madd insns.
2732 (define_expand "multi3"
2733 [(set (match_operand:TI 0 "register_operand")
2734 (mult:TI (match_operand:TI 1 "register_operand")
2735 (match_operand:TI 2 "register_operand")))]
2738 rtx l0 = gen_reg_rtx (DImode);
2739 rtx l1 = gen_lowpart (DImode, operands[1]);
2740 rtx l2 = gen_lowpart (DImode, operands[2]);
2741 rtx h0 = gen_reg_rtx (DImode);
2742 rtx h1 = gen_highpart (DImode, operands[1]);
2743 rtx h2 = gen_highpart (DImode, operands[2]);
2745 emit_insn (gen_muldi3 (l0, l1, l2));
2746 emit_insn (gen_umuldi3_highpart (h0, l1, l2));
2747 emit_insn (gen_madddi (h0, h1, l2, h0));
2748 emit_insn (gen_madddi (h0, l1, h2, h0));
2750 emit_move_insn (gen_lowpart (DImode, operands[0]), l0);
2751 emit_move_insn (gen_highpart (DImode, operands[0]), h0);
2755 (define_insn "<su>muldi3_highpart"
2756 [(set (match_operand:DI 0 "register_operand" "=r")
2760 (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2761 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2764 "<su>mulh\\t%0, %1, %2"
2765 [(set_attr "type" "<su>mull")]
2768 (define_insn "<su_optab>div<mode>3"
2769 [(set (match_operand:GPI 0 "register_operand" "=r")
2770 (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2771 (match_operand:GPI 2 "register_operand" "r")))]
2773 "<su>div\\t%<w>0, %<w>1, %<w>2"
2774 [(set_attr "type" "<su>div")]
2777 ;; zero_extend version of above
2778 (define_insn "*<su_optab>divsi3_uxtw"
2779 [(set (match_operand:DI 0 "register_operand" "=r")
2781 (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2782 (match_operand:SI 2 "register_operand" "r"))))]
2784 "<su>div\\t%w0, %w1, %w2"
2785 [(set_attr "type" "<su>div")]
2788 ;; -------------------------------------------------------------------
2790 ;; -------------------------------------------------------------------
2792 (define_insn "*cmp<mode>"
2793 [(set (reg:CC CC_REGNUM)
2794 (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2795 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2801 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
2804 (define_insn "*cmp<mode>"
2805 [(set (reg:CCFP CC_REGNUM)
2806 (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2807 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2811 fcmp\\t%<s>0, %<s>1"
2812 [(set_attr "type" "fcmp<s>")]
2815 (define_insn "*cmpe<mode>"
2816 [(set (reg:CCFPE CC_REGNUM)
2817 (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2818 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2822 fcmpe\\t%<s>0, %<s>1"
2823 [(set_attr "type" "fcmp<s>")]
2826 (define_insn "*cmp_swp_<shift>_reg<mode>"
2827 [(set (reg:CC_SWP CC_REGNUM)
2828 (compare:CC_SWP (ASHIFT:GPI
2829 (match_operand:GPI 0 "register_operand" "r")
2830 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2831 (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2833 "cmp\\t%<w>2, %<w>0, <shift> %1"
2834 [(set_attr "type" "alus_shift_imm")]
2837 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2838 [(set (reg:CC_SWP CC_REGNUM)
2839 (compare:CC_SWP (ANY_EXTEND:GPI
2840 (match_operand:ALLX 0 "register_operand" "r"))
2841 (match_operand:GPI 1 "register_operand" "r")))]
2843 "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2844 [(set_attr "type" "alus_ext")]
2847 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2848 [(set (reg:CC_SWP CC_REGNUM)
2849 (compare:CC_SWP (ashift:GPI
2851 (match_operand:ALLX 0 "register_operand" "r"))
2852 (match_operand 1 "aarch64_imm3" "Ui3"))
2853 (match_operand:GPI 2 "register_operand" "r")))]
2855 "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2856 [(set_attr "type" "alus_ext")]
2859 ;; -------------------------------------------------------------------
2860 ;; Store-flag and conditional select insns
2861 ;; -------------------------------------------------------------------
2863 (define_expand "cstore<mode>4"
2864 [(set (match_operand:SI 0 "register_operand" "")
2865 (match_operator:SI 1 "aarch64_comparison_operator"
2866 [(match_operand:GPI 2 "register_operand" "")
2867 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2870 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2872 operands[3] = const0_rtx;
2876 (define_expand "cstorecc4"
2877 [(set (match_operand:SI 0 "register_operand")
2878 (match_operator 1 "aarch64_comparison_operator"
2879 [(match_operand 2 "ccmp_cc_register")
2880 (match_operand 3 "const0_operand")]))]
2883 emit_insn (gen_rtx_SET (operands[0], operands[1]));
2888 (define_expand "cstore<mode>4"
2889 [(set (match_operand:SI 0 "register_operand" "")
2890 (match_operator:SI 1 "aarch64_comparison_operator"
2891 [(match_operand:GPF 2 "register_operand" "")
2892 (match_operand:GPF 3 "register_operand" "")]))]
2895 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2897 operands[3] = const0_rtx;
2901 (define_insn "*cstore<mode>_insn"
2902 [(set (match_operand:ALLI 0 "register_operand" "=r")
2903 (match_operator:ALLI 1 "aarch64_comparison_operator"
2904 [(match_operand 2 "cc_register" "") (const_int 0)]))]
2907 [(set_attr "type" "csel")]
2910 ;; zero_extend version of the above
2911 (define_insn "*cstoresi_insn_uxtw"
2912 [(set (match_operand:DI 0 "register_operand" "=r")
2914 (match_operator:SI 1 "aarch64_comparison_operator"
2915 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2918 [(set_attr "type" "csel")]
2921 (define_insn "cstore<mode>_neg"
2922 [(set (match_operand:ALLI 0 "register_operand" "=r")
2923 (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2924 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2926 "csetm\\t%<w>0, %m1"
2927 [(set_attr "type" "csel")]
2930 ;; zero_extend version of the above
2931 (define_insn "*cstoresi_neg_uxtw"
2932 [(set (match_operand:DI 0 "register_operand" "=r")
2934 (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2935 [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2938 [(set_attr "type" "csel")]
2941 (define_expand "cmov<mode>6"
2942 [(set (match_operand:GPI 0 "register_operand" "")
2944 (match_operator 1 "aarch64_comparison_operator"
2945 [(match_operand:GPI 2 "register_operand" "")
2946 (match_operand:GPI 3 "aarch64_plus_operand" "")])
2947 (match_operand:GPI 4 "register_operand" "")
2948 (match_operand:GPI 5 "register_operand" "")))]
2951 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2953 operands[3] = const0_rtx;
2957 (define_expand "cmov<mode>6"
2958 [(set (match_operand:GPF 0 "register_operand" "")
2960 (match_operator 1 "aarch64_comparison_operator"
2961 [(match_operand:GPF 2 "register_operand" "")
2962 (match_operand:GPF 3 "register_operand" "")])
2963 (match_operand:GPF 4 "register_operand" "")
2964 (match_operand:GPF 5 "register_operand" "")))]
2967 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2969 operands[3] = const0_rtx;
2973 (define_insn "*cmov<mode>_insn"
2974 [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2976 (match_operator 1 "aarch64_comparison_operator"
2977 [(match_operand 2 "cc_register" "") (const_int 0)])
2978 (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2979 (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2980 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2981 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2982 ;; Final two alternatives should be unreachable, but included for completeness
2984 csel\\t%<w>0, %<w>3, %<w>4, %m1
2985 csinv\\t%<w>0, %<w>3, <w>zr, %m1
2986 csinv\\t%<w>0, %<w>4, <w>zr, %M1
2987 csinc\\t%<w>0, %<w>3, <w>zr, %m1
2988 csinc\\t%<w>0, %<w>4, <w>zr, %M1
2991 [(set_attr "type" "csel")]
2994 ;; zero_extend version of above
2995 (define_insn "*cmovsi_insn_uxtw"
2996 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2999 (match_operator 1 "aarch64_comparison_operator"
3000 [(match_operand 2 "cc_register" "") (const_int 0)])
3001 (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
3002 (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
3003 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
3004 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
3005 ;; Final two alternatives should be unreachable, but included for completeness
3007 csel\\t%w0, %w3, %w4, %m1
3008 csinv\\t%w0, %w3, wzr, %m1
3009 csinv\\t%w0, %w4, wzr, %M1
3010 csinc\\t%w0, %w3, wzr, %m1
3011 csinc\\t%w0, %w4, wzr, %M1
3014 [(set_attr "type" "csel")]
3017 (define_insn "*cmovdi_insn_uxtw"
3018 [(set (match_operand:DI 0 "register_operand" "=r")
3020 (match_operator 1 "aarch64_comparison_operator"
3021 [(match_operand 2 "cc_register" "") (const_int 0)])
3022 (zero_extend:DI (match_operand:SI 3 "register_operand" "r"))
3023 (zero_extend:DI (match_operand:SI 4 "register_operand" "r"))))]
3025 "csel\\t%w0, %w3, %w4, %m1"
3026 [(set_attr "type" "csel")]
3029 (define_insn "*cmov<mode>_insn"
3030 [(set (match_operand:GPF 0 "register_operand" "=w")
3032 (match_operator 1 "aarch64_comparison_operator"
3033 [(match_operand 2 "cc_register" "") (const_int 0)])
3034 (match_operand:GPF 3 "register_operand" "w")
3035 (match_operand:GPF 4 "register_operand" "w")))]
3037 "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
3038 [(set_attr "type" "fcsel")]
3041 (define_expand "mov<mode>cc"
3042 [(set (match_operand:ALLI 0 "register_operand" "")
3043 (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
3044 (match_operand:ALLI 2 "register_operand" "")
3045 (match_operand:ALLI 3 "register_operand" "")))]
3048 enum rtx_code code = GET_CODE (operands[1]);
3050 if (code == UNEQ || code == LTGT)
3053 if (!ccmp_cc_register (XEXP (operands[1], 0),
3054 GET_MODE (XEXP (operands[1], 0))))
3057 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
3058 XEXP (operands[1], 1));
3059 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
3064 (define_expand "mov<GPF:mode><GPI:mode>cc"
3065 [(set (match_operand:GPI 0 "register_operand" "")
3066 (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
3067 (match_operand:GPF 2 "register_operand" "")
3068 (match_operand:GPF 3 "register_operand" "")))]
3072 enum rtx_code code = GET_CODE (operands[1]);
3074 if (code == UNEQ || code == LTGT)
3077 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
3078 XEXP (operands[1], 1));
3079 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
3083 (define_expand "mov<mode>cc"
3084 [(set (match_operand:GPF 0 "register_operand" "")
3085 (if_then_else:GPF (match_operand 1 "aarch64_comparison_operator" "")
3086 (match_operand:GPF 2 "register_operand" "")
3087 (match_operand:GPF 3 "register_operand" "")))]
3091 enum rtx_code code = GET_CODE (operands[1]);
3093 if (code == UNEQ || code == LTGT)
3096 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
3097 XEXP (operands[1], 1));
3098 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
3103 ;; CRC32 instructions.
3104 (define_insn "aarch64_<crc_variant>"
3105 [(set (match_operand:SI 0 "register_operand" "=r")
3106 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
3107 (match_operand:<crc_mode> 2 "register_operand" "r")]
3111 if (GET_MODE_BITSIZE (GET_MODE (operands[2])) >= 64)
3112 return "<crc_variant>\\t%w0, %w1, %x2";
3114 return "<crc_variant>\\t%w0, %w1, %w2";
3116 [(set_attr "type" "crc")]
3119 (define_insn "*csinc2<mode>_insn"
3120 [(set (match_operand:GPI 0 "register_operand" "=r")
3121 (plus:GPI (match_operand 2 "aarch64_comparison_operation" "")
3122 (match_operand:GPI 1 "register_operand" "r")))]
3124 "cinc\\t%<w>0, %<w>1, %m2"
3125 [(set_attr "type" "csel")]
3128 (define_insn "csinc3<mode>_insn"
3129 [(set (match_operand:GPI 0 "register_operand" "=r")
3131 (match_operand 1 "aarch64_comparison_operation" "")
3132 (plus:GPI (match_operand:GPI 2 "register_operand" "r")
3134 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
3136 "csinc\\t%<w>0, %<w>3, %<w>2, %M1"
3137 [(set_attr "type" "csel")]
3140 (define_insn "*csinv3<mode>_insn"
3141 [(set (match_operand:GPI 0 "register_operand" "=r")
3143 (match_operand 1 "aarch64_comparison_operation" "")
3144 (not:GPI (match_operand:GPI 2 "register_operand" "r"))
3145 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
3147 "csinv\\t%<w>0, %<w>3, %<w>2, %M1"
3148 [(set_attr "type" "csel")]
3151 (define_insn "csneg3_uxtw_insn"
3152 [(set (match_operand:DI 0 "register_operand" "=r")
3155 (match_operand 1 "aarch64_comparison_operation" "")
3156 (neg:SI (match_operand:SI 2 "register_operand" "r"))
3157 (match_operand:SI 3 "aarch64_reg_or_zero" "rZ"))))]
3159 "csneg\\t%w0, %w3, %w2, %M1"
3160 [(set_attr "type" "csel")]
3163 (define_insn "csneg3<mode>_insn"
3164 [(set (match_operand:GPI 0 "register_operand" "=r")
3166 (match_operand 1 "aarch64_comparison_operation" "")
3167 (neg:GPI (match_operand:GPI 2 "register_operand" "r"))
3168 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
3170 "csneg\\t%<w>0, %<w>3, %<w>2, %M1"
3171 [(set_attr "type" "csel")]
3174 ;; -------------------------------------------------------------------
3175 ;; Logical operations
3176 ;; -------------------------------------------------------------------
3178 (define_insn "<optab><mode>3"
3179 [(set (match_operand:GPI 0 "register_operand" "=r,rk,w")
3180 (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r,w")
3181 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>,w")))]
3184 <logical>\\t%<w>0, %<w>1, %<w>2
3185 <logical>\\t%<w>0, %<w>1, %<w>2
3186 <logical>\\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
3187 [(set_attr "type" "logic_reg,logic_imm,neon_logic")
3188 (set_attr "simd" "*,*,yes")]
3191 ;; zero_extend version of above
3192 (define_insn "*<optab>si3_uxtw"
3193 [(set (match_operand:DI 0 "register_operand" "=r,rk")
3195 (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
3196 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
3198 "<logical>\\t%w0, %w1, %w2"
3199 [(set_attr "type" "logic_reg,logic_imm")]
3202 (define_insn "*and<mode>3_compare0"
3203 [(set (reg:CC_NZ CC_REGNUM)
3205 (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
3206 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
3208 (set (match_operand:GPI 0 "register_operand" "=r,r")
3209 (and:GPI (match_dup 1) (match_dup 2)))]
3211 "ands\\t%<w>0, %<w>1, %<w>2"
3212 [(set_attr "type" "logics_reg,logics_imm")]
3215 ;; zero_extend version of above
3216 (define_insn "*andsi3_compare0_uxtw"
3217 [(set (reg:CC_NZ CC_REGNUM)
3219 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
3220 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
3222 (set (match_operand:DI 0 "register_operand" "=r,r")
3223 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
3225 "ands\\t%w0, %w1, %w2"
3226 [(set_attr "type" "logics_reg,logics_imm")]
3229 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
3230 [(set (reg:CC_NZ CC_REGNUM)
3233 (match_operand:GPI 1 "register_operand" "r")
3234 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3235 (match_operand:GPI 3 "register_operand" "r"))
3237 (set (match_operand:GPI 0 "register_operand" "=r")
3238 (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
3240 "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3241 [(set_attr "type" "logics_shift_imm")]
3244 ;; zero_extend version of above
3245 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
3246 [(set (reg:CC_NZ CC_REGNUM)
3249 (match_operand:SI 1 "register_operand" "r")
3250 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3251 (match_operand:SI 3 "register_operand" "r"))
3253 (set (match_operand:DI 0 "register_operand" "=r")
3254 (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
3257 "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3258 [(set_attr "type" "logics_shift_imm")]
3261 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
3262 [(set (match_operand:GPI 0 "register_operand" "=r")
3263 (LOGICAL:GPI (SHIFT:GPI
3264 (match_operand:GPI 1 "register_operand" "r")
3265 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3266 (match_operand:GPI 3 "register_operand" "r")))]
3268 "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3269 [(set_attr "type" "logic_shift_imm")]
3272 (define_insn "*<optab>_rol<mode>3"
3273 [(set (match_operand:GPI 0 "register_operand" "=r")
3274 (LOGICAL:GPI (rotate:GPI
3275 (match_operand:GPI 1 "register_operand" "r")
3276 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3277 (match_operand:GPI 3 "register_operand" "r")))]
3279 "<logical>\\t%<w>0, %<w>3, %<w>1, ror (<sizen> - %2)"
3280 [(set_attr "type" "logic_shift_imm")]
3283 ;; zero_extend versions of above
3284 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
3285 [(set (match_operand:DI 0 "register_operand" "=r")
3287 (LOGICAL:SI (SHIFT:SI
3288 (match_operand:SI 1 "register_operand" "r")
3289 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3290 (match_operand:SI 3 "register_operand" "r"))))]
3292 "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3293 [(set_attr "type" "logic_shift_imm")]
3296 (define_insn "*<optab>_rolsi3_uxtw"
3297 [(set (match_operand:DI 0 "register_operand" "=r")
3299 (LOGICAL:SI (rotate:SI
3300 (match_operand:SI 1 "register_operand" "r")
3301 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3302 (match_operand:SI 3 "register_operand" "r"))))]
3304 "<logical>\\t%w0, %w3, %w1, ror (32 - %2)"
3305 [(set_attr "type" "logic_shift_imm")]
3308 (define_insn "one_cmpl<mode>2"
3309 [(set (match_operand:GPI 0 "register_operand" "=r,w")
3310 (not:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
3315 [(set_attr "type" "logic_reg,neon_logic")
3316 (set_attr "simd" "*,yes")]
3319 (define_insn "*one_cmpl_<optab><mode>2"
3320 [(set (match_operand:GPI 0 "register_operand" "=r")
3321 (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
3322 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
3324 "mvn\\t%<w>0, %<w>1, <shift> %2"
3325 [(set_attr "type" "logic_shift_imm")]
3328 ;; Binary logical operators negating one operand, i.e. (a & !b), (a | !b).
3330 (define_insn "*<NLOGICAL:optab>_one_cmpl<mode>3"
3331 [(set (match_operand:GPI 0 "register_operand" "=r,w")
3332 (NLOGICAL:GPI (not:GPI (match_operand:GPI 1 "register_operand" "r,w"))
3333 (match_operand:GPI 2 "register_operand" "r,w")))]
3336 <NLOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1
3337 <NLOGICAL:nlogical>\\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>"
3338 [(set_attr "type" "logic_reg,neon_logic")
3339 (set_attr "simd" "*,yes")]
3342 (define_insn "*<NLOGICAL:optab>_one_cmplsidi3_ze"
3343 [(set (match_operand:DI 0 "register_operand" "=r")
3345 (NLOGICAL:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
3346 (match_operand:SI 2 "register_operand" "r"))))]
3348 "<NLOGICAL:nlogical>\\t%w0, %w2, %w1"
3349 [(set_attr "type" "logic_reg")]
3352 (define_insn "*xor_one_cmplsidi3_ze"
3353 [(set (match_operand:DI 0 "register_operand" "=r")
3355 (not:SI (xor:SI (match_operand:SI 1 "register_operand" "r")
3356 (match_operand:SI 2 "register_operand" "r")))))]
3358 "eon\\t%w0, %w1, %w2"
3359 [(set_attr "type" "logic_reg")]
3362 ;; (xor (not a) b) is simplify_rtx-ed down to (not (xor a b)).
3363 ;; eon does not operate on SIMD registers so the vector variant must be split.
3364 (define_insn_and_split "*xor_one_cmpl<mode>3"
3365 [(set (match_operand:GPI 0 "register_operand" "=r,w")
3366 (not:GPI (xor:GPI (match_operand:GPI 1 "register_operand" "r,?w")
3367 (match_operand:GPI 2 "register_operand" "r,w"))))]
3370 eon\\t%<w>0, %<w>1, %<w>2
3372 "reload_completed && FP_REGNUM_P (REGNO (operands[0]))" ;; For SIMD registers.
3373 [(set (match_operand:GPI 0 "register_operand" "=w")
3374 (xor:GPI (match_operand:GPI 1 "register_operand" "w")
3375 (match_operand:GPI 2 "register_operand" "w")))
3376 (set (match_dup 0) (not:GPI (match_dup 0)))]
3378 [(set_attr "type" "logic_reg,multiple")
3379 (set_attr "simd" "*,yes")]
3382 (define_insn "*and_one_cmpl<mode>3_compare0"
3383 [(set (reg:CC_NZ CC_REGNUM)
3386 (match_operand:GPI 1 "register_operand" "r"))
3387 (match_operand:GPI 2 "register_operand" "r"))
3389 (set (match_operand:GPI 0 "register_operand" "=r")
3390 (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
3392 "bics\\t%<w>0, %<w>2, %<w>1"
3393 [(set_attr "type" "logics_reg")]
3396 ;; zero_extend version of above
3397 (define_insn "*and_one_cmplsi3_compare0_uxtw"
3398 [(set (reg:CC_NZ CC_REGNUM)
3401 (match_operand:SI 1 "register_operand" "r"))
3402 (match_operand:SI 2 "register_operand" "r"))
3404 (set (match_operand:DI 0 "register_operand" "=r")
3405 (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
3407 "bics\\t%w0, %w2, %w1"
3408 [(set_attr "type" "logics_reg")]
3411 (define_insn "*and_one_cmpl<mode>3_compare0_no_reuse"
3412 [(set (reg:CC_NZ CC_REGNUM)
3415 (match_operand:GPI 0 "register_operand" "r"))
3416 (match_operand:GPI 1 "register_operand" "r"))
3419 "bics\\t<w>zr, %<w>1, %<w>0"
3420 [(set_attr "type" "logics_reg")]
3423 (define_insn "<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
3424 [(set (match_operand:GPI 0 "register_operand" "=r")
3425 (LOGICAL:GPI (not:GPI
3427 (match_operand:GPI 1 "register_operand" "r")
3428 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
3429 (match_operand:GPI 3 "register_operand" "r")))]
3431 "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3432 [(set_attr "type" "logic_shift_imm")]
3435 (define_insn "*eor_one_cmpl_<SHIFT:optab><mode>3_alt"
3436 [(set (match_operand:GPI 0 "register_operand" "=r")
3439 (match_operand:GPI 1 "register_operand" "r")
3440 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
3441 (match_operand:GPI 3 "register_operand" "r"))))]
3443 "eon\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3444 [(set_attr "type" "logic_shift_imm")]
3447 ;; Zero-extend version of the above.
3448 (define_insn "*eor_one_cmpl_<SHIFT:optab>sidi3_alt_ze"
3449 [(set (match_operand:DI 0 "register_operand" "=r")
3453 (match_operand:SI 1 "register_operand" "r")
3454 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3455 (match_operand:SI 3 "register_operand" "r")))))]
3457 "eon\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3458 [(set_attr "type" "logic_shift_imm")]
3461 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
3462 [(set (reg:CC_NZ CC_REGNUM)
3466 (match_operand:GPI 1 "register_operand" "r")
3467 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
3468 (match_operand:GPI 3 "register_operand" "r"))
3470 (set (match_operand:GPI 0 "register_operand" "=r")
3473 (match_dup 1) (match_dup 2))) (match_dup 3)))]
3475 "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3476 [(set_attr "type" "logics_shift_imm")]
3479 ;; zero_extend version of above
3480 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
3481 [(set (reg:CC_NZ CC_REGNUM)
3485 (match_operand:SI 1 "register_operand" "r")
3486 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
3487 (match_operand:SI 3 "register_operand" "r"))
3489 (set (match_operand:DI 0 "register_operand" "=r")
3490 (zero_extend:DI (and:SI
3492 (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
3494 "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3495 [(set_attr "type" "logics_shift_imm")]
3498 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0_no_reuse"
3499 [(set (reg:CC_NZ CC_REGNUM)
3503 (match_operand:GPI 0 "register_operand" "r")
3504 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n")))
3505 (match_operand:GPI 2 "register_operand" "r"))
3508 "bics\\t<w>zr, %<w>2, %<w>0, <SHIFT:shift> %1"
3509 [(set_attr "type" "logics_shift_imm")]
3512 (define_insn "clz<mode>2"
3513 [(set (match_operand:GPI 0 "register_operand" "=r")
3514 (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
3516 "clz\\t%<w>0, %<w>1"
3517 [(set_attr "type" "clz")]
3520 (define_expand "ffs<mode>2"
3521 [(match_operand:GPI 0 "register_operand")
3522 (match_operand:GPI 1 "register_operand")]
3525 rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
3526 rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
3528 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3529 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3530 emit_insn (gen_csinc3<mode>_insn (operands[0], x, operands[0], const0_rtx));
3535 (define_insn "clrsb<mode>2"
3536 [(set (match_operand:GPI 0 "register_operand" "=r")
3537 (clrsb:GPI (match_operand:GPI 1 "register_operand" "r")))]
3539 "cls\\t%<w>0, %<w>1"
3540 [(set_attr "type" "clz")]
3543 (define_insn "rbit<mode>2"
3544 [(set (match_operand:GPI 0 "register_operand" "=r")
3545 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
3547 "rbit\\t%<w>0, %<w>1"
3548 [(set_attr "type" "rbit")]
3551 (define_expand "ctz<mode>2"
3552 [(match_operand:GPI 0 "register_operand")
3553 (match_operand:GPI 1 "register_operand")]
3556 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3557 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3562 (define_insn "*and<mode>3nr_compare0"
3563 [(set (reg:CC_NZ CC_REGNUM)
3565 (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
3566 (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
3569 "tst\\t%<w>0, %<w>1"
3570 [(set_attr "type" "logics_reg,logics_imm")]
3573 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
3574 [(set (reg:CC_NZ CC_REGNUM)
3577 (match_operand:GPI 0 "register_operand" "r")
3578 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
3579 (match_operand:GPI 2 "register_operand" "r"))
3582 "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
3583 [(set_attr "type" "logics_shift_imm")]
3586 ;; -------------------------------------------------------------------
3588 ;; -------------------------------------------------------------------
3590 (define_expand "<optab><mode>3"
3591 [(set (match_operand:GPI 0 "register_operand")
3592 (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
3593 (match_operand:QI 2 "nonmemory_operand")))]
3596 if (CONST_INT_P (operands[2]))
3598 operands[2] = GEN_INT (INTVAL (operands[2])
3599 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3601 if (operands[2] == const0_rtx)
3603 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3610 (define_expand "ashl<mode>3"
3611 [(set (match_operand:SHORT 0 "register_operand")
3612 (ashift:SHORT (match_operand:SHORT 1 "register_operand")
3613 (match_operand:QI 2 "nonmemory_operand")))]
3616 if (CONST_INT_P (operands[2]))
3618 operands[2] = GEN_INT (INTVAL (operands[2])
3619 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3621 if (operands[2] == const0_rtx)
3623 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3632 (define_expand "rotr<mode>3"
3633 [(set (match_operand:GPI 0 "register_operand")
3634 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3635 (match_operand:QI 2 "nonmemory_operand")))]
3638 if (CONST_INT_P (operands[2]))
3640 operands[2] = GEN_INT (INTVAL (operands[2])
3641 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3643 if (operands[2] == const0_rtx)
3645 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3652 (define_expand "rotl<mode>3"
3653 [(set (match_operand:GPI 0 "register_operand")
3654 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3655 (match_operand:QI 2 "nonmemory_operand")))]
3658 /* (SZ - cnt) % SZ == -cnt % SZ */
3659 if (CONST_INT_P (operands[2]))
3661 operands[2] = GEN_INT ((-INTVAL (operands[2]))
3662 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3663 if (operands[2] == const0_rtx)
3665 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3670 operands[2] = expand_simple_unop (QImode, NEG, operands[2],
3675 ;; Logical left shift using SISD or Integer instruction
3676 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
3677 [(set (match_operand:GPI 0 "register_operand" "=r,w,w")
3679 (match_operand:GPI 1 "register_operand" "r,w,w")
3680 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>,Us<cmode>,w")))]
3683 lsl\t%<w>0, %<w>1, %<w>2
3684 shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3685 ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>"
3686 [(set_attr "simd" "no,yes,yes")
3687 (set_attr "type" "shift_reg,neon_shift_imm<q>, neon_shift_reg<q>")]
3690 ;; Logical right shift using SISD or Integer instruction
3691 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3692 [(set (match_operand:GPI 0 "register_operand" "=r,w,&w,&w")
3694 (match_operand:GPI 1 "register_operand" "r,w,w,w")
3695 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>,Us<cmode>,w,0")))]
3698 lsr\t%<w>0, %<w>1, %<w>2
3699 ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3702 [(set_attr "simd" "no,yes,yes,yes")
3703 (set_attr "type" "shift_reg,neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>")]
3707 [(set (match_operand:DI 0 "aarch64_simd_register")
3709 (match_operand:DI 1 "aarch64_simd_register")
3710 (match_operand:QI 2 "aarch64_simd_register")))]
3711 "TARGET_SIMD && reload_completed"
3713 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3715 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_USHL))]
3717 operands[3] = gen_lowpart (QImode, operands[0]);
3722 [(set (match_operand:SI 0 "aarch64_simd_register")
3724 (match_operand:SI 1 "aarch64_simd_register")
3725 (match_operand:QI 2 "aarch64_simd_register")))]
3726 "TARGET_SIMD && reload_completed"
3728 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3730 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_USHL_2S))]
3732 operands[3] = gen_lowpart (QImode, operands[0]);
3736 ;; Arithmetic right shift using SISD or Integer instruction
3737 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3738 [(set (match_operand:GPI 0 "register_operand" "=r,w,&w,&w")
3740 (match_operand:GPI 1 "register_operand" "r,w,w,w")
3741 (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "rUs<cmode>,Us<cmode>,w,0")))]
3744 asr\t%<w>0, %<w>1, %<w>2
3745 sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3748 [(set_attr "simd" "no,yes,yes,yes")
3749 (set_attr "type" "shift_reg,neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>")]
3753 [(set (match_operand:DI 0 "aarch64_simd_register")
3755 (match_operand:DI 1 "aarch64_simd_register")
3756 (match_operand:QI 2 "aarch64_simd_register")))]
3757 "TARGET_SIMD && reload_completed"
3759 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3761 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_SSHL))]
3763 operands[3] = gen_lowpart (QImode, operands[0]);
3768 [(set (match_operand:SI 0 "aarch64_simd_register")
3770 (match_operand:SI 1 "aarch64_simd_register")
3771 (match_operand:QI 2 "aarch64_simd_register")))]
3772 "TARGET_SIMD && reload_completed"
3774 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3776 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_SSHL_2S))]
3778 operands[3] = gen_lowpart (QImode, operands[0]);
3782 (define_insn "*aarch64_sisd_ushl"
3783 [(set (match_operand:DI 0 "register_operand" "=w")
3784 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3785 (match_operand:QI 2 "register_operand" "w")]
3788 "ushl\t%d0, %d1, %d2"
3789 [(set_attr "simd" "yes")
3790 (set_attr "type" "neon_shift_reg")]
3793 (define_insn "*aarch64_ushl_2s"
3794 [(set (match_operand:SI 0 "register_operand" "=w")
3795 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3796 (match_operand:QI 2 "register_operand" "w")]
3799 "ushl\t%0.2s, %1.2s, %2.2s"
3800 [(set_attr "simd" "yes")
3801 (set_attr "type" "neon_shift_reg")]
3804 (define_insn "*aarch64_sisd_sshl"
3805 [(set (match_operand:DI 0 "register_operand" "=w")
3806 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3807 (match_operand:QI 2 "register_operand" "w")]
3810 "sshl\t%d0, %d1, %d2"
3811 [(set_attr "simd" "yes")
3812 (set_attr "type" "neon_shift_reg")]
3815 (define_insn "*aarch64_sshl_2s"
3816 [(set (match_operand:SI 0 "register_operand" "=w")
3817 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3818 (match_operand:QI 2 "register_operand" "w")]
3821 "sshl\t%0.2s, %1.2s, %2.2s"
3822 [(set_attr "simd" "yes")
3823 (set_attr "type" "neon_shift_reg")]
3826 (define_insn "*aarch64_sisd_neg_qi"
3827 [(set (match_operand:QI 0 "register_operand" "=w")
3828 (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3832 [(set_attr "simd" "yes")
3833 (set_attr "type" "neon_neg")]
3837 (define_insn "*ror<mode>3_insn"
3838 [(set (match_operand:GPI 0 "register_operand" "=r,r")
3840 (match_operand:GPI 1 "register_operand" "r,r")
3841 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "r,Us<cmode>")))]
3843 "ror\\t%<w>0, %<w>1, %<w>2"
3844 [(set_attr "type" "shift_reg, rotate_imm")]
3847 ;; zero_extend version of above
3848 (define_insn "*<optab>si3_insn_uxtw"
3849 [(set (match_operand:DI 0 "register_operand" "=r")
3850 (zero_extend:DI (SHIFT:SI
3851 (match_operand:SI 1 "register_operand" "r")
3852 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3854 "<shift>\\t%w0, %w1, %w2"
3855 [(set_attr "type" "shift_reg")]
3858 (define_insn "*<optab><mode>3_insn"
3859 [(set (match_operand:SHORT 0 "register_operand" "=r")
3860 (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3861 (match_operand 2 "const_int_operand" "n")))]
3862 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3864 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3865 return "<bfshift>\t%w0, %w1, %2, %3";
3867 [(set_attr "type" "bfm")]
3870 (define_insn "*extr<mode>5_insn"
3871 [(set (match_operand:GPI 0 "register_operand" "=r")
3872 (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3873 (match_operand 3 "const_int_operand" "n"))
3874 (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3875 (match_operand 4 "const_int_operand" "n"))))]
3876 "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3877 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3878 "extr\\t%<w>0, %<w>1, %<w>2, %4"
3879 [(set_attr "type" "shift_imm")]
3882 ;; There are no canonicalisation rules for ashift and lshiftrt inside an ior
3883 ;; so we have to match both orderings.
3884 (define_insn "*extr<mode>5_insn_alt"
3885 [(set (match_operand:GPI 0 "register_operand" "=r")
3886 (ior:GPI (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3887 (match_operand 4 "const_int_operand" "n"))
3888 (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3889 (match_operand 3 "const_int_operand" "n"))))]
3890 "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode)
3891 && (UINTVAL (operands[3]) + UINTVAL (operands[4])
3892 == GET_MODE_BITSIZE (<MODE>mode))"
3893 "extr\\t%<w>0, %<w>1, %<w>2, %4"
3894 [(set_attr "type" "shift_imm")]
3897 ;; zero_extend version of the above
3898 (define_insn "*extrsi5_insn_uxtw"
3899 [(set (match_operand:DI 0 "register_operand" "=r")
3901 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3902 (match_operand 3 "const_int_operand" "n"))
3903 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3904 (match_operand 4 "const_int_operand" "n")))))]
3905 "UINTVAL (operands[3]) < 32 &&
3906 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3907 "extr\\t%w0, %w1, %w2, %4"
3908 [(set_attr "type" "shift_imm")]
3911 (define_insn "*extrsi5_insn_uxtw_alt"
3912 [(set (match_operand:DI 0 "register_operand" "=r")
3914 (ior:SI (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3915 (match_operand 4 "const_int_operand" "n"))
3916 (ashift:SI (match_operand:SI 1 "register_operand" "r")
3917 (match_operand 3 "const_int_operand" "n")))))]
3918 "UINTVAL (operands[3]) < 32 &&
3919 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3920 "extr\\t%w0, %w1, %w2, %4"
3921 [(set_attr "type" "shift_imm")]
3924 (define_insn "*ror<mode>3_insn"
3925 [(set (match_operand:GPI 0 "register_operand" "=r")
3926 (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3927 (match_operand 2 "const_int_operand" "n")))]
3928 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3930 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3931 return "ror\\t%<w>0, %<w>1, %3";
3933 [(set_attr "type" "rotate_imm")]
3936 ;; zero_extend version of the above
3937 (define_insn "*rorsi3_insn_uxtw"
3938 [(set (match_operand:DI 0 "register_operand" "=r")
3940 (rotate:SI (match_operand:SI 1 "register_operand" "r")
3941 (match_operand 2 "const_int_operand" "n"))))]
3942 "UINTVAL (operands[2]) < 32"
3944 operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3945 return "ror\\t%w0, %w1, %3";
3947 [(set_attr "type" "rotate_imm")]
3950 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3951 [(set (match_operand:GPI 0 "register_operand" "=r")
3953 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3954 (match_operand 2 "const_int_operand" "n"))))]
3955 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3957 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3958 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3960 [(set_attr "type" "bfm")]
3963 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3964 [(set (match_operand:GPI 0 "register_operand" "=r")
3966 (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3967 (match_operand 2 "const_int_operand" "n"))))]
3968 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3970 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3971 return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3973 [(set_attr "type" "bfm")]
3976 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3977 [(set (match_operand:GPI 0 "register_operand" "=r")
3979 (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3980 (match_operand 2 "const_int_operand" "n"))))]
3981 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3983 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3984 return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3986 [(set_attr "type" "bfm")]
3989 ;; -------------------------------------------------------------------
3991 ;; -------------------------------------------------------------------
3993 (define_expand "<optab>"
3994 [(set (match_operand:DI 0 "register_operand" "=r")
3995 (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3996 (match_operand 2 "const_int_operand" "n")
3997 (match_operand 3 "const_int_operand" "n")))]
4002 (define_insn "*<optab><mode>"
4003 [(set (match_operand:GPI 0 "register_operand" "=r")
4004 (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
4005 (match_operand 2 "const_int_operand" "n")
4006 (match_operand 3 "const_int_operand" "n")))]
4008 "<su>bfx\\t%<w>0, %<w>1, %3, %2"
4009 [(set_attr "type" "bfm")]
4012 ;; Bitfield Insert (insv)
4013 (define_expand "insv<mode>"
4014 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
4015 (match_operand 1 "const_int_operand")
4016 (match_operand 2 "const_int_operand"))
4017 (match_operand:GPI 3 "general_operand"))]
4020 unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
4021 unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
4022 rtx value = operands[3];
4024 if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
4027 if (CONST_INT_P (value))
4029 unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
4031 /* Prefer AND/OR for inserting all zeros or all ones. */
4032 if ((UINTVAL (value) & mask) == 0
4033 || (UINTVAL (value) & mask) == mask)
4036 /* 16-bit aligned 16-bit wide insert is handled by insv_imm. */
4037 if (width == 16 && (pos % 16) == 0)
4040 operands[3] = force_reg (<MODE>mode, value);
4043 (define_insn "*insv_reg<mode>"
4044 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
4045 (match_operand 1 "const_int_operand" "n")
4046 (match_operand 2 "const_int_operand" "n"))
4047 (match_operand:GPI 3 "register_operand" "r"))]
4048 "!(UINTVAL (operands[1]) == 0
4049 || (UINTVAL (operands[2]) + UINTVAL (operands[1])
4050 > GET_MODE_BITSIZE (<MODE>mode)))"
4051 "bfi\\t%<w>0, %<w>3, %2, %1"
4052 [(set_attr "type" "bfm")]
4055 (define_insn "*aarch64_bfi<GPI:mode><ALLX:mode>4"
4056 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
4057 (match_operand 1 "const_int_operand" "n")
4058 (match_operand 2 "const_int_operand" "n"))
4059 (zero_extend:GPI (match_operand:ALLX 3 "register_operand" "r")))]
4060 "UINTVAL (operands[1]) <= <ALLX:sizen>"
4061 "bfi\\t%<GPI:w>0, %<GPI:w>3, %2, %1"
4062 [(set_attr "type" "bfm")]
4065 (define_insn "*extr_insv_lower_reg<mode>"
4066 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
4067 (match_operand 1 "const_int_operand" "n")
4069 (zero_extract:GPI (match_operand:GPI 2 "register_operand" "r")
4071 (match_operand 3 "const_int_operand" "n")))]
4072 "!(UINTVAL (operands[1]) == 0
4073 || (UINTVAL (operands[3]) + UINTVAL (operands[1])
4074 > GET_MODE_BITSIZE (<MODE>mode)))"
4075 "bfxil\\t%<w>0, %<w>2, %3, %1"
4076 [(set_attr "type" "bfm")]
4079 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
4080 [(set (match_operand:GPI 0 "register_operand" "=r")
4081 (ashift:GPI (ANY_EXTEND:GPI
4082 (match_operand:ALLX 1 "register_operand" "r"))
4083 (match_operand 2 "const_int_operand" "n")))]
4084 "UINTVAL (operands[2]) < <GPI:sizen>"
4086 operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
4087 ? GEN_INT (<ALLX:sizen>)
4088 : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
4089 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
4091 [(set_attr "type" "bfm")]
4094 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
4096 (define_insn "*andim_ashift<mode>_bfiz"
4097 [(set (match_operand:GPI 0 "register_operand" "=r")
4098 (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
4099 (match_operand 2 "const_int_operand" "n"))
4100 (match_operand 3 "const_int_operand" "n")))]
4101 "(INTVAL (operands[2]) < (<GPI:sizen>))
4102 && exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
4103 && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
4104 "ubfiz\\t%<w>0, %<w>1, %2, %P3"
4105 [(set_attr "type" "bfm")]
4108 (define_insn "bswap<mode>2"
4109 [(set (match_operand:GPI 0 "register_operand" "=r")
4110 (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
4112 "rev\\t%<w>0, %<w>1"
4113 [(set_attr "type" "rev")]
4116 (define_insn "bswaphi2"
4117 [(set (match_operand:HI 0 "register_operand" "=r")
4118 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
4121 [(set_attr "type" "rev")]
4124 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
4125 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
4126 ;; each valid permutation.
4128 (define_insn "rev16<mode>2"
4129 [(set (match_operand:GPI 0 "register_operand" "=r")
4130 (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
4132 (match_operand:GPI 3 "const_int_operand" "n"))
4133 (and:GPI (lshiftrt:GPI (match_dup 1)
4135 (match_operand:GPI 2 "const_int_operand" "n"))))]
4136 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
4137 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
4138 "rev16\\t%<w>0, %<w>1"
4139 [(set_attr "type" "rev")]
4142 (define_insn "rev16<mode>2_alt"
4143 [(set (match_operand:GPI 0 "register_operand" "=r")
4144 (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r")
4146 (match_operand:GPI 2 "const_int_operand" "n"))
4147 (and:GPI (ashift:GPI (match_dup 1)
4149 (match_operand:GPI 3 "const_int_operand" "n"))))]
4150 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
4151 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
4152 "rev16\\t%<w>0, %<w>1"
4153 [(set_attr "type" "rev")]
4156 ;; zero_extend version of above
4157 (define_insn "*bswapsi2_uxtw"
4158 [(set (match_operand:DI 0 "register_operand" "=r")
4159 (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
4162 [(set_attr "type" "rev")]
4165 ;; -------------------------------------------------------------------
4166 ;; Floating-point intrinsics
4167 ;; -------------------------------------------------------------------
4169 ;; frint floating-point round to integral standard patterns.
4170 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round, frintn.
4172 (define_insn "<frint_pattern><mode>2"
4173 [(set (match_operand:GPF 0 "register_operand" "=w")
4174 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
4177 "frint<frint_suffix>\\t%<s>0, %<s>1"
4178 [(set_attr "type" "f_rint<s>")]
4181 ;; frcvt floating-point round to integer and convert standard patterns.
4182 ;; Expands to lbtrunc, lceil, lfloor, lround.
4183 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
4184 [(set (match_operand:GPI 0 "register_operand" "=r")
4185 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
4188 "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
4189 [(set_attr "type" "f_cvtf2i")]
4192 (define_insn "*aarch64_fcvt<su_optab><GPF:mode><GPI:mode>2_mult"
4193 [(set (match_operand:GPI 0 "register_operand" "=r")
4196 (match_operand:GPF 1 "register_operand" "w")
4197 (match_operand:GPF 2 "aarch64_fp_pow2" "F"))))]
4199 && IN_RANGE (aarch64_fpconst_pow_of_2 (operands[2]), 1,
4200 GET_MODE_BITSIZE (<GPI:MODE>mode))"
4202 int fbits = aarch64_fpconst_pow_of_2 (operands[2]);
4204 snprintf (buf, 64, "fcvtz<su>\\t%%<GPI:w>0, %%<GPF:s>1, #%d", fbits);
4205 output_asm_insn (buf, operands);
4208 [(set_attr "type" "f_cvtf2i")]
4213 (define_insn "fma<mode>4"
4214 [(set (match_operand:GPF 0 "register_operand" "=w")
4215 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
4216 (match_operand:GPF 2 "register_operand" "w")
4217 (match_operand:GPF 3 "register_operand" "w")))]
4219 "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
4220 [(set_attr "type" "fmac<s>")]
4223 (define_insn "fnma<mode>4"
4224 [(set (match_operand:GPF 0 "register_operand" "=w")
4225 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
4226 (match_operand:GPF 2 "register_operand" "w")
4227 (match_operand:GPF 3 "register_operand" "w")))]
4229 "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
4230 [(set_attr "type" "fmac<s>")]
4233 (define_insn "fms<mode>4"
4234 [(set (match_operand:GPF 0 "register_operand" "=w")
4235 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
4236 (match_operand:GPF 2 "register_operand" "w")
4237 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
4239 "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
4240 [(set_attr "type" "fmac<s>")]
4243 (define_insn "fnms<mode>4"
4244 [(set (match_operand:GPF 0 "register_operand" "=w")
4245 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
4246 (match_operand:GPF 2 "register_operand" "w")
4247 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
4249 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
4250 [(set_attr "type" "fmac<s>")]
4253 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
4254 (define_insn "*fnmadd<mode>4"
4255 [(set (match_operand:GPF 0 "register_operand" "=w")
4256 (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
4257 (match_operand:GPF 2 "register_operand" "w")
4258 (match_operand:GPF 3 "register_operand" "w"))))]
4259 "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
4260 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
4261 [(set_attr "type" "fmac<s>")]
4264 ;; -------------------------------------------------------------------
4265 ;; Floating-point conversions
4266 ;; -------------------------------------------------------------------
4268 (define_insn "extendsfdf2"
4269 [(set (match_operand:DF 0 "register_operand" "=w")
4270 (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
4273 [(set_attr "type" "f_cvt")]
4276 (define_insn "extendhfsf2"
4277 [(set (match_operand:SF 0 "register_operand" "=w")
4278 (float_extend:SF (match_operand:HF 1 "register_operand" "w")))]
4281 [(set_attr "type" "f_cvt")]
4284 (define_insn "extendhfdf2"
4285 [(set (match_operand:DF 0 "register_operand" "=w")
4286 (float_extend:DF (match_operand:HF 1 "register_operand" "w")))]
4289 [(set_attr "type" "f_cvt")]
4292 (define_insn "truncdfsf2"
4293 [(set (match_operand:SF 0 "register_operand" "=w")
4294 (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
4297 [(set_attr "type" "f_cvt")]
4300 (define_insn "truncsfhf2"
4301 [(set (match_operand:HF 0 "register_operand" "=w")
4302 (float_truncate:HF (match_operand:SF 1 "register_operand" "w")))]
4305 [(set_attr "type" "f_cvt")]
4308 (define_insn "truncdfhf2"
4309 [(set (match_operand:HF 0 "register_operand" "=w")
4310 (float_truncate:HF (match_operand:DF 1 "register_operand" "w")))]
4313 [(set_attr "type" "f_cvt")]
4316 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
4317 [(set (match_operand:GPI 0 "register_operand" "=r")
4318 (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
4320 "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
4321 [(set_attr "type" "f_cvtf2i")]
4324 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
4325 [(set (match_operand:GPI 0 "register_operand" "=r")
4326 (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
4328 "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
4329 [(set_attr "type" "f_cvtf2i")]
4332 (define_insn "<optab><fcvt_target><GPF:mode>2"
4333 [(set (match_operand:GPF 0 "register_operand" "=w,w")
4334 (FLOATUORS:GPF (match_operand:<FCVT_TARGET> 1 "register_operand" "w,r")))]
4337 <su_optab>cvtf\t%<GPF:s>0, %<s>1
4338 <su_optab>cvtf\t%<GPF:s>0, %<w1>1"
4339 [(set_attr "simd" "yes,no")
4340 (set_attr "fp" "no,yes")
4341 (set_attr "type" "neon_int_to_fp_<Vetype>,f_cvti2f")]
4344 (define_insn "<optab><fcvt_iesize><GPF:mode>2"
4345 [(set (match_operand:GPF 0 "register_operand" "=w")
4346 (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand" "r")))]
4348 "<su_optab>cvtf\t%<GPF:s>0, %<w2>1"
4349 [(set_attr "type" "f_cvti2f")]
4352 ;; -------------------------------------------------------------------
4353 ;; Floating-point arithmetic
4354 ;; -------------------------------------------------------------------
4356 (define_insn "add<mode>3"
4357 [(set (match_operand:GPF 0 "register_operand" "=w")
4359 (match_operand:GPF 1 "register_operand" "w")
4360 (match_operand:GPF 2 "register_operand" "w")))]
4362 "fadd\\t%<s>0, %<s>1, %<s>2"
4363 [(set_attr "type" "fadd<s>")]
4366 (define_insn "sub<mode>3"
4367 [(set (match_operand:GPF 0 "register_operand" "=w")
4369 (match_operand:GPF 1 "register_operand" "w")
4370 (match_operand:GPF 2 "register_operand" "w")))]
4372 "fsub\\t%<s>0, %<s>1, %<s>2"
4373 [(set_attr "type" "fadd<s>")]
4376 (define_insn "mul<mode>3"
4377 [(set (match_operand:GPF 0 "register_operand" "=w")
4379 (match_operand:GPF 1 "register_operand" "w")
4380 (match_operand:GPF 2 "register_operand" "w")))]
4382 "fmul\\t%<s>0, %<s>1, %<s>2"
4383 [(set_attr "type" "fmul<s>")]
4386 (define_insn "*fnmul<mode>3"
4387 [(set (match_operand:GPF 0 "register_operand" "=w")
4389 (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
4390 (match_operand:GPF 2 "register_operand" "w")))]
4391 "TARGET_FLOAT && !flag_rounding_math"
4392 "fnmul\\t%<s>0, %<s>1, %<s>2"
4393 [(set_attr "type" "fmul<s>")]
4396 (define_insn "*fnmul<mode>3"
4397 [(set (match_operand:GPF 0 "register_operand" "=w")
4399 (match_operand:GPF 1 "register_operand" "w")
4400 (match_operand:GPF 2 "register_operand" "w"))))]
4402 "fnmul\\t%<s>0, %<s>1, %<s>2"
4403 [(set_attr "type" "fmul<s>")]
4406 (define_insn "div<mode>3"
4407 [(set (match_operand:GPF 0 "register_operand" "=w")
4409 (match_operand:GPF 1 "register_operand" "w")
4410 (match_operand:GPF 2 "register_operand" "w")))]
4412 "fdiv\\t%<s>0, %<s>1, %<s>2"
4413 [(set_attr "type" "fdiv<s>")]
4416 (define_insn "neg<mode>2"
4417 [(set (match_operand:GPF 0 "register_operand" "=w")
4418 (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
4420 "fneg\\t%<s>0, %<s>1"
4421 [(set_attr "type" "ffarith<s>")]
4424 (define_insn "sqrt<mode>2"
4425 [(set (match_operand:GPF 0 "register_operand" "=w")
4426 (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
4428 "fsqrt\\t%<s>0, %<s>1"
4429 [(set_attr "type" "fsqrt<s>")]
4432 (define_insn "abs<mode>2"
4433 [(set (match_operand:GPF 0 "register_operand" "=w")
4434 (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
4436 "fabs\\t%<s>0, %<s>1"
4437 [(set_attr "type" "ffarith<s>")]
4440 ;; Given that smax/smin do not specify the result when either input is NaN,
4441 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
4444 (define_insn "smax<mode>3"
4445 [(set (match_operand:GPF 0 "register_operand" "=w")
4446 (smax:GPF (match_operand:GPF 1 "register_operand" "w")
4447 (match_operand:GPF 2 "register_operand" "w")))]
4449 "fmaxnm\\t%<s>0, %<s>1, %<s>2"
4450 [(set_attr "type" "f_minmax<s>")]
4453 (define_insn "smin<mode>3"
4454 [(set (match_operand:GPF 0 "register_operand" "=w")
4455 (smin:GPF (match_operand:GPF 1 "register_operand" "w")
4456 (match_operand:GPF 2 "register_operand" "w")))]
4458 "fminnm\\t%<s>0, %<s>1, %<s>2"
4459 [(set_attr "type" "f_minmax<s>")]
4462 ;; For copysign (x, y), we want to generate:
4464 ;; LDR d2, #(1 << 63)
4465 ;; BSL v2.8b, [y], [x]
4467 ;; or another, equivalent, sequence using one of BSL/BIT/BIF.
4468 ;; aarch64_simd_bsldf will select the best suited of these instructions
4469 ;; to generate based on register allocation, and knows how to partially
4470 ;; constant fold based on the values of X and Y, so expand through that.
4472 (define_expand "copysigndf3"
4473 [(match_operand:DF 0 "register_operand")
4474 (match_operand:DF 1 "register_operand")
4475 (match_operand:DF 2 "register_operand")]
4476 "TARGET_FLOAT && TARGET_SIMD"
4478 rtx mask = gen_reg_rtx (DImode);
4479 emit_move_insn (mask, GEN_INT (HOST_WIDE_INT_1U << 63));
4480 emit_insn (gen_aarch64_simd_bsldf (operands[0], mask,
4481 operands[2], operands[1]));
4486 ;; As above, but we must first get to a 64-bit value if we wish to use
4487 ;; aarch64_simd_bslv2sf.
4489 (define_expand "copysignsf3"
4490 [(match_operand:SF 0 "register_operand")
4491 (match_operand:SF 1 "register_operand")
4492 (match_operand:SF 2 "register_operand")]
4493 "TARGET_FLOAT && TARGET_SIMD"
4495 rtx mask = gen_reg_rtx (DImode);
4497 /* Juggle modes to get us in to a vector mode for BSL. */
4498 rtx op1 = lowpart_subreg (V2SFmode, operands[1], SFmode);
4499 rtx op2 = lowpart_subreg (V2SFmode, operands[2], SFmode);
4500 rtx tmp = gen_reg_rtx (V2SFmode);
4501 emit_move_insn (mask, GEN_INT (HOST_WIDE_INT_1U << 31));
4502 emit_insn (gen_aarch64_simd_bslv2sf (tmp, mask, op2, op1));
4503 emit_move_insn (operands[0], lowpart_subreg (SFmode, tmp, V2SFmode));
4508 ;; -------------------------------------------------------------------
4510 ;; -------------------------------------------------------------------
4511 ;; Reload Scalar Floating point modes from constant pool.
4512 ;; The AArch64 port doesn't have __int128 constant move support.
4513 (define_expand "aarch64_reload_movcp<GPF_TF:mode><P:mode>"
4514 [(set (match_operand:GPF_TF 0 "register_operand" "=w")
4515 (mem:GPF_TF (match_operand 1 "aarch64_constant_pool_symref" "S")))
4516 (clobber (match_operand:P 2 "register_operand" "=&r"))]
4517 "TARGET_FLOAT && aarch64_nopcrelative_literal_loads"
4519 aarch64_expand_mov_immediate (operands[2], XEXP (operands[1], 0));
4520 emit_move_insn (operands[0], gen_rtx_MEM (<GPF_TF:MODE>mode, operands[2]));
4525 ;; Reload Vector modes from constant pool.
4526 (define_expand "aarch64_reload_movcp<VALL:mode><P:mode>"
4527 [(set (match_operand:VALL 0 "register_operand" "=w")
4528 (mem:VALL (match_operand 1 "aarch64_constant_pool_symref" "S")))
4529 (clobber (match_operand:P 2 "register_operand" "=&r"))]
4530 "TARGET_FLOAT && aarch64_nopcrelative_literal_loads"
4532 aarch64_expand_mov_immediate (operands[2], XEXP (operands[1], 0));
4533 emit_move_insn (operands[0], gen_rtx_MEM (<VALL:MODE>mode, operands[2]));
4538 (define_expand "aarch64_reload_mov<mode>"
4539 [(set (match_operand:TX 0 "register_operand" "=w")
4540 (match_operand:TX 1 "register_operand" "w"))
4541 (clobber (match_operand:DI 2 "register_operand" "=&r"))
4545 rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
4546 rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
4547 gen_aarch64_movtilow_tilow (op0, op1);
4548 gen_aarch64_movdi_tihigh (operands[2], op1);
4549 gen_aarch64_movtihigh_di (op0, operands[2]);
4554 ;; The following secondary reload helpers patterns are invoked
4555 ;; after or during reload as we don't want these patterns to start
4556 ;; kicking in during the combiner.
4558 (define_insn "aarch64_movdi_<mode>low"
4559 [(set (match_operand:DI 0 "register_operand" "=r")
4560 (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
4561 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4563 [(set_attr "type" "f_mrc")
4564 (set_attr "length" "4")
4567 (define_insn "aarch64_movdi_<mode>high"
4568 [(set (match_operand:DI 0 "register_operand" "=r")
4570 (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
4572 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4573 "fmov\\t%x0, %1.d[1]"
4574 [(set_attr "type" "f_mrc")
4575 (set_attr "length" "4")
4578 (define_insn "aarch64_mov<mode>high_di"
4579 [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
4580 (const_int 64) (const_int 64))
4581 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4582 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4583 "fmov\\t%0.d[1], %x1"
4584 [(set_attr "type" "f_mcr")
4585 (set_attr "length" "4")
4588 (define_insn "aarch64_mov<mode>low_di"
4589 [(set (match_operand:TX 0 "register_operand" "=w")
4590 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4591 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4593 [(set_attr "type" "f_mcr")
4594 (set_attr "length" "4")
4597 (define_insn "aarch64_movtilow_tilow"
4598 [(set (match_operand:TI 0 "register_operand" "=w")
4600 (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
4601 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4603 [(set_attr "type" "fmov")
4604 (set_attr "length" "4")
4607 ;; There is a deliberate reason why the parameters of high and lo_sum's
4608 ;; don't have modes for ADRP and ADD instructions. This is to allow high
4609 ;; and lo_sum's to be used with the labels defining the jump tables in
4612 (define_expand "add_losym"
4613 [(set (match_operand 0 "register_operand" "=r")
4614 (lo_sum (match_operand 1 "register_operand" "r")
4615 (match_operand 2 "aarch64_valid_symref" "S")))]
4618 machine_mode mode = GET_MODE (operands[0]);
4620 emit_insn ((mode == DImode
4622 : gen_add_losym_si) (operands[0],
4628 (define_insn "add_losym_<mode>"
4629 [(set (match_operand:P 0 "register_operand" "=r")
4630 (lo_sum:P (match_operand:P 1 "register_operand" "r")
4631 (match_operand 2 "aarch64_valid_symref" "S")))]
4633 "add\\t%<w>0, %<w>1, :lo12:%a2"
4634 [(set_attr "type" "alu_imm")]
4637 (define_insn "ldr_got_small_<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_GOTSMALLPIC))]
4644 "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
4645 [(set_attr "type" "load1")]
4648 (define_insn "ldr_got_small_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_GOTSMALLPIC)))]
4656 "ldr\\t%w0, [%1, #:got_lo12:%a2]"
4657 [(set_attr "type" "load1")]
4660 (define_insn "ldr_got_small_28k_<mode>"
4661 [(set (match_operand:PTR 0 "register_operand" "=r")
4662 (unspec:PTR [(mem:PTR (lo_sum:PTR
4663 (match_operand:PTR 1 "register_operand" "r")
4664 (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
4665 UNSPEC_GOTSMALLPIC28K))]
4667 "ldr\\t%<w>0, [%1, #:<got_modifier>:%a2]"
4668 [(set_attr "type" "load1")]
4671 (define_insn "ldr_got_small_28k_sidi"
4672 [(set (match_operand:DI 0 "register_operand" "=r")
4674 (unspec:SI [(mem:SI (lo_sum:DI
4675 (match_operand:DI 1 "register_operand" "r")
4676 (match_operand:DI 2 "aarch64_valid_symref" "S")))]
4677 UNSPEC_GOTSMALLPIC28K)))]
4679 "ldr\\t%w0, [%1, #:gotpage_lo14:%a2]"
4680 [(set_attr "type" "load1")]
4683 (define_insn "ldr_got_tiny"
4684 [(set (match_operand:DI 0 "register_operand" "=r")
4685 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
4686 UNSPEC_GOTTINYPIC))]
4689 [(set_attr "type" "load1")]
4692 (define_insn "aarch64_load_tp_hard"
4693 [(set (match_operand:DI 0 "register_operand" "=r")
4694 (unspec:DI [(const_int 0)] UNSPEC_TLS))]
4696 "mrs\\t%0, tpidr_el0"
4697 [(set_attr "type" "mrs")]
4700 ;; The TLS ABI specifically requires that the compiler does not schedule
4701 ;; instructions in the TLS stubs, in order to enable linker relaxation.
4702 ;; Therefore we treat the stubs as an atomic sequence.
4703 (define_expand "tlsgd_small"
4704 [(parallel [(set (match_operand 0 "register_operand" "")
4705 (call (mem:DI (match_dup 2)) (const_int 1)))
4706 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
4707 (clobber (reg:DI LR_REGNUM))])]
4710 operands[2] = aarch64_tls_get_addr ();
4713 (define_insn "*tlsgd_small"
4714 [(set (match_operand 0 "register_operand" "")
4715 (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
4716 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
4717 (clobber (reg:DI LR_REGNUM))
4720 "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
4721 [(set_attr "type" "call")
4722 (set_attr "length" "16")])
4724 (define_insn "tlsie_small_<mode>"
4725 [(set (match_operand:PTR 0 "register_operand" "=r")
4726 (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
4727 UNSPEC_GOTSMALLTLS))]
4729 "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
4730 [(set_attr "type" "load1")
4731 (set_attr "length" "8")]
4734 (define_insn "tlsie_small_sidi"
4735 [(set (match_operand:DI 0 "register_operand" "=r")
4737 (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")]
4738 UNSPEC_GOTSMALLTLS)))]
4740 "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
4741 [(set_attr "type" "load1")
4742 (set_attr "length" "8")]
4745 (define_insn "tlsie_tiny_<mode>"
4746 [(set (match_operand:PTR 0 "register_operand" "=&r")
4747 (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")
4748 (match_operand:PTR 2 "register_operand" "r")]
4749 UNSPEC_GOTTINYTLS))]
4751 "ldr\\t%<w>0, %L1\;add\\t%<w>0, %<w>0, %<w>2"
4752 [(set_attr "type" "multiple")
4753 (set_attr "length" "8")]
4756 (define_insn "tlsie_tiny_sidi"
4757 [(set (match_operand:DI 0 "register_operand" "=&r")
4759 (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")
4760 (match_operand:DI 2 "register_operand" "r")
4762 UNSPEC_GOTTINYTLS)))]
4764 "ldr\\t%w0, %L1\;add\\t%w0, %w0, %w2"
4765 [(set_attr "type" "multiple")
4766 (set_attr "length" "8")]
4769 (define_insn "tlsle12_<mode>"
4770 [(set (match_operand:P 0 "register_operand" "=r")
4771 (unspec:P [(match_operand:P 1 "register_operand" "r")
4772 (match_operand 2 "aarch64_tls_le_symref" "S")]
4775 "add\\t%<w>0, %<w>1, #%L2";
4776 [(set_attr "type" "alu_sreg")
4777 (set_attr "length" "4")]
4780 (define_insn "tlsle24_<mode>"
4781 [(set (match_operand:P 0 "register_operand" "=r")
4782 (unspec:P [(match_operand:P 1 "register_operand" "r")
4783 (match_operand 2 "aarch64_tls_le_symref" "S")]
4786 "add\\t%<w>0, %<w>1, #%G2, lsl #12\;add\\t%<w>0, %<w>0, #%L2"
4787 [(set_attr "type" "multiple")
4788 (set_attr "length" "8")]
4791 (define_insn "tlsle32_<mode>"
4792 [(set (match_operand:P 0 "register_operand" "=r")
4793 (unspec:P [(match_operand 1 "aarch64_tls_le_symref" "S")]
4796 "movz\\t%<w>0, #:tprel_g1:%1\;movk\\t%<w>0, #:tprel_g0_nc:%1"
4797 [(set_attr "type" "multiple")
4798 (set_attr "length" "8")]
4801 (define_insn "tlsle48_<mode>"
4802 [(set (match_operand:P 0 "register_operand" "=r")
4803 (unspec:P [(match_operand 1 "aarch64_tls_le_symref" "S")]
4806 "movz\\t%<w>0, #:tprel_g2:%1\;movk\\t%<w>0, #:tprel_g1_nc:%1\;movk\\t%<w>0, #:tprel_g0_nc:%1"
4807 [(set_attr "type" "multiple")
4808 (set_attr "length" "12")]
4811 (define_insn "tlsdesc_small_<mode>"
4812 [(set (reg:PTR R0_REGNUM)
4813 (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
4815 (clobber (reg:DI LR_REGNUM))
4816 (clobber (reg:CC CC_REGNUM))
4817 (clobber (match_scratch:DI 1 "=r"))]
4819 "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
4820 [(set_attr "type" "call")
4821 (set_attr "length" "16")])
4823 (define_insn "stack_tie"
4824 [(set (mem:BLK (scratch))
4825 (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
4826 (match_operand:DI 1 "register_operand" "rk")]
4830 [(set_attr "length" "0")]
4833 ;; Named pattern for expanding thread pointer reference.
4834 (define_expand "get_thread_pointerdi"
4835 [(match_operand:DI 0 "register_operand" "=r")]
4838 rtx tmp = aarch64_load_tp (operands[0]);
4839 if (tmp != operands[0])
4840 emit_move_insn (operands[0], tmp);
4844 ;; Named patterns for stack smashing protection.
4845 (define_expand "stack_protect_set"
4846 [(match_operand 0 "memory_operand")
4847 (match_operand 1 "memory_operand")]
4850 machine_mode mode = GET_MODE (operands[0]);
4852 emit_insn ((mode == DImode
4853 ? gen_stack_protect_set_di
4854 : gen_stack_protect_set_si) (operands[0], operands[1]));
4858 (define_insn "stack_protect_set_<mode>"
4859 [(set (match_operand:PTR 0 "memory_operand" "=m")
4860 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
4862 (set (match_scratch:PTR 2 "=&r") (const_int 0))]
4864 "ldr\\t%<w>2, %1\;str\\t%<w>2, %0\;mov\t%<w>2,0"
4865 [(set_attr "length" "12")
4866 (set_attr "type" "multiple")])
4868 (define_expand "stack_protect_test"
4869 [(match_operand 0 "memory_operand")
4870 (match_operand 1 "memory_operand")
4875 machine_mode mode = GET_MODE (operands[0]);
4877 result = gen_reg_rtx(mode);
4879 emit_insn ((mode == DImode
4880 ? gen_stack_protect_test_di
4881 : gen_stack_protect_test_si) (result,
4886 emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4887 result, const0_rtx, operands[2]));
4889 emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4890 result, const0_rtx, operands[2]));
4894 (define_insn "stack_protect_test_<mode>"
4895 [(set (match_operand:PTR 0 "register_operand" "=r")
4896 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
4897 (match_operand:PTR 2 "memory_operand" "m")]
4899 (clobber (match_scratch:PTR 3 "=&r"))]
4901 "ldr\t%<w>3, %x1\;ldr\t%<w>0, %x2\;eor\t%<w>0, %<w>3, %<w>0"
4902 [(set_attr "length" "12")
4903 (set_attr "type" "multiple")])
4905 ;; Write Floating-point Control Register.
4906 (define_insn "set_fpcr"
4907 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
4910 [(set_attr "type" "mrs")])
4912 ;; Read Floating-point Control Register.
4913 (define_insn "get_fpcr"
4914 [(set (match_operand:SI 0 "register_operand" "=r")
4915 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
4918 [(set_attr "type" "mrs")])
4920 ;; Write Floating-point Status Register.
4921 (define_insn "set_fpsr"
4922 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
4925 [(set_attr "type" "mrs")])
4927 ;; Read Floating-point Status Register.
4928 (define_insn "get_fpsr"
4929 [(set (match_operand:SI 0 "register_operand" "=r")
4930 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
4933 [(set_attr "type" "mrs")])
4936 ;; Define the subtract-one-and-jump insns so loop.c
4937 ;; knows what to generate.
4938 (define_expand "doloop_end"
4939 [(use (match_operand 0 "" "")) ; loop pseudo
4940 (use (match_operand 1 "" ""))] ; label
4941 "optimize > 0 && flag_modulo_sched"
4950 /* Currently SMS relies on the do-loop pattern to recognize loops
4951 where (1) the control part consists of all insns defining and/or
4952 using a certain 'count' register and (2) the loop count can be
4953 adjusted by modifying this register prior to the loop.
4954 ??? The possible introduction of a new block to initialize the
4955 new IV can potentially affect branch optimizations. */
4957 if (GET_MODE (operands[0]) != DImode)
4961 insn = emit_insn (gen_adddi3_compare0 (s0, s0, GEN_INT (-1)));
4963 cmp = XVECEXP (PATTERN (insn), 0, 0);
4964 cc_reg = SET_DEST (cmp);
4965 bcomp = gen_rtx_NE (VOIDmode, cc_reg, const0_rtx);
4966 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
4967 emit_jump_insn (gen_rtx_SET (pc_rtx,
4968 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
4974 (include "aarch64-simd.md")
4976 ;; Atomic Operations
4977 (include "atomics.md")
4979 ;; ldp/stp peephole patterns
4980 (include "aarch64-ldpstp.md")