1 ;; Machine description for AArch64 architecture.
2 ;; Copyright (C) 2009-2014 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" [
120 (define_c_enum "unspecv" [
121 UNSPECV_EH_RETURN ; Represent EH_RETURN
122 UNSPECV_GET_FPCR ; Represent fetch of FPCR content.
123 UNSPECV_SET_FPCR ; Represent assign of FPCR content.
124 UNSPECV_GET_FPSR ; Represent fetch of FPSR content.
125 UNSPECV_SET_FPSR ; Represent assign of FPSR content.
129 ;; If further include files are added the defintion of MD_INCLUDES
132 (include "constraints.md")
133 (include "predicates.md")
134 (include "iterators.md")
136 ;; -------------------------------------------------------------------
137 ;; Instruction types and attributes
138 ;; -------------------------------------------------------------------
140 ; The "type" attribute is is included here from AArch32 backend to be able
141 ; to share pipeline descriptions.
142 (include "../arm/types.md")
144 ;; Attribute that specifies whether or not the instruction touches fp
146 (define_attr "fp" "no,yes" (const_string "no"))
148 ;; Attribute that specifies whether or not the instruction touches simd
150 (define_attr "simd" "no,yes" (const_string "no"))
152 (define_attr "length" ""
155 ;; Attribute that controls whether an alternative is enabled or not.
156 ;; Currently it is only used to disable alternatives which touch fp or simd
157 ;; registers when -mgeneral-regs-only is specified.
158 (define_attr "enabled" "no,yes"
160 (and (eq_attr "fp" "yes")
161 (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
162 (and (eq_attr "simd" "yes")
163 (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
165 ] (const_string "yes")))
167 ;; -------------------------------------------------------------------
168 ;; Pipeline descriptions and scheduling
169 ;; -------------------------------------------------------------------
172 (include "aarch64-tune.md")
174 ;; True if the generic scheduling description should be used.
176 (define_attr "generic_sched" "yes,no"
178 (eq_attr "tune" "cortexa53,cortexa15")
180 (const_string "yes"))))
183 (include "../arm/cortex-a53.md")
184 (include "../arm/cortex-a15.md")
186 ;; -------------------------------------------------------------------
187 ;; Jumps and other miscellaneous insns
188 ;; -------------------------------------------------------------------
190 (define_insn "indirect_jump"
191 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
194 [(set_attr "type" "branch")]
198 [(set (pc) (label_ref (match_operand 0 "" "")))]
201 [(set_attr "type" "branch")]
204 (define_expand "cbranch<mode>4"
205 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
206 [(match_operand:GPI 1 "register_operand" "")
207 (match_operand:GPI 2 "aarch64_plus_operand" "")])
208 (label_ref (match_operand 3 "" ""))
212 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
214 operands[2] = const0_rtx;
218 (define_expand "cbranch<mode>4"
219 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
220 [(match_operand:GPF 1 "register_operand" "")
221 (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
222 (label_ref (match_operand 3 "" ""))
226 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
228 operands[2] = const0_rtx;
232 (define_insn "*condjump"
233 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
234 [(match_operand 1 "cc_register" "") (const_int 0)])
235 (label_ref (match_operand 2 "" ""))
239 [(set_attr "type" "branch")]
242 (define_expand "casesi"
243 [(match_operand:SI 0 "register_operand" "") ; Index
244 (match_operand:SI 1 "const_int_operand" "") ; Lower bound
245 (match_operand:SI 2 "const_int_operand" "") ; Total range
246 (match_operand:DI 3 "" "") ; Table label
247 (match_operand:DI 4 "" "")] ; Out of range label
250 if (operands[1] != const0_rtx)
252 rtx reg = gen_reg_rtx (SImode);
254 /* Canonical RTL says that if you have:
258 then this should be emitted as:
262 The use of trunc_int_for_mode ensures that the resulting
263 constant can be represented in SImode, this is important
264 for the corner case where operand[1] is INT_MIN. */
266 operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
268 if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
269 (operands[1], SImode))
270 operands[1] = force_reg (SImode, operands[1]);
271 emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
275 if (!aarch64_plus_operand (operands[2], SImode))
276 operands[2] = force_reg (SImode, operands[2]);
277 emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
279 operands[0], operands[2], operands[4]));
281 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
282 emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
288 (define_insn "casesi_dispatch"
291 (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
292 (match_operand:SI 1 "register_operand" "r")]
294 (clobber (reg:CC CC_REGNUM))
295 (clobber (match_scratch:DI 3 "=r"))
296 (clobber (match_scratch:DI 4 "=r"))
297 (use (label_ref (match_operand 2 "" "")))])]
300 return aarch64_output_casesi (operands);
302 [(set_attr "length" "16")
303 (set_attr "type" "branch")]
307 [(unspec[(const_int 0)] UNSPEC_NOP)]
310 [(set_attr "type" "no_insn")]
314 [(trap_if (const_int 1) (const_int 8))]
317 [(set_attr "type" "trap")])
319 (define_expand "prologue"
320 [(clobber (const_int 0))]
323 aarch64_expand_prologue ();
328 (define_expand "epilogue"
329 [(clobber (const_int 0))]
332 aarch64_expand_epilogue (false);
337 (define_expand "sibcall_epilogue"
338 [(clobber (const_int 0))]
341 aarch64_expand_epilogue (true);
346 (define_insn "*do_return"
350 [(set_attr "type" "branch")]
353 (define_insn "eh_return"
354 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
358 [(set_attr "type" "branch")]
363 [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
366 [(set (match_dup 1) (match_dup 0))]
368 operands[1] = aarch64_final_eh_return_addr ();
372 (define_insn "*cb<optab><mode>1"
373 [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
375 (label_ref (match_operand 1 "" ""))
379 [(set_attr "type" "branch")]
383 (define_insn "*tb<optab><mode>1"
384 [(set (pc) (if_then_else
385 (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
387 (match_operand 1 "const_int_operand" "n"))
389 (label_ref (match_operand 2 "" ""))
391 (clobber (match_scratch:DI 3 "=r"))]
394 if (get_attr_length (insn) == 8)
395 return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
396 return \"<tbz>\\t%<w>0, %1, %l2\";
398 [(set_attr "type" "branch")
400 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
401 (lt (minus (match_dup 2) (pc)) (const_int 32764)))
406 (define_insn "*cb<optab><mode>1"
407 [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
409 (label_ref (match_operand 1 "" ""))
411 (clobber (match_scratch:DI 2 "=r"))]
414 if (get_attr_length (insn) == 8)
415 return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
416 return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
418 [(set_attr "type" "branch")
420 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
421 (lt (minus (match_dup 1) (pc)) (const_int 32764)))
426 ;; -------------------------------------------------------------------
427 ;; Subroutine calls and sibcalls
428 ;; -------------------------------------------------------------------
430 (define_expand "call_internal"
431 [(parallel [(call (match_operand 0 "memory_operand" "")
432 (match_operand 1 "general_operand" ""))
433 (use (match_operand 2 "" ""))
434 (clobber (reg:DI LR_REGNUM))])])
436 (define_expand "call"
437 [(parallel [(call (match_operand 0 "memory_operand" "")
438 (match_operand 1 "general_operand" ""))
439 (use (match_operand 2 "" ""))
440 (clobber (reg:DI LR_REGNUM))])]
446 /* In an untyped call, we can get NULL for operand 2. */
447 if (operands[2] == NULL)
448 operands[2] = const0_rtx;
450 /* Decide if we should generate indirect calls by loading the
451 64-bit address of the callee into a register before performing
452 the branch-and-link. */
453 callee = XEXP (operands[0], 0);
454 if (GET_CODE (callee) == SYMBOL_REF
455 ? aarch64_is_long_call_p (callee)
457 XEXP (operands[0], 0) = force_reg (Pmode, callee);
459 pat = gen_call_internal (operands[0], operands[1], operands[2]);
460 aarch64_emit_call_insn (pat);
465 (define_insn "*call_reg"
466 [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
467 (match_operand 1 "" ""))
468 (use (match_operand 2 "" ""))
469 (clobber (reg:DI LR_REGNUM))]
472 [(set_attr "type" "call")]
475 (define_insn "*call_symbol"
476 [(call (mem:DI (match_operand:DI 0 "" ""))
477 (match_operand 1 "" ""))
478 (use (match_operand 2 "" ""))
479 (clobber (reg:DI LR_REGNUM))]
480 "GET_CODE (operands[0]) == SYMBOL_REF
481 && !aarch64_is_long_call_p (operands[0])"
483 [(set_attr "type" "call")]
486 (define_expand "call_value_internal"
487 [(parallel [(set (match_operand 0 "" "")
488 (call (match_operand 1 "memory_operand" "")
489 (match_operand 2 "general_operand" "")))
490 (use (match_operand 3 "" ""))
491 (clobber (reg:DI LR_REGNUM))])])
493 (define_expand "call_value"
494 [(parallel [(set (match_operand 0 "" "")
495 (call (match_operand 1 "memory_operand" "")
496 (match_operand 2 "general_operand" "")))
497 (use (match_operand 3 "" ""))
498 (clobber (reg:DI LR_REGNUM))])]
504 /* In an untyped call, we can get NULL for operand 3. */
505 if (operands[3] == NULL)
506 operands[3] = const0_rtx;
508 /* Decide if we should generate indirect calls by loading the
509 64-bit address of the callee into a register before performing
510 the branch-and-link. */
511 callee = XEXP (operands[1], 0);
512 if (GET_CODE (callee) == SYMBOL_REF
513 ? aarch64_is_long_call_p (callee)
515 XEXP (operands[1], 0) = force_reg (Pmode, callee);
517 pat = gen_call_value_internal (operands[0], operands[1], operands[2],
519 aarch64_emit_call_insn (pat);
524 (define_insn "*call_value_reg"
525 [(set (match_operand 0 "" "")
526 (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
527 (match_operand 2 "" "")))
528 (use (match_operand 3 "" ""))
529 (clobber (reg:DI LR_REGNUM))]
532 [(set_attr "type" "call")]
536 (define_insn "*call_value_symbol"
537 [(set (match_operand 0 "" "")
538 (call (mem:DI (match_operand:DI 1 "" ""))
539 (match_operand 2 "" "")))
540 (use (match_operand 3 "" ""))
541 (clobber (reg:DI LR_REGNUM))]
542 "GET_CODE (operands[1]) == SYMBOL_REF
543 && !aarch64_is_long_call_p (operands[1])"
545 [(set_attr "type" "call")]
548 (define_expand "sibcall_internal"
549 [(parallel [(call (match_operand 0 "memory_operand" "")
550 (match_operand 1 "general_operand" ""))
552 (use (match_operand 2 "" ""))])])
554 (define_expand "sibcall"
555 [(parallel [(call (match_operand 0 "memory_operand" "")
556 (match_operand 1 "general_operand" ""))
558 (use (match_operand 2 "" ""))])]
563 if (!REG_P (XEXP (operands[0], 0))
564 && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
565 XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
567 if (operands[2] == NULL_RTX)
568 operands[2] = const0_rtx;
570 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
571 aarch64_emit_call_insn (pat);
576 (define_expand "sibcall_value_internal"
577 [(parallel [(set (match_operand 0 "" "")
578 (call (match_operand 1 "memory_operand" "")
579 (match_operand 2 "general_operand" "")))
581 (use (match_operand 3 "" ""))])])
583 (define_expand "sibcall_value"
584 [(parallel [(set (match_operand 0 "" "")
585 (call (match_operand 1 "memory_operand" "")
586 (match_operand 2 "general_operand" "")))
588 (use (match_operand 3 "" ""))])]
593 if (!REG_P (XEXP (operands[1], 0))
594 && (GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF))
595 XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
597 if (operands[3] == NULL_RTX)
598 operands[3] = const0_rtx;
600 pat = gen_sibcall_value_internal (operands[0], operands[1], operands[2],
602 aarch64_emit_call_insn (pat);
607 (define_insn "*sibcall_insn"
608 [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucs, Usf"))
609 (match_operand 1 "" ""))
611 (use (match_operand 2 "" ""))]
612 "SIBLING_CALL_P (insn)"
616 [(set_attr "type" "branch, branch")]
619 (define_insn "*sibcall_value_insn"
620 [(set (match_operand 0 "" "")
621 (call (mem:DI (match_operand 1 "aarch64_call_insn_operand" "Ucs, Usf"))
622 (match_operand 2 "" "")))
624 (use (match_operand 3 "" ""))]
625 "SIBLING_CALL_P (insn)"
629 [(set_attr "type" "branch, branch")]
632 ;; Call subroutine returning any type.
634 (define_expand "untyped_call"
635 [(parallel [(call (match_operand 0 "")
638 (match_operand 2 "")])]
643 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
645 for (i = 0; i < XVECLEN (operands[2], 0); i++)
647 rtx set = XVECEXP (operands[2], 0, i);
648 emit_move_insn (SET_DEST (set), SET_SRC (set));
651 /* The optimizer does not know that the call sets the function value
652 registers we stored in the result block. We avoid problems by
653 claiming that all hard registers are used and clobbered at this
655 emit_insn (gen_blockage ());
659 ;; -------------------------------------------------------------------
661 ;; -------------------------------------------------------------------
663 (define_expand "mov<mode>"
664 [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
665 (match_operand:SHORT 1 "general_operand" ""))]
668 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
669 operands[1] = force_reg (<MODE>mode, operands[1]);
673 (define_insn "*mov<mode>_aarch64"
674 [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r, *w,r,*w, m, m, r,*w,*w")
675 (match_operand:SHORT 1 "general_operand" " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
676 "(register_operand (operands[0], <MODE>mode)
677 || aarch64_reg_or_zero (operands[1], <MODE>mode))"
679 switch (which_alternative)
682 return "mov\t%w0, %w1";
684 return "mov\t%w0, %1";
686 return aarch64_output_scalar_simd_mov_immediate (operands[1],
689 return "ldr<size>\t%w0, %1";
691 return "ldr\t%<size>0, %1";
693 return "str<size>\t%w1, %0";
695 return "str\t%<size>1, %0";
697 return "umov\t%w0, %1.<v>[0]";
699 return "dup\t%0.<Vallxd>, %w1";
701 return "dup\t%<Vetype>0, %1.<v>[0]";
706 [(set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
707 neon_from_gp<q>,neon_from_gp<q>, neon_dup")
708 (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")]
711 (define_expand "mov<mode>"
712 [(set (match_operand:GPI 0 "nonimmediate_operand" "")
713 (match_operand:GPI 1 "general_operand" ""))]
716 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
717 operands[1] = force_reg (<MODE>mode, operands[1]);
719 if (CONSTANT_P (operands[1]))
721 aarch64_expand_mov_immediate (operands[0], operands[1]);
727 (define_insn "*movsi_aarch64"
728 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m, m,r,r ,*w, r,*w")
729 (match_operand:SI 1 "aarch64_mov_operand" " r,r,k,M,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
730 "(register_operand (operands[0], SImode)
731 || aarch64_reg_or_zero (operands[1], SImode))"
746 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
747 adr,adr,f_mcr,f_mrc,fmov")
748 (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
751 (define_insn "*movdi_aarch64"
752 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m, m,r,r, *w, r,*w,w")
753 (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))]
754 "(register_operand (operands[0], DImode)
755 || aarch64_reg_or_zero (operands[1], DImode))"
771 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
772 adr,adr,f_mcr,f_mrc,fmov,fmov")
773 (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
774 (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
777 (define_insn "insv_imm<mode>"
778 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
780 (match_operand:GPI 1 "const_int_operand" "n"))
781 (match_operand:GPI 2 "const_int_operand" "n"))]
782 "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
783 && UINTVAL (operands[1]) % 16 == 0"
784 "movk\\t%<w>0, %X2, lsl %1"
785 [(set_attr "type" "mov_imm")]
788 (define_expand "movti"
789 [(set (match_operand:TI 0 "nonimmediate_operand" "")
790 (match_operand:TI 1 "general_operand" ""))]
793 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
794 operands[1] = force_reg (TImode, operands[1]);
798 (define_insn "*movti_aarch64"
799 [(set (match_operand:TI 0
800 "nonimmediate_operand" "=r, *w,r ,*w,r ,Ump,Ump,*w,m")
802 "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r ,Z , m,*w"))]
803 "(register_operand (operands[0], TImode)
804 || aarch64_reg_or_zero (operands[1], TImode))"
809 orr\\t%0.16b, %1.16b, %1.16b
815 [(set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \
816 load2,store2,store2,f_loadd,f_stored")
817 (set_attr "length" "8,8,8,4,4,4,4,4,4")
818 (set_attr "simd" "*,*,*,yes,*,*,*,*,*")
819 (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
822 ;; Split a TImode register-register or register-immediate move into
823 ;; its component DImode pieces, taking care to handle overlapping
824 ;; source and dest registers.
826 [(set (match_operand:TI 0 "register_operand" "")
827 (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
828 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
831 aarch64_split_128bit_move (operands[0], operands[1]);
835 (define_expand "mov<mode>"
836 [(set (match_operand:GPF 0 "nonimmediate_operand" "")
837 (match_operand:GPF 1 "general_operand" ""))]
842 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
846 if (GET_CODE (operands[0]) == MEM)
847 operands[1] = force_reg (<MODE>mode, operands[1]);
851 (define_insn "*movsf_aarch64"
852 [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
853 (match_operand:SF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
854 "TARGET_FLOAT && (register_operand (operands[0], SFmode)
855 || register_operand (operands[1], SFmode))"
866 [(set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
867 f_loads,f_stores,f_loads,f_stores,mov_reg")]
870 (define_insn "*movdf_aarch64"
871 [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
872 (match_operand:DF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
873 "TARGET_FLOAT && (register_operand (operands[0], DFmode)
874 || register_operand (operands[1], DFmode))"
885 [(set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
886 f_loadd,f_stored,f_loadd,f_stored,mov_reg")]
889 (define_expand "movtf"
890 [(set (match_operand:TF 0 "nonimmediate_operand" "")
891 (match_operand:TF 1 "general_operand" ""))]
896 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
900 if (GET_CODE (operands[0]) == MEM)
901 operands[1] = force_reg (TFmode, operands[1]);
905 (define_insn "*movtf_aarch64"
906 [(set (match_operand:TF 0
907 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
909 "general_operand" " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
910 "TARGET_FLOAT && (register_operand (operands[0], TFmode)
911 || register_operand (operands[1], TFmode))"
913 orr\\t%0.16b, %1.16b, %1.16b
923 [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,fconstd,fconstd,\
924 f_loadd,f_stored,neon_load1_2reg,neon_store1_2reg")
925 (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
926 (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
927 (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
931 [(set (match_operand:TF 0 "register_operand" "")
932 (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
933 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
936 aarch64_split_128bit_move (operands[0], operands[1]);
943 ;; 2 is size of move in bytes
946 (define_expand "movmemdi"
947 [(match_operand:BLK 0 "memory_operand")
948 (match_operand:BLK 1 "memory_operand")
949 (match_operand:DI 2 "immediate_operand")
950 (match_operand:DI 3 "immediate_operand")]
953 if (aarch64_expand_movmem (operands))
959 ;; Operands 1 and 3 are tied together by the final condition; so we allow
960 ;; fairly lax checking on the second memory operation.
961 (define_insn "load_pair<mode>"
962 [(set (match_operand:GPI 0 "register_operand" "=r")
963 (match_operand:GPI 1 "aarch64_mem_pair_operand" "Ump"))
964 (set (match_operand:GPI 2 "register_operand" "=r")
965 (match_operand:GPI 3 "memory_operand" "m"))]
966 "rtx_equal_p (XEXP (operands[3], 0),
967 plus_constant (Pmode,
968 XEXP (operands[1], 0),
969 GET_MODE_SIZE (<MODE>mode)))"
970 "ldp\\t%<w>0, %<w>2, %1"
971 [(set_attr "type" "load2")]
974 ;; Operands 0 and 2 are tied together by the final condition; so we allow
975 ;; fairly lax checking on the second memory operation.
976 (define_insn "store_pair<mode>"
977 [(set (match_operand:GPI 0 "aarch64_mem_pair_operand" "=Ump")
978 (match_operand:GPI 1 "register_operand" "r"))
979 (set (match_operand:GPI 2 "memory_operand" "=m")
980 (match_operand:GPI 3 "register_operand" "r"))]
981 "rtx_equal_p (XEXP (operands[2], 0),
982 plus_constant (Pmode,
983 XEXP (operands[0], 0),
984 GET_MODE_SIZE (<MODE>mode)))"
985 "stp\\t%<w>1, %<w>3, %0"
986 [(set_attr "type" "store2")]
989 ;; Operands 1 and 3 are tied together by the final condition; so we allow
990 ;; fairly lax checking on the second memory operation.
991 (define_insn "load_pair<mode>"
992 [(set (match_operand:GPF 0 "register_operand" "=w")
993 (match_operand:GPF 1 "aarch64_mem_pair_operand" "Ump"))
994 (set (match_operand:GPF 2 "register_operand" "=w")
995 (match_operand:GPF 3 "memory_operand" "m"))]
996 "rtx_equal_p (XEXP (operands[3], 0),
997 plus_constant (Pmode,
998 XEXP (operands[1], 0),
999 GET_MODE_SIZE (<MODE>mode)))"
1000 "ldp\\t%<w>0, %<w>2, %1"
1001 [(set_attr "type" "neon_load1_2reg<q>")]
1004 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1005 ;; fairly lax checking on the second memory operation.
1006 (define_insn "store_pair<mode>"
1007 [(set (match_operand:GPF 0 "aarch64_mem_pair_operand" "=Ump")
1008 (match_operand:GPF 1 "register_operand" "w"))
1009 (set (match_operand:GPF 2 "memory_operand" "=m")
1010 (match_operand:GPF 3 "register_operand" "w"))]
1011 "rtx_equal_p (XEXP (operands[2], 0),
1012 plus_constant (Pmode,
1013 XEXP (operands[0], 0),
1014 GET_MODE_SIZE (<MODE>mode)))"
1015 "stp\\t%<w>1, %<w>3, %0"
1016 [(set_attr "type" "neon_store1_2reg<q>")]
1019 ;; Load pair with writeback. This is primarily used in function epilogues
1020 ;; when restoring [fp,lr]
1021 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
1023 [(set (match_operand:P 0 "register_operand" "=k")
1024 (plus:P (match_operand:P 1 "register_operand" "0")
1025 (match_operand:P 4 "const_int_operand" "n")))
1026 (set (match_operand:GPI 2 "register_operand" "=r")
1027 (mem:GPI (plus:P (match_dup 1)
1029 (set (match_operand:GPI 3 "register_operand" "=r")
1030 (mem:GPI (plus:P (match_dup 1)
1031 (match_operand:P 5 "const_int_operand" "n"))))])]
1032 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1033 "ldp\\t%<w>2, %<w>3, [%1], %4"
1034 [(set_attr "type" "load2")]
1037 (define_insn "loadwb_pair<GPF:mode>_<P:mode>"
1039 [(set (match_operand:P 0 "register_operand" "=k")
1040 (plus:P (match_operand:P 1 "register_operand" "0")
1041 (match_operand:P 4 "const_int_operand" "n")))
1042 (set (match_operand:GPF 2 "register_operand" "=w")
1043 (mem:GPF (plus:P (match_dup 1)
1045 (set (match_operand:GPF 3 "register_operand" "=w")
1046 (mem:GPF (plus:P (match_dup 1)
1047 (match_operand:P 5 "const_int_operand" "n"))))])]
1048 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPF:MODE>mode)"
1049 "ldp\\t%<w>2, %<w>3, [%1], %4"
1050 [(set_attr "type" "neon_load1_2reg")]
1053 ;; Store pair with writeback. This is primarily used in function prologues
1054 ;; when saving [fp,lr]
1055 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
1057 [(set (match_operand:P 0 "register_operand" "=&k")
1058 (plus:P (match_operand:P 1 "register_operand" "0")
1059 (match_operand:P 4 "const_int_operand" "n")))
1060 (set (mem:GPI (plus:P (match_dup 0)
1062 (match_operand:GPI 2 "register_operand" "r"))
1063 (set (mem:GPI (plus:P (match_dup 0)
1064 (match_operand:P 5 "const_int_operand" "n")))
1065 (match_operand:GPI 3 "register_operand" "r"))])]
1066 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1067 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1068 [(set_attr "type" "store2")]
1071 (define_insn "storewb_pair<GPF:mode>_<P:mode>"
1073 [(set (match_operand:P 0 "register_operand" "=&k")
1074 (plus:P (match_operand:P 1 "register_operand" "0")
1075 (match_operand:P 4 "const_int_operand" "n")))
1076 (set (mem:GPF (plus:P (match_dup 0)
1078 (match_operand:GPF 2 "register_operand" "w"))
1079 (set (mem:GPF (plus:P (match_dup 0)
1080 (match_operand:P 5 "const_int_operand" "n")))
1081 (match_operand:GPF 3 "register_operand" "w"))])]
1082 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPF:MODE>mode)"
1083 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1084 [(set_attr "type" "neon_store1_2reg<q>")]
1087 ;; -------------------------------------------------------------------
1088 ;; Sign/Zero extension
1089 ;; -------------------------------------------------------------------
1091 (define_expand "<optab>sidi2"
1092 [(set (match_operand:DI 0 "register_operand")
1093 (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1097 (define_insn "*extendsidi2_aarch64"
1098 [(set (match_operand:DI 0 "register_operand" "=r,r")
1099 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1104 [(set_attr "type" "extend,load1")]
1107 (define_insn "*zero_extendsidi2_aarch64"
1108 [(set (match_operand:DI 0 "register_operand" "=r,r")
1109 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1114 [(set_attr "type" "extend,load1")]
1117 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1118 [(set (match_operand:GPI 0 "register_operand")
1119 (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1123 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1124 [(set (match_operand:GPI 0 "register_operand" "=r,r")
1125 (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1128 sxt<SHORT:size>\t%<GPI:w>0, %w1
1129 ldrs<SHORT:size>\t%<GPI:w>0, %1"
1130 [(set_attr "type" "extend,load1")]
1133 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1134 [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1135 (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1138 uxt<SHORT:size>\t%<GPI:w>0, %w1
1139 ldr<SHORT:size>\t%w0, %1
1140 ldr\t%<SHORT:size>0, %1"
1141 [(set_attr "type" "extend,load1,load1")]
1144 (define_expand "<optab>qihi2"
1145 [(set (match_operand:HI 0 "register_operand")
1146 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1150 (define_insn "*<optab>qihi2_aarch64"
1151 [(set (match_operand:HI 0 "register_operand" "=r,r")
1152 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1157 [(set_attr "type" "extend,load1")]
1160 ;; -------------------------------------------------------------------
1161 ;; Simple arithmetic
1162 ;; -------------------------------------------------------------------
1164 (define_expand "add<mode>3"
1166 (match_operand:GPI 0 "register_operand" "")
1167 (plus:GPI (match_operand:GPI 1 "register_operand" "")
1168 (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1171 if (! aarch64_plus_operand (operands[2], VOIDmode))
1173 rtx subtarget = ((optimize && can_create_pseudo_p ())
1174 ? gen_reg_rtx (<MODE>mode) : operands[0]);
1175 HOST_WIDE_INT imm = INTVAL (operands[2]);
1178 imm = -(-imm & ~0xfff);
1182 emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1183 operands[1] = subtarget;
1184 operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1189 (define_insn "*addsi3_aarch64"
1191 (match_operand:SI 0 "register_operand" "=rk,rk,w,rk")
1193 (match_operand:SI 1 "register_operand" "%rk,rk,w,rk")
1194 (match_operand:SI 2 "aarch64_plus_operand" "I,r,w,J")))]
1199 add\\t%0.2s, %1.2s, %2.2s
1200 sub\\t%w0, %w1, #%n2"
1201 [(set_attr "type" "alu_imm,alu_sreg,neon_add,alu_imm")
1202 (set_attr "simd" "*,*,yes,*")]
1205 ;; zero_extend version of above
1206 (define_insn "*addsi3_aarch64_uxtw"
1208 (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1210 (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1211 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1216 sub\\t%w0, %w1, #%n2"
1217 [(set_attr "type" "alu_imm,alu_sreg,alu_imm")]
1220 (define_insn "*adddi3_aarch64"
1222 (match_operand:DI 0 "register_operand" "=rk,rk,rk,!w")
1224 (match_operand:DI 1 "register_operand" "%rk,rk,rk,!w")
1225 (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,!w")))]
1230 sub\\t%x0, %x1, #%n2
1231 add\\t%d0, %d1, %d2"
1232 [(set_attr "type" "alu_imm,alu_sreg,alu_imm,alu_sreg")
1233 (set_attr "simd" "*,*,*,yes")]
1236 (define_expand "addti3"
1237 [(set (match_operand:TI 0 "register_operand" "")
1238 (plus:TI (match_operand:TI 1 "register_operand" "")
1239 (match_operand:TI 2 "register_operand" "")))]
1242 rtx low = gen_reg_rtx (DImode);
1243 emit_insn (gen_adddi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1244 gen_lowpart (DImode, operands[2])));
1246 rtx high = gen_reg_rtx (DImode);
1247 emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]),
1248 gen_highpart (DImode, operands[2])));
1250 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1251 emit_move_insn (gen_highpart (DImode, operands[0]), high);
1255 (define_insn "add<mode>3_compare0"
1256 [(set (reg:CC_NZ CC_REGNUM)
1258 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1259 (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1261 (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1262 (plus:GPI (match_dup 1) (match_dup 2)))]
1265 adds\\t%<w>0, %<w>1, %<w>2
1266 adds\\t%<w>0, %<w>1, %<w>2
1267 subs\\t%<w>0, %<w>1, #%n2"
1268 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1271 ;; zero_extend version of above
1272 (define_insn "*addsi3_compare0_uxtw"
1273 [(set (reg:CC_NZ CC_REGNUM)
1275 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1276 (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1278 (set (match_operand:DI 0 "register_operand" "=r,r,r")
1279 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1282 adds\\t%w0, %w1, %w2
1283 adds\\t%w0, %w1, %w2
1284 subs\\t%w0, %w1, #%n2"
1285 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1288 (define_insn "*adds_mul_imm_<mode>"
1289 [(set (reg:CC_NZ CC_REGNUM)
1292 (match_operand:GPI 1 "register_operand" "r")
1293 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1294 (match_operand:GPI 3 "register_operand" "r"))
1296 (set (match_operand:GPI 0 "register_operand" "=r")
1297 (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1300 "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1301 [(set_attr "type" "alus_shift_imm")]
1304 (define_insn "*subs_mul_imm_<mode>"
1305 [(set (reg:CC_NZ CC_REGNUM)
1307 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1309 (match_operand:GPI 2 "register_operand" "r")
1310 (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1312 (set (match_operand:GPI 0 "register_operand" "=r")
1313 (minus:GPI (match_dup 1)
1314 (mult:GPI (match_dup 2) (match_dup 3))))]
1316 "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1317 [(set_attr "type" "alus_shift_imm")]
1320 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1321 [(set (reg:CC_NZ CC_REGNUM)
1324 (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1325 (match_operand:GPI 2 "register_operand" "r"))
1327 (set (match_operand:GPI 0 "register_operand" "=r")
1328 (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1330 "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1331 [(set_attr "type" "alus_ext")]
1334 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1335 [(set (reg:CC_NZ CC_REGNUM)
1337 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1339 (match_operand:ALLX 2 "register_operand" "r")))
1341 (set (match_operand:GPI 0 "register_operand" "=r")
1342 (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1344 "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1345 [(set_attr "type" "alus_ext")]
1348 (define_insn "*adds_<optab><mode>_multp2"
1349 [(set (reg:CC_NZ CC_REGNUM)
1351 (plus:GPI (ANY_EXTRACT:GPI
1352 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1353 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1354 (match_operand 3 "const_int_operand" "n")
1356 (match_operand:GPI 4 "register_operand" "r"))
1358 (set (match_operand:GPI 0 "register_operand" "=r")
1359 (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1363 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1364 "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1365 [(set_attr "type" "alus_ext")]
1368 (define_insn "*subs_<optab><mode>_multp2"
1369 [(set (reg:CC_NZ CC_REGNUM)
1371 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1373 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1374 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1375 (match_operand 3 "const_int_operand" "n")
1378 (set (match_operand:GPI 0 "register_operand" "=r")
1379 (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1380 (mult:GPI (match_dup 1) (match_dup 2))
1383 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1384 "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1385 [(set_attr "type" "alus_ext")]
1388 (define_insn "*add<mode>3nr_compare0"
1389 [(set (reg:CC_NZ CC_REGNUM)
1391 (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1392 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1399 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1402 (define_insn "*compare_neg<mode>"
1403 [(set (reg:CC_Z CC_REGNUM)
1405 (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1406 (match_operand:GPI 1 "register_operand" "r")))]
1408 "cmn\\t%<w>1, %<w>0"
1409 [(set_attr "type" "alus_sreg")]
1412 (define_insn "*add_<shift>_<mode>"
1413 [(set (match_operand:GPI 0 "register_operand" "=r")
1414 (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1415 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1416 (match_operand:GPI 3 "register_operand" "r")))]
1418 "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1419 [(set_attr "type" "alu_shift_imm")]
1422 ;; zero_extend version of above
1423 (define_insn "*add_<shift>_si_uxtw"
1424 [(set (match_operand:DI 0 "register_operand" "=r")
1426 (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1427 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1428 (match_operand:SI 3 "register_operand" "r"))))]
1430 "add\\t%w0, %w3, %w1, <shift> %2"
1431 [(set_attr "type" "alu_shift_imm")]
1434 (define_insn "*add_mul_imm_<mode>"
1435 [(set (match_operand:GPI 0 "register_operand" "=r")
1436 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1437 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1438 (match_operand:GPI 3 "register_operand" "r")))]
1440 "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1441 [(set_attr "type" "alu_shift_imm")]
1444 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1445 [(set (match_operand:GPI 0 "register_operand" "=rk")
1446 (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1447 (match_operand:GPI 2 "register_operand" "r")))]
1449 "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1450 [(set_attr "type" "alu_ext")]
1453 ;; zero_extend version of above
1454 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1455 [(set (match_operand:DI 0 "register_operand" "=rk")
1457 (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1458 (match_operand:GPI 2 "register_operand" "r"))))]
1460 "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1461 [(set_attr "type" "alu_ext")]
1464 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1465 [(set (match_operand:GPI 0 "register_operand" "=rk")
1466 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1467 (match_operand:ALLX 1 "register_operand" "r"))
1468 (match_operand 2 "aarch64_imm3" "Ui3"))
1469 (match_operand:GPI 3 "register_operand" "r")))]
1471 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1472 [(set_attr "type" "alu_ext")]
1475 ;; zero_extend version of above
1476 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1477 [(set (match_operand:DI 0 "register_operand" "=rk")
1479 (plus:SI (ashift:SI (ANY_EXTEND:SI
1480 (match_operand:SHORT 1 "register_operand" "r"))
1481 (match_operand 2 "aarch64_imm3" "Ui3"))
1482 (match_operand:SI 3 "register_operand" "r"))))]
1484 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1485 [(set_attr "type" "alu_ext")]
1488 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1489 [(set (match_operand:GPI 0 "register_operand" "=rk")
1490 (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1491 (match_operand:ALLX 1 "register_operand" "r"))
1492 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1493 (match_operand:GPI 3 "register_operand" "r")))]
1495 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1496 [(set_attr "type" "alu_ext")]
1499 ;; zero_extend version of above
1500 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1501 [(set (match_operand:DI 0 "register_operand" "=rk")
1502 (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1503 (match_operand:SHORT 1 "register_operand" "r"))
1504 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1505 (match_operand:SI 3 "register_operand" "r"))))]
1507 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1508 [(set_attr "type" "alu_ext")]
1511 (define_insn "*add_<optab><mode>_multp2"
1512 [(set (match_operand:GPI 0 "register_operand" "=rk")
1513 (plus:GPI (ANY_EXTRACT:GPI
1514 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1515 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1516 (match_operand 3 "const_int_operand" "n")
1518 (match_operand:GPI 4 "register_operand" "r")))]
1519 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1520 "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1521 [(set_attr "type" "alu_ext")]
1524 ;; zero_extend version of above
1525 (define_insn "*add_<optab>si_multp2_uxtw"
1526 [(set (match_operand:DI 0 "register_operand" "=rk")
1528 (plus:SI (ANY_EXTRACT:SI
1529 (mult:SI (match_operand:SI 1 "register_operand" "r")
1530 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1531 (match_operand 3 "const_int_operand" "n")
1533 (match_operand:SI 4 "register_operand" "r"))))]
1534 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1535 "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1536 [(set_attr "type" "alu_ext")]
1539 (define_insn "add<mode>3_carryin"
1541 (match_operand:GPI 0 "register_operand" "=r")
1542 (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1544 (match_operand:GPI 1 "register_operand" "r")
1545 (match_operand:GPI 2 "register_operand" "r"))))]
1547 "adc\\t%<w>0, %<w>1, %<w>2"
1548 [(set_attr "type" "adc_reg")]
1551 ;; zero_extend version of above
1552 (define_insn "*addsi3_carryin_uxtw"
1554 (match_operand:DI 0 "register_operand" "=r")
1556 (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1558 (match_operand:SI 1 "register_operand" "r")
1559 (match_operand:SI 2 "register_operand" "r")))))]
1561 "adc\\t%w0, %w1, %w2"
1562 [(set_attr "type" "adc_reg")]
1565 (define_insn "*add<mode>3_carryin_alt1"
1567 (match_operand:GPI 0 "register_operand" "=r")
1569 (match_operand:GPI 1 "register_operand" "r")
1570 (match_operand:GPI 2 "register_operand" "r"))
1571 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1573 "adc\\t%<w>0, %<w>1, %<w>2"
1574 [(set_attr "type" "adc_reg")]
1577 ;; zero_extend version of above
1578 (define_insn "*addsi3_carryin_alt1_uxtw"
1580 (match_operand:DI 0 "register_operand" "=r")
1583 (match_operand:SI 1 "register_operand" "r")
1584 (match_operand:SI 2 "register_operand" "r"))
1585 (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1587 "adc\\t%w0, %w1, %w2"
1588 [(set_attr "type" "adc_reg")]
1591 (define_insn "*add<mode>3_carryin_alt2"
1593 (match_operand:GPI 0 "register_operand" "=r")
1595 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1596 (match_operand:GPI 1 "register_operand" "r"))
1597 (match_operand:GPI 2 "register_operand" "r")))]
1599 "adc\\t%<w>0, %<w>1, %<w>2"
1600 [(set_attr "type" "adc_reg")]
1603 ;; zero_extend version of above
1604 (define_insn "*addsi3_carryin_alt2_uxtw"
1606 (match_operand:DI 0 "register_operand" "=r")
1609 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1610 (match_operand:SI 1 "register_operand" "r"))
1611 (match_operand:SI 2 "register_operand" "r"))))]
1613 "adc\\t%w0, %w1, %w2"
1614 [(set_attr "type" "adc_reg")]
1617 (define_insn "*add<mode>3_carryin_alt3"
1619 (match_operand:GPI 0 "register_operand" "=r")
1621 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1622 (match_operand:GPI 2 "register_operand" "r"))
1623 (match_operand:GPI 1 "register_operand" "r")))]
1625 "adc\\t%<w>0, %<w>1, %<w>2"
1626 [(set_attr "type" "adc_reg")]
1629 ;; zero_extend version of above
1630 (define_insn "*addsi3_carryin_alt3_uxtw"
1632 (match_operand:DI 0 "register_operand" "=r")
1635 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1636 (match_operand:SI 2 "register_operand" "r"))
1637 (match_operand:SI 1 "register_operand" "r"))))]
1639 "adc\\t%w0, %w1, %w2"
1640 [(set_attr "type" "adc_reg")]
1643 (define_insn "*add_uxt<mode>_multp2"
1644 [(set (match_operand:GPI 0 "register_operand" "=rk")
1646 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1647 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1648 (match_operand 3 "const_int_operand" "n"))
1649 (match_operand:GPI 4 "register_operand" "r")))]
1650 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1652 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1653 INTVAL (operands[3])));
1654 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1655 [(set_attr "type" "alu_ext")]
1658 ;; zero_extend version of above
1659 (define_insn "*add_uxtsi_multp2_uxtw"
1660 [(set (match_operand:DI 0 "register_operand" "=rk")
1663 (mult:SI (match_operand:SI 1 "register_operand" "r")
1664 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1665 (match_operand 3 "const_int_operand" "n"))
1666 (match_operand:SI 4 "register_operand" "r"))))]
1667 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1669 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1670 INTVAL (operands[3])));
1671 return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1672 [(set_attr "type" "alu_ext")]
1675 (define_insn "subsi3"
1676 [(set (match_operand:SI 0 "register_operand" "=rk")
1677 (minus:SI (match_operand:SI 1 "register_operand" "r")
1678 (match_operand:SI 2 "register_operand" "r")))]
1680 "sub\\t%w0, %w1, %w2"
1681 [(set_attr "type" "alu_sreg")]
1684 ;; zero_extend version of above
1685 (define_insn "*subsi3_uxtw"
1686 [(set (match_operand:DI 0 "register_operand" "=rk")
1688 (minus:SI (match_operand:SI 1 "register_operand" "r")
1689 (match_operand:SI 2 "register_operand" "r"))))]
1691 "sub\\t%w0, %w1, %w2"
1692 [(set_attr "type" "alu_sreg")]
1695 (define_insn "subdi3"
1696 [(set (match_operand:DI 0 "register_operand" "=rk,!w")
1697 (minus:DI (match_operand:DI 1 "register_operand" "r,!w")
1698 (match_operand:DI 2 "register_operand" "r,!w")))]
1702 sub\\t%d0, %d1, %d2"
1703 [(set_attr "type" "alu_sreg, neon_sub")
1704 (set_attr "simd" "*,yes")]
1707 (define_expand "subti3"
1708 [(set (match_operand:TI 0 "register_operand" "")
1709 (minus:TI (match_operand:TI 1 "register_operand" "")
1710 (match_operand:TI 2 "register_operand" "")))]
1713 rtx low = gen_reg_rtx (DImode);
1714 emit_insn (gen_subdi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1715 gen_lowpart (DImode, operands[2])));
1717 rtx high = gen_reg_rtx (DImode);
1718 emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]),
1719 gen_highpart (DImode, operands[2])));
1721 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1722 emit_move_insn (gen_highpart (DImode, operands[0]), high);
1726 (define_insn "sub<mode>3_compare0"
1727 [(set (reg:CC_NZ CC_REGNUM)
1728 (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1729 (match_operand:GPI 2 "register_operand" "r"))
1731 (set (match_operand:GPI 0 "register_operand" "=r")
1732 (minus:GPI (match_dup 1) (match_dup 2)))]
1734 "subs\\t%<w>0, %<w>1, %<w>2"
1735 [(set_attr "type" "alus_sreg")]
1738 ;; zero_extend version of above
1739 (define_insn "*subsi3_compare0_uxtw"
1740 [(set (reg:CC_NZ CC_REGNUM)
1741 (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1742 (match_operand:SI 2 "register_operand" "r"))
1744 (set (match_operand:DI 0 "register_operand" "=r")
1745 (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1747 "subs\\t%w0, %w1, %w2"
1748 [(set_attr "type" "alus_sreg")]
1751 (define_insn "*sub_<shift>_<mode>"
1752 [(set (match_operand:GPI 0 "register_operand" "=r")
1753 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1755 (match_operand:GPI 1 "register_operand" "r")
1756 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1758 "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1759 [(set_attr "type" "alu_shift_imm")]
1762 ;; zero_extend version of above
1763 (define_insn "*sub_<shift>_si_uxtw"
1764 [(set (match_operand:DI 0 "register_operand" "=r")
1766 (minus:SI (match_operand:SI 3 "register_operand" "r")
1768 (match_operand:SI 1 "register_operand" "r")
1769 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1771 "sub\\t%w0, %w3, %w1, <shift> %2"
1772 [(set_attr "type" "alu_shift_imm")]
1775 (define_insn "*sub_mul_imm_<mode>"
1776 [(set (match_operand:GPI 0 "register_operand" "=r")
1777 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1779 (match_operand:GPI 1 "register_operand" "r")
1780 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1782 "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1783 [(set_attr "type" "alu_shift_imm")]
1786 ;; zero_extend version of above
1787 (define_insn "*sub_mul_imm_si_uxtw"
1788 [(set (match_operand:DI 0 "register_operand" "=r")
1790 (minus:SI (match_operand:SI 3 "register_operand" "r")
1792 (match_operand:SI 1 "register_operand" "r")
1793 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
1795 "sub\\t%w0, %w3, %w1, lsl %p2"
1796 [(set_attr "type" "alu_shift_imm")]
1799 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
1800 [(set (match_operand:GPI 0 "register_operand" "=rk")
1801 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1803 (match_operand:ALLX 2 "register_operand" "r"))))]
1805 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1806 [(set_attr "type" "alu_ext")]
1809 ;; zero_extend version of above
1810 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
1811 [(set (match_operand:DI 0 "register_operand" "=rk")
1813 (minus:SI (match_operand:SI 1 "register_operand" "r")
1815 (match_operand:SHORT 2 "register_operand" "r")))))]
1817 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
1818 [(set_attr "type" "alu_ext")]
1821 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
1822 [(set (match_operand:GPI 0 "register_operand" "=rk")
1823 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1824 (ashift:GPI (ANY_EXTEND:GPI
1825 (match_operand:ALLX 2 "register_operand" "r"))
1826 (match_operand 3 "aarch64_imm3" "Ui3"))))]
1828 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1829 [(set_attr "type" "alu_ext")]
1832 ;; zero_extend version of above
1833 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
1834 [(set (match_operand:DI 0 "register_operand" "=rk")
1836 (minus:SI (match_operand:SI 1 "register_operand" "r")
1837 (ashift:SI (ANY_EXTEND:SI
1838 (match_operand:SHORT 2 "register_operand" "r"))
1839 (match_operand 3 "aarch64_imm3" "Ui3")))))]
1841 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
1842 [(set_attr "type" "alu_ext")]
1845 (define_insn "*sub_<optab><mode>_multp2"
1846 [(set (match_operand:GPI 0 "register_operand" "=rk")
1847 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1849 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1850 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1851 (match_operand 3 "const_int_operand" "n")
1853 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1854 "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1855 [(set_attr "type" "alu_ext")]
1858 ;; zero_extend version of above
1859 (define_insn "*sub_<optab>si_multp2_uxtw"
1860 [(set (match_operand:DI 0 "register_operand" "=rk")
1862 (minus:SI (match_operand:SI 4 "register_operand" "r")
1864 (mult:SI (match_operand:SI 1 "register_operand" "r")
1865 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1866 (match_operand 3 "const_int_operand" "n")
1868 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1869 "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1870 [(set_attr "type" "alu_ext")]
1873 (define_insn "sub<mode>3_carryin"
1875 (match_operand:GPI 0 "register_operand" "=r")
1876 (minus:GPI (minus:GPI
1877 (match_operand:GPI 1 "register_operand" "r")
1878 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
1879 (match_operand:GPI 2 "register_operand" "r")))]
1881 "sbc\\t%<w>0, %<w>1, %<w>2"
1882 [(set_attr "type" "adc_reg")]
1885 ;; zero_extend version of the above
1886 (define_insn "*subsi3_carryin_uxtw"
1888 (match_operand:DI 0 "register_operand" "=r")
1891 (match_operand:SI 1 "register_operand" "r")
1892 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
1893 (match_operand:SI 2 "register_operand" "r"))))]
1895 "sbc\\t%w0, %w1, %w2"
1896 [(set_attr "type" "adc_reg")]
1899 (define_insn "*sub_uxt<mode>_multp2"
1900 [(set (match_operand:GPI 0 "register_operand" "=rk")
1901 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1903 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1904 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1905 (match_operand 3 "const_int_operand" "n"))))]
1906 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1908 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1909 INTVAL (operands[3])));
1910 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1911 [(set_attr "type" "alu_ext")]
1914 ;; zero_extend version of above
1915 (define_insn "*sub_uxtsi_multp2_uxtw"
1916 [(set (match_operand:DI 0 "register_operand" "=rk")
1918 (minus:SI (match_operand:SI 4 "register_operand" "r")
1920 (mult:SI (match_operand:SI 1 "register_operand" "r")
1921 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1922 (match_operand 3 "const_int_operand" "n")))))]
1923 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1925 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1926 INTVAL (operands[3])));
1927 return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
1928 [(set_attr "type" "alu_ext")]
1931 (define_insn_and_split "absdi2"
1932 [(set (match_operand:DI 0 "register_operand" "=r,w")
1933 (abs:DI (match_operand:DI 1 "register_operand" "r,w")))
1934 (clobber (match_scratch:DI 2 "=&r,X"))]
1940 && GP_REGNUM_P (REGNO (operands[0]))
1941 && GP_REGNUM_P (REGNO (operands[1]))"
1944 emit_insn (gen_rtx_SET (VOIDmode, operands[2],
1945 gen_rtx_XOR (DImode,
1946 gen_rtx_ASHIFTRT (DImode,
1950 emit_insn (gen_rtx_SET (VOIDmode,
1952 gen_rtx_MINUS (DImode,
1954 gen_rtx_ASHIFTRT (DImode,
1959 [(set_attr "type" "alu_sreg")]
1962 (define_insn "neg<mode>2"
1963 [(set (match_operand:GPI 0 "register_operand" "=r,w")
1964 (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
1968 neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
1969 [(set_attr "type" "alu_sreg, neon_neg<q>")
1970 (set_attr "simd" "*,yes")]
1973 ;; zero_extend version of above
1974 (define_insn "*negsi2_uxtw"
1975 [(set (match_operand:DI 0 "register_operand" "=r")
1976 (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
1979 [(set_attr "type" "alu_sreg")]
1982 (define_insn "*ngc<mode>"
1983 [(set (match_operand:GPI 0 "register_operand" "=r")
1984 (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
1985 (match_operand:GPI 1 "register_operand" "r")))]
1987 "ngc\\t%<w>0, %<w>1"
1988 [(set_attr "type" "adc_reg")]
1991 (define_insn "*ngcsi_uxtw"
1992 [(set (match_operand:DI 0 "register_operand" "=r")
1994 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
1995 (match_operand:SI 1 "register_operand" "r"))))]
1998 [(set_attr "type" "adc_reg")]
2001 (define_insn "*neg<mode>2_compare0"
2002 [(set (reg:CC_NZ CC_REGNUM)
2003 (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2005 (set (match_operand:GPI 0 "register_operand" "=r")
2006 (neg:GPI (match_dup 1)))]
2008 "negs\\t%<w>0, %<w>1"
2009 [(set_attr "type" "alus_sreg")]
2012 ;; zero_extend version of above
2013 (define_insn "*negsi2_compare0_uxtw"
2014 [(set (reg:CC_NZ CC_REGNUM)
2015 (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
2017 (set (match_operand:DI 0 "register_operand" "=r")
2018 (zero_extend:DI (neg:SI (match_dup 1))))]
2021 [(set_attr "type" "alus_sreg")]
2024 (define_insn "*neg_<shift><mode>3_compare0"
2025 [(set (reg:CC_NZ CC_REGNUM)
2027 (neg:GPI (ASHIFT:GPI
2028 (match_operand:GPI 1 "register_operand" "r")
2029 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2031 (set (match_operand:GPI 0 "register_operand" "=r")
2032 (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2034 "negs\\t%<w>0, %<w>1, <shift> %2"
2035 [(set_attr "type" "alus_shift_imm")]
2038 (define_insn "*neg_<shift>_<mode>2"
2039 [(set (match_operand:GPI 0 "register_operand" "=r")
2040 (neg:GPI (ASHIFT:GPI
2041 (match_operand:GPI 1 "register_operand" "r")
2042 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2044 "neg\\t%<w>0, %<w>1, <shift> %2"
2045 [(set_attr "type" "alu_shift_imm")]
2048 ;; zero_extend version of above
2049 (define_insn "*neg_<shift>_si2_uxtw"
2050 [(set (match_operand:DI 0 "register_operand" "=r")
2053 (match_operand:SI 1 "register_operand" "r")
2054 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2056 "neg\\t%w0, %w1, <shift> %2"
2057 [(set_attr "type" "alu_shift_imm")]
2060 (define_insn "*neg_mul_imm_<mode>2"
2061 [(set (match_operand:GPI 0 "register_operand" "=r")
2063 (match_operand:GPI 1 "register_operand" "r")
2064 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2066 "neg\\t%<w>0, %<w>1, lsl %p2"
2067 [(set_attr "type" "alu_shift_imm")]
2070 ;; zero_extend version of above
2071 (define_insn "*neg_mul_imm_si2_uxtw"
2072 [(set (match_operand:DI 0 "register_operand" "=r")
2075 (match_operand:SI 1 "register_operand" "r")
2076 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2078 "neg\\t%w0, %w1, lsl %p2"
2079 [(set_attr "type" "alu_shift_imm")]
2082 (define_insn "mul<mode>3"
2083 [(set (match_operand:GPI 0 "register_operand" "=r")
2084 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2085 (match_operand:GPI 2 "register_operand" "r")))]
2087 "mul\\t%<w>0, %<w>1, %<w>2"
2088 [(set_attr "type" "mul")]
2091 ;; zero_extend version of above
2092 (define_insn "*mulsi3_uxtw"
2093 [(set (match_operand:DI 0 "register_operand" "=r")
2095 (mult:SI (match_operand:SI 1 "register_operand" "r")
2096 (match_operand:SI 2 "register_operand" "r"))))]
2098 "mul\\t%w0, %w1, %w2"
2099 [(set_attr "type" "mul")]
2102 (define_insn "madd<mode>"
2103 [(set (match_operand:GPI 0 "register_operand" "=r")
2104 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2105 (match_operand:GPI 2 "register_operand" "r"))
2106 (match_operand:GPI 3 "register_operand" "r")))]
2108 "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2109 [(set_attr "type" "mla")]
2112 ;; zero_extend version of above
2113 (define_insn "*maddsi_uxtw"
2114 [(set (match_operand:DI 0 "register_operand" "=r")
2116 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2117 (match_operand:SI 2 "register_operand" "r"))
2118 (match_operand:SI 3 "register_operand" "r"))))]
2120 "madd\\t%w0, %w1, %w2, %w3"
2121 [(set_attr "type" "mla")]
2124 (define_insn "*msub<mode>"
2125 [(set (match_operand:GPI 0 "register_operand" "=r")
2126 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2127 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2128 (match_operand:GPI 2 "register_operand" "r"))))]
2131 "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2132 [(set_attr "type" "mla")]
2135 ;; zero_extend version of above
2136 (define_insn "*msubsi_uxtw"
2137 [(set (match_operand:DI 0 "register_operand" "=r")
2139 (minus:SI (match_operand:SI 3 "register_operand" "r")
2140 (mult:SI (match_operand:SI 1 "register_operand" "r")
2141 (match_operand:SI 2 "register_operand" "r")))))]
2144 "msub\\t%w0, %w1, %w2, %w3"
2145 [(set_attr "type" "mla")]
2148 (define_insn "*mul<mode>_neg"
2149 [(set (match_operand:GPI 0 "register_operand" "=r")
2150 (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2151 (match_operand:GPI 2 "register_operand" "r")))]
2154 "mneg\\t%<w>0, %<w>1, %<w>2"
2155 [(set_attr "type" "mul")]
2158 ;; zero_extend version of above
2159 (define_insn "*mulsi_neg_uxtw"
2160 [(set (match_operand:DI 0 "register_operand" "=r")
2162 (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2163 (match_operand:SI 2 "register_operand" "r"))))]
2166 "mneg\\t%w0, %w1, %w2"
2167 [(set_attr "type" "mul")]
2170 (define_insn "<su_optab>mulsidi3"
2171 [(set (match_operand:DI 0 "register_operand" "=r")
2172 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2173 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2175 "<su>mull\\t%0, %w1, %w2"
2176 [(set_attr "type" "<su>mull")]
2179 (define_insn "<su_optab>maddsidi4"
2180 [(set (match_operand:DI 0 "register_operand" "=r")
2182 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2183 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2184 (match_operand:DI 3 "register_operand" "r")))]
2186 "<su>maddl\\t%0, %w1, %w2, %3"
2187 [(set_attr "type" "<su>mlal")]
2190 (define_insn "<su_optab>msubsidi4"
2191 [(set (match_operand:DI 0 "register_operand" "=r")
2193 (match_operand:DI 3 "register_operand" "r")
2194 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2196 (match_operand:SI 2 "register_operand" "r")))))]
2198 "<su>msubl\\t%0, %w1, %w2, %3"
2199 [(set_attr "type" "<su>mlal")]
2202 (define_insn "*<su_optab>mulsidi_neg"
2203 [(set (match_operand:DI 0 "register_operand" "=r")
2205 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2206 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2208 "<su>mnegl\\t%0, %w1, %w2"
2209 [(set_attr "type" "<su>mull")]
2212 (define_expand "<su_optab>mulditi3"
2213 [(set (match_operand:TI 0 "register_operand")
2214 (mult:TI (ANY_EXTEND:TI (match_operand:DI 1 "register_operand"))
2215 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand"))))]
2218 rtx low = gen_reg_rtx (DImode);
2219 emit_insn (gen_muldi3 (low, operands[1], operands[2]));
2221 rtx high = gen_reg_rtx (DImode);
2222 emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2]));
2224 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2225 emit_move_insn (gen_highpart (DImode, operands[0]), high);
2229 ;; The default expansion of multi3 using umuldi3_highpart will perform
2230 ;; the additions in an order that fails to combine into two madd insns.
2231 (define_expand "multi3"
2232 [(set (match_operand:TI 0 "register_operand")
2233 (mult:TI (match_operand:TI 1 "register_operand")
2234 (match_operand:TI 2 "register_operand")))]
2237 rtx l0 = gen_reg_rtx (DImode);
2238 rtx l1 = gen_lowpart (DImode, operands[1]);
2239 rtx l2 = gen_lowpart (DImode, operands[2]);
2240 rtx h0 = gen_reg_rtx (DImode);
2241 rtx h1 = gen_highpart (DImode, operands[1]);
2242 rtx h2 = gen_highpart (DImode, operands[2]);
2244 emit_insn (gen_muldi3 (l0, l1, l2));
2245 emit_insn (gen_umuldi3_highpart (h0, l1, l2));
2246 emit_insn (gen_madddi (h0, h1, l2, h0));
2247 emit_insn (gen_madddi (h0, l1, h2, h0));
2249 emit_move_insn (gen_lowpart (DImode, operands[0]), l0);
2250 emit_move_insn (gen_highpart (DImode, operands[0]), h0);
2254 (define_insn "<su>muldi3_highpart"
2255 [(set (match_operand:DI 0 "register_operand" "=r")
2259 (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2260 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2263 "<su>mulh\\t%0, %1, %2"
2264 [(set_attr "type" "<su>mull")]
2267 (define_insn "<su_optab>div<mode>3"
2268 [(set (match_operand:GPI 0 "register_operand" "=r")
2269 (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2270 (match_operand:GPI 2 "register_operand" "r")))]
2272 "<su>div\\t%<w>0, %<w>1, %<w>2"
2273 [(set_attr "type" "<su>div")]
2276 ;; zero_extend version of above
2277 (define_insn "*<su_optab>divsi3_uxtw"
2278 [(set (match_operand:DI 0 "register_operand" "=r")
2280 (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2281 (match_operand:SI 2 "register_operand" "r"))))]
2283 "<su>div\\t%w0, %w1, %w2"
2284 [(set_attr "type" "<su>div")]
2287 ;; -------------------------------------------------------------------
2289 ;; -------------------------------------------------------------------
2291 (define_insn "*cmp<mode>"
2292 [(set (reg:CC CC_REGNUM)
2293 (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2294 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2300 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
2303 (define_insn "*cmp<mode>"
2304 [(set (reg:CCFP CC_REGNUM)
2305 (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2306 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2310 fcmp\\t%<s>0, %<s>1"
2311 [(set_attr "type" "fcmp<s>")]
2314 (define_insn "*cmpe<mode>"
2315 [(set (reg:CCFPE CC_REGNUM)
2316 (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2317 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2321 fcmpe\\t%<s>0, %<s>1"
2322 [(set_attr "type" "fcmp<s>")]
2325 (define_insn "*cmp_swp_<shift>_reg<mode>"
2326 [(set (reg:CC_SWP CC_REGNUM)
2327 (compare:CC_SWP (ASHIFT:GPI
2328 (match_operand:GPI 0 "register_operand" "r")
2329 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2330 (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2332 "cmp\\t%<w>2, %<w>0, <shift> %1"
2333 [(set_attr "type" "alus_shift_imm")]
2336 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2337 [(set (reg:CC_SWP CC_REGNUM)
2338 (compare:CC_SWP (ANY_EXTEND:GPI
2339 (match_operand:ALLX 0 "register_operand" "r"))
2340 (match_operand:GPI 1 "register_operand" "r")))]
2342 "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2343 [(set_attr "type" "alus_ext")]
2346 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2347 [(set (reg:CC_SWP CC_REGNUM)
2348 (compare:CC_SWP (ashift:GPI
2350 (match_operand:ALLX 0 "register_operand" "r"))
2351 (match_operand 1 "aarch64_imm3" "Ui3"))
2352 (match_operand:GPI 2 "register_operand" "r")))]
2354 "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2355 [(set_attr "type" "alus_ext")]
2358 ;; -------------------------------------------------------------------
2359 ;; Store-flag and conditional select insns
2360 ;; -------------------------------------------------------------------
2362 (define_expand "cstore<mode>4"
2363 [(set (match_operand:SI 0 "register_operand" "")
2364 (match_operator:SI 1 "aarch64_comparison_operator"
2365 [(match_operand:GPI 2 "register_operand" "")
2366 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2369 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2371 operands[3] = const0_rtx;
2375 (define_expand "cstore<mode>4"
2376 [(set (match_operand:SI 0 "register_operand" "")
2377 (match_operator:SI 1 "aarch64_comparison_operator"
2378 [(match_operand:GPF 2 "register_operand" "")
2379 (match_operand:GPF 3 "register_operand" "")]))]
2382 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2384 operands[3] = const0_rtx;
2388 (define_insn "*cstore<mode>_insn"
2389 [(set (match_operand:ALLI 0 "register_operand" "=r")
2390 (match_operator:ALLI 1 "aarch64_comparison_operator"
2391 [(match_operand 2 "cc_register" "") (const_int 0)]))]
2394 [(set_attr "type" "csel")]
2397 ;; zero_extend version of the above
2398 (define_insn "*cstoresi_insn_uxtw"
2399 [(set (match_operand:DI 0 "register_operand" "=r")
2401 (match_operator:SI 1 "aarch64_comparison_operator"
2402 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2405 [(set_attr "type" "csel")]
2408 (define_insn "cstore<mode>_neg"
2409 [(set (match_operand:ALLI 0 "register_operand" "=r")
2410 (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2411 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2413 "csetm\\t%<w>0, %m1"
2414 [(set_attr "type" "csel")]
2417 ;; zero_extend version of the above
2418 (define_insn "*cstoresi_neg_uxtw"
2419 [(set (match_operand:DI 0 "register_operand" "=r")
2421 (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2422 [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2425 [(set_attr "type" "csel")]
2428 (define_expand "cmov<mode>6"
2429 [(set (match_operand:GPI 0 "register_operand" "")
2431 (match_operator 1 "aarch64_comparison_operator"
2432 [(match_operand:GPI 2 "register_operand" "")
2433 (match_operand:GPI 3 "aarch64_plus_operand" "")])
2434 (match_operand:GPI 4 "register_operand" "")
2435 (match_operand:GPI 5 "register_operand" "")))]
2438 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2440 operands[3] = const0_rtx;
2444 (define_expand "cmov<mode>6"
2445 [(set (match_operand:GPF 0 "register_operand" "")
2447 (match_operator 1 "aarch64_comparison_operator"
2448 [(match_operand:GPF 2 "register_operand" "")
2449 (match_operand:GPF 3 "register_operand" "")])
2450 (match_operand:GPF 4 "register_operand" "")
2451 (match_operand:GPF 5 "register_operand" "")))]
2454 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2456 operands[3] = const0_rtx;
2460 (define_insn "*cmov<mode>_insn"
2461 [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2463 (match_operator 1 "aarch64_comparison_operator"
2464 [(match_operand 2 "cc_register" "") (const_int 0)])
2465 (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2466 (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2467 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2468 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2469 ;; Final two alternatives should be unreachable, but included for completeness
2471 csel\\t%<w>0, %<w>3, %<w>4, %m1
2472 csinv\\t%<w>0, %<w>3, <w>zr, %m1
2473 csinv\\t%<w>0, %<w>4, <w>zr, %M1
2474 csinc\\t%<w>0, %<w>3, <w>zr, %m1
2475 csinc\\t%<w>0, %<w>4, <w>zr, %M1
2478 [(set_attr "type" "csel")]
2481 ;; zero_extend version of above
2482 (define_insn "*cmovsi_insn_uxtw"
2483 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2486 (match_operator 1 "aarch64_comparison_operator"
2487 [(match_operand 2 "cc_register" "") (const_int 0)])
2488 (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2489 (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2490 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2491 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2492 ;; Final two alternatives should be unreachable, but included for completeness
2494 csel\\t%w0, %w3, %w4, %m1
2495 csinv\\t%w0, %w3, wzr, %m1
2496 csinv\\t%w0, %w4, wzr, %M1
2497 csinc\\t%w0, %w3, wzr, %m1
2498 csinc\\t%w0, %w4, wzr, %M1
2501 [(set_attr "type" "csel")]
2504 (define_insn "*cmov<mode>_insn"
2505 [(set (match_operand:GPF 0 "register_operand" "=w")
2507 (match_operator 1 "aarch64_comparison_operator"
2508 [(match_operand 2 "cc_register" "") (const_int 0)])
2509 (match_operand:GPF 3 "register_operand" "w")
2510 (match_operand:GPF 4 "register_operand" "w")))]
2512 "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2513 [(set_attr "type" "fcsel")]
2516 (define_expand "mov<mode>cc"
2517 [(set (match_operand:ALLI 0 "register_operand" "")
2518 (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2519 (match_operand:ALLI 2 "register_operand" "")
2520 (match_operand:ALLI 3 "register_operand" "")))]
2524 enum rtx_code code = GET_CODE (operands[1]);
2526 if (code == UNEQ || code == LTGT)
2529 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2530 XEXP (operands[1], 1));
2531 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2535 (define_expand "mov<GPF:mode><GPI:mode>cc"
2536 [(set (match_operand:GPI 0 "register_operand" "")
2537 (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2538 (match_operand:GPF 2 "register_operand" "")
2539 (match_operand:GPF 3 "register_operand" "")))]
2543 enum rtx_code code = GET_CODE (operands[1]);
2545 if (code == UNEQ || code == LTGT)
2548 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2549 XEXP (operands[1], 1));
2550 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2554 (define_expand "mov<mode>cc"
2555 [(set (match_operand:GPF 0 "register_operand" "")
2556 (if_then_else:GPF (match_operand 1 "aarch64_comparison_operator" "")
2557 (match_operand:GPF 2 "register_operand" "")
2558 (match_operand:GPF 3 "register_operand" "")))]
2562 enum rtx_code code = GET_CODE (operands[1]);
2564 if (code == UNEQ || code == LTGT)
2567 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2568 XEXP (operands[1], 1));
2569 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2574 ;; CRC32 instructions.
2575 (define_insn "aarch64_<crc_variant>"
2576 [(set (match_operand:SI 0 "register_operand" "=r")
2577 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2578 (match_operand:<crc_mode> 2 "register_operand" "r")]
2582 if (GET_MODE_BITSIZE (GET_MODE (operands[2])) >= 64)
2583 return "<crc_variant>\\t%w0, %w1, %x2";
2585 return "<crc_variant>\\t%w0, %w1, %w2";
2587 [(set_attr "type" "crc")]
2590 (define_insn "*csinc2<mode>_insn"
2591 [(set (match_operand:GPI 0 "register_operand" "=r")
2592 (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator"
2593 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
2594 (match_operand:GPI 1 "register_operand" "r")))]
2596 "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2597 [(set_attr "type" "csel")]
2600 (define_insn "csinc3<mode>_insn"
2601 [(set (match_operand:GPI 0 "register_operand" "=r")
2603 (match_operator:GPI 1 "aarch64_comparison_operator"
2604 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2605 (plus:GPI (match_operand:GPI 3 "register_operand" "r")
2607 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2609 "csinc\\t%<w>0, %<w>4, %<w>3, %M1"
2610 [(set_attr "type" "csel")]
2613 (define_insn "*csinv3<mode>_insn"
2614 [(set (match_operand:GPI 0 "register_operand" "=r")
2616 (match_operator:GPI 1 "aarch64_comparison_operator"
2617 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2618 (not:GPI (match_operand:GPI 3 "register_operand" "r"))
2619 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2621 "csinv\\t%<w>0, %<w>4, %<w>3, %M1"
2622 [(set_attr "type" "csel")]
2625 (define_insn "*csneg3<mode>_insn"
2626 [(set (match_operand:GPI 0 "register_operand" "=r")
2628 (match_operator:GPI 1 "aarch64_comparison_operator"
2629 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2630 (neg:GPI (match_operand:GPI 3 "register_operand" "r"))
2631 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2633 "csneg\\t%<w>0, %<w>4, %<w>3, %M1"
2634 [(set_attr "type" "csel")]
2637 ;; -------------------------------------------------------------------
2638 ;; Logical operations
2639 ;; -------------------------------------------------------------------
2641 (define_insn "<optab><mode>3"
2642 [(set (match_operand:GPI 0 "register_operand" "=r,rk")
2643 (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2644 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
2646 "<logical>\\t%<w>0, %<w>1, %<w>2"
2647 [(set_attr "type" "logic_reg,logic_imm")]
2650 ;; zero_extend version of above
2651 (define_insn "*<optab>si3_uxtw"
2652 [(set (match_operand:DI 0 "register_operand" "=r,rk")
2654 (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2655 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2657 "<logical>\\t%w0, %w1, %w2"
2658 [(set_attr "type" "logic_reg,logic_imm")]
2661 (define_insn "*and<mode>3_compare0"
2662 [(set (reg:CC_NZ CC_REGNUM)
2664 (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2665 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2667 (set (match_operand:GPI 0 "register_operand" "=r,r")
2668 (and:GPI (match_dup 1) (match_dup 2)))]
2670 "ands\\t%<w>0, %<w>1, %<w>2"
2671 [(set_attr "type" "logics_reg,logics_imm")]
2674 ;; zero_extend version of above
2675 (define_insn "*andsi3_compare0_uxtw"
2676 [(set (reg:CC_NZ CC_REGNUM)
2678 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2679 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2681 (set (match_operand:DI 0 "register_operand" "=r,r")
2682 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2684 "ands\\t%w0, %w1, %w2"
2685 [(set_attr "type" "logics_reg,logics_imm")]
2688 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2689 [(set (reg:CC_NZ CC_REGNUM)
2692 (match_operand:GPI 1 "register_operand" "r")
2693 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2694 (match_operand:GPI 3 "register_operand" "r"))
2696 (set (match_operand:GPI 0 "register_operand" "=r")
2697 (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2699 "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2700 [(set_attr "type" "logics_shift_imm")]
2703 ;; zero_extend version of above
2704 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2705 [(set (reg:CC_NZ CC_REGNUM)
2708 (match_operand:SI 1 "register_operand" "r")
2709 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2710 (match_operand:SI 3 "register_operand" "r"))
2712 (set (match_operand:DI 0 "register_operand" "=r")
2713 (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2716 "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2717 [(set_attr "type" "logics_shift_imm")]
2720 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2721 [(set (match_operand:GPI 0 "register_operand" "=r")
2722 (LOGICAL:GPI (SHIFT:GPI
2723 (match_operand:GPI 1 "register_operand" "r")
2724 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2725 (match_operand:GPI 3 "register_operand" "r")))]
2727 "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2728 [(set_attr "type" "logic_shift_imm")]
2731 (define_insn "*<optab>_rol<mode>3"
2732 [(set (match_operand:GPI 0 "register_operand" "=r")
2733 (LOGICAL:GPI (rotate:GPI
2734 (match_operand:GPI 1 "register_operand" "r")
2735 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2736 (match_operand:GPI 3 "register_operand" "r")))]
2738 "<logical>\\t%<w>0, %<w>3, %<w>1, ror (<sizen> - %2)"
2739 [(set_attr "type" "logic_shift_imm")]
2742 ;; zero_extend versions of above
2743 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
2744 [(set (match_operand:DI 0 "register_operand" "=r")
2746 (LOGICAL:SI (SHIFT:SI
2747 (match_operand:SI 1 "register_operand" "r")
2748 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2749 (match_operand:SI 3 "register_operand" "r"))))]
2751 "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2752 [(set_attr "type" "logic_shift_imm")]
2755 (define_insn "*<optab>_rolsi3_uxtw"
2756 [(set (match_operand:DI 0 "register_operand" "=r")
2758 (LOGICAL:SI (rotate:SI
2759 (match_operand:SI 1 "register_operand" "r")
2760 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2761 (match_operand:SI 3 "register_operand" "r"))))]
2763 "<logical>\\t%w0, %w3, %w1, ror (32 - %2)"
2764 [(set_attr "type" "logic_shift_imm")]
2767 (define_insn "one_cmpl<mode>2"
2768 [(set (match_operand:GPI 0 "register_operand" "=r")
2769 (not:GPI (match_operand:GPI 1 "register_operand" "r")))]
2771 "mvn\\t%<w>0, %<w>1"
2772 [(set_attr "type" "logic_reg")]
2775 (define_insn "*one_cmpl_<optab><mode>2"
2776 [(set (match_operand:GPI 0 "register_operand" "=r")
2777 (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
2778 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2780 "mvn\\t%<w>0, %<w>1, <shift> %2"
2781 [(set_attr "type" "logic_shift_imm")]
2784 (define_insn "*<LOGICAL:optab>_one_cmpl<mode>3"
2785 [(set (match_operand:GPI 0 "register_operand" "=r")
2786 (LOGICAL:GPI (not:GPI
2787 (match_operand:GPI 1 "register_operand" "r"))
2788 (match_operand:GPI 2 "register_operand" "r")))]
2790 "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1"
2791 [(set_attr "type" "logic_reg")]
2794 (define_insn "*and_one_cmpl<mode>3_compare0"
2795 [(set (reg:CC_NZ CC_REGNUM)
2798 (match_operand:GPI 1 "register_operand" "r"))
2799 (match_operand:GPI 2 "register_operand" "r"))
2801 (set (match_operand:GPI 0 "register_operand" "=r")
2802 (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
2804 "bics\\t%<w>0, %<w>2, %<w>1"
2805 [(set_attr "type" "logics_reg")]
2808 ;; zero_extend version of above
2809 (define_insn "*and_one_cmplsi3_compare0_uxtw"
2810 [(set (reg:CC_NZ CC_REGNUM)
2813 (match_operand:SI 1 "register_operand" "r"))
2814 (match_operand:SI 2 "register_operand" "r"))
2816 (set (match_operand:DI 0 "register_operand" "=r")
2817 (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
2819 "bics\\t%w0, %w2, %w1"
2820 [(set_attr "type" "logics_reg")]
2823 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
2824 [(set (match_operand:GPI 0 "register_operand" "=r")
2825 (LOGICAL:GPI (not:GPI
2827 (match_operand:GPI 1 "register_operand" "r")
2828 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2829 (match_operand:GPI 3 "register_operand" "r")))]
2831 "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2832 [(set_attr "type" "logics_shift_imm")]
2835 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
2836 [(set (reg:CC_NZ CC_REGNUM)
2840 (match_operand:GPI 1 "register_operand" "r")
2841 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2842 (match_operand:GPI 3 "register_operand" "r"))
2844 (set (match_operand:GPI 0 "register_operand" "=r")
2847 (match_dup 1) (match_dup 2))) (match_dup 3)))]
2849 "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2850 [(set_attr "type" "logics_shift_imm")]
2853 ;; zero_extend version of above
2854 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
2855 [(set (reg:CC_NZ CC_REGNUM)
2859 (match_operand:SI 1 "register_operand" "r")
2860 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
2861 (match_operand:SI 3 "register_operand" "r"))
2863 (set (match_operand:DI 0 "register_operand" "=r")
2864 (zero_extend:DI (and:SI
2866 (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
2868 "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2869 [(set_attr "type" "logics_shift_imm")]
2872 (define_insn "clz<mode>2"
2873 [(set (match_operand:GPI 0 "register_operand" "=r")
2874 (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
2876 "clz\\t%<w>0, %<w>1"
2877 [(set_attr "type" "clz")]
2880 (define_expand "ffs<mode>2"
2881 [(match_operand:GPI 0 "register_operand")
2882 (match_operand:GPI 1 "register_operand")]
2885 rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
2886 rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
2888 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2889 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2890 emit_insn (gen_csinc3<mode>_insn (operands[0], x, ccreg, operands[0], const0_rtx));
2895 (define_insn "clrsb<mode>2"
2896 [(set (match_operand:GPI 0 "register_operand" "=r")
2897 (clrsb:GPI (match_operand:GPI 1 "register_operand" "r")))]
2899 "cls\\t%<w>0, %<w>1"
2900 [(set_attr "type" "clz")]
2903 (define_insn "rbit<mode>2"
2904 [(set (match_operand:GPI 0 "register_operand" "=r")
2905 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
2907 "rbit\\t%<w>0, %<w>1"
2908 [(set_attr "type" "rbit")]
2911 (define_expand "ctz<mode>2"
2912 [(match_operand:GPI 0 "register_operand")
2913 (match_operand:GPI 1 "register_operand")]
2916 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2917 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2922 (define_insn "*and<mode>3nr_compare0"
2923 [(set (reg:CC_NZ CC_REGNUM)
2925 (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
2926 (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
2929 "tst\\t%<w>0, %<w>1"
2930 [(set_attr "type" "logics_reg")]
2933 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
2934 [(set (reg:CC_NZ CC_REGNUM)
2937 (match_operand:GPI 0 "register_operand" "r")
2938 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2939 (match_operand:GPI 2 "register_operand" "r"))
2942 "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
2943 [(set_attr "type" "logics_shift_imm")]
2946 ;; -------------------------------------------------------------------
2948 ;; -------------------------------------------------------------------
2950 (define_expand "<optab><mode>3"
2951 [(set (match_operand:GPI 0 "register_operand")
2952 (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
2953 (match_operand:QI 2 "nonmemory_operand")))]
2956 if (CONST_INT_P (operands[2]))
2958 operands[2] = GEN_INT (INTVAL (operands[2])
2959 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2961 if (operands[2] == const0_rtx)
2963 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2970 (define_expand "ashl<mode>3"
2971 [(set (match_operand:SHORT 0 "register_operand")
2972 (ashift:SHORT (match_operand:SHORT 1 "register_operand")
2973 (match_operand:QI 2 "nonmemory_operand")))]
2976 if (CONST_INT_P (operands[2]))
2978 operands[2] = GEN_INT (INTVAL (operands[2])
2979 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2981 if (operands[2] == const0_rtx)
2983 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2990 (define_expand "rotr<mode>3"
2991 [(set (match_operand:GPI 0 "register_operand")
2992 (rotatert:GPI (match_operand:GPI 1 "register_operand")
2993 (match_operand:QI 2 "nonmemory_operand")))]
2996 if (CONST_INT_P (operands[2]))
2998 operands[2] = GEN_INT (INTVAL (operands[2])
2999 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3001 if (operands[2] == const0_rtx)
3003 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3010 (define_expand "rotl<mode>3"
3011 [(set (match_operand:GPI 0 "register_operand")
3012 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3013 (match_operand:QI 2 "nonmemory_operand")))]
3016 /* (SZ - cnt) % SZ == -cnt % SZ */
3017 if (CONST_INT_P (operands[2]))
3019 operands[2] = GEN_INT ((-INTVAL (operands[2]))
3020 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3021 if (operands[2] == const0_rtx)
3023 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3028 operands[2] = expand_simple_unop (QImode, NEG, operands[2],
3033 ;; Logical left shift using SISD or Integer instruction
3034 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
3035 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3037 (match_operand:GPI 1 "register_operand" "w,w,r")
3038 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3041 shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3042 ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
3043 lsl\t%<w>0, %<w>1, %<w>2"
3044 [(set_attr "simd" "yes,yes,no")
3045 (set_attr "type" "neon_shift_imm<q>, neon_shift_reg<q>,shift_reg")]
3048 ;; Logical right shift using SISD or Integer instruction
3049 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3050 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3052 (match_operand:GPI 1 "register_operand" "w,w,r")
3053 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3056 ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3058 lsr\t%<w>0, %<w>1, %<w>2"
3059 [(set_attr "simd" "yes,yes,no")
3060 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")]
3064 [(set (match_operand:DI 0 "aarch64_simd_register")
3066 (match_operand:DI 1 "aarch64_simd_register")
3067 (match_operand:QI 2 "aarch64_simd_register")))]
3068 "TARGET_SIMD && reload_completed"
3070 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3072 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_USHL))]
3077 [(set (match_operand:SI 0 "aarch64_simd_register")
3079 (match_operand:SI 1 "aarch64_simd_register")
3080 (match_operand:QI 2 "aarch64_simd_register")))]
3081 "TARGET_SIMD && reload_completed"
3083 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3085 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_USHL_2S))]
3089 ;; Arithmetic right shift using SISD or Integer instruction
3090 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3091 [(set (match_operand:GPI 0 "register_operand" "=w,&w,&w,r")
3093 (match_operand:GPI 1 "register_operand" "w,w,w,r")
3094 (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,0,rUs<cmode>")))]
3097 sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3100 asr\t%<w>0, %<w>1, %<w>2"
3101 [(set_attr "simd" "yes,yes,yes,no")
3102 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>,shift_reg")]
3106 [(set (match_operand:DI 0 "aarch64_simd_register")
3108 (match_operand:DI 1 "aarch64_simd_register")
3109 (match_operand:QI 2 "aarch64_simd_register")))]
3110 "TARGET_SIMD && reload_completed"
3112 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3114 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_SSHL))]
3116 operands[3] = gen_lowpart (QImode, operands[0]);
3121 [(set (match_operand:SI 0 "aarch64_simd_register")
3123 (match_operand:SI 1 "aarch64_simd_register")
3124 (match_operand:QI 2 "aarch64_simd_register")))]
3125 "TARGET_SIMD && reload_completed"
3127 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3129 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_SSHL_2S))]
3131 operands[3] = gen_lowpart (QImode, operands[0]);
3135 (define_insn "*aarch64_sisd_ushl"
3136 [(set (match_operand:DI 0 "register_operand" "=w")
3137 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3138 (match_operand:QI 2 "register_operand" "w")]
3141 "ushl\t%d0, %d1, %d2"
3142 [(set_attr "simd" "yes")
3143 (set_attr "type" "neon_shift_reg")]
3146 (define_insn "*aarch64_ushl_2s"
3147 [(set (match_operand:SI 0 "register_operand" "=w")
3148 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3149 (match_operand:QI 2 "register_operand" "w")]
3152 "ushl\t%0.2s, %1.2s, %2.2s"
3153 [(set_attr "simd" "yes")
3154 (set_attr "type" "neon_shift_reg")]
3157 (define_insn "*aarch64_sisd_sshl"
3158 [(set (match_operand:DI 0 "register_operand" "=w")
3159 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3160 (match_operand:QI 2 "register_operand" "w")]
3163 "sshl\t%d0, %d1, %d2"
3164 [(set_attr "simd" "yes")
3165 (set_attr "type" "neon_shift_reg")]
3168 (define_insn "*aarch64_sshl_2s"
3169 [(set (match_operand:SI 0 "register_operand" "=w")
3170 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3171 (match_operand:QI 2 "register_operand" "w")]
3174 "sshl\t%0.2s, %1.2s, %2.2s"
3175 [(set_attr "simd" "yes")
3176 (set_attr "type" "neon_shift_reg")]
3179 (define_insn "*aarch64_sisd_neg_qi"
3180 [(set (match_operand:QI 0 "register_operand" "=w")
3181 (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3185 [(set_attr "simd" "yes")
3186 (set_attr "type" "neon_neg")]
3190 (define_insn "*ror<mode>3_insn"
3191 [(set (match_operand:GPI 0 "register_operand" "=r")
3193 (match_operand:GPI 1 "register_operand" "r")
3194 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3196 "ror\\t%<w>0, %<w>1, %<w>2"
3197 [(set_attr "type" "shift_reg")]
3200 ;; zero_extend version of above
3201 (define_insn "*<optab>si3_insn_uxtw"
3202 [(set (match_operand:DI 0 "register_operand" "=r")
3203 (zero_extend:DI (SHIFT:SI
3204 (match_operand:SI 1 "register_operand" "r")
3205 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3207 "<shift>\\t%w0, %w1, %w2"
3208 [(set_attr "type" "shift_reg")]
3211 (define_insn "*ashl<mode>3_insn"
3212 [(set (match_operand:SHORT 0 "register_operand" "=r")
3213 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3214 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
3216 "lsl\\t%<w>0, %<w>1, %<w>2"
3217 [(set_attr "type" "shift_reg")]
3220 (define_insn "*<optab><mode>3_insn"
3221 [(set (match_operand:SHORT 0 "register_operand" "=r")
3222 (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3223 (match_operand 2 "const_int_operand" "n")))]
3224 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3226 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3227 return "<bfshift>\t%w0, %w1, %2, %3";
3229 [(set_attr "type" "bfm")]
3232 (define_insn "*extr<mode>5_insn"
3233 [(set (match_operand:GPI 0 "register_operand" "=r")
3234 (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3235 (match_operand 3 "const_int_operand" "n"))
3236 (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3237 (match_operand 4 "const_int_operand" "n"))))]
3238 "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3239 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3240 "extr\\t%<w>0, %<w>1, %<w>2, %4"
3241 [(set_attr "type" "shift_imm")]
3244 ;; zero_extend version of the above
3245 (define_insn "*extrsi5_insn_uxtw"
3246 [(set (match_operand:DI 0 "register_operand" "=r")
3248 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3249 (match_operand 3 "const_int_operand" "n"))
3250 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3251 (match_operand 4 "const_int_operand" "n")))))]
3252 "UINTVAL (operands[3]) < 32 &&
3253 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3254 "extr\\t%w0, %w1, %w2, %4"
3255 [(set_attr "type" "shift_imm")]
3258 (define_insn "*ror<mode>3_insn"
3259 [(set (match_operand:GPI 0 "register_operand" "=r")
3260 (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3261 (match_operand 2 "const_int_operand" "n")))]
3262 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3264 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3265 return "ror\\t%<w>0, %<w>1, %3";
3267 [(set_attr "type" "shift_imm")]
3270 ;; zero_extend version of the above
3271 (define_insn "*rorsi3_insn_uxtw"
3272 [(set (match_operand:DI 0 "register_operand" "=r")
3274 (rotate:SI (match_operand:SI 1 "register_operand" "r")
3275 (match_operand 2 "const_int_operand" "n"))))]
3276 "UINTVAL (operands[2]) < 32"
3278 operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3279 return "ror\\t%w0, %w1, %3";
3281 [(set_attr "type" "shift_imm")]
3284 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3285 [(set (match_operand:GPI 0 "register_operand" "=r")
3287 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3288 (match_operand 2 "const_int_operand" "n"))))]
3289 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3291 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3292 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3294 [(set_attr "type" "bfm")]
3297 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3298 [(set (match_operand:GPI 0 "register_operand" "=r")
3300 (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3301 (match_operand 2 "const_int_operand" "n"))))]
3302 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3304 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3305 return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3307 [(set_attr "type" "bfm")]
3310 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3311 [(set (match_operand:GPI 0 "register_operand" "=r")
3313 (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3314 (match_operand 2 "const_int_operand" "n"))))]
3315 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3317 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3318 return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3320 [(set_attr "type" "bfm")]
3323 ;; -------------------------------------------------------------------
3325 ;; -------------------------------------------------------------------
3327 (define_expand "<optab>"
3328 [(set (match_operand:DI 0 "register_operand" "=r")
3329 (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3330 (match_operand 2 "const_int_operand" "n")
3331 (match_operand 3 "const_int_operand" "n")))]
3336 (define_insn "*<optab><mode>"
3337 [(set (match_operand:GPI 0 "register_operand" "=r")
3338 (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3339 (match_operand 2 "const_int_operand" "n")
3340 (match_operand 3 "const_int_operand" "n")))]
3342 "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3343 [(set_attr "type" "bfm")]
3346 ;; Bitfield Insert (insv)
3347 (define_expand "insv<mode>"
3348 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3349 (match_operand 1 "const_int_operand")
3350 (match_operand 2 "const_int_operand"))
3351 (match_operand:GPI 3 "general_operand"))]
3354 unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3355 unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3356 rtx value = operands[3];
3358 if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3361 if (CONST_INT_P (value))
3363 unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3365 /* Prefer AND/OR for inserting all zeros or all ones. */
3366 if ((UINTVAL (value) & mask) == 0
3367 || (UINTVAL (value) & mask) == mask)
3370 /* 16-bit aligned 16-bit wide insert is handled by insv_imm. */
3371 if (width == 16 && (pos % 16) == 0)
3374 operands[3] = force_reg (<MODE>mode, value);
3377 (define_insn "*insv_reg<mode>"
3378 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3379 (match_operand 1 "const_int_operand" "n")
3380 (match_operand 2 "const_int_operand" "n"))
3381 (match_operand:GPI 3 "register_operand" "r"))]
3382 "!(UINTVAL (operands[1]) == 0
3383 || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3384 > GET_MODE_BITSIZE (<MODE>mode)))"
3385 "bfi\\t%<w>0, %<w>3, %2, %1"
3386 [(set_attr "type" "bfm")]
3389 (define_insn "*extr_insv_lower_reg<mode>"
3390 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3391 (match_operand 1 "const_int_operand" "n")
3393 (zero_extract:GPI (match_operand:GPI 2 "register_operand" "+r")
3395 (match_operand 3 "const_int_operand" "n")))]
3396 "!(UINTVAL (operands[1]) == 0
3397 || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3398 > GET_MODE_BITSIZE (<MODE>mode)))"
3399 "bfxil\\t%<w>0, %<w>2, %3, %1"
3400 [(set_attr "type" "bfm")]
3403 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3404 [(set (match_operand:GPI 0 "register_operand" "=r")
3405 (ashift:GPI (ANY_EXTEND:GPI
3406 (match_operand:ALLX 1 "register_operand" "r"))
3407 (match_operand 2 "const_int_operand" "n")))]
3408 "UINTVAL (operands[2]) < <GPI:sizen>"
3410 operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3411 ? GEN_INT (<ALLX:sizen>)
3412 : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3413 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3415 [(set_attr "type" "bfm")]
3418 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3420 (define_insn "*andim_ashift<mode>_bfiz"
3421 [(set (match_operand:GPI 0 "register_operand" "=r")
3422 (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3423 (match_operand 2 "const_int_operand" "n"))
3424 (match_operand 3 "const_int_operand" "n")))]
3425 "exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3426 && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3427 "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3428 [(set_attr "type" "bfm")]
3431 (define_insn "bswap<mode>2"
3432 [(set (match_operand:GPI 0 "register_operand" "=r")
3433 (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3435 "rev\\t%<w>0, %<w>1"
3436 [(set_attr "type" "rev")]
3439 (define_insn "bswaphi2"
3440 [(set (match_operand:HI 0 "register_operand" "=r")
3441 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3444 [(set_attr "type" "rev")]
3447 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
3448 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
3449 ;; each valid permutation.
3451 (define_insn "rev16<mode>2"
3452 [(set (match_operand:GPI 0 "register_operand" "=r")
3453 (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3455 (match_operand:GPI 3 "const_int_operand" "n"))
3456 (and:GPI (lshiftrt:GPI (match_dup 1)
3458 (match_operand:GPI 2 "const_int_operand" "n"))))]
3459 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3460 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3461 "rev16\\t%<w>0, %<w>1"
3462 [(set_attr "type" "rev")]
3465 (define_insn "rev16<mode>2_alt"
3466 [(set (match_operand:GPI 0 "register_operand" "=r")
3467 (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r")
3469 (match_operand:GPI 2 "const_int_operand" "n"))
3470 (and:GPI (ashift:GPI (match_dup 1)
3472 (match_operand:GPI 3 "const_int_operand" "n"))))]
3473 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3474 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3475 "rev16\\t%<w>0, %<w>1"
3476 [(set_attr "type" "rev")]
3479 ;; zero_extend version of above
3480 (define_insn "*bswapsi2_uxtw"
3481 [(set (match_operand:DI 0 "register_operand" "=r")
3482 (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3485 [(set_attr "type" "rev")]
3488 ;; -------------------------------------------------------------------
3489 ;; Floating-point intrinsics
3490 ;; -------------------------------------------------------------------
3492 ;; frint floating-point round to integral standard patterns.
3493 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round, frintn.
3495 (define_insn "<frint_pattern><mode>2"
3496 [(set (match_operand:GPF 0 "register_operand" "=w")
3497 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3500 "frint<frint_suffix>\\t%<s>0, %<s>1"
3501 [(set_attr "type" "f_rint<s>")]
3504 ;; frcvt floating-point round to integer and convert standard patterns.
3505 ;; Expands to lbtrunc, lceil, lfloor, lround.
3506 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3507 [(set (match_operand:GPI 0 "register_operand" "=r")
3508 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3511 "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3512 [(set_attr "type" "f_cvtf2i")]
3517 (define_insn "fma<mode>4"
3518 [(set (match_operand:GPF 0 "register_operand" "=w")
3519 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3520 (match_operand:GPF 2 "register_operand" "w")
3521 (match_operand:GPF 3 "register_operand" "w")))]
3523 "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3524 [(set_attr "type" "fmac<s>")]
3527 (define_insn "fnma<mode>4"
3528 [(set (match_operand:GPF 0 "register_operand" "=w")
3529 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3530 (match_operand:GPF 2 "register_operand" "w")
3531 (match_operand:GPF 3 "register_operand" "w")))]
3533 "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3534 [(set_attr "type" "fmac<s>")]
3537 (define_insn "fms<mode>4"
3538 [(set (match_operand:GPF 0 "register_operand" "=w")
3539 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3540 (match_operand:GPF 2 "register_operand" "w")
3541 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3543 "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3544 [(set_attr "type" "fmac<s>")]
3547 (define_insn "fnms<mode>4"
3548 [(set (match_operand:GPF 0 "register_operand" "=w")
3549 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3550 (match_operand:GPF 2 "register_operand" "w")
3551 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3553 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3554 [(set_attr "type" "fmac<s>")]
3557 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3558 (define_insn "*fnmadd<mode>4"
3559 [(set (match_operand:GPF 0 "register_operand" "=w")
3560 (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3561 (match_operand:GPF 2 "register_operand" "w")
3562 (match_operand:GPF 3 "register_operand" "w"))))]
3563 "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3564 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3565 [(set_attr "type" "fmac<s>")]
3568 ;; -------------------------------------------------------------------
3569 ;; Floating-point conversions
3570 ;; -------------------------------------------------------------------
3572 (define_insn "extendsfdf2"
3573 [(set (match_operand:DF 0 "register_operand" "=w")
3574 (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3577 [(set_attr "type" "f_cvt")]
3580 (define_insn "truncdfsf2"
3581 [(set (match_operand:SF 0 "register_operand" "=w")
3582 (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3585 [(set_attr "type" "f_cvt")]
3588 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3589 [(set (match_operand:GPI 0 "register_operand" "=r")
3590 (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3592 "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3593 [(set_attr "type" "f_cvtf2i")]
3596 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3597 [(set (match_operand:GPI 0 "register_operand" "=r")
3598 (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3600 "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3601 [(set_attr "type" "f_cvtf2i")]
3604 (define_insn "<optab><fcvt_target><GPF:mode>2"
3605 [(set (match_operand:GPF 0 "register_operand" "=w,w")
3606 (FLOATUORS:GPF (match_operand:<FCVT_TARGET> 1 "register_operand" "w,r")))]
3609 <su_optab>cvtf\t%<GPF:s>0, %<s>1
3610 <su_optab>cvtf\t%<GPF:s>0, %<w1>1"
3611 [(set_attr "simd" "yes,no")
3612 (set_attr "fp" "no,yes")
3613 (set_attr "type" "neon_int_to_fp_<Vetype>,f_cvti2f")]
3616 (define_insn "<optab><fcvt_iesize><GPF:mode>2"
3617 [(set (match_operand:GPF 0 "register_operand" "=w")
3618 (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand" "r")))]
3620 "<su_optab>cvtf\t%<GPF:s>0, %<w2>1"
3621 [(set_attr "type" "f_cvti2f")]
3624 ;; -------------------------------------------------------------------
3625 ;; Floating-point arithmetic
3626 ;; -------------------------------------------------------------------
3628 (define_insn "add<mode>3"
3629 [(set (match_operand:GPF 0 "register_operand" "=w")
3631 (match_operand:GPF 1 "register_operand" "w")
3632 (match_operand:GPF 2 "register_operand" "w")))]
3634 "fadd\\t%<s>0, %<s>1, %<s>2"
3635 [(set_attr "type" "fadd<s>")]
3638 (define_insn "sub<mode>3"
3639 [(set (match_operand:GPF 0 "register_operand" "=w")
3641 (match_operand:GPF 1 "register_operand" "w")
3642 (match_operand:GPF 2 "register_operand" "w")))]
3644 "fsub\\t%<s>0, %<s>1, %<s>2"
3645 [(set_attr "type" "fadd<s>")]
3648 (define_insn "mul<mode>3"
3649 [(set (match_operand:GPF 0 "register_operand" "=w")
3651 (match_operand:GPF 1 "register_operand" "w")
3652 (match_operand:GPF 2 "register_operand" "w")))]
3654 "fmul\\t%<s>0, %<s>1, %<s>2"
3655 [(set_attr "type" "fmul<s>")]
3658 (define_insn "*fnmul<mode>3"
3659 [(set (match_operand:GPF 0 "register_operand" "=w")
3661 (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3662 (match_operand:GPF 2 "register_operand" "w")))]
3664 "fnmul\\t%<s>0, %<s>1, %<s>2"
3665 [(set_attr "type" "fmul<s>")]
3668 (define_insn "div<mode>3"
3669 [(set (match_operand:GPF 0 "register_operand" "=w")
3671 (match_operand:GPF 1 "register_operand" "w")
3672 (match_operand:GPF 2 "register_operand" "w")))]
3674 "fdiv\\t%<s>0, %<s>1, %<s>2"
3675 [(set_attr "type" "fdiv<s>")]
3678 (define_insn "neg<mode>2"
3679 [(set (match_operand:GPF 0 "register_operand" "=w")
3680 (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
3682 "fneg\\t%<s>0, %<s>1"
3683 [(set_attr "type" "ffarith<s>")]
3686 (define_insn "sqrt<mode>2"
3687 [(set (match_operand:GPF 0 "register_operand" "=w")
3688 (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
3690 "fsqrt\\t%<s>0, %<s>1"
3691 [(set_attr "type" "fsqrt<s>")]
3694 (define_insn "abs<mode>2"
3695 [(set (match_operand:GPF 0 "register_operand" "=w")
3696 (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
3698 "fabs\\t%<s>0, %<s>1"
3699 [(set_attr "type" "ffarith<s>")]
3702 ;; Given that smax/smin do not specify the result when either input is NaN,
3703 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
3706 (define_insn "smax<mode>3"
3707 [(set (match_operand:GPF 0 "register_operand" "=w")
3708 (smax:GPF (match_operand:GPF 1 "register_operand" "w")
3709 (match_operand:GPF 2 "register_operand" "w")))]
3711 "fmaxnm\\t%<s>0, %<s>1, %<s>2"
3712 [(set_attr "type" "f_minmax<s>")]
3715 (define_insn "smin<mode>3"
3716 [(set (match_operand:GPF 0 "register_operand" "=w")
3717 (smin:GPF (match_operand:GPF 1 "register_operand" "w")
3718 (match_operand:GPF 2 "register_operand" "w")))]
3720 "fminnm\\t%<s>0, %<s>1, %<s>2"
3721 [(set_attr "type" "f_minmax<s>")]
3724 ;; -------------------------------------------------------------------
3726 ;; -------------------------------------------------------------------
3728 (define_expand "aarch64_reload_mov<mode>"
3729 [(set (match_operand:TX 0 "register_operand" "=w")
3730 (match_operand:TX 1 "register_operand" "w"))
3731 (clobber (match_operand:DI 2 "register_operand" "=&r"))
3735 rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
3736 rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
3737 gen_aarch64_movtilow_tilow (op0, op1);
3738 gen_aarch64_movdi_tihigh (operands[2], op1);
3739 gen_aarch64_movtihigh_di (op0, operands[2]);
3744 ;; The following secondary reload helpers patterns are invoked
3745 ;; after or during reload as we don't want these patterns to start
3746 ;; kicking in during the combiner.
3748 (define_insn "aarch64_movdi_<mode>low"
3749 [(set (match_operand:DI 0 "register_operand" "=r")
3750 (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
3751 "reload_completed || reload_in_progress"
3753 [(set_attr "type" "f_mrc")
3754 (set_attr "length" "4")
3757 (define_insn "aarch64_movdi_<mode>high"
3758 [(set (match_operand:DI 0 "register_operand" "=r")
3760 (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
3762 "reload_completed || reload_in_progress"
3763 "fmov\\t%x0, %1.d[1]"
3764 [(set_attr "type" "f_mrc")
3765 (set_attr "length" "4")
3768 (define_insn "aarch64_mov<mode>high_di"
3769 [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
3770 (const_int 64) (const_int 64))
3771 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
3772 "reload_completed || reload_in_progress"
3773 "fmov\\t%0.d[1], %x1"
3774 [(set_attr "type" "f_mcr")
3775 (set_attr "length" "4")
3778 (define_insn "aarch64_mov<mode>low_di"
3779 [(set (match_operand:TX 0 "register_operand" "=w")
3780 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
3781 "reload_completed || reload_in_progress"
3783 [(set_attr "type" "f_mcr")
3784 (set_attr "length" "4")
3787 (define_insn "aarch64_movtilow_tilow"
3788 [(set (match_operand:TI 0 "register_operand" "=w")
3790 (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
3791 "reload_completed || reload_in_progress"
3793 [(set_attr "type" "fmov")
3794 (set_attr "length" "4")
3797 ;; There is a deliberate reason why the parameters of high and lo_sum's
3798 ;; don't have modes for ADRP and ADD instructions. This is to allow high
3799 ;; and lo_sum's to be used with the labels defining the jump tables in
3802 (define_expand "add_losym"
3803 [(set (match_operand 0 "register_operand" "=r")
3804 (lo_sum (match_operand 1 "register_operand" "r")
3805 (match_operand 2 "aarch64_valid_symref" "S")))]
3808 enum machine_mode mode = GET_MODE (operands[0]);
3810 emit_insn ((mode == DImode
3812 : gen_add_losym_si) (operands[0],
3818 (define_insn "add_losym_<mode>"
3819 [(set (match_operand:P 0 "register_operand" "=r")
3820 (lo_sum:P (match_operand:P 1 "register_operand" "r")
3821 (match_operand 2 "aarch64_valid_symref" "S")))]
3823 "add\\t%<w>0, %<w>1, :lo12:%a2"
3824 [(set_attr "type" "alu_imm")]
3827 (define_insn "ldr_got_small_<mode>"
3828 [(set (match_operand:PTR 0 "register_operand" "=r")
3829 (unspec:PTR [(mem:PTR (lo_sum:PTR
3830 (match_operand:PTR 1 "register_operand" "r")
3831 (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
3832 UNSPEC_GOTSMALLPIC))]
3834 "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
3835 [(set_attr "type" "load1")]
3838 (define_insn "ldr_got_small_sidi"
3839 [(set (match_operand:DI 0 "register_operand" "=r")
3841 (unspec:SI [(mem:SI (lo_sum:DI
3842 (match_operand:DI 1 "register_operand" "r")
3843 (match_operand:DI 2 "aarch64_valid_symref" "S")))]
3844 UNSPEC_GOTSMALLPIC)))]
3846 "ldr\\t%w0, [%1, #:got_lo12:%a2]"
3847 [(set_attr "type" "load1")]
3850 (define_insn "ldr_got_tiny"
3851 [(set (match_operand:DI 0 "register_operand" "=r")
3852 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
3853 UNSPEC_GOTTINYPIC))]
3856 [(set_attr "type" "load1")]
3859 (define_insn "aarch64_load_tp_hard"
3860 [(set (match_operand:DI 0 "register_operand" "=r")
3861 (unspec:DI [(const_int 0)] UNSPEC_TLS))]
3863 "mrs\\t%0, tpidr_el0"
3864 [(set_attr "type" "mrs")]
3867 ;; The TLS ABI specifically requires that the compiler does not schedule
3868 ;; instructions in the TLS stubs, in order to enable linker relaxation.
3869 ;; Therefore we treat the stubs as an atomic sequence.
3870 (define_expand "tlsgd_small"
3871 [(parallel [(set (match_operand 0 "register_operand" "")
3872 (call (mem:DI (match_dup 2)) (const_int 1)))
3873 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
3874 (clobber (reg:DI LR_REGNUM))])]
3877 operands[2] = aarch64_tls_get_addr ();
3880 (define_insn "*tlsgd_small"
3881 [(set (match_operand 0 "register_operand" "")
3882 (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
3883 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
3884 (clobber (reg:DI LR_REGNUM))
3887 "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
3888 [(set_attr "type" "call")
3889 (set_attr "length" "16")])
3891 (define_insn "tlsie_small_<mode>"
3892 [(set (match_operand:PTR 0 "register_operand" "=r")
3893 (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
3894 UNSPEC_GOTSMALLTLS))]
3896 "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
3897 [(set_attr "type" "load1")
3898 (set_attr "length" "8")]
3901 (define_insn "tlsie_small_sidi"
3902 [(set (match_operand:DI 0 "register_operand" "=r")
3904 (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")]
3905 UNSPEC_GOTSMALLTLS)))]
3907 "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
3908 [(set_attr "type" "load1")
3909 (set_attr "length" "8")]
3912 (define_expand "tlsle_small"
3913 [(set (match_operand 0 "register_operand" "=r")
3914 (unspec [(match_operand 1 "register_operand" "r")
3915 (match_operand 2 "aarch64_tls_le_symref" "S")]
3916 UNSPEC_GOTSMALLTLS))]
3919 enum machine_mode mode = GET_MODE (operands[0]);
3920 emit_insn ((mode == DImode
3921 ? gen_tlsle_small_di
3922 : gen_tlsle_small_si) (operands[0],
3928 (define_insn "tlsle_small_<mode>"
3929 [(set (match_operand:P 0 "register_operand" "=r")
3930 (unspec:P [(match_operand:P 1 "register_operand" "r")
3931 (match_operand 2 "aarch64_tls_le_symref" "S")]
3932 UNSPEC_GOTSMALLTLS))]
3934 "add\\t%<w>0, %<w>1, #%G2\;add\\t%<w>0, %<w>0, #%L2"
3935 [(set_attr "type" "alu_sreg")
3936 (set_attr "length" "8")]
3939 (define_insn "tlsdesc_small_<mode>"
3940 [(set (reg:PTR R0_REGNUM)
3941 (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
3943 (clobber (reg:DI LR_REGNUM))
3944 (clobber (reg:CC CC_REGNUM))
3945 (clobber (match_scratch:DI 1 "=r"))]
3947 "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
3948 [(set_attr "type" "call")
3949 (set_attr "length" "16")])
3951 (define_insn "stack_tie"
3952 [(set (mem:BLK (scratch))
3953 (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
3954 (match_operand:DI 1 "register_operand" "rk")]
3958 [(set_attr "length" "0")]
3961 ;; Named pattern for expanding thread pointer reference.
3962 (define_expand "get_thread_pointerdi"
3963 [(match_operand:DI 0 "register_operand" "=r")]
3966 rtx tmp = aarch64_load_tp (operands[0]);
3967 if (tmp != operands[0])
3968 emit_move_insn (operands[0], tmp);
3972 ;; Named patterns for stack smashing protection.
3973 (define_expand "stack_protect_set"
3974 [(match_operand 0 "memory_operand")
3975 (match_operand 1 "memory_operand")]
3978 enum machine_mode mode = GET_MODE (operands[0]);
3980 emit_insn ((mode == DImode
3981 ? gen_stack_protect_set_di
3982 : gen_stack_protect_set_si) (operands[0], operands[1]));
3986 (define_insn "stack_protect_set_<mode>"
3987 [(set (match_operand:PTR 0 "memory_operand" "=m")
3988 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
3990 (set (match_scratch:PTR 2 "=&r") (const_int 0))]
3992 "ldr\\t%<w>2, %1\;str\\t%<w>2, %0\;mov\t%<w>2,0"
3993 [(set_attr "length" "12")
3994 (set_attr "type" "multiple")])
3996 (define_expand "stack_protect_test"
3997 [(match_operand 0 "memory_operand")
3998 (match_operand 1 "memory_operand")
4003 enum machine_mode mode = GET_MODE (operands[0]);
4005 result = gen_reg_rtx(mode);
4007 emit_insn ((mode == DImode
4008 ? gen_stack_protect_test_di
4009 : gen_stack_protect_test_si) (result,
4014 emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4015 result, const0_rtx, operands[2]));
4017 emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4018 result, const0_rtx, operands[2]));
4022 (define_insn "stack_protect_test_<mode>"
4023 [(set (match_operand:PTR 0 "register_operand")
4024 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
4025 (match_operand:PTR 2 "memory_operand" "m")]
4027 (clobber (match_scratch:PTR 3 "=&r"))]
4029 "ldr\t%<w>3, %x1\;ldr\t%<w>0, %x2\;eor\t%<w>0, %<w>3, %<w>0"
4030 [(set_attr "length" "12")
4031 (set_attr "type" "multiple")])
4033 ;; Write Floating-point Control Register.
4034 (define_insn "set_fpcr"
4035 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
4038 [(set_attr "type" "mrs")])
4040 ;; Read Floating-point Control Register.
4041 (define_insn "get_fpcr"
4042 [(set (match_operand:SI 0 "register_operand" "=r")
4043 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
4046 [(set_attr "type" "mrs")])
4048 ;; Write Floating-point Status Register.
4049 (define_insn "set_fpsr"
4050 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
4053 [(set_attr "type" "mrs")])
4055 ;; Read Floating-point Status Register.
4056 (define_insn "get_fpsr"
4057 [(set (match_operand:SI 0 "register_operand" "=r")
4058 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
4061 [(set_attr "type" "mrs")])
4065 (include "aarch64-simd.md")
4067 ;; Atomic Operations
4068 (include "atomics.md")