1 ;; Machine description for AArch64 architecture.
2 ;; Copyright (C) 2009-2015 Free Software Foundation, Inc.
3 ;; Contributed by ARM Ltd.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; GCC is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ;; General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
68 (define_c_enum "unspec" [
125 (define_c_enum "unspecv" [
126 UNSPECV_EH_RETURN ; Represent EH_RETURN
127 UNSPECV_GET_FPCR ; Represent fetch of FPCR content.
128 UNSPECV_SET_FPCR ; Represent assign of FPCR content.
129 UNSPECV_GET_FPSR ; Represent fetch of FPSR content.
130 UNSPECV_SET_FPSR ; Represent assign of FPSR content.
134 ;; If further include files are added the defintion of MD_INCLUDES
137 (include "constraints.md")
138 (include "predicates.md")
139 (include "iterators.md")
141 ;; -------------------------------------------------------------------
142 ;; Instruction types and attributes
143 ;; -------------------------------------------------------------------
145 ; The "type" attribute is is included here from AArch32 backend to be able
146 ; to share pipeline descriptions.
147 (include "../arm/types.md")
149 ;; It is important to set the fp or simd attributes to yes when a pattern
150 ;; alternative uses the FP or SIMD register files, usually signified by use of
151 ;; the 'w' constraint. This will ensure that the alternative will be
152 ;; disabled when compiling with -mgeneral-regs-only or with the +nofp/+nosimd
153 ;; architecture extensions. If all the alternatives in a pattern use the
154 ;; FP or SIMD registers then the pattern predicate should include TARGET_FLOAT
157 ;; Attribute that specifies whether or not the instruction touches fp
158 ;; registers. When this is set to yes for an alternative, that alternative
159 ;; will be disabled when !TARGET_FLOAT.
160 (define_attr "fp" "no,yes" (const_string "no"))
162 ;; Attribute that specifies whether or not the instruction touches simd
163 ;; registers. When this is set to yes for an alternative, that alternative
164 ;; will be disabled when !TARGET_SIMD.
165 (define_attr "simd" "no,yes" (const_string "no"))
167 (define_attr "length" ""
170 ;; Attribute that controls whether an alternative is enabled or not.
171 ;; Currently it is only used to disable alternatives which touch fp or simd
172 ;; registers when -mgeneral-regs-only is specified.
173 (define_attr "enabled" "no,yes"
175 (and (eq_attr "fp" "yes")
176 (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
177 (and (eq_attr "simd" "yes")
178 (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
180 ] (const_string "yes")))
182 ;; -------------------------------------------------------------------
183 ;; Pipeline descriptions and scheduling
184 ;; -------------------------------------------------------------------
187 (include "aarch64-tune.md")
190 (include "../arm/cortex-a53.md")
191 (include "../arm/cortex-a57.md")
192 (include "thunderx.md")
193 (include "../arm/xgene1.md")
195 ;; -------------------------------------------------------------------
196 ;; Jumps and other miscellaneous insns
197 ;; -------------------------------------------------------------------
199 (define_insn "indirect_jump"
200 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
203 [(set_attr "type" "branch")]
207 [(set (pc) (label_ref (match_operand 0 "" "")))]
210 [(set_attr "type" "branch")]
213 (define_expand "cbranch<mode>4"
214 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
215 [(match_operand:GPI 1 "register_operand" "")
216 (match_operand:GPI 2 "aarch64_plus_operand" "")])
217 (label_ref (match_operand 3 "" ""))
221 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
223 operands[2] = const0_rtx;
227 (define_expand "cbranch<mode>4"
228 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
229 [(match_operand:GPF 1 "register_operand" "")
230 (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
231 (label_ref (match_operand 3 "" ""))
235 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
237 operands[2] = const0_rtx;
241 (define_expand "cbranchcc4"
242 [(set (pc) (if_then_else
243 (match_operator 0 "aarch64_comparison_operator"
244 [(match_operand 1 "cc_register" "")
245 (match_operand 2 "const0_operand")])
246 (label_ref (match_operand 3 "" ""))
251 (define_insn "ccmp_and<mode>"
252 [(set (match_operand 1 "ccmp_cc_register" "")
255 (match_operator 4 "aarch64_comparison_operator"
256 [(match_operand 0 "ccmp_cc_register" "")
258 (match_operator 5 "aarch64_comparison_operator"
259 [(match_operand:GPI 2 "register_operand" "r,r,r")
260 (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")]))
262 "aarch64_ccmp_mode_to_code (GET_MODE (operands[1])) == GET_CODE (operands[5])"
264 ccmp\\t%<w>2, %<w>3, %k5, %m4
265 ccmp\\t%<w>2, %<w>3, %k5, %m4
266 ccmn\\t%<w>2, #%n3, %k5, %m4"
267 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
270 (define_insn "ccmp_ior<mode>"
271 [(set (match_operand 1 "ccmp_cc_register" "")
274 (match_operator 4 "aarch64_comparison_operator"
275 [(match_operand 0 "ccmp_cc_register" "")
277 (match_operator 5 "aarch64_comparison_operator"
278 [(match_operand:GPI 2 "register_operand" "r,r,r")
279 (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")]))
281 "aarch64_ccmp_mode_to_code (GET_MODE (operands[1])) == GET_CODE (operands[5])"
283 ccmp\\t%<w>2, %<w>3, %K5, %M4
284 ccmp\\t%<w>2, %<w>3, %K5, %M4
285 ccmn\\t%<w>2, #%n3, %K5, %M4"
286 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
289 (define_expand "cmp<mode>"
290 [(set (match_operand 0 "cc_register" "")
291 (match_operator:CC 1 "aarch64_comparison_operator"
292 [(match_operand:GPI 2 "register_operand" "")
293 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
296 operands[1] = gen_rtx_fmt_ee (COMPARE,
297 SELECT_CC_MODE (GET_CODE (operands[1]),
298 operands[2], operands[3]),
299 operands[2], operands[3]);
303 (define_insn "*condjump"
304 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
305 [(match_operand 1 "cc_register" "") (const_int 0)])
306 (label_ref (match_operand 2 "" ""))
310 [(set_attr "type" "branch")]
313 (define_expand "casesi"
314 [(match_operand:SI 0 "register_operand" "") ; Index
315 (match_operand:SI 1 "const_int_operand" "") ; Lower bound
316 (match_operand:SI 2 "const_int_operand" "") ; Total range
317 (match_operand:DI 3 "" "") ; Table label
318 (match_operand:DI 4 "" "")] ; Out of range label
321 if (operands[1] != const0_rtx)
323 rtx reg = gen_reg_rtx (SImode);
325 /* Canonical RTL says that if you have:
329 then this should be emitted as:
333 The use of trunc_int_for_mode ensures that the resulting
334 constant can be represented in SImode, this is important
335 for the corner case where operand[1] is INT_MIN. */
337 operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
339 if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
340 (operands[1], SImode))
341 operands[1] = force_reg (SImode, operands[1]);
342 emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
346 if (!aarch64_plus_operand (operands[2], SImode))
347 operands[2] = force_reg (SImode, operands[2]);
348 emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
350 operands[0], operands[2], operands[4]));
352 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
353 emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
359 (define_insn "casesi_dispatch"
362 (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
363 (match_operand:SI 1 "register_operand" "r")]
365 (clobber (reg:CC CC_REGNUM))
366 (clobber (match_scratch:DI 3 "=r"))
367 (clobber (match_scratch:DI 4 "=r"))
368 (use (label_ref (match_operand 2 "" "")))])]
371 return aarch64_output_casesi (operands);
373 [(set_attr "length" "16")
374 (set_attr "type" "branch")]
378 [(unspec[(const_int 0)] UNSPEC_NOP)]
381 [(set_attr "type" "no_insn")]
384 (define_insn "prefetch"
385 [(prefetch (match_operand:DI 0 "address_operand" "r")
386 (match_operand:QI 1 "const_int_operand" "")
387 (match_operand:QI 2 "const_int_operand" ""))]
390 const char * pftype[2][4] =
392 {"prfm\\tPLDL1STRM, %a0",
393 "prfm\\tPLDL3KEEP, %a0",
394 "prfm\\tPLDL2KEEP, %a0",
395 "prfm\\tPLDL1KEEP, %a0"},
396 {"prfm\\tPSTL1STRM, %a0",
397 "prfm\\tPSTL3KEEP, %a0",
398 "prfm\\tPSTL2KEEP, %a0",
399 "prfm\\tPSTL1KEEP, %a0"},
402 int locality = INTVAL (operands[2]);
404 gcc_assert (IN_RANGE (locality, 0, 3));
406 return pftype[INTVAL(operands[1])][locality];
408 [(set_attr "type" "load1")]
412 [(trap_if (const_int 1) (const_int 8))]
415 [(set_attr "type" "trap")])
417 (define_expand "prologue"
418 [(clobber (const_int 0))]
421 aarch64_expand_prologue ();
426 (define_expand "epilogue"
427 [(clobber (const_int 0))]
430 aarch64_expand_epilogue (false);
435 (define_expand "sibcall_epilogue"
436 [(clobber (const_int 0))]
439 aarch64_expand_epilogue (true);
444 (define_insn "*do_return"
448 [(set_attr "type" "branch")]
451 (define_expand "return"
453 "aarch64_use_return_insn_p ()"
457 (define_insn "simple_return"
461 [(set_attr "type" "branch")]
464 (define_insn "eh_return"
465 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
469 [(set_attr "type" "branch")]
474 [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
477 [(set (match_dup 1) (match_dup 0))]
479 operands[1] = aarch64_final_eh_return_addr ();
483 (define_insn "*cb<optab><mode>1"
484 [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
486 (label_ref (match_operand 1 "" ""))
490 [(set_attr "type" "branch")]
494 (define_insn "*tb<optab><mode>1"
495 [(set (pc) (if_then_else
496 (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
498 (match_operand 1 "const_int_operand" "n"))
500 (label_ref (match_operand 2 "" ""))
502 (clobber (match_scratch:DI 3 "=r"))]
505 if (get_attr_length (insn) == 8)
506 return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
507 return \"<tbz>\\t%<w>0, %1, %l2\";
509 [(set_attr "type" "branch")
511 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
512 (lt (minus (match_dup 2) (pc)) (const_int 32764)))
517 (define_insn "*cb<optab><mode>1"
518 [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
520 (label_ref (match_operand 1 "" ""))
522 (clobber (match_scratch:DI 2 "=r"))]
525 if (get_attr_length (insn) == 8)
526 return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
527 return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
529 [(set_attr "type" "branch")
531 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
532 (lt (minus (match_dup 1) (pc)) (const_int 32764)))
537 ;; -------------------------------------------------------------------
538 ;; Subroutine calls and sibcalls
539 ;; -------------------------------------------------------------------
541 (define_expand "call_internal"
542 [(parallel [(call (match_operand 0 "memory_operand" "")
543 (match_operand 1 "general_operand" ""))
544 (use (match_operand 2 "" ""))
545 (clobber (reg:DI LR_REGNUM))])])
547 (define_expand "call"
548 [(parallel [(call (match_operand 0 "memory_operand" "")
549 (match_operand 1 "general_operand" ""))
550 (use (match_operand 2 "" ""))
551 (clobber (reg:DI LR_REGNUM))])]
557 /* In an untyped call, we can get NULL for operand 2. */
558 if (operands[2] == NULL)
559 operands[2] = const0_rtx;
561 /* Decide if we should generate indirect calls by loading the
562 64-bit address of the callee into a register before performing
563 the branch-and-link. */
564 callee = XEXP (operands[0], 0);
565 if (GET_CODE (callee) == SYMBOL_REF
566 ? aarch64_is_long_call_p (callee)
568 XEXP (operands[0], 0) = force_reg (Pmode, callee);
570 pat = gen_call_internal (operands[0], operands[1], operands[2]);
571 aarch64_emit_call_insn (pat);
576 (define_insn "*call_reg"
577 [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
578 (match_operand 1 "" ""))
579 (use (match_operand 2 "" ""))
580 (clobber (reg:DI LR_REGNUM))]
583 [(set_attr "type" "call")]
586 (define_insn "*call_symbol"
587 [(call (mem:DI (match_operand:DI 0 "" ""))
588 (match_operand 1 "" ""))
589 (use (match_operand 2 "" ""))
590 (clobber (reg:DI LR_REGNUM))]
591 "GET_CODE (operands[0]) == SYMBOL_REF
592 && !aarch64_is_long_call_p (operands[0])"
594 [(set_attr "type" "call")]
597 (define_expand "call_value_internal"
598 [(parallel [(set (match_operand 0 "" "")
599 (call (match_operand 1 "memory_operand" "")
600 (match_operand 2 "general_operand" "")))
601 (use (match_operand 3 "" ""))
602 (clobber (reg:DI LR_REGNUM))])])
604 (define_expand "call_value"
605 [(parallel [(set (match_operand 0 "" "")
606 (call (match_operand 1 "memory_operand" "")
607 (match_operand 2 "general_operand" "")))
608 (use (match_operand 3 "" ""))
609 (clobber (reg:DI LR_REGNUM))])]
615 /* In an untyped call, we can get NULL for operand 3. */
616 if (operands[3] == NULL)
617 operands[3] = const0_rtx;
619 /* Decide if we should generate indirect calls by loading the
620 64-bit address of the callee into a register before performing
621 the branch-and-link. */
622 callee = XEXP (operands[1], 0);
623 if (GET_CODE (callee) == SYMBOL_REF
624 ? aarch64_is_long_call_p (callee)
626 XEXP (operands[1], 0) = force_reg (Pmode, callee);
628 pat = gen_call_value_internal (operands[0], operands[1], operands[2],
630 aarch64_emit_call_insn (pat);
635 (define_insn "*call_value_reg"
636 [(set (match_operand 0 "" "")
637 (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
638 (match_operand 2 "" "")))
639 (use (match_operand 3 "" ""))
640 (clobber (reg:DI LR_REGNUM))]
643 [(set_attr "type" "call")]
647 (define_insn "*call_value_symbol"
648 [(set (match_operand 0 "" "")
649 (call (mem:DI (match_operand:DI 1 "" ""))
650 (match_operand 2 "" "")))
651 (use (match_operand 3 "" ""))
652 (clobber (reg:DI LR_REGNUM))]
653 "GET_CODE (operands[1]) == SYMBOL_REF
654 && !aarch64_is_long_call_p (operands[1])"
656 [(set_attr "type" "call")]
659 (define_expand "sibcall_internal"
660 [(parallel [(call (match_operand 0 "memory_operand" "")
661 (match_operand 1 "general_operand" ""))
663 (use (match_operand 2 "" ""))])])
665 (define_expand "sibcall"
666 [(parallel [(call (match_operand 0 "memory_operand" "")
667 (match_operand 1 "general_operand" ""))
669 (use (match_operand 2 "" ""))])]
674 if (!REG_P (XEXP (operands[0], 0))
675 && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
676 XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
678 if (operands[2] == NULL_RTX)
679 operands[2] = const0_rtx;
681 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
682 aarch64_emit_call_insn (pat);
687 (define_expand "sibcall_value_internal"
688 [(parallel [(set (match_operand 0 "" "")
689 (call (match_operand 1 "memory_operand" "")
690 (match_operand 2 "general_operand" "")))
692 (use (match_operand 3 "" ""))])])
694 (define_expand "sibcall_value"
695 [(parallel [(set (match_operand 0 "" "")
696 (call (match_operand 1 "memory_operand" "")
697 (match_operand 2 "general_operand" "")))
699 (use (match_operand 3 "" ""))])]
704 if (!REG_P (XEXP (operands[1], 0))
705 && (GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF))
706 XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
708 if (operands[3] == NULL_RTX)
709 operands[3] = const0_rtx;
711 pat = gen_sibcall_value_internal (operands[0], operands[1], operands[2],
713 aarch64_emit_call_insn (pat);
718 (define_insn "*sibcall_insn"
719 [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucs, Usf"))
720 (match_operand 1 "" ""))
722 (use (match_operand 2 "" ""))]
723 "SIBLING_CALL_P (insn)"
727 [(set_attr "type" "branch, branch")]
730 (define_insn "*sibcall_value_insn"
731 [(set (match_operand 0 "" "")
733 (match_operand:DI 1 "aarch64_call_insn_operand" "Ucs, Usf"))
734 (match_operand 2 "" "")))
736 (use (match_operand 3 "" ""))]
737 "SIBLING_CALL_P (insn)"
741 [(set_attr "type" "branch, branch")]
744 ;; Call subroutine returning any type.
746 (define_expand "untyped_call"
747 [(parallel [(call (match_operand 0 "")
750 (match_operand 2 "")])]
755 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
757 for (i = 0; i < XVECLEN (operands[2], 0); i++)
759 rtx set = XVECEXP (operands[2], 0, i);
760 emit_move_insn (SET_DEST (set), SET_SRC (set));
763 /* The optimizer does not know that the call sets the function value
764 registers we stored in the result block. We avoid problems by
765 claiming that all hard registers are used and clobbered at this
767 emit_insn (gen_blockage ());
771 ;; -------------------------------------------------------------------
773 ;; -------------------------------------------------------------------
775 (define_expand "mov<mode>"
776 [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
777 (match_operand:SHORT 1 "general_operand" ""))]
780 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
781 operands[1] = force_reg (<MODE>mode, operands[1]);
785 (define_insn "*mov<mode>_aarch64"
786 [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r, *w,r,*w, m, m, r,*w,*w")
787 (match_operand:SHORT 1 "general_operand" " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
788 "(register_operand (operands[0], <MODE>mode)
789 || aarch64_reg_or_zero (operands[1], <MODE>mode))"
791 switch (which_alternative)
794 return "mov\t%w0, %w1";
796 return "mov\t%w0, %1";
798 return aarch64_output_scalar_simd_mov_immediate (operands[1],
801 return "ldr<size>\t%w0, %1";
803 return "ldr\t%<size>0, %1";
805 return "str<size>\t%w1, %0";
807 return "str\t%<size>1, %0";
809 return "umov\t%w0, %1.<v>[0]";
811 return "dup\t%0.<Vallxd>, %w1";
813 return "dup\t%<Vetype>0, %1.<v>[0]";
818 [(set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
819 neon_from_gp<q>,neon_from_gp<q>, neon_dup")
820 (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")]
823 (define_expand "mov<mode>"
824 [(set (match_operand:GPI 0 "nonimmediate_operand" "")
825 (match_operand:GPI 1 "general_operand" ""))]
828 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
829 operands[1] = force_reg (<MODE>mode, operands[1]);
831 /* FIXME: RR we still need to fix up what we are doing with
832 symbol_refs and other types of constants. */
833 if (CONSTANT_P (operands[1])
834 && !CONST_INT_P (operands[1]))
836 aarch64_expand_mov_immediate (operands[0], operands[1]);
842 (define_insn_and_split "*movsi_aarch64"
843 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,r,*w,m, m,r,r ,*w, r,*w")
844 (match_operand:SI 1 "aarch64_mov_operand" " r,r,k,M,n,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
845 "(register_operand (operands[0], SImode)
846 || aarch64_reg_or_zero (operands[1], SImode))"
862 "CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), SImode)"
865 aarch64_expand_mov_immediate (operands[0], operands[1]);
868 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
869 adr,adr,f_mcr,f_mrc,fmov")
870 (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
873 (define_insn_and_split "*movdi_aarch64"
874 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,r,*w,m, m,r,r, *w, r,*w,w")
875 (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,n,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))]
876 "(register_operand (operands[0], DImode)
877 || aarch64_reg_or_zero (operands[1], DImode))"
894 "(CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), DImode))"
897 aarch64_expand_mov_immediate (operands[0], operands[1]);
900 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
901 adr,adr,f_mcr,f_mrc,fmov,fmov")
902 (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
903 (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
906 (define_insn "insv_imm<mode>"
907 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
909 (match_operand:GPI 1 "const_int_operand" "n"))
910 (match_operand:GPI 2 "const_int_operand" "n"))]
911 "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
912 && UINTVAL (operands[1]) % 16 == 0"
913 "movk\\t%<w>0, %X2, lsl %1"
914 [(set_attr "type" "mov_imm")]
917 (define_expand "movti"
918 [(set (match_operand:TI 0 "nonimmediate_operand" "")
919 (match_operand:TI 1 "general_operand" ""))]
922 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
923 operands[1] = force_reg (TImode, operands[1]);
927 (define_insn "*movti_aarch64"
928 [(set (match_operand:TI 0
929 "nonimmediate_operand" "=r, *w,r ,*w,r ,Ump,Ump,*w,m")
931 "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r ,Z , m,*w"))]
932 "(register_operand (operands[0], TImode)
933 || aarch64_reg_or_zero (operands[1], TImode))"
938 orr\\t%0.16b, %1.16b, %1.16b
944 [(set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \
945 load2,store2,store2,f_loadd,f_stored")
946 (set_attr "length" "8,8,8,4,4,4,4,4,4")
947 (set_attr "simd" "*,*,*,yes,*,*,*,*,*")
948 (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
951 ;; Split a TImode register-register or register-immediate move into
952 ;; its component DImode pieces, taking care to handle overlapping
953 ;; source and dest registers.
955 [(set (match_operand:TI 0 "register_operand" "")
956 (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
957 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
960 aarch64_split_128bit_move (operands[0], operands[1]);
964 (define_expand "mov<mode>"
965 [(set (match_operand:GPF 0 "nonimmediate_operand" "")
966 (match_operand:GPF 1 "general_operand" ""))]
971 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
975 if (GET_CODE (operands[0]) == MEM)
976 operands[1] = force_reg (<MODE>mode, operands[1]);
980 (define_insn "*movsf_aarch64"
981 [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
982 (match_operand:SF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
983 "TARGET_FLOAT && (register_operand (operands[0], SFmode)
984 || register_operand (operands[1], SFmode))"
995 [(set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
996 f_loads,f_stores,f_loads,f_stores,mov_reg")]
999 (define_insn "*movdf_aarch64"
1000 [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
1001 (match_operand:DF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
1002 "TARGET_FLOAT && (register_operand (operands[0], DFmode)
1003 || register_operand (operands[1], DFmode))"
1014 [(set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
1015 f_loadd,f_stored,f_loadd,f_stored,mov_reg")]
1018 (define_expand "movtf"
1019 [(set (match_operand:TF 0 "nonimmediate_operand" "")
1020 (match_operand:TF 1 "general_operand" ""))]
1025 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
1029 if (GET_CODE (operands[0]) == MEM)
1030 operands[1] = force_reg (TFmode, operands[1]);
1034 (define_insn "*movtf_aarch64"
1035 [(set (match_operand:TF 0
1036 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
1038 "general_operand" " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
1039 "TARGET_FLOAT && (register_operand (operands[0], TFmode)
1040 || register_operand (operands[1], TFmode))"
1042 orr\\t%0.16b, %1.16b, %1.16b
1052 [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,fconstd,fconstd,\
1053 f_loadd,f_stored,neon_load1_2reg,neon_store1_2reg")
1054 (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
1055 (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
1056 (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
1060 [(set (match_operand:TF 0 "register_operand" "")
1061 (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
1062 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
1065 aarch64_split_128bit_move (operands[0], operands[1]);
1072 ;; 2 is size of move in bytes
1075 (define_expand "movmemdi"
1076 [(match_operand:BLK 0 "memory_operand")
1077 (match_operand:BLK 1 "memory_operand")
1078 (match_operand:DI 2 "immediate_operand")
1079 (match_operand:DI 3 "immediate_operand")]
1082 if (aarch64_expand_movmem (operands))
1088 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1089 ;; fairly lax checking on the second memory operation.
1090 (define_insn "load_pairsi"
1091 [(set (match_operand:SI 0 "register_operand" "=r,*w")
1092 (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1093 (set (match_operand:SI 2 "register_operand" "=r,*w")
1094 (match_operand:SI 3 "memory_operand" "m,m"))]
1095 "rtx_equal_p (XEXP (operands[3], 0),
1096 plus_constant (Pmode,
1097 XEXP (operands[1], 0),
1098 GET_MODE_SIZE (SImode)))"
1102 [(set_attr "type" "load2,neon_load1_2reg")
1103 (set_attr "fp" "*,yes")]
1106 (define_insn "load_pairdi"
1107 [(set (match_operand:DI 0 "register_operand" "=r,*w")
1108 (match_operand:DI 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1109 (set (match_operand:DI 2 "register_operand" "=r,*w")
1110 (match_operand:DI 3 "memory_operand" "m,m"))]
1111 "rtx_equal_p (XEXP (operands[3], 0),
1112 plus_constant (Pmode,
1113 XEXP (operands[1], 0),
1114 GET_MODE_SIZE (DImode)))"
1118 [(set_attr "type" "load2,neon_load1_2reg")
1119 (set_attr "fp" "*,yes")]
1123 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1124 ;; fairly lax checking on the second memory operation.
1125 (define_insn "store_pairsi"
1126 [(set (match_operand:SI 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1127 (match_operand:SI 1 "aarch64_reg_or_zero" "rZ,*w"))
1128 (set (match_operand:SI 2 "memory_operand" "=m,m")
1129 (match_operand:SI 3 "aarch64_reg_or_zero" "rZ,*w"))]
1130 "rtx_equal_p (XEXP (operands[2], 0),
1131 plus_constant (Pmode,
1132 XEXP (operands[0], 0),
1133 GET_MODE_SIZE (SImode)))"
1137 [(set_attr "type" "store2,neon_store1_2reg")
1138 (set_attr "fp" "*,yes")]
1141 (define_insn "store_pairdi"
1142 [(set (match_operand:DI 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1143 (match_operand:DI 1 "aarch64_reg_or_zero" "rZ,*w"))
1144 (set (match_operand:DI 2 "memory_operand" "=m,m")
1145 (match_operand:DI 3 "aarch64_reg_or_zero" "rZ,*w"))]
1146 "rtx_equal_p (XEXP (operands[2], 0),
1147 plus_constant (Pmode,
1148 XEXP (operands[0], 0),
1149 GET_MODE_SIZE (DImode)))"
1153 [(set_attr "type" "store2,neon_store1_2reg")
1154 (set_attr "fp" "*,yes")]
1157 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1158 ;; fairly lax checking on the second memory operation.
1159 (define_insn "load_pairsf"
1160 [(set (match_operand:SF 0 "register_operand" "=w,*r")
1161 (match_operand:SF 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1162 (set (match_operand:SF 2 "register_operand" "=w,*r")
1163 (match_operand:SF 3 "memory_operand" "m,m"))]
1164 "rtx_equal_p (XEXP (operands[3], 0),
1165 plus_constant (Pmode,
1166 XEXP (operands[1], 0),
1167 GET_MODE_SIZE (SFmode)))"
1171 [(set_attr "type" "neon_load1_2reg,load2")
1172 (set_attr "fp" "yes,*")]
1175 (define_insn "load_pairdf"
1176 [(set (match_operand:DF 0 "register_operand" "=w,*r")
1177 (match_operand:DF 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1178 (set (match_operand:DF 2 "register_operand" "=w,*r")
1179 (match_operand:DF 3 "memory_operand" "m,m"))]
1180 "rtx_equal_p (XEXP (operands[3], 0),
1181 plus_constant (Pmode,
1182 XEXP (operands[1], 0),
1183 GET_MODE_SIZE (DFmode)))"
1187 [(set_attr "type" "neon_load1_2reg,load2")
1188 (set_attr "fp" "yes,*")]
1191 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1192 ;; fairly lax checking on the second memory operation.
1193 (define_insn "store_pairsf"
1194 [(set (match_operand:SF 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1195 (match_operand:SF 1 "register_operand" "w,*r"))
1196 (set (match_operand:SF 2 "memory_operand" "=m,m")
1197 (match_operand:SF 3 "register_operand" "w,*r"))]
1198 "rtx_equal_p (XEXP (operands[2], 0),
1199 plus_constant (Pmode,
1200 XEXP (operands[0], 0),
1201 GET_MODE_SIZE (SFmode)))"
1205 [(set_attr "type" "neon_store1_2reg,store2")
1206 (set_attr "fp" "yes,*")]
1209 (define_insn "store_pairdf"
1210 [(set (match_operand:DF 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1211 (match_operand:DF 1 "register_operand" "w,*r"))
1212 (set (match_operand:DF 2 "memory_operand" "=m,m")
1213 (match_operand:DF 3 "register_operand" "w,*r"))]
1214 "rtx_equal_p (XEXP (operands[2], 0),
1215 plus_constant (Pmode,
1216 XEXP (operands[0], 0),
1217 GET_MODE_SIZE (DFmode)))"
1221 [(set_attr "type" "neon_store1_2reg,store2")
1222 (set_attr "fp" "yes,*")]
1225 ;; Load pair with post-index writeback. This is primarily used in function
1227 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
1229 [(set (match_operand:P 0 "register_operand" "=k")
1230 (plus:P (match_operand:P 1 "register_operand" "0")
1231 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1232 (set (match_operand:GPI 2 "register_operand" "=r")
1233 (mem:GPI (match_dup 1)))
1234 (set (match_operand:GPI 3 "register_operand" "=r")
1235 (mem:GPI (plus:P (match_dup 1)
1236 (match_operand:P 5 "const_int_operand" "n"))))])]
1237 "INTVAL (operands[5]) == GET_MODE_SIZE (<GPI:MODE>mode)"
1238 "ldp\\t%<w>2, %<w>3, [%1], %4"
1239 [(set_attr "type" "load2")]
1242 (define_insn "loadwb_pair<GPF:mode>_<P:mode>"
1244 [(set (match_operand:P 0 "register_operand" "=k")
1245 (plus:P (match_operand:P 1 "register_operand" "0")
1246 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1247 (set (match_operand:GPF 2 "register_operand" "=w")
1248 (mem:GPF (match_dup 1)))
1249 (set (match_operand:GPF 3 "register_operand" "=w")
1250 (mem:GPF (plus:P (match_dup 1)
1251 (match_operand:P 5 "const_int_operand" "n"))))])]
1252 "INTVAL (operands[5]) == GET_MODE_SIZE (<GPF:MODE>mode)"
1253 "ldp\\t%<w>2, %<w>3, [%1], %4"
1254 [(set_attr "type" "neon_load1_2reg")]
1257 ;; Store pair with pre-index writeback. This is primarily used in function
1259 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
1261 [(set (match_operand:P 0 "register_operand" "=&k")
1262 (plus:P (match_operand:P 1 "register_operand" "0")
1263 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1264 (set (mem:GPI (plus:P (match_dup 0)
1266 (match_operand:GPI 2 "register_operand" "r"))
1267 (set (mem:GPI (plus:P (match_dup 0)
1268 (match_operand:P 5 "const_int_operand" "n")))
1269 (match_operand:GPI 3 "register_operand" "r"))])]
1270 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1271 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1272 [(set_attr "type" "store2")]
1275 (define_insn "storewb_pair<GPF:mode>_<P:mode>"
1277 [(set (match_operand:P 0 "register_operand" "=&k")
1278 (plus:P (match_operand:P 1 "register_operand" "0")
1279 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1280 (set (mem:GPF (plus:P (match_dup 0)
1282 (match_operand:GPF 2 "register_operand" "w"))
1283 (set (mem:GPF (plus:P (match_dup 0)
1284 (match_operand:P 5 "const_int_operand" "n")))
1285 (match_operand:GPF 3 "register_operand" "w"))])]
1286 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPF:MODE>mode)"
1287 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1288 [(set_attr "type" "neon_store1_2reg<q>")]
1291 ;; -------------------------------------------------------------------
1292 ;; Sign/Zero extension
1293 ;; -------------------------------------------------------------------
1295 (define_expand "<optab>sidi2"
1296 [(set (match_operand:DI 0 "register_operand")
1297 (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1301 (define_insn "*extendsidi2_aarch64"
1302 [(set (match_operand:DI 0 "register_operand" "=r,r")
1303 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1308 [(set_attr "type" "extend,load1")]
1311 (define_insn "*load_pair_extendsidi2_aarch64"
1312 [(set (match_operand:DI 0 "register_operand" "=r")
1313 (sign_extend:DI (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump")))
1314 (set (match_operand:DI 2 "register_operand" "=r")
1315 (sign_extend:DI (match_operand:SI 3 "memory_operand" "m")))]
1316 "rtx_equal_p (XEXP (operands[3], 0),
1317 plus_constant (Pmode,
1318 XEXP (operands[1], 0),
1319 GET_MODE_SIZE (SImode)))"
1320 "ldpsw\\t%0, %2, %1"
1321 [(set_attr "type" "load2")]
1324 (define_insn "*zero_extendsidi2_aarch64"
1325 [(set (match_operand:DI 0 "register_operand" "=r,r")
1326 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1331 [(set_attr "type" "extend,load1")]
1334 (define_insn "*load_pair_zero_extendsidi2_aarch64"
1335 [(set (match_operand:DI 0 "register_operand" "=r")
1336 (zero_extend:DI (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump")))
1337 (set (match_operand:DI 2 "register_operand" "=r")
1338 (zero_extend:DI (match_operand:SI 3 "memory_operand" "m")))]
1339 "rtx_equal_p (XEXP (operands[3], 0),
1340 plus_constant (Pmode,
1341 XEXP (operands[1], 0),
1342 GET_MODE_SIZE (SImode)))"
1343 "ldp\\t%w0, %w2, %1"
1344 [(set_attr "type" "load2")]
1347 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1348 [(set (match_operand:GPI 0 "register_operand")
1349 (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1353 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1354 [(set (match_operand:GPI 0 "register_operand" "=r,r")
1355 (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1358 sxt<SHORT:size>\t%<GPI:w>0, %w1
1359 ldrs<SHORT:size>\t%<GPI:w>0, %1"
1360 [(set_attr "type" "extend,load1")]
1363 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1364 [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1365 (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1368 uxt<SHORT:size>\t%<GPI:w>0, %w1
1369 ldr<SHORT:size>\t%w0, %1
1370 ldr\t%<SHORT:size>0, %1"
1371 [(set_attr "type" "extend,load1,load1")]
1374 (define_expand "<optab>qihi2"
1375 [(set (match_operand:HI 0 "register_operand")
1376 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1380 (define_insn "*<optab>qihi2_aarch64"
1381 [(set (match_operand:HI 0 "register_operand" "=r,r")
1382 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1387 [(set_attr "type" "extend,load1")]
1390 ;; -------------------------------------------------------------------
1391 ;; Simple arithmetic
1392 ;; -------------------------------------------------------------------
1394 (define_expand "add<mode>3"
1396 (match_operand:GPI 0 "register_operand" "")
1397 (plus:GPI (match_operand:GPI 1 "register_operand" "")
1398 (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1401 if (! aarch64_plus_operand (operands[2], VOIDmode))
1403 rtx subtarget = ((optimize && can_create_pseudo_p ())
1404 ? gen_reg_rtx (<MODE>mode) : operands[0]);
1405 HOST_WIDE_INT imm = INTVAL (operands[2]);
1408 imm = -(-imm & ~0xfff);
1412 emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1413 operands[1] = subtarget;
1414 operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1419 (define_insn "*addsi3_aarch64"
1421 (match_operand:SI 0 "register_operand" "=rk,rk,w,rk")
1423 (match_operand:SI 1 "register_operand" "%rk,rk,w,rk")
1424 (match_operand:SI 2 "aarch64_plus_operand" "I,r,w,J")))]
1429 add\\t%0.2s, %1.2s, %2.2s
1430 sub\\t%w0, %w1, #%n2"
1431 [(set_attr "type" "alu_imm,alu_sreg,neon_add,alu_imm")
1432 (set_attr "simd" "*,*,yes,*")]
1435 ;; zero_extend version of above
1436 (define_insn "*addsi3_aarch64_uxtw"
1438 (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1440 (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1441 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1446 sub\\t%w0, %w1, #%n2"
1447 [(set_attr "type" "alu_imm,alu_sreg,alu_imm")]
1450 (define_insn "*adddi3_aarch64"
1452 (match_operand:DI 0 "register_operand" "=rk,rk,rk,w")
1454 (match_operand:DI 1 "register_operand" "%rk,rk,rk,w")
1455 (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,w")))]
1460 sub\\t%x0, %x1, #%n2
1461 add\\t%d0, %d1, %d2"
1462 [(set_attr "type" "alu_imm,alu_sreg,alu_imm,neon_add")
1463 (set_attr "simd" "*,*,*,yes")]
1466 (define_expand "addti3"
1467 [(set (match_operand:TI 0 "register_operand" "")
1468 (plus:TI (match_operand:TI 1 "register_operand" "")
1469 (match_operand:TI 2 "register_operand" "")))]
1472 rtx low = gen_reg_rtx (DImode);
1473 emit_insn (gen_adddi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1474 gen_lowpart (DImode, operands[2])));
1476 rtx high = gen_reg_rtx (DImode);
1477 emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]),
1478 gen_highpart (DImode, operands[2])));
1480 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1481 emit_move_insn (gen_highpart (DImode, operands[0]), high);
1485 (define_insn "add<mode>3_compare0"
1486 [(set (reg:CC_NZ CC_REGNUM)
1488 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1489 (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1491 (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1492 (plus:GPI (match_dup 1) (match_dup 2)))]
1495 adds\\t%<w>0, %<w>1, %<w>2
1496 adds\\t%<w>0, %<w>1, %<w>2
1497 subs\\t%<w>0, %<w>1, #%n2"
1498 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1501 ;; zero_extend version of above
1502 (define_insn "*addsi3_compare0_uxtw"
1503 [(set (reg:CC_NZ CC_REGNUM)
1505 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1506 (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1508 (set (match_operand:DI 0 "register_operand" "=r,r,r")
1509 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1512 adds\\t%w0, %w1, %w2
1513 adds\\t%w0, %w1, %w2
1514 subs\\t%w0, %w1, #%n2"
1515 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1518 (define_insn "*adds_mul_imm_<mode>"
1519 [(set (reg:CC_NZ CC_REGNUM)
1522 (match_operand:GPI 1 "register_operand" "r")
1523 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1524 (match_operand:GPI 3 "register_operand" "r"))
1526 (set (match_operand:GPI 0 "register_operand" "=r")
1527 (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1530 "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1531 [(set_attr "type" "alus_shift_imm")]
1534 (define_insn "*subs_mul_imm_<mode>"
1535 [(set (reg:CC_NZ CC_REGNUM)
1537 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1539 (match_operand:GPI 2 "register_operand" "r")
1540 (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1542 (set (match_operand:GPI 0 "register_operand" "=r")
1543 (minus:GPI (match_dup 1)
1544 (mult:GPI (match_dup 2) (match_dup 3))))]
1546 "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1547 [(set_attr "type" "alus_shift_imm")]
1550 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1551 [(set (reg:CC_NZ CC_REGNUM)
1554 (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1555 (match_operand:GPI 2 "register_operand" "r"))
1557 (set (match_operand:GPI 0 "register_operand" "=r")
1558 (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1560 "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1561 [(set_attr "type" "alus_ext")]
1564 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1565 [(set (reg:CC_NZ CC_REGNUM)
1567 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1569 (match_operand:ALLX 2 "register_operand" "r")))
1571 (set (match_operand:GPI 0 "register_operand" "=r")
1572 (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1574 "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1575 [(set_attr "type" "alus_ext")]
1578 (define_insn "*adds_<optab><mode>_multp2"
1579 [(set (reg:CC_NZ CC_REGNUM)
1581 (plus:GPI (ANY_EXTRACT:GPI
1582 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1583 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1584 (match_operand 3 "const_int_operand" "n")
1586 (match_operand:GPI 4 "register_operand" "r"))
1588 (set (match_operand:GPI 0 "register_operand" "=r")
1589 (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1593 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1594 "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1595 [(set_attr "type" "alus_ext")]
1598 (define_insn "*subs_<optab><mode>_multp2"
1599 [(set (reg:CC_NZ CC_REGNUM)
1601 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1603 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1604 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1605 (match_operand 3 "const_int_operand" "n")
1608 (set (match_operand:GPI 0 "register_operand" "=r")
1609 (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1610 (mult:GPI (match_dup 1) (match_dup 2))
1613 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1614 "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1615 [(set_attr "type" "alus_ext")]
1618 (define_insn "*add<mode>3nr_compare0"
1619 [(set (reg:CC_NZ CC_REGNUM)
1621 (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1622 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1629 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1632 (define_insn "*compare_neg<mode>"
1633 [(set (reg:CC_Z CC_REGNUM)
1635 (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1636 (match_operand:GPI 1 "register_operand" "r")))]
1638 "cmn\\t%<w>1, %<w>0"
1639 [(set_attr "type" "alus_sreg")]
1642 (define_insn "*add_<shift>_<mode>"
1643 [(set (match_operand:GPI 0 "register_operand" "=r")
1644 (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1645 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1646 (match_operand:GPI 3 "register_operand" "r")))]
1648 "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1649 [(set_attr "type" "alu_shift_imm")]
1652 ;; zero_extend version of above
1653 (define_insn "*add_<shift>_si_uxtw"
1654 [(set (match_operand:DI 0 "register_operand" "=r")
1656 (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1657 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1658 (match_operand:SI 3 "register_operand" "r"))))]
1660 "add\\t%w0, %w3, %w1, <shift> %2"
1661 [(set_attr "type" "alu_shift_imm")]
1664 (define_insn "*add_mul_imm_<mode>"
1665 [(set (match_operand:GPI 0 "register_operand" "=r")
1666 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1667 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1668 (match_operand:GPI 3 "register_operand" "r")))]
1670 "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1671 [(set_attr "type" "alu_shift_imm")]
1674 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1675 [(set (match_operand:GPI 0 "register_operand" "=rk")
1676 (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1677 (match_operand:GPI 2 "register_operand" "r")))]
1679 "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1680 [(set_attr "type" "alu_ext")]
1683 ;; zero_extend version of above
1684 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1685 [(set (match_operand:DI 0 "register_operand" "=rk")
1687 (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1688 (match_operand:GPI 2 "register_operand" "r"))))]
1690 "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1691 [(set_attr "type" "alu_ext")]
1694 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1695 [(set (match_operand:GPI 0 "register_operand" "=rk")
1696 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1697 (match_operand:ALLX 1 "register_operand" "r"))
1698 (match_operand 2 "aarch64_imm3" "Ui3"))
1699 (match_operand:GPI 3 "register_operand" "r")))]
1701 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1702 [(set_attr "type" "alu_ext")]
1705 ;; zero_extend version of above
1706 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1707 [(set (match_operand:DI 0 "register_operand" "=rk")
1709 (plus:SI (ashift:SI (ANY_EXTEND:SI
1710 (match_operand:SHORT 1 "register_operand" "r"))
1711 (match_operand 2 "aarch64_imm3" "Ui3"))
1712 (match_operand:SI 3 "register_operand" "r"))))]
1714 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1715 [(set_attr "type" "alu_ext")]
1718 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1719 [(set (match_operand:GPI 0 "register_operand" "=rk")
1720 (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1721 (match_operand:ALLX 1 "register_operand" "r"))
1722 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1723 (match_operand:GPI 3 "register_operand" "r")))]
1725 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1726 [(set_attr "type" "alu_ext")]
1729 ;; zero_extend version of above
1730 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1731 [(set (match_operand:DI 0 "register_operand" "=rk")
1732 (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1733 (match_operand:SHORT 1 "register_operand" "r"))
1734 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1735 (match_operand:SI 3 "register_operand" "r"))))]
1737 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1738 [(set_attr "type" "alu_ext")]
1741 (define_insn "*add_<optab><mode>_multp2"
1742 [(set (match_operand:GPI 0 "register_operand" "=rk")
1743 (plus:GPI (ANY_EXTRACT:GPI
1744 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1745 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1746 (match_operand 3 "const_int_operand" "n")
1748 (match_operand:GPI 4 "register_operand" "r")))]
1749 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1750 "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1751 [(set_attr "type" "alu_ext")]
1754 ;; zero_extend version of above
1755 (define_insn "*add_<optab>si_multp2_uxtw"
1756 [(set (match_operand:DI 0 "register_operand" "=rk")
1758 (plus:SI (ANY_EXTRACT:SI
1759 (mult:SI (match_operand:SI 1 "register_operand" "r")
1760 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1761 (match_operand 3 "const_int_operand" "n")
1763 (match_operand:SI 4 "register_operand" "r"))))]
1764 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1765 "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1766 [(set_attr "type" "alu_ext")]
1769 (define_insn "add<mode>3_carryin"
1771 (match_operand:GPI 0 "register_operand" "=r")
1772 (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1774 (match_operand:GPI 1 "register_operand" "r")
1775 (match_operand:GPI 2 "register_operand" "r"))))]
1777 "adc\\t%<w>0, %<w>1, %<w>2"
1778 [(set_attr "type" "adc_reg")]
1781 ;; zero_extend version of above
1782 (define_insn "*addsi3_carryin_uxtw"
1784 (match_operand:DI 0 "register_operand" "=r")
1786 (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1788 (match_operand:SI 1 "register_operand" "r")
1789 (match_operand:SI 2 "register_operand" "r")))))]
1791 "adc\\t%w0, %w1, %w2"
1792 [(set_attr "type" "adc_reg")]
1795 (define_insn "*add<mode>3_carryin_alt1"
1797 (match_operand:GPI 0 "register_operand" "=r")
1799 (match_operand:GPI 1 "register_operand" "r")
1800 (match_operand:GPI 2 "register_operand" "r"))
1801 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1803 "adc\\t%<w>0, %<w>1, %<w>2"
1804 [(set_attr "type" "adc_reg")]
1807 ;; zero_extend version of above
1808 (define_insn "*addsi3_carryin_alt1_uxtw"
1810 (match_operand:DI 0 "register_operand" "=r")
1813 (match_operand:SI 1 "register_operand" "r")
1814 (match_operand:SI 2 "register_operand" "r"))
1815 (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1817 "adc\\t%w0, %w1, %w2"
1818 [(set_attr "type" "adc_reg")]
1821 (define_insn "*add<mode>3_carryin_alt2"
1823 (match_operand:GPI 0 "register_operand" "=r")
1825 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1826 (match_operand:GPI 1 "register_operand" "r"))
1827 (match_operand:GPI 2 "register_operand" "r")))]
1829 "adc\\t%<w>0, %<w>1, %<w>2"
1830 [(set_attr "type" "adc_reg")]
1833 ;; zero_extend version of above
1834 (define_insn "*addsi3_carryin_alt2_uxtw"
1836 (match_operand:DI 0 "register_operand" "=r")
1839 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1840 (match_operand:SI 1 "register_operand" "r"))
1841 (match_operand:SI 2 "register_operand" "r"))))]
1843 "adc\\t%w0, %w1, %w2"
1844 [(set_attr "type" "adc_reg")]
1847 (define_insn "*add<mode>3_carryin_alt3"
1849 (match_operand:GPI 0 "register_operand" "=r")
1851 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1852 (match_operand:GPI 2 "register_operand" "r"))
1853 (match_operand:GPI 1 "register_operand" "r")))]
1855 "adc\\t%<w>0, %<w>1, %<w>2"
1856 [(set_attr "type" "adc_reg")]
1859 ;; zero_extend version of above
1860 (define_insn "*addsi3_carryin_alt3_uxtw"
1862 (match_operand:DI 0 "register_operand" "=r")
1865 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1866 (match_operand:SI 2 "register_operand" "r"))
1867 (match_operand:SI 1 "register_operand" "r"))))]
1869 "adc\\t%w0, %w1, %w2"
1870 [(set_attr "type" "adc_reg")]
1873 (define_insn "*add_uxt<mode>_multp2"
1874 [(set (match_operand:GPI 0 "register_operand" "=rk")
1876 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1877 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1878 (match_operand 3 "const_int_operand" "n"))
1879 (match_operand:GPI 4 "register_operand" "r")))]
1880 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1882 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1883 INTVAL (operands[3])));
1884 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1885 [(set_attr "type" "alu_ext")]
1888 ;; zero_extend version of above
1889 (define_insn "*add_uxtsi_multp2_uxtw"
1890 [(set (match_operand:DI 0 "register_operand" "=rk")
1893 (mult:SI (match_operand:SI 1 "register_operand" "r")
1894 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1895 (match_operand 3 "const_int_operand" "n"))
1896 (match_operand:SI 4 "register_operand" "r"))))]
1897 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1899 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1900 INTVAL (operands[3])));
1901 return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1902 [(set_attr "type" "alu_ext")]
1905 (define_insn "subsi3"
1906 [(set (match_operand:SI 0 "register_operand" "=rk")
1907 (minus:SI (match_operand:SI 1 "register_operand" "rk")
1908 (match_operand:SI 2 "register_operand" "r")))]
1910 "sub\\t%w0, %w1, %w2"
1911 [(set_attr "type" "alu_sreg")]
1914 ;; zero_extend version of above
1915 (define_insn "*subsi3_uxtw"
1916 [(set (match_operand:DI 0 "register_operand" "=rk")
1918 (minus:SI (match_operand:SI 1 "register_operand" "rk")
1919 (match_operand:SI 2 "register_operand" "r"))))]
1921 "sub\\t%w0, %w1, %w2"
1922 [(set_attr "type" "alu_sreg")]
1925 (define_insn "subdi3"
1926 [(set (match_operand:DI 0 "register_operand" "=rk,w")
1927 (minus:DI (match_operand:DI 1 "register_operand" "rk,w")
1928 (match_operand:DI 2 "register_operand" "r,w")))]
1932 sub\\t%d0, %d1, %d2"
1933 [(set_attr "type" "alu_sreg, neon_sub")
1934 (set_attr "simd" "*,yes")]
1937 (define_expand "subti3"
1938 [(set (match_operand:TI 0 "register_operand" "")
1939 (minus:TI (match_operand:TI 1 "register_operand" "")
1940 (match_operand:TI 2 "register_operand" "")))]
1943 rtx low = gen_reg_rtx (DImode);
1944 emit_insn (gen_subdi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1945 gen_lowpart (DImode, operands[2])));
1947 rtx high = gen_reg_rtx (DImode);
1948 emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]),
1949 gen_highpart (DImode, operands[2])));
1951 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1952 emit_move_insn (gen_highpart (DImode, operands[0]), high);
1956 (define_insn "sub<mode>3_compare0"
1957 [(set (reg:CC_NZ CC_REGNUM)
1958 (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1959 (match_operand:GPI 2 "register_operand" "r"))
1961 (set (match_operand:GPI 0 "register_operand" "=r")
1962 (minus:GPI (match_dup 1) (match_dup 2)))]
1964 "subs\\t%<w>0, %<w>1, %<w>2"
1965 [(set_attr "type" "alus_sreg")]
1968 ;; zero_extend version of above
1969 (define_insn "*subsi3_compare0_uxtw"
1970 [(set (reg:CC_NZ CC_REGNUM)
1971 (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1972 (match_operand:SI 2 "register_operand" "r"))
1974 (set (match_operand:DI 0 "register_operand" "=r")
1975 (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1977 "subs\\t%w0, %w1, %w2"
1978 [(set_attr "type" "alus_sreg")]
1981 (define_insn "*sub_<shift>_<mode>"
1982 [(set (match_operand:GPI 0 "register_operand" "=r")
1983 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1985 (match_operand:GPI 1 "register_operand" "r")
1986 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1988 "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1989 [(set_attr "type" "alu_shift_imm")]
1992 ;; zero_extend version of above
1993 (define_insn "*sub_<shift>_si_uxtw"
1994 [(set (match_operand:DI 0 "register_operand" "=r")
1996 (minus:SI (match_operand:SI 3 "register_operand" "r")
1998 (match_operand:SI 1 "register_operand" "r")
1999 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2001 "sub\\t%w0, %w3, %w1, <shift> %2"
2002 [(set_attr "type" "alu_shift_imm")]
2005 (define_insn "*sub_mul_imm_<mode>"
2006 [(set (match_operand:GPI 0 "register_operand" "=r")
2007 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2009 (match_operand:GPI 1 "register_operand" "r")
2010 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2012 "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
2013 [(set_attr "type" "alu_shift_imm")]
2016 ;; zero_extend version of above
2017 (define_insn "*sub_mul_imm_si_uxtw"
2018 [(set (match_operand:DI 0 "register_operand" "=r")
2020 (minus:SI (match_operand:SI 3 "register_operand" "r")
2022 (match_operand:SI 1 "register_operand" "r")
2023 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2025 "sub\\t%w0, %w3, %w1, lsl %p2"
2026 [(set_attr "type" "alu_shift_imm")]
2029 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
2030 [(set (match_operand:GPI 0 "register_operand" "=rk")
2031 (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
2033 (match_operand:ALLX 2 "register_operand" "r"))))]
2035 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
2036 [(set_attr "type" "alu_ext")]
2039 ;; zero_extend version of above
2040 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
2041 [(set (match_operand:DI 0 "register_operand" "=rk")
2043 (minus:SI (match_operand:SI 1 "register_operand" "rk")
2045 (match_operand:SHORT 2 "register_operand" "r")))))]
2047 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
2048 [(set_attr "type" "alu_ext")]
2051 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
2052 [(set (match_operand:GPI 0 "register_operand" "=rk")
2053 (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
2054 (ashift:GPI (ANY_EXTEND:GPI
2055 (match_operand:ALLX 2 "register_operand" "r"))
2056 (match_operand 3 "aarch64_imm3" "Ui3"))))]
2058 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
2059 [(set_attr "type" "alu_ext")]
2062 ;; zero_extend version of above
2063 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
2064 [(set (match_operand:DI 0 "register_operand" "=rk")
2066 (minus:SI (match_operand:SI 1 "register_operand" "rk")
2067 (ashift:SI (ANY_EXTEND:SI
2068 (match_operand:SHORT 2 "register_operand" "r"))
2069 (match_operand 3 "aarch64_imm3" "Ui3")))))]
2071 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
2072 [(set_attr "type" "alu_ext")]
2075 (define_insn "*sub_<optab><mode>_multp2"
2076 [(set (match_operand:GPI 0 "register_operand" "=rk")
2077 (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
2079 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2080 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2081 (match_operand 3 "const_int_operand" "n")
2083 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
2084 "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
2085 [(set_attr "type" "alu_ext")]
2088 ;; zero_extend version of above
2089 (define_insn "*sub_<optab>si_multp2_uxtw"
2090 [(set (match_operand:DI 0 "register_operand" "=rk")
2092 (minus:SI (match_operand:SI 4 "register_operand" "rk")
2094 (mult:SI (match_operand:SI 1 "register_operand" "r")
2095 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2096 (match_operand 3 "const_int_operand" "n")
2098 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
2099 "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
2100 [(set_attr "type" "alu_ext")]
2103 (define_insn "sub<mode>3_carryin"
2105 (match_operand:GPI 0 "register_operand" "=r")
2106 (minus:GPI (minus:GPI
2107 (match_operand:GPI 1 "register_operand" "r")
2108 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2109 (match_operand:GPI 2 "register_operand" "r")))]
2111 "sbc\\t%<w>0, %<w>1, %<w>2"
2112 [(set_attr "type" "adc_reg")]
2115 ;; zero_extend version of the above
2116 (define_insn "*subsi3_carryin_uxtw"
2118 (match_operand:DI 0 "register_operand" "=r")
2121 (match_operand:SI 1 "register_operand" "r")
2122 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2123 (match_operand:SI 2 "register_operand" "r"))))]
2125 "sbc\\t%w0, %w1, %w2"
2126 [(set_attr "type" "adc_reg")]
2129 (define_insn "*sub_uxt<mode>_multp2"
2130 [(set (match_operand:GPI 0 "register_operand" "=rk")
2131 (minus:GPI (match_operand:GPI 4 "register_operand" "rk")
2133 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2134 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2135 (match_operand 3 "const_int_operand" "n"))))]
2136 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2138 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2139 INTVAL (operands[3])));
2140 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
2141 [(set_attr "type" "alu_ext")]
2144 ;; zero_extend version of above
2145 (define_insn "*sub_uxtsi_multp2_uxtw"
2146 [(set (match_operand:DI 0 "register_operand" "=rk")
2148 (minus:SI (match_operand:SI 4 "register_operand" "rk")
2150 (mult:SI (match_operand:SI 1 "register_operand" "r")
2151 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2152 (match_operand 3 "const_int_operand" "n")))))]
2153 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2155 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2156 INTVAL (operands[3])));
2157 return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
2158 [(set_attr "type" "alu_ext")]
2161 (define_insn_and_split "absdi2"
2162 [(set (match_operand:DI 0 "register_operand" "=&r,w")
2163 (abs:DI (match_operand:DI 1 "register_operand" "r,w")))]
2169 && GP_REGNUM_P (REGNO (operands[0]))
2170 && GP_REGNUM_P (REGNO (operands[1]))"
2173 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2174 gen_rtx_XOR (DImode,
2175 gen_rtx_ASHIFTRT (DImode,
2179 emit_insn (gen_rtx_SET (VOIDmode,
2181 gen_rtx_MINUS (DImode,
2183 gen_rtx_ASHIFTRT (DImode,
2188 [(set_attr "type" "alu_sreg")
2189 (set_attr "simd" "no,yes")]
2192 (define_insn "neg<mode>2"
2193 [(set (match_operand:GPI 0 "register_operand" "=r,w")
2194 (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
2198 neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
2199 [(set_attr "type" "alu_sreg, neon_neg<q>")
2200 (set_attr "simd" "*,yes")]
2203 ;; zero_extend version of above
2204 (define_insn "*negsi2_uxtw"
2205 [(set (match_operand:DI 0 "register_operand" "=r")
2206 (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
2209 [(set_attr "type" "alu_sreg")]
2212 (define_insn "*ngc<mode>"
2213 [(set (match_operand:GPI 0 "register_operand" "=r")
2214 (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2215 (match_operand:GPI 1 "register_operand" "r")))]
2217 "ngc\\t%<w>0, %<w>1"
2218 [(set_attr "type" "adc_reg")]
2221 (define_insn "*ngcsi_uxtw"
2222 [(set (match_operand:DI 0 "register_operand" "=r")
2224 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2225 (match_operand:SI 1 "register_operand" "r"))))]
2228 [(set_attr "type" "adc_reg")]
2231 (define_insn "*neg<mode>2_compare0"
2232 [(set (reg:CC_NZ CC_REGNUM)
2233 (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2235 (set (match_operand:GPI 0 "register_operand" "=r")
2236 (neg:GPI (match_dup 1)))]
2238 "negs\\t%<w>0, %<w>1"
2239 [(set_attr "type" "alus_sreg")]
2242 ;; zero_extend version of above
2243 (define_insn "*negsi2_compare0_uxtw"
2244 [(set (reg:CC_NZ CC_REGNUM)
2245 (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
2247 (set (match_operand:DI 0 "register_operand" "=r")
2248 (zero_extend:DI (neg:SI (match_dup 1))))]
2251 [(set_attr "type" "alus_sreg")]
2254 (define_insn "*neg_<shift><mode>3_compare0"
2255 [(set (reg:CC_NZ CC_REGNUM)
2257 (neg:GPI (ASHIFT:GPI
2258 (match_operand:GPI 1 "register_operand" "r")
2259 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2261 (set (match_operand:GPI 0 "register_operand" "=r")
2262 (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2264 "negs\\t%<w>0, %<w>1, <shift> %2"
2265 [(set_attr "type" "alus_shift_imm")]
2268 (define_insn "*neg_<shift>_<mode>2"
2269 [(set (match_operand:GPI 0 "register_operand" "=r")
2270 (neg:GPI (ASHIFT:GPI
2271 (match_operand:GPI 1 "register_operand" "r")
2272 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2274 "neg\\t%<w>0, %<w>1, <shift> %2"
2275 [(set_attr "type" "alu_shift_imm")]
2278 ;; zero_extend version of above
2279 (define_insn "*neg_<shift>_si2_uxtw"
2280 [(set (match_operand:DI 0 "register_operand" "=r")
2283 (match_operand:SI 1 "register_operand" "r")
2284 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2286 "neg\\t%w0, %w1, <shift> %2"
2287 [(set_attr "type" "alu_shift_imm")]
2290 (define_insn "*neg_mul_imm_<mode>2"
2291 [(set (match_operand:GPI 0 "register_operand" "=r")
2293 (match_operand:GPI 1 "register_operand" "r")
2294 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2296 "neg\\t%<w>0, %<w>1, lsl %p2"
2297 [(set_attr "type" "alu_shift_imm")]
2300 ;; zero_extend version of above
2301 (define_insn "*neg_mul_imm_si2_uxtw"
2302 [(set (match_operand:DI 0 "register_operand" "=r")
2305 (match_operand:SI 1 "register_operand" "r")
2306 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2308 "neg\\t%w0, %w1, lsl %p2"
2309 [(set_attr "type" "alu_shift_imm")]
2312 (define_insn "mul<mode>3"
2313 [(set (match_operand:GPI 0 "register_operand" "=r")
2314 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2315 (match_operand:GPI 2 "register_operand" "r")))]
2317 "mul\\t%<w>0, %<w>1, %<w>2"
2318 [(set_attr "type" "mul")]
2321 ;; zero_extend version of above
2322 (define_insn "*mulsi3_uxtw"
2323 [(set (match_operand:DI 0 "register_operand" "=r")
2325 (mult:SI (match_operand:SI 1 "register_operand" "r")
2326 (match_operand:SI 2 "register_operand" "r"))))]
2328 "mul\\t%w0, %w1, %w2"
2329 [(set_attr "type" "mul")]
2332 (define_insn "madd<mode>"
2333 [(set (match_operand:GPI 0 "register_operand" "=r")
2334 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2335 (match_operand:GPI 2 "register_operand" "r"))
2336 (match_operand:GPI 3 "register_operand" "r")))]
2338 "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2339 [(set_attr "type" "mla")]
2342 ;; zero_extend version of above
2343 (define_insn "*maddsi_uxtw"
2344 [(set (match_operand:DI 0 "register_operand" "=r")
2346 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2347 (match_operand:SI 2 "register_operand" "r"))
2348 (match_operand:SI 3 "register_operand" "r"))))]
2350 "madd\\t%w0, %w1, %w2, %w3"
2351 [(set_attr "type" "mla")]
2354 (define_insn "*msub<mode>"
2355 [(set (match_operand:GPI 0 "register_operand" "=r")
2356 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2357 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2358 (match_operand:GPI 2 "register_operand" "r"))))]
2361 "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2362 [(set_attr "type" "mla")]
2365 ;; zero_extend version of above
2366 (define_insn "*msubsi_uxtw"
2367 [(set (match_operand:DI 0 "register_operand" "=r")
2369 (minus:SI (match_operand:SI 3 "register_operand" "r")
2370 (mult:SI (match_operand:SI 1 "register_operand" "r")
2371 (match_operand:SI 2 "register_operand" "r")))))]
2374 "msub\\t%w0, %w1, %w2, %w3"
2375 [(set_attr "type" "mla")]
2378 (define_insn "*mul<mode>_neg"
2379 [(set (match_operand:GPI 0 "register_operand" "=r")
2380 (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2381 (match_operand:GPI 2 "register_operand" "r")))]
2384 "mneg\\t%<w>0, %<w>1, %<w>2"
2385 [(set_attr "type" "mul")]
2388 ;; zero_extend version of above
2389 (define_insn "*mulsi_neg_uxtw"
2390 [(set (match_operand:DI 0 "register_operand" "=r")
2392 (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2393 (match_operand:SI 2 "register_operand" "r"))))]
2396 "mneg\\t%w0, %w1, %w2"
2397 [(set_attr "type" "mul")]
2400 (define_insn "<su_optab>mulsidi3"
2401 [(set (match_operand:DI 0 "register_operand" "=r")
2402 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2403 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2405 "<su>mull\\t%0, %w1, %w2"
2406 [(set_attr "type" "<su>mull")]
2409 (define_insn "<su_optab>maddsidi4"
2410 [(set (match_operand:DI 0 "register_operand" "=r")
2412 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2413 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2414 (match_operand:DI 3 "register_operand" "r")))]
2416 "<su>maddl\\t%0, %w1, %w2, %3"
2417 [(set_attr "type" "<su>mlal")]
2420 (define_insn "<su_optab>msubsidi4"
2421 [(set (match_operand:DI 0 "register_operand" "=r")
2423 (match_operand:DI 3 "register_operand" "r")
2424 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2426 (match_operand:SI 2 "register_operand" "r")))))]
2428 "<su>msubl\\t%0, %w1, %w2, %3"
2429 [(set_attr "type" "<su>mlal")]
2432 (define_insn "*<su_optab>mulsidi_neg"
2433 [(set (match_operand:DI 0 "register_operand" "=r")
2435 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2436 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2438 "<su>mnegl\\t%0, %w1, %w2"
2439 [(set_attr "type" "<su>mull")]
2442 (define_expand "<su_optab>mulditi3"
2443 [(set (match_operand:TI 0 "register_operand")
2444 (mult:TI (ANY_EXTEND:TI (match_operand:DI 1 "register_operand"))
2445 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand"))))]
2448 rtx low = gen_reg_rtx (DImode);
2449 emit_insn (gen_muldi3 (low, operands[1], operands[2]));
2451 rtx high = gen_reg_rtx (DImode);
2452 emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2]));
2454 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2455 emit_move_insn (gen_highpart (DImode, operands[0]), high);
2459 ;; The default expansion of multi3 using umuldi3_highpart will perform
2460 ;; the additions in an order that fails to combine into two madd insns.
2461 (define_expand "multi3"
2462 [(set (match_operand:TI 0 "register_operand")
2463 (mult:TI (match_operand:TI 1 "register_operand")
2464 (match_operand:TI 2 "register_operand")))]
2467 rtx l0 = gen_reg_rtx (DImode);
2468 rtx l1 = gen_lowpart (DImode, operands[1]);
2469 rtx l2 = gen_lowpart (DImode, operands[2]);
2470 rtx h0 = gen_reg_rtx (DImode);
2471 rtx h1 = gen_highpart (DImode, operands[1]);
2472 rtx h2 = gen_highpart (DImode, operands[2]);
2474 emit_insn (gen_muldi3 (l0, l1, l2));
2475 emit_insn (gen_umuldi3_highpart (h0, l1, l2));
2476 emit_insn (gen_madddi (h0, h1, l2, h0));
2477 emit_insn (gen_madddi (h0, l1, h2, h0));
2479 emit_move_insn (gen_lowpart (DImode, operands[0]), l0);
2480 emit_move_insn (gen_highpart (DImode, operands[0]), h0);
2484 (define_insn "<su>muldi3_highpart"
2485 [(set (match_operand:DI 0 "register_operand" "=r")
2489 (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2490 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2493 "<su>mulh\\t%0, %1, %2"
2494 [(set_attr "type" "<su>mull")]
2497 (define_insn "<su_optab>div<mode>3"
2498 [(set (match_operand:GPI 0 "register_operand" "=r")
2499 (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2500 (match_operand:GPI 2 "register_operand" "r")))]
2502 "<su>div\\t%<w>0, %<w>1, %<w>2"
2503 [(set_attr "type" "<su>div")]
2506 ;; zero_extend version of above
2507 (define_insn "*<su_optab>divsi3_uxtw"
2508 [(set (match_operand:DI 0 "register_operand" "=r")
2510 (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2511 (match_operand:SI 2 "register_operand" "r"))))]
2513 "<su>div\\t%w0, %w1, %w2"
2514 [(set_attr "type" "<su>div")]
2517 ;; -------------------------------------------------------------------
2519 ;; -------------------------------------------------------------------
2521 (define_insn "*cmp<mode>"
2522 [(set (reg:CC CC_REGNUM)
2523 (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2524 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2530 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
2533 (define_insn "*cmp<mode>"
2534 [(set (reg:CCFP CC_REGNUM)
2535 (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2536 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2540 fcmp\\t%<s>0, %<s>1"
2541 [(set_attr "type" "fcmp<s>")]
2544 (define_insn "*cmpe<mode>"
2545 [(set (reg:CCFPE CC_REGNUM)
2546 (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2547 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2551 fcmpe\\t%<s>0, %<s>1"
2552 [(set_attr "type" "fcmp<s>")]
2555 (define_insn "*cmp_swp_<shift>_reg<mode>"
2556 [(set (reg:CC_SWP CC_REGNUM)
2557 (compare:CC_SWP (ASHIFT:GPI
2558 (match_operand:GPI 0 "register_operand" "r")
2559 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2560 (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2562 "cmp\\t%<w>2, %<w>0, <shift> %1"
2563 [(set_attr "type" "alus_shift_imm")]
2566 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2567 [(set (reg:CC_SWP CC_REGNUM)
2568 (compare:CC_SWP (ANY_EXTEND:GPI
2569 (match_operand:ALLX 0 "register_operand" "r"))
2570 (match_operand:GPI 1 "register_operand" "r")))]
2572 "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2573 [(set_attr "type" "alus_ext")]
2576 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2577 [(set (reg:CC_SWP CC_REGNUM)
2578 (compare:CC_SWP (ashift:GPI
2580 (match_operand:ALLX 0 "register_operand" "r"))
2581 (match_operand 1 "aarch64_imm3" "Ui3"))
2582 (match_operand:GPI 2 "register_operand" "r")))]
2584 "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2585 [(set_attr "type" "alus_ext")]
2588 ;; -------------------------------------------------------------------
2589 ;; Store-flag and conditional select insns
2590 ;; -------------------------------------------------------------------
2592 (define_expand "cstore<mode>4"
2593 [(set (match_operand:SI 0 "register_operand" "")
2594 (match_operator:SI 1 "aarch64_comparison_operator"
2595 [(match_operand:GPI 2 "register_operand" "")
2596 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2599 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2601 operands[3] = const0_rtx;
2605 (define_expand "cstorecc4"
2606 [(set (match_operand:SI 0 "register_operand")
2607 (match_operator 1 "aarch64_comparison_operator"
2608 [(match_operand 2 "ccmp_cc_register")
2609 (match_operand 3 "const0_operand")]))]
2612 emit_insn (gen_rtx_SET (SImode, operands[0], operands[1]));
2617 (define_expand "cstore<mode>4"
2618 [(set (match_operand:SI 0 "register_operand" "")
2619 (match_operator:SI 1 "aarch64_comparison_operator"
2620 [(match_operand:GPF 2 "register_operand" "")
2621 (match_operand:GPF 3 "register_operand" "")]))]
2624 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2626 operands[3] = const0_rtx;
2630 (define_insn "*cstore<mode>_insn"
2631 [(set (match_operand:ALLI 0 "register_operand" "=r")
2632 (match_operator:ALLI 1 "aarch64_comparison_operator"
2633 [(match_operand 2 "cc_register" "") (const_int 0)]))]
2636 [(set_attr "type" "csel")]
2639 ;; zero_extend version of the above
2640 (define_insn "*cstoresi_insn_uxtw"
2641 [(set (match_operand:DI 0 "register_operand" "=r")
2643 (match_operator:SI 1 "aarch64_comparison_operator"
2644 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2647 [(set_attr "type" "csel")]
2650 (define_insn "cstore<mode>_neg"
2651 [(set (match_operand:ALLI 0 "register_operand" "=r")
2652 (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2653 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2655 "csetm\\t%<w>0, %m1"
2656 [(set_attr "type" "csel")]
2659 ;; zero_extend version of the above
2660 (define_insn "*cstoresi_neg_uxtw"
2661 [(set (match_operand:DI 0 "register_operand" "=r")
2663 (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2664 [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2667 [(set_attr "type" "csel")]
2670 (define_expand "cmov<mode>6"
2671 [(set (match_operand:GPI 0 "register_operand" "")
2673 (match_operator 1 "aarch64_comparison_operator"
2674 [(match_operand:GPI 2 "register_operand" "")
2675 (match_operand:GPI 3 "aarch64_plus_operand" "")])
2676 (match_operand:GPI 4 "register_operand" "")
2677 (match_operand:GPI 5 "register_operand" "")))]
2680 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2682 operands[3] = const0_rtx;
2686 (define_expand "cmov<mode>6"
2687 [(set (match_operand:GPF 0 "register_operand" "")
2689 (match_operator 1 "aarch64_comparison_operator"
2690 [(match_operand:GPF 2 "register_operand" "")
2691 (match_operand:GPF 3 "register_operand" "")])
2692 (match_operand:GPF 4 "register_operand" "")
2693 (match_operand:GPF 5 "register_operand" "")))]
2696 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2698 operands[3] = const0_rtx;
2702 (define_insn "*cmov<mode>_insn"
2703 [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2705 (match_operator 1 "aarch64_comparison_operator"
2706 [(match_operand 2 "cc_register" "") (const_int 0)])
2707 (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2708 (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2709 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2710 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2711 ;; Final two alternatives should be unreachable, but included for completeness
2713 csel\\t%<w>0, %<w>3, %<w>4, %m1
2714 csinv\\t%<w>0, %<w>3, <w>zr, %m1
2715 csinv\\t%<w>0, %<w>4, <w>zr, %M1
2716 csinc\\t%<w>0, %<w>3, <w>zr, %m1
2717 csinc\\t%<w>0, %<w>4, <w>zr, %M1
2720 [(set_attr "type" "csel")]
2723 ;; zero_extend version of above
2724 (define_insn "*cmovsi_insn_uxtw"
2725 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2728 (match_operator 1 "aarch64_comparison_operator"
2729 [(match_operand 2 "cc_register" "") (const_int 0)])
2730 (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2731 (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2732 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2733 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2734 ;; Final two alternatives should be unreachable, but included for completeness
2736 csel\\t%w0, %w3, %w4, %m1
2737 csinv\\t%w0, %w3, wzr, %m1
2738 csinv\\t%w0, %w4, wzr, %M1
2739 csinc\\t%w0, %w3, wzr, %m1
2740 csinc\\t%w0, %w4, wzr, %M1
2743 [(set_attr "type" "csel")]
2746 (define_insn "*cmov<mode>_insn"
2747 [(set (match_operand:GPF 0 "register_operand" "=w")
2749 (match_operator 1 "aarch64_comparison_operator"
2750 [(match_operand 2 "cc_register" "") (const_int 0)])
2751 (match_operand:GPF 3 "register_operand" "w")
2752 (match_operand:GPF 4 "register_operand" "w")))]
2754 "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2755 [(set_attr "type" "fcsel")]
2758 (define_expand "mov<mode>cc"
2759 [(set (match_operand:ALLI 0 "register_operand" "")
2760 (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2761 (match_operand:ALLI 2 "register_operand" "")
2762 (match_operand:ALLI 3 "register_operand" "")))]
2765 enum rtx_code code = GET_CODE (operands[1]);
2767 if (code == UNEQ || code == LTGT)
2770 if (!ccmp_cc_register (XEXP (operands[1], 0),
2771 GET_MODE (XEXP (operands[1], 0))))
2774 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2775 XEXP (operands[1], 1));
2776 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2781 (define_expand "mov<GPF:mode><GPI:mode>cc"
2782 [(set (match_operand:GPI 0 "register_operand" "")
2783 (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2784 (match_operand:GPF 2 "register_operand" "")
2785 (match_operand:GPF 3 "register_operand" "")))]
2789 enum rtx_code code = GET_CODE (operands[1]);
2791 if (code == UNEQ || code == LTGT)
2794 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2795 XEXP (operands[1], 1));
2796 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2800 (define_expand "mov<mode>cc"
2801 [(set (match_operand:GPF 0 "register_operand" "")
2802 (if_then_else:GPF (match_operand 1 "aarch64_comparison_operator" "")
2803 (match_operand:GPF 2 "register_operand" "")
2804 (match_operand:GPF 3 "register_operand" "")))]
2808 enum rtx_code code = GET_CODE (operands[1]);
2810 if (code == UNEQ || code == LTGT)
2813 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2814 XEXP (operands[1], 1));
2815 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2820 ;; CRC32 instructions.
2821 (define_insn "aarch64_<crc_variant>"
2822 [(set (match_operand:SI 0 "register_operand" "=r")
2823 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2824 (match_operand:<crc_mode> 2 "register_operand" "r")]
2828 if (GET_MODE_BITSIZE (GET_MODE (operands[2])) >= 64)
2829 return "<crc_variant>\\t%w0, %w1, %x2";
2831 return "<crc_variant>\\t%w0, %w1, %w2";
2833 [(set_attr "type" "crc")]
2836 (define_insn "*csinc2<mode>_insn"
2837 [(set (match_operand:GPI 0 "register_operand" "=r")
2838 (plus:GPI (match_operand 2 "aarch64_comparison_operation" "")
2839 (match_operand:GPI 1 "register_operand" "r")))]
2841 "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2842 [(set_attr "type" "csel")]
2845 (define_insn "csinc3<mode>_insn"
2846 [(set (match_operand:GPI 0 "register_operand" "=r")
2848 (match_operand 1 "aarch64_comparison_operation" "")
2849 (plus:GPI (match_operand:GPI 2 "register_operand" "r")
2851 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2853 "csinc\\t%<w>0, %<w>3, %<w>2, %M1"
2854 [(set_attr "type" "csel")]
2857 (define_insn "*csinv3<mode>_insn"
2858 [(set (match_operand:GPI 0 "register_operand" "=r")
2860 (match_operand 1 "aarch64_comparison_operation" "")
2861 (not:GPI (match_operand:GPI 2 "register_operand" "r"))
2862 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2864 "csinv\\t%<w>0, %<w>3, %<w>2, %M1"
2865 [(set_attr "type" "csel")]
2868 (define_insn "*csneg3<mode>_insn"
2869 [(set (match_operand:GPI 0 "register_operand" "=r")
2871 (match_operand 1 "aarch64_comparison_operation" "")
2872 (neg:GPI (match_operand:GPI 2 "register_operand" "r"))
2873 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2875 "csneg\\t%<w>0, %<w>3, %<w>2, %M1"
2876 [(set_attr "type" "csel")]
2879 ;; -------------------------------------------------------------------
2880 ;; Logical operations
2881 ;; -------------------------------------------------------------------
2883 (define_insn "<optab><mode>3"
2884 [(set (match_operand:GPI 0 "register_operand" "=r,rk,w")
2885 (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r,w")
2886 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>,w")))]
2889 <logical>\\t%<w>0, %<w>1, %<w>2
2890 <logical>\\t%<w>0, %<w>1, %<w>2
2891 <logical>\\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
2892 [(set_attr "type" "logic_reg,logic_imm,neon_logic")
2893 (set_attr "simd" "*,*,yes")]
2896 ;; zero_extend version of above
2897 (define_insn "*<optab>si3_uxtw"
2898 [(set (match_operand:DI 0 "register_operand" "=r,rk")
2900 (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2901 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2903 "<logical>\\t%w0, %w1, %w2"
2904 [(set_attr "type" "logic_reg,logic_imm")]
2907 (define_insn "*and<mode>3_compare0"
2908 [(set (reg:CC_NZ CC_REGNUM)
2910 (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2911 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2913 (set (match_operand:GPI 0 "register_operand" "=r,r")
2914 (and:GPI (match_dup 1) (match_dup 2)))]
2916 "ands\\t%<w>0, %<w>1, %<w>2"
2917 [(set_attr "type" "logics_reg,logics_imm")]
2920 ;; zero_extend version of above
2921 (define_insn "*andsi3_compare0_uxtw"
2922 [(set (reg:CC_NZ CC_REGNUM)
2924 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2925 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2927 (set (match_operand:DI 0 "register_operand" "=r,r")
2928 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2930 "ands\\t%w0, %w1, %w2"
2931 [(set_attr "type" "logics_reg,logics_imm")]
2934 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2935 [(set (reg:CC_NZ CC_REGNUM)
2938 (match_operand:GPI 1 "register_operand" "r")
2939 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2940 (match_operand:GPI 3 "register_operand" "r"))
2942 (set (match_operand:GPI 0 "register_operand" "=r")
2943 (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2945 "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2946 [(set_attr "type" "logics_shift_imm")]
2949 ;; zero_extend version of above
2950 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2951 [(set (reg:CC_NZ CC_REGNUM)
2954 (match_operand:SI 1 "register_operand" "r")
2955 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2956 (match_operand:SI 3 "register_operand" "r"))
2958 (set (match_operand:DI 0 "register_operand" "=r")
2959 (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2962 "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2963 [(set_attr "type" "logics_shift_imm")]
2966 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2967 [(set (match_operand:GPI 0 "register_operand" "=r")
2968 (LOGICAL:GPI (SHIFT:GPI
2969 (match_operand:GPI 1 "register_operand" "r")
2970 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2971 (match_operand:GPI 3 "register_operand" "r")))]
2973 "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2974 [(set_attr "type" "logic_shift_imm")]
2977 (define_insn "*<optab>_rol<mode>3"
2978 [(set (match_operand:GPI 0 "register_operand" "=r")
2979 (LOGICAL:GPI (rotate:GPI
2980 (match_operand:GPI 1 "register_operand" "r")
2981 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2982 (match_operand:GPI 3 "register_operand" "r")))]
2984 "<logical>\\t%<w>0, %<w>3, %<w>1, ror (<sizen> - %2)"
2985 [(set_attr "type" "logic_shift_imm")]
2988 ;; zero_extend versions of above
2989 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
2990 [(set (match_operand:DI 0 "register_operand" "=r")
2992 (LOGICAL:SI (SHIFT:SI
2993 (match_operand:SI 1 "register_operand" "r")
2994 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2995 (match_operand:SI 3 "register_operand" "r"))))]
2997 "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2998 [(set_attr "type" "logic_shift_imm")]
3001 (define_insn "*<optab>_rolsi3_uxtw"
3002 [(set (match_operand:DI 0 "register_operand" "=r")
3004 (LOGICAL:SI (rotate:SI
3005 (match_operand:SI 1 "register_operand" "r")
3006 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
3007 (match_operand:SI 3 "register_operand" "r"))))]
3009 "<logical>\\t%w0, %w3, %w1, ror (32 - %2)"
3010 [(set_attr "type" "logic_shift_imm")]
3013 (define_insn "one_cmpl<mode>2"
3014 [(set (match_operand:GPI 0 "register_operand" "=r,w")
3015 (not:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
3020 [(set_attr "type" "logic_reg,neon_logic")
3021 (set_attr "simd" "*,yes")]
3024 (define_insn "*one_cmpl_<optab><mode>2"
3025 [(set (match_operand:GPI 0 "register_operand" "=r")
3026 (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
3027 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
3029 "mvn\\t%<w>0, %<w>1, <shift> %2"
3030 [(set_attr "type" "logic_shift_imm")]
3033 ;; Binary logical operators negating one operand, i.e. (a & !b), (a | !b).
3035 (define_insn "*<NLOGICAL:optab>_one_cmpl<mode>3"
3036 [(set (match_operand:GPI 0 "register_operand" "=r,w")
3037 (NLOGICAL:GPI (not:GPI (match_operand:GPI 1 "register_operand" "r,w"))
3038 (match_operand:GPI 2 "register_operand" "r,w")))]
3041 <NLOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1
3042 <NLOGICAL:nlogical>\\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>"
3043 [(set_attr "type" "logic_reg,neon_logic")
3044 (set_attr "simd" "*,yes")]
3047 ;; (xor (not a) b) is simplify_rtx-ed down to (not (xor a b)).
3048 ;; eon does not operate on SIMD registers so the vector variant must be split.
3049 (define_insn_and_split "*xor_one_cmpl<mode>3"
3050 [(set (match_operand:GPI 0 "register_operand" "=r,w")
3051 (not:GPI (xor:GPI (match_operand:GPI 1 "register_operand" "r,?w")
3052 (match_operand:GPI 2 "register_operand" "r,w"))))]
3054 "eon\\t%<w>0, %<w>1, %<w>2" ;; For GPR registers (only).
3055 "reload_completed && (which_alternative == 1)" ;; For SIMD registers.
3056 [(set (match_operand:GPI 0 "register_operand" "=w")
3057 (xor:GPI (match_operand:GPI 1 "register_operand" "w")
3058 (match_operand:GPI 2 "register_operand" "w")))
3059 (set (match_dup 0) (not:GPI (match_dup 0)))]
3061 [(set_attr "type" "logic_reg,multiple")
3062 (set_attr "simd" "*,yes")]
3065 (define_insn "*and_one_cmpl<mode>3_compare0"
3066 [(set (reg:CC_NZ CC_REGNUM)
3069 (match_operand:GPI 1 "register_operand" "r"))
3070 (match_operand:GPI 2 "register_operand" "r"))
3072 (set (match_operand:GPI 0 "register_operand" "=r")
3073 (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
3075 "bics\\t%<w>0, %<w>2, %<w>1"
3076 [(set_attr "type" "logics_reg")]
3079 ;; zero_extend version of above
3080 (define_insn "*and_one_cmplsi3_compare0_uxtw"
3081 [(set (reg:CC_NZ CC_REGNUM)
3084 (match_operand:SI 1 "register_operand" "r"))
3085 (match_operand:SI 2 "register_operand" "r"))
3087 (set (match_operand:DI 0 "register_operand" "=r")
3088 (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
3090 "bics\\t%w0, %w2, %w1"
3091 [(set_attr "type" "logics_reg")]
3094 (define_insn "*and_one_cmpl<mode>3_compare0_no_reuse"
3095 [(set (reg:CC_NZ CC_REGNUM)
3098 (match_operand:GPI 0 "register_operand" "r"))
3099 (match_operand:GPI 1 "register_operand" "r"))
3102 "bics\\t<w>zr, %<w>1, %<w>0"
3103 [(set_attr "type" "logics_reg")]
3106 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
3107 [(set (match_operand:GPI 0 "register_operand" "=r")
3108 (LOGICAL:GPI (not:GPI
3110 (match_operand:GPI 1 "register_operand" "r")
3111 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
3112 (match_operand:GPI 3 "register_operand" "r")))]
3114 "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3115 [(set_attr "type" "logics_shift_imm")]
3118 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
3119 [(set (reg:CC_NZ CC_REGNUM)
3123 (match_operand:GPI 1 "register_operand" "r")
3124 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
3125 (match_operand:GPI 3 "register_operand" "r"))
3127 (set (match_operand:GPI 0 "register_operand" "=r")
3130 (match_dup 1) (match_dup 2))) (match_dup 3)))]
3132 "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
3133 [(set_attr "type" "logics_shift_imm")]
3136 ;; zero_extend version of above
3137 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
3138 [(set (reg:CC_NZ CC_REGNUM)
3142 (match_operand:SI 1 "register_operand" "r")
3143 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
3144 (match_operand:SI 3 "register_operand" "r"))
3146 (set (match_operand:DI 0 "register_operand" "=r")
3147 (zero_extend:DI (and:SI
3149 (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
3151 "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3152 [(set_attr "type" "logics_shift_imm")]
3155 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0_no_reuse"
3156 [(set (reg:CC_NZ CC_REGNUM)
3160 (match_operand:GPI 0 "register_operand" "r")
3161 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n")))
3162 (match_operand:GPI 2 "register_operand" "r"))
3165 "bics\\t<w>zr, %<w>2, %<w>0, <SHIFT:shift> %1"
3166 [(set_attr "type" "logics_shift_imm")]
3169 (define_insn "clz<mode>2"
3170 [(set (match_operand:GPI 0 "register_operand" "=r")
3171 (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
3173 "clz\\t%<w>0, %<w>1"
3174 [(set_attr "type" "clz")]
3177 (define_expand "ffs<mode>2"
3178 [(match_operand:GPI 0 "register_operand")
3179 (match_operand:GPI 1 "register_operand")]
3182 rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
3183 rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
3185 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3186 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3187 emit_insn (gen_csinc3<mode>_insn (operands[0], x, operands[0], const0_rtx));
3192 (define_insn "clrsb<mode>2"
3193 [(set (match_operand:GPI 0 "register_operand" "=r")
3194 (clrsb:GPI (match_operand:GPI 1 "register_operand" "r")))]
3196 "cls\\t%<w>0, %<w>1"
3197 [(set_attr "type" "clz")]
3200 (define_insn "rbit<mode>2"
3201 [(set (match_operand:GPI 0 "register_operand" "=r")
3202 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
3204 "rbit\\t%<w>0, %<w>1"
3205 [(set_attr "type" "rbit")]
3208 (define_expand "ctz<mode>2"
3209 [(match_operand:GPI 0 "register_operand")
3210 (match_operand:GPI 1 "register_operand")]
3213 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3214 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3219 (define_insn "*and<mode>3nr_compare0"
3220 [(set (reg:CC_NZ CC_REGNUM)
3222 (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
3223 (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
3226 "tst\\t%<w>0, %<w>1"
3227 [(set_attr "type" "logics_reg")]
3230 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
3231 [(set (reg:CC_NZ CC_REGNUM)
3234 (match_operand:GPI 0 "register_operand" "r")
3235 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
3236 (match_operand:GPI 2 "register_operand" "r"))
3239 "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
3240 [(set_attr "type" "logics_shift_imm")]
3243 ;; -------------------------------------------------------------------
3245 ;; -------------------------------------------------------------------
3247 (define_expand "<optab><mode>3"
3248 [(set (match_operand:GPI 0 "register_operand")
3249 (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
3250 (match_operand:QI 2 "nonmemory_operand")))]
3253 if (CONST_INT_P (operands[2]))
3255 operands[2] = GEN_INT (INTVAL (operands[2])
3256 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3258 if (operands[2] == const0_rtx)
3260 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3267 (define_expand "ashl<mode>3"
3268 [(set (match_operand:SHORT 0 "register_operand")
3269 (ashift:SHORT (match_operand:SHORT 1 "register_operand")
3270 (match_operand:QI 2 "nonmemory_operand")))]
3273 if (CONST_INT_P (operands[2]))
3275 operands[2] = GEN_INT (INTVAL (operands[2])
3276 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3278 if (operands[2] == const0_rtx)
3280 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3287 (define_expand "rotr<mode>3"
3288 [(set (match_operand:GPI 0 "register_operand")
3289 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3290 (match_operand:QI 2 "nonmemory_operand")))]
3293 if (CONST_INT_P (operands[2]))
3295 operands[2] = GEN_INT (INTVAL (operands[2])
3296 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3298 if (operands[2] == const0_rtx)
3300 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3307 (define_expand "rotl<mode>3"
3308 [(set (match_operand:GPI 0 "register_operand")
3309 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3310 (match_operand:QI 2 "nonmemory_operand")))]
3313 /* (SZ - cnt) % SZ == -cnt % SZ */
3314 if (CONST_INT_P (operands[2]))
3316 operands[2] = GEN_INT ((-INTVAL (operands[2]))
3317 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3318 if (operands[2] == const0_rtx)
3320 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3325 operands[2] = expand_simple_unop (QImode, NEG, operands[2],
3330 ;; Logical left shift using SISD or Integer instruction
3331 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
3332 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3334 (match_operand:GPI 1 "register_operand" "w,w,r")
3335 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3338 shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3339 ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
3340 lsl\t%<w>0, %<w>1, %<w>2"
3341 [(set_attr "simd" "yes,yes,no")
3342 (set_attr "type" "neon_shift_imm<q>, neon_shift_reg<q>,shift_reg")]
3345 ;; Logical right shift using SISD or Integer instruction
3346 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3347 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3349 (match_operand:GPI 1 "register_operand" "w,w,r")
3350 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3353 ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3355 lsr\t%<w>0, %<w>1, %<w>2"
3356 [(set_attr "simd" "yes,yes,no")
3357 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")]
3361 [(set (match_operand:DI 0 "aarch64_simd_register")
3363 (match_operand:DI 1 "aarch64_simd_register")
3364 (match_operand:QI 2 "aarch64_simd_register")))]
3365 "TARGET_SIMD && reload_completed"
3367 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3369 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_USHL))]
3374 [(set (match_operand:SI 0 "aarch64_simd_register")
3376 (match_operand:SI 1 "aarch64_simd_register")
3377 (match_operand:QI 2 "aarch64_simd_register")))]
3378 "TARGET_SIMD && reload_completed"
3380 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3382 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_USHL_2S))]
3386 ;; Arithmetic right shift using SISD or Integer instruction
3387 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3388 [(set (match_operand:GPI 0 "register_operand" "=w,&w,&w,r")
3390 (match_operand:GPI 1 "register_operand" "w,w,w,r")
3391 (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,0,rUs<cmode>")))]
3394 sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3397 asr\t%<w>0, %<w>1, %<w>2"
3398 [(set_attr "simd" "yes,yes,yes,no")
3399 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>,shift_reg")]
3403 [(set (match_operand:DI 0 "aarch64_simd_register")
3405 (match_operand:DI 1 "aarch64_simd_register")
3406 (match_operand:QI 2 "aarch64_simd_register")))]
3407 "TARGET_SIMD && reload_completed"
3409 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3411 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_SSHL))]
3413 operands[3] = gen_lowpart (QImode, operands[0]);
3418 [(set (match_operand:SI 0 "aarch64_simd_register")
3420 (match_operand:SI 1 "aarch64_simd_register")
3421 (match_operand:QI 2 "aarch64_simd_register")))]
3422 "TARGET_SIMD && reload_completed"
3424 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3426 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_SSHL_2S))]
3428 operands[3] = gen_lowpart (QImode, operands[0]);
3432 (define_insn "*aarch64_sisd_ushl"
3433 [(set (match_operand:DI 0 "register_operand" "=w")
3434 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3435 (match_operand:QI 2 "register_operand" "w")]
3438 "ushl\t%d0, %d1, %d2"
3439 [(set_attr "simd" "yes")
3440 (set_attr "type" "neon_shift_reg")]
3443 (define_insn "*aarch64_ushl_2s"
3444 [(set (match_operand:SI 0 "register_operand" "=w")
3445 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3446 (match_operand:QI 2 "register_operand" "w")]
3449 "ushl\t%0.2s, %1.2s, %2.2s"
3450 [(set_attr "simd" "yes")
3451 (set_attr "type" "neon_shift_reg")]
3454 (define_insn "*aarch64_sisd_sshl"
3455 [(set (match_operand:DI 0 "register_operand" "=w")
3456 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3457 (match_operand:QI 2 "register_operand" "w")]
3460 "sshl\t%d0, %d1, %d2"
3461 [(set_attr "simd" "yes")
3462 (set_attr "type" "neon_shift_reg")]
3465 (define_insn "*aarch64_sshl_2s"
3466 [(set (match_operand:SI 0 "register_operand" "=w")
3467 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3468 (match_operand:QI 2 "register_operand" "w")]
3471 "sshl\t%0.2s, %1.2s, %2.2s"
3472 [(set_attr "simd" "yes")
3473 (set_attr "type" "neon_shift_reg")]
3476 (define_insn "*aarch64_sisd_neg_qi"
3477 [(set (match_operand:QI 0 "register_operand" "=w")
3478 (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3482 [(set_attr "simd" "yes")
3483 (set_attr "type" "neon_neg")]
3487 (define_insn "*ror<mode>3_insn"
3488 [(set (match_operand:GPI 0 "register_operand" "=r")
3490 (match_operand:GPI 1 "register_operand" "r")
3491 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3493 "ror\\t%<w>0, %<w>1, %<w>2"
3494 [(set_attr "type" "shift_reg")]
3497 ;; zero_extend version of above
3498 (define_insn "*<optab>si3_insn_uxtw"
3499 [(set (match_operand:DI 0 "register_operand" "=r")
3500 (zero_extend:DI (SHIFT:SI
3501 (match_operand:SI 1 "register_operand" "r")
3502 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3504 "<shift>\\t%w0, %w1, %w2"
3505 [(set_attr "type" "shift_reg")]
3508 (define_insn "*ashl<mode>3_insn"
3509 [(set (match_operand:SHORT 0 "register_operand" "=r")
3510 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3511 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
3513 "lsl\\t%<w>0, %<w>1, %<w>2"
3514 [(set_attr "type" "shift_reg")]
3517 (define_insn "*<optab><mode>3_insn"
3518 [(set (match_operand:SHORT 0 "register_operand" "=r")
3519 (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3520 (match_operand 2 "const_int_operand" "n")))]
3521 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3523 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3524 return "<bfshift>\t%w0, %w1, %2, %3";
3526 [(set_attr "type" "bfm")]
3529 (define_insn "*extr<mode>5_insn"
3530 [(set (match_operand:GPI 0 "register_operand" "=r")
3531 (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3532 (match_operand 3 "const_int_operand" "n"))
3533 (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3534 (match_operand 4 "const_int_operand" "n"))))]
3535 "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3536 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3537 "extr\\t%<w>0, %<w>1, %<w>2, %4"
3538 [(set_attr "type" "shift_imm")]
3541 ;; zero_extend version of the above
3542 (define_insn "*extrsi5_insn_uxtw"
3543 [(set (match_operand:DI 0 "register_operand" "=r")
3545 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3546 (match_operand 3 "const_int_operand" "n"))
3547 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3548 (match_operand 4 "const_int_operand" "n")))))]
3549 "UINTVAL (operands[3]) < 32 &&
3550 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3551 "extr\\t%w0, %w1, %w2, %4"
3552 [(set_attr "type" "shift_imm")]
3555 (define_insn "*ror<mode>3_insn"
3556 [(set (match_operand:GPI 0 "register_operand" "=r")
3557 (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3558 (match_operand 2 "const_int_operand" "n")))]
3559 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3561 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3562 return "ror\\t%<w>0, %<w>1, %3";
3564 [(set_attr "type" "shift_imm")]
3567 ;; zero_extend version of the above
3568 (define_insn "*rorsi3_insn_uxtw"
3569 [(set (match_operand:DI 0 "register_operand" "=r")
3571 (rotate:SI (match_operand:SI 1 "register_operand" "r")
3572 (match_operand 2 "const_int_operand" "n"))))]
3573 "UINTVAL (operands[2]) < 32"
3575 operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3576 return "ror\\t%w0, %w1, %3";
3578 [(set_attr "type" "shift_imm")]
3581 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3582 [(set (match_operand:GPI 0 "register_operand" "=r")
3584 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3585 (match_operand 2 "const_int_operand" "n"))))]
3586 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3588 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3589 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3591 [(set_attr "type" "bfm")]
3594 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3595 [(set (match_operand:GPI 0 "register_operand" "=r")
3597 (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3598 (match_operand 2 "const_int_operand" "n"))))]
3599 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3601 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3602 return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3604 [(set_attr "type" "bfm")]
3607 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3608 [(set (match_operand:GPI 0 "register_operand" "=r")
3610 (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3611 (match_operand 2 "const_int_operand" "n"))))]
3612 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3614 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3615 return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3617 [(set_attr "type" "bfm")]
3620 ;; -------------------------------------------------------------------
3622 ;; -------------------------------------------------------------------
3624 (define_expand "<optab>"
3625 [(set (match_operand:DI 0 "register_operand" "=r")
3626 (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3627 (match_operand 2 "const_int_operand" "n")
3628 (match_operand 3 "const_int_operand" "n")))]
3633 (define_insn "*<optab><mode>"
3634 [(set (match_operand:GPI 0 "register_operand" "=r")
3635 (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3636 (match_operand 2 "const_int_operand" "n")
3637 (match_operand 3 "const_int_operand" "n")))]
3639 "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3640 [(set_attr "type" "bfm")]
3643 ;; Bitfield Insert (insv)
3644 (define_expand "insv<mode>"
3645 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3646 (match_operand 1 "const_int_operand")
3647 (match_operand 2 "const_int_operand"))
3648 (match_operand:GPI 3 "general_operand"))]
3651 unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3652 unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3653 rtx value = operands[3];
3655 if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3658 if (CONST_INT_P (value))
3660 unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3662 /* Prefer AND/OR for inserting all zeros or all ones. */
3663 if ((UINTVAL (value) & mask) == 0
3664 || (UINTVAL (value) & mask) == mask)
3667 /* 16-bit aligned 16-bit wide insert is handled by insv_imm. */
3668 if (width == 16 && (pos % 16) == 0)
3671 operands[3] = force_reg (<MODE>mode, value);
3674 (define_insn "*insv_reg<mode>"
3675 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3676 (match_operand 1 "const_int_operand" "n")
3677 (match_operand 2 "const_int_operand" "n"))
3678 (match_operand:GPI 3 "register_operand" "r"))]
3679 "!(UINTVAL (operands[1]) == 0
3680 || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3681 > GET_MODE_BITSIZE (<MODE>mode)))"
3682 "bfi\\t%<w>0, %<w>3, %2, %1"
3683 [(set_attr "type" "bfm")]
3686 (define_insn "*extr_insv_lower_reg<mode>"
3687 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3688 (match_operand 1 "const_int_operand" "n")
3690 (zero_extract:GPI (match_operand:GPI 2 "register_operand" "r")
3692 (match_operand 3 "const_int_operand" "n")))]
3693 "!(UINTVAL (operands[1]) == 0
3694 || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3695 > GET_MODE_BITSIZE (<MODE>mode)))"
3696 "bfxil\\t%<w>0, %<w>2, %3, %1"
3697 [(set_attr "type" "bfm")]
3700 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3701 [(set (match_operand:GPI 0 "register_operand" "=r")
3702 (ashift:GPI (ANY_EXTEND:GPI
3703 (match_operand:ALLX 1 "register_operand" "r"))
3704 (match_operand 2 "const_int_operand" "n")))]
3705 "UINTVAL (operands[2]) < <GPI:sizen>"
3707 operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3708 ? GEN_INT (<ALLX:sizen>)
3709 : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3710 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3712 [(set_attr "type" "bfm")]
3715 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3717 (define_insn "*andim_ashift<mode>_bfiz"
3718 [(set (match_operand:GPI 0 "register_operand" "=r")
3719 (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3720 (match_operand 2 "const_int_operand" "n"))
3721 (match_operand 3 "const_int_operand" "n")))]
3722 "(INTVAL (operands[2]) < (<GPI:sizen>))
3723 && exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3724 && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3725 "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3726 [(set_attr "type" "bfm")]
3729 (define_insn "bswap<mode>2"
3730 [(set (match_operand:GPI 0 "register_operand" "=r")
3731 (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3733 "rev\\t%<w>0, %<w>1"
3734 [(set_attr "type" "rev")]
3737 (define_insn "bswaphi2"
3738 [(set (match_operand:HI 0 "register_operand" "=r")
3739 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3742 [(set_attr "type" "rev")]
3745 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
3746 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
3747 ;; each valid permutation.
3749 (define_insn "rev16<mode>2"
3750 [(set (match_operand:GPI 0 "register_operand" "=r")
3751 (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3753 (match_operand:GPI 3 "const_int_operand" "n"))
3754 (and:GPI (lshiftrt:GPI (match_dup 1)
3756 (match_operand:GPI 2 "const_int_operand" "n"))))]
3757 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3758 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3759 "rev16\\t%<w>0, %<w>1"
3760 [(set_attr "type" "rev")]
3763 (define_insn "rev16<mode>2_alt"
3764 [(set (match_operand:GPI 0 "register_operand" "=r")
3765 (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r")
3767 (match_operand:GPI 2 "const_int_operand" "n"))
3768 (and:GPI (ashift:GPI (match_dup 1)
3770 (match_operand:GPI 3 "const_int_operand" "n"))))]
3771 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3772 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3773 "rev16\\t%<w>0, %<w>1"
3774 [(set_attr "type" "rev")]
3777 ;; zero_extend version of above
3778 (define_insn "*bswapsi2_uxtw"
3779 [(set (match_operand:DI 0 "register_operand" "=r")
3780 (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3783 [(set_attr "type" "rev")]
3786 ;; -------------------------------------------------------------------
3787 ;; Floating-point intrinsics
3788 ;; -------------------------------------------------------------------
3790 ;; frint floating-point round to integral standard patterns.
3791 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round, frintn.
3793 (define_insn "<frint_pattern><mode>2"
3794 [(set (match_operand:GPF 0 "register_operand" "=w")
3795 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3798 "frint<frint_suffix>\\t%<s>0, %<s>1"
3799 [(set_attr "type" "f_rint<s>")]
3802 ;; frcvt floating-point round to integer and convert standard patterns.
3803 ;; Expands to lbtrunc, lceil, lfloor, lround.
3804 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3805 [(set (match_operand:GPI 0 "register_operand" "=r")
3806 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3809 "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3810 [(set_attr "type" "f_cvtf2i")]
3815 (define_insn "fma<mode>4"
3816 [(set (match_operand:GPF 0 "register_operand" "=w")
3817 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3818 (match_operand:GPF 2 "register_operand" "w")
3819 (match_operand:GPF 3 "register_operand" "w")))]
3821 "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3822 [(set_attr "type" "fmac<s>")]
3825 (define_insn "fnma<mode>4"
3826 [(set (match_operand:GPF 0 "register_operand" "=w")
3827 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3828 (match_operand:GPF 2 "register_operand" "w")
3829 (match_operand:GPF 3 "register_operand" "w")))]
3831 "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3832 [(set_attr "type" "fmac<s>")]
3835 (define_insn "fms<mode>4"
3836 [(set (match_operand:GPF 0 "register_operand" "=w")
3837 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3838 (match_operand:GPF 2 "register_operand" "w")
3839 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3841 "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3842 [(set_attr "type" "fmac<s>")]
3845 (define_insn "fnms<mode>4"
3846 [(set (match_operand:GPF 0 "register_operand" "=w")
3847 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3848 (match_operand:GPF 2 "register_operand" "w")
3849 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3851 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3852 [(set_attr "type" "fmac<s>")]
3855 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3856 (define_insn "*fnmadd<mode>4"
3857 [(set (match_operand:GPF 0 "register_operand" "=w")
3858 (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3859 (match_operand:GPF 2 "register_operand" "w")
3860 (match_operand:GPF 3 "register_operand" "w"))))]
3861 "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3862 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3863 [(set_attr "type" "fmac<s>")]
3866 ;; -------------------------------------------------------------------
3867 ;; Floating-point conversions
3868 ;; -------------------------------------------------------------------
3870 (define_insn "extendsfdf2"
3871 [(set (match_operand:DF 0 "register_operand" "=w")
3872 (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3875 [(set_attr "type" "f_cvt")]
3878 (define_insn "truncdfsf2"
3879 [(set (match_operand:SF 0 "register_operand" "=w")
3880 (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3883 [(set_attr "type" "f_cvt")]
3886 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3887 [(set (match_operand:GPI 0 "register_operand" "=r")
3888 (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3890 "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3891 [(set_attr "type" "f_cvtf2i")]
3894 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3895 [(set (match_operand:GPI 0 "register_operand" "=r")
3896 (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3898 "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3899 [(set_attr "type" "f_cvtf2i")]
3902 (define_insn "<optab><fcvt_target><GPF:mode>2"
3903 [(set (match_operand:GPF 0 "register_operand" "=w,w")
3904 (FLOATUORS:GPF (match_operand:<FCVT_TARGET> 1 "register_operand" "w,r")))]
3907 <su_optab>cvtf\t%<GPF:s>0, %<s>1
3908 <su_optab>cvtf\t%<GPF:s>0, %<w1>1"
3909 [(set_attr "simd" "yes,no")
3910 (set_attr "fp" "no,yes")
3911 (set_attr "type" "neon_int_to_fp_<Vetype>,f_cvti2f")]
3914 (define_insn "<optab><fcvt_iesize><GPF:mode>2"
3915 [(set (match_operand:GPF 0 "register_operand" "=w")
3916 (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand" "r")))]
3918 "<su_optab>cvtf\t%<GPF:s>0, %<w2>1"
3919 [(set_attr "type" "f_cvti2f")]
3922 ;; -------------------------------------------------------------------
3923 ;; Floating-point arithmetic
3924 ;; -------------------------------------------------------------------
3926 (define_insn "add<mode>3"
3927 [(set (match_operand:GPF 0 "register_operand" "=w")
3929 (match_operand:GPF 1 "register_operand" "w")
3930 (match_operand:GPF 2 "register_operand" "w")))]
3932 "fadd\\t%<s>0, %<s>1, %<s>2"
3933 [(set_attr "type" "fadd<s>")]
3936 (define_insn "sub<mode>3"
3937 [(set (match_operand:GPF 0 "register_operand" "=w")
3939 (match_operand:GPF 1 "register_operand" "w")
3940 (match_operand:GPF 2 "register_operand" "w")))]
3942 "fsub\\t%<s>0, %<s>1, %<s>2"
3943 [(set_attr "type" "fadd<s>")]
3946 (define_insn "mul<mode>3"
3947 [(set (match_operand:GPF 0 "register_operand" "=w")
3949 (match_operand:GPF 1 "register_operand" "w")
3950 (match_operand:GPF 2 "register_operand" "w")))]
3952 "fmul\\t%<s>0, %<s>1, %<s>2"
3953 [(set_attr "type" "fmul<s>")]
3956 (define_insn "*fnmul<mode>3"
3957 [(set (match_operand:GPF 0 "register_operand" "=w")
3959 (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3960 (match_operand:GPF 2 "register_operand" "w")))]
3962 "fnmul\\t%<s>0, %<s>1, %<s>2"
3963 [(set_attr "type" "fmul<s>")]
3966 (define_insn "div<mode>3"
3967 [(set (match_operand:GPF 0 "register_operand" "=w")
3969 (match_operand:GPF 1 "register_operand" "w")
3970 (match_operand:GPF 2 "register_operand" "w")))]
3972 "fdiv\\t%<s>0, %<s>1, %<s>2"
3973 [(set_attr "type" "fdiv<s>")]
3976 (define_insn "neg<mode>2"
3977 [(set (match_operand:GPF 0 "register_operand" "=w")
3978 (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
3980 "fneg\\t%<s>0, %<s>1"
3981 [(set_attr "type" "ffarith<s>")]
3984 (define_insn "sqrt<mode>2"
3985 [(set (match_operand:GPF 0 "register_operand" "=w")
3986 (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
3988 "fsqrt\\t%<s>0, %<s>1"
3989 [(set_attr "type" "fsqrt<s>")]
3992 (define_insn "abs<mode>2"
3993 [(set (match_operand:GPF 0 "register_operand" "=w")
3994 (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
3996 "fabs\\t%<s>0, %<s>1"
3997 [(set_attr "type" "ffarith<s>")]
4000 ;; Given that smax/smin do not specify the result when either input is NaN,
4001 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
4004 (define_insn "smax<mode>3"
4005 [(set (match_operand:GPF 0 "register_operand" "=w")
4006 (smax:GPF (match_operand:GPF 1 "register_operand" "w")
4007 (match_operand:GPF 2 "register_operand" "w")))]
4009 "fmaxnm\\t%<s>0, %<s>1, %<s>2"
4010 [(set_attr "type" "f_minmax<s>")]
4013 (define_insn "smin<mode>3"
4014 [(set (match_operand:GPF 0 "register_operand" "=w")
4015 (smin:GPF (match_operand:GPF 1 "register_operand" "w")
4016 (match_operand:GPF 2 "register_operand" "w")))]
4018 "fminnm\\t%<s>0, %<s>1, %<s>2"
4019 [(set_attr "type" "f_minmax<s>")]
4022 ;; -------------------------------------------------------------------
4024 ;; -------------------------------------------------------------------
4026 (define_expand "aarch64_reload_mov<mode>"
4027 [(set (match_operand:TX 0 "register_operand" "=w")
4028 (match_operand:TX 1 "register_operand" "w"))
4029 (clobber (match_operand:DI 2 "register_operand" "=&r"))
4033 rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
4034 rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
4035 gen_aarch64_movtilow_tilow (op0, op1);
4036 gen_aarch64_movdi_tihigh (operands[2], op1);
4037 gen_aarch64_movtihigh_di (op0, operands[2]);
4042 ;; The following secondary reload helpers patterns are invoked
4043 ;; after or during reload as we don't want these patterns to start
4044 ;; kicking in during the combiner.
4046 (define_insn "aarch64_movdi_<mode>low"
4047 [(set (match_operand:DI 0 "register_operand" "=r")
4048 (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
4049 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4051 [(set_attr "type" "f_mrc")
4052 (set_attr "length" "4")
4055 (define_insn "aarch64_movdi_<mode>high"
4056 [(set (match_operand:DI 0 "register_operand" "=r")
4058 (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
4060 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4061 "fmov\\t%x0, %1.d[1]"
4062 [(set_attr "type" "f_mrc")
4063 (set_attr "length" "4")
4066 (define_insn "aarch64_mov<mode>high_di"
4067 [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
4068 (const_int 64) (const_int 64))
4069 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4070 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4071 "fmov\\t%0.d[1], %x1"
4072 [(set_attr "type" "f_mcr")
4073 (set_attr "length" "4")
4076 (define_insn "aarch64_mov<mode>low_di"
4077 [(set (match_operand:TX 0 "register_operand" "=w")
4078 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4079 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4081 [(set_attr "type" "f_mcr")
4082 (set_attr "length" "4")
4085 (define_insn "aarch64_movtilow_tilow"
4086 [(set (match_operand:TI 0 "register_operand" "=w")
4088 (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
4089 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
4091 [(set_attr "type" "fmov")
4092 (set_attr "length" "4")
4095 ;; There is a deliberate reason why the parameters of high and lo_sum's
4096 ;; don't have modes for ADRP and ADD instructions. This is to allow high
4097 ;; and lo_sum's to be used with the labels defining the jump tables in
4100 (define_expand "add_losym"
4101 [(set (match_operand 0 "register_operand" "=r")
4102 (lo_sum (match_operand 1 "register_operand" "r")
4103 (match_operand 2 "aarch64_valid_symref" "S")))]
4106 machine_mode mode = GET_MODE (operands[0]);
4108 emit_insn ((mode == DImode
4110 : gen_add_losym_si) (operands[0],
4116 (define_insn "add_losym_<mode>"
4117 [(set (match_operand:P 0 "register_operand" "=r")
4118 (lo_sum:P (match_operand:P 1 "register_operand" "r")
4119 (match_operand 2 "aarch64_valid_symref" "S")))]
4121 "add\\t%<w>0, %<w>1, :lo12:%a2"
4122 [(set_attr "type" "alu_imm")]
4125 (define_insn "ldr_got_small_<mode>"
4126 [(set (match_operand:PTR 0 "register_operand" "=r")
4127 (unspec:PTR [(mem:PTR (lo_sum:PTR
4128 (match_operand:PTR 1 "register_operand" "r")
4129 (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
4130 UNSPEC_GOTSMALLPIC))]
4132 "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
4133 [(set_attr "type" "load1")]
4136 (define_insn "ldr_got_small_sidi"
4137 [(set (match_operand:DI 0 "register_operand" "=r")
4139 (unspec:SI [(mem:SI (lo_sum:DI
4140 (match_operand:DI 1 "register_operand" "r")
4141 (match_operand:DI 2 "aarch64_valid_symref" "S")))]
4142 UNSPEC_GOTSMALLPIC)))]
4144 "ldr\\t%w0, [%1, #:got_lo12:%a2]"
4145 [(set_attr "type" "load1")]
4148 (define_insn "ldr_got_tiny"
4149 [(set (match_operand:DI 0 "register_operand" "=r")
4150 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
4151 UNSPEC_GOTTINYPIC))]
4154 [(set_attr "type" "load1")]
4157 (define_insn "aarch64_load_tp_hard"
4158 [(set (match_operand:DI 0 "register_operand" "=r")
4159 (unspec:DI [(const_int 0)] UNSPEC_TLS))]
4161 "mrs\\t%0, tpidr_el0"
4162 [(set_attr "type" "mrs")]
4165 ;; The TLS ABI specifically requires that the compiler does not schedule
4166 ;; instructions in the TLS stubs, in order to enable linker relaxation.
4167 ;; Therefore we treat the stubs as an atomic sequence.
4168 (define_expand "tlsgd_small"
4169 [(parallel [(set (match_operand 0 "register_operand" "")
4170 (call (mem:DI (match_dup 2)) (const_int 1)))
4171 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
4172 (clobber (reg:DI LR_REGNUM))])]
4175 operands[2] = aarch64_tls_get_addr ();
4178 (define_insn "*tlsgd_small"
4179 [(set (match_operand 0 "register_operand" "")
4180 (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
4181 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
4182 (clobber (reg:DI LR_REGNUM))
4185 "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
4186 [(set_attr "type" "call")
4187 (set_attr "length" "16")])
4189 (define_insn "tlsie_small_<mode>"
4190 [(set (match_operand:PTR 0 "register_operand" "=r")
4191 (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
4192 UNSPEC_GOTSMALLTLS))]
4194 "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
4195 [(set_attr "type" "load1")
4196 (set_attr "length" "8")]
4199 (define_insn "tlsie_small_sidi"
4200 [(set (match_operand:DI 0 "register_operand" "=r")
4202 (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")]
4203 UNSPEC_GOTSMALLTLS)))]
4205 "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
4206 [(set_attr "type" "load1")
4207 (set_attr "length" "8")]
4210 (define_expand "tlsle_small"
4211 [(set (match_operand 0 "register_operand" "=r")
4212 (unspec [(match_operand 1 "register_operand" "r")
4213 (match_operand 2 "aarch64_tls_le_symref" "S")]
4214 UNSPEC_GOTSMALLTLS))]
4217 machine_mode mode = GET_MODE (operands[0]);
4218 emit_insn ((mode == DImode
4219 ? gen_tlsle_small_di
4220 : gen_tlsle_small_si) (operands[0],
4226 (define_insn "tlsle_small_<mode>"
4227 [(set (match_operand:P 0 "register_operand" "=r")
4228 (unspec:P [(match_operand:P 1 "register_operand" "r")
4229 (match_operand 2 "aarch64_tls_le_symref" "S")]
4230 UNSPEC_GOTSMALLTLS))]
4232 "add\\t%<w>0, %<w>1, #%G2\;add\\t%<w>0, %<w>0, #%L2"
4233 [(set_attr "type" "alu_sreg")
4234 (set_attr "length" "8")]
4237 (define_insn "tlsdesc_small_<mode>"
4238 [(set (reg:PTR R0_REGNUM)
4239 (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
4241 (clobber (reg:DI LR_REGNUM))
4242 (clobber (reg:CC CC_REGNUM))
4243 (clobber (match_scratch:DI 1 "=r"))]
4245 "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
4246 [(set_attr "type" "call")
4247 (set_attr "length" "16")])
4249 (define_insn "stack_tie"
4250 [(set (mem:BLK (scratch))
4251 (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
4252 (match_operand:DI 1 "register_operand" "rk")]
4256 [(set_attr "length" "0")]
4259 ;; Named pattern for expanding thread pointer reference.
4260 (define_expand "get_thread_pointerdi"
4261 [(match_operand:DI 0 "register_operand" "=r")]
4264 rtx tmp = aarch64_load_tp (operands[0]);
4265 if (tmp != operands[0])
4266 emit_move_insn (operands[0], tmp);
4270 ;; Named patterns for stack smashing protection.
4271 (define_expand "stack_protect_set"
4272 [(match_operand 0 "memory_operand")
4273 (match_operand 1 "memory_operand")]
4276 machine_mode mode = GET_MODE (operands[0]);
4278 emit_insn ((mode == DImode
4279 ? gen_stack_protect_set_di
4280 : gen_stack_protect_set_si) (operands[0], operands[1]));
4284 (define_insn "stack_protect_set_<mode>"
4285 [(set (match_operand:PTR 0 "memory_operand" "=m")
4286 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
4288 (set (match_scratch:PTR 2 "=&r") (const_int 0))]
4290 "ldr\\t%<w>2, %1\;str\\t%<w>2, %0\;mov\t%<w>2,0"
4291 [(set_attr "length" "12")
4292 (set_attr "type" "multiple")])
4294 (define_expand "stack_protect_test"
4295 [(match_operand 0 "memory_operand")
4296 (match_operand 1 "memory_operand")
4301 machine_mode mode = GET_MODE (operands[0]);
4303 result = gen_reg_rtx(mode);
4305 emit_insn ((mode == DImode
4306 ? gen_stack_protect_test_di
4307 : gen_stack_protect_test_si) (result,
4312 emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4313 result, const0_rtx, operands[2]));
4315 emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4316 result, const0_rtx, operands[2]));
4320 (define_insn "stack_protect_test_<mode>"
4321 [(set (match_operand:PTR 0 "register_operand" "=r")
4322 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
4323 (match_operand:PTR 2 "memory_operand" "m")]
4325 (clobber (match_scratch:PTR 3 "=&r"))]
4327 "ldr\t%<w>3, %x1\;ldr\t%<w>0, %x2\;eor\t%<w>0, %<w>3, %<w>0"
4328 [(set_attr "length" "12")
4329 (set_attr "type" "multiple")])
4331 ;; Write Floating-point Control Register.
4332 (define_insn "set_fpcr"
4333 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
4336 [(set_attr "type" "mrs")])
4338 ;; Read Floating-point Control Register.
4339 (define_insn "get_fpcr"
4340 [(set (match_operand:SI 0 "register_operand" "=r")
4341 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
4344 [(set_attr "type" "mrs")])
4346 ;; Write Floating-point Status Register.
4347 (define_insn "set_fpsr"
4348 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
4351 [(set_attr "type" "mrs")])
4353 ;; Read Floating-point Status Register.
4354 (define_insn "get_fpsr"
4355 [(set (match_operand:SI 0 "register_operand" "=r")
4356 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
4359 [(set_attr "type" "mrs")])
4362 ;; Define the subtract-one-and-jump insns so loop.c
4363 ;; knows what to generate.
4364 (define_expand "doloop_end"
4365 [(use (match_operand 0 "" "")) ; loop pseudo
4366 (use (match_operand 1 "" ""))] ; label
4367 "optimize > 0 && flag_modulo_sched"
4376 /* Currently SMS relies on the do-loop pattern to recognize loops
4377 where (1) the control part consists of all insns defining and/or
4378 using a certain 'count' register and (2) the loop count can be
4379 adjusted by modifying this register prior to the loop.
4380 ??? The possible introduction of a new block to initialize the
4381 new IV can potentially affect branch optimizations. */
4383 if (GET_MODE (operands[0]) != DImode)
4387 insn = emit_insn (gen_adddi3_compare0 (s0, s0, GEN_INT (-1)));
4389 cmp = XVECEXP (PATTERN (insn), 0, 0);
4390 cc_reg = SET_DEST (cmp);
4391 bcomp = gen_rtx_NE (VOIDmode, cc_reg, const0_rtx);
4392 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
4393 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4394 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
4400 (include "aarch64-simd.md")
4402 ;; Atomic Operations
4403 (include "atomics.md")
4405 ;; ldp/stp peephole patterns
4406 (include "aarch64-ldpstp.md")