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 ;; It is important to set the fp or simd attributes to yes when a pattern
145 ;; alternative uses the FP or SIMD register files, usually signified by use of
146 ;; the 'w' constraint. This will ensure that the alternative will be
147 ;; disabled when compiling with -mgeneral-regs-only or with the +nofp/+nosimd
148 ;; architecture extensions. If all the alternatives in a pattern use the
149 ;; FP or SIMD registers then the pattern predicate should include TARGET_FLOAT
152 ;; Attribute that specifies whether or not the instruction touches fp
153 ;; registers. When this is set to yes for an alternative, that alternative
154 ;; will be disabled when !TARGET_FLOAT.
155 (define_attr "fp" "no,yes" (const_string "no"))
157 ;; Attribute that specifies whether or not the instruction touches simd
158 ;; registers. When this is set to yes for an alternative, that alternative
159 ;; will be disabled when !TARGET_SIMD.
160 (define_attr "simd" "no,yes" (const_string "no"))
162 (define_attr "length" ""
165 ;; Attribute that controls whether an alternative is enabled or not.
166 ;; Currently it is only used to disable alternatives which touch fp or simd
167 ;; registers when -mgeneral-regs-only is specified.
168 (define_attr "enabled" "no,yes"
170 (and (eq_attr "fp" "yes")
171 (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
172 (and (eq_attr "simd" "yes")
173 (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
175 ] (const_string "yes")))
177 ;; -------------------------------------------------------------------
178 ;; Pipeline descriptions and scheduling
179 ;; -------------------------------------------------------------------
182 (include "aarch64-tune.md")
184 ;; True if the generic scheduling description should be used.
186 (define_attr "generic_sched" "yes,no"
188 (eq_attr "tune" "cortexa53,cortexa15")
190 (const_string "yes"))))
193 (include "../arm/cortex-a53.md")
194 (include "../arm/cortex-a15.md")
196 ;; -------------------------------------------------------------------
197 ;; Jumps and other miscellaneous insns
198 ;; -------------------------------------------------------------------
200 (define_insn "indirect_jump"
201 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
204 [(set_attr "type" "branch")]
208 [(set (pc) (label_ref (match_operand 0 "" "")))]
211 [(set_attr "type" "branch")]
214 (define_expand "cbranch<mode>4"
215 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
216 [(match_operand:GPI 1 "register_operand" "")
217 (match_operand:GPI 2 "aarch64_plus_operand" "")])
218 (label_ref (match_operand 3 "" ""))
222 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
224 operands[2] = const0_rtx;
228 (define_expand "cbranch<mode>4"
229 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
230 [(match_operand:GPF 1 "register_operand" "")
231 (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
232 (label_ref (match_operand 3 "" ""))
236 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
238 operands[2] = const0_rtx;
242 (define_insn "*condjump"
243 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
244 [(match_operand 1 "cc_register" "") (const_int 0)])
245 (label_ref (match_operand 2 "" ""))
249 [(set_attr "type" "branch")]
252 (define_expand "casesi"
253 [(match_operand:SI 0 "register_operand" "") ; Index
254 (match_operand:SI 1 "const_int_operand" "") ; Lower bound
255 (match_operand:SI 2 "const_int_operand" "") ; Total range
256 (match_operand:DI 3 "" "") ; Table label
257 (match_operand:DI 4 "" "")] ; Out of range label
260 if (operands[1] != const0_rtx)
262 rtx reg = gen_reg_rtx (SImode);
264 /* Canonical RTL says that if you have:
268 then this should be emitted as:
272 The use of trunc_int_for_mode ensures that the resulting
273 constant can be represented in SImode, this is important
274 for the corner case where operand[1] is INT_MIN. */
276 operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
278 if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
279 (operands[1], SImode))
280 operands[1] = force_reg (SImode, operands[1]);
281 emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
285 if (!aarch64_plus_operand (operands[2], SImode))
286 operands[2] = force_reg (SImode, operands[2]);
287 emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
289 operands[0], operands[2], operands[4]));
291 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
292 emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
298 (define_insn "casesi_dispatch"
301 (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
302 (match_operand:SI 1 "register_operand" "r")]
304 (clobber (reg:CC CC_REGNUM))
305 (clobber (match_scratch:DI 3 "=r"))
306 (clobber (match_scratch:DI 4 "=r"))
307 (use (label_ref (match_operand 2 "" "")))])]
310 return aarch64_output_casesi (operands);
312 [(set_attr "length" "16")
313 (set_attr "type" "branch")]
317 [(unspec[(const_int 0)] UNSPEC_NOP)]
320 [(set_attr "type" "no_insn")]
324 [(trap_if (const_int 1) (const_int 8))]
327 [(set_attr "type" "trap")])
329 (define_expand "prologue"
330 [(clobber (const_int 0))]
333 aarch64_expand_prologue ();
338 (define_expand "epilogue"
339 [(clobber (const_int 0))]
342 aarch64_expand_epilogue (false);
347 (define_expand "sibcall_epilogue"
348 [(clobber (const_int 0))]
351 aarch64_expand_epilogue (true);
356 (define_insn "*do_return"
360 [(set_attr "type" "branch")]
363 (define_insn "eh_return"
364 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
368 [(set_attr "type" "branch")]
373 [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
376 [(set (match_dup 1) (match_dup 0))]
378 operands[1] = aarch64_final_eh_return_addr ();
382 (define_insn "*cb<optab><mode>1"
383 [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
385 (label_ref (match_operand 1 "" ""))
389 [(set_attr "type" "branch")]
393 (define_insn "*tb<optab><mode>1"
394 [(set (pc) (if_then_else
395 (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
397 (match_operand 1 "const_int_operand" "n"))
399 (label_ref (match_operand 2 "" ""))
401 (clobber (match_scratch:DI 3 "=r"))]
404 if (get_attr_length (insn) == 8)
405 return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
406 return \"<tbz>\\t%<w>0, %1, %l2\";
408 [(set_attr "type" "branch")
410 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
411 (lt (minus (match_dup 2) (pc)) (const_int 32764)))
416 (define_insn "*cb<optab><mode>1"
417 [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
419 (label_ref (match_operand 1 "" ""))
421 (clobber (match_scratch:DI 2 "=r"))]
424 if (get_attr_length (insn) == 8)
425 return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
426 return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
428 [(set_attr "type" "branch")
430 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
431 (lt (minus (match_dup 1) (pc)) (const_int 32764)))
436 ;; -------------------------------------------------------------------
437 ;; Subroutine calls and sibcalls
438 ;; -------------------------------------------------------------------
440 (define_expand "call"
441 [(parallel [(call (match_operand 0 "memory_operand" "")
442 (match_operand 1 "general_operand" ""))
443 (use (match_operand 2 "" ""))
444 (clobber (reg:DI LR_REGNUM))])]
450 /* In an untyped call, we can get NULL for operand 2. */
451 if (operands[2] == NULL)
452 operands[2] = const0_rtx;
454 /* Decide if we should generate indirect calls by loading the
455 64-bit address of the callee into a register before performing
456 the branch-and-link. */
457 callee = XEXP (operands[0], 0);
458 if (GET_CODE (callee) == SYMBOL_REF
459 ? aarch64_is_long_call_p (callee)
461 XEXP (operands[0], 0) = force_reg (Pmode, callee);
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"
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))])]
497 /* In an untyped call, we can get NULL for operand 3. */
498 if (operands[3] == NULL)
499 operands[3] = const0_rtx;
501 /* Decide if we should generate indirect calls by loading the
502 64-bit address of the callee into a register before performing
503 the branch-and-link. */
504 callee = XEXP (operands[1], 0);
505 if (GET_CODE (callee) == SYMBOL_REF
506 ? aarch64_is_long_call_p (callee)
508 XEXP (operands[1], 0) = force_reg (Pmode, callee);
512 (define_insn "*call_value_reg"
513 [(set (match_operand 0 "" "")
514 (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
515 (match_operand 2 "" "")))
516 (use (match_operand 3 "" ""))
517 (clobber (reg:DI LR_REGNUM))]
520 [(set_attr "type" "call")]
524 (define_insn "*call_value_symbol"
525 [(set (match_operand 0 "" "")
526 (call (mem:DI (match_operand:DI 1 "" ""))
527 (match_operand 2 "" "")))
528 (use (match_operand 3 "" ""))
529 (clobber (reg:DI LR_REGNUM))]
530 "GET_CODE (operands[1]) == SYMBOL_REF
531 && !aarch64_is_long_call_p (operands[1])"
533 [(set_attr "type" "call")]
536 (define_expand "sibcall"
537 [(parallel [(call (match_operand 0 "memory_operand" "")
538 (match_operand 1 "general_operand" ""))
540 (use (match_operand 2 "" ""))])]
543 if (!REG_P (XEXP (operands[0], 0))
544 && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
545 XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
547 if (operands[2] == NULL_RTX)
548 operands[2] = const0_rtx;
552 (define_expand "sibcall_value"
553 [(parallel [(set (match_operand 0 "" "")
554 (call (match_operand 1 "memory_operand" "")
555 (match_operand 2 "general_operand" "")))
557 (use (match_operand 3 "" ""))])]
560 if (!REG_P (XEXP (operands[1], 0))
561 && (GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF))
562 XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
564 if (operands[3] == NULL_RTX)
565 operands[3] = const0_rtx;
569 (define_insn "*sibcall_insn"
570 [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucs, Usf"))
571 (match_operand 1 "" ""))
573 (use (match_operand 2 "" ""))]
574 "SIBLING_CALL_P (insn)"
578 [(set_attr "type" "branch, branch")]
581 (define_insn "*sibcall_value_insn"
582 [(set (match_operand 0 "" "")
583 (call (mem:DI (match_operand 1 "aarch64_call_insn_operand" "Ucs, Usf"))
584 (match_operand 2 "" "")))
586 (use (match_operand 3 "" ""))]
587 "SIBLING_CALL_P (insn)"
591 [(set_attr "type" "branch, branch")]
594 ;; Call subroutine returning any type.
596 (define_expand "untyped_call"
597 [(parallel [(call (match_operand 0 "")
600 (match_operand 2 "")])]
605 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
607 for (i = 0; i < XVECLEN (operands[2], 0); i++)
609 rtx set = XVECEXP (operands[2], 0, i);
610 emit_move_insn (SET_DEST (set), SET_SRC (set));
613 /* The optimizer does not know that the call sets the function value
614 registers we stored in the result block. We avoid problems by
615 claiming that all hard registers are used and clobbered at this
617 emit_insn (gen_blockage ());
621 ;; -------------------------------------------------------------------
623 ;; -------------------------------------------------------------------
625 (define_expand "mov<mode>"
626 [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
627 (match_operand:SHORT 1 "general_operand" ""))]
630 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
631 operands[1] = force_reg (<MODE>mode, operands[1]);
635 (define_insn "*mov<mode>_aarch64"
636 [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r, *w,r,*w, m, m, r,*w,*w")
637 (match_operand:SHORT 1 "general_operand" " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
638 "(register_operand (operands[0], <MODE>mode)
639 || aarch64_reg_or_zero (operands[1], <MODE>mode))"
641 switch (which_alternative)
644 return "mov\t%w0, %w1";
646 return "mov\t%w0, %1";
648 return aarch64_output_scalar_simd_mov_immediate (operands[1],
651 return "ldr<size>\t%w0, %1";
653 return "ldr\t%<size>0, %1";
655 return "str<size>\t%w1, %0";
657 return "str\t%<size>1, %0";
659 return "umov\t%w0, %1.<v>[0]";
661 return "dup\t%0.<Vallxd>, %w1";
663 return "dup\t%<Vetype>0, %1.<v>[0]";
668 [(set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
669 neon_from_gp<q>,neon_from_gp<q>, neon_dup")
670 (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")]
673 (define_expand "mov<mode>"
674 [(set (match_operand:GPI 0 "nonimmediate_operand" "")
675 (match_operand:GPI 1 "general_operand" ""))]
678 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
679 operands[1] = force_reg (<MODE>mode, operands[1]);
681 if (CONSTANT_P (operands[1]))
683 aarch64_expand_mov_immediate (operands[0], operands[1]);
689 (define_insn "*movsi_aarch64"
690 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m, m,r,r ,*w, r,*w")
691 (match_operand:SI 1 "aarch64_mov_operand" " r,r,k,M,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
692 "(register_operand (operands[0], SImode)
693 || aarch64_reg_or_zero (operands[1], SImode))"
708 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
709 adr,adr,f_mcr,f_mrc,fmov")
710 (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
713 (define_insn "*movdi_aarch64"
714 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m, m,r,r, *w, r,*w,w")
715 (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))]
716 "(register_operand (operands[0], DImode)
717 || aarch64_reg_or_zero (operands[1], DImode))"
733 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
734 adr,adr,f_mcr,f_mrc,fmov,fmov")
735 (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
736 (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
739 (define_insn "insv_imm<mode>"
740 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
742 (match_operand:GPI 1 "const_int_operand" "n"))
743 (match_operand:GPI 2 "const_int_operand" "n"))]
744 "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
745 && UINTVAL (operands[1]) % 16 == 0"
746 "movk\\t%<w>0, %X2, lsl %1"
747 [(set_attr "type" "mov_imm")]
750 (define_expand "movti"
751 [(set (match_operand:TI 0 "nonimmediate_operand" "")
752 (match_operand:TI 1 "general_operand" ""))]
755 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
756 operands[1] = force_reg (TImode, operands[1]);
760 (define_insn "*movti_aarch64"
761 [(set (match_operand:TI 0
762 "nonimmediate_operand" "=r, *w,r ,*w,r ,Ump,Ump,*w,m")
764 "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r ,Z , m,*w"))]
765 "(register_operand (operands[0], TImode)
766 || aarch64_reg_or_zero (operands[1], TImode))"
771 orr\\t%0.16b, %1.16b, %1.16b
777 [(set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \
778 load2,store2,store2,f_loadd,f_stored")
779 (set_attr "length" "8,8,8,4,4,4,4,4,4")
780 (set_attr "simd" "*,*,*,yes,*,*,*,*,*")
781 (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
784 ;; Split a TImode register-register or register-immediate move into
785 ;; its component DImode pieces, taking care to handle overlapping
786 ;; source and dest registers.
788 [(set (match_operand:TI 0 "register_operand" "")
789 (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
790 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
793 aarch64_split_128bit_move (operands[0], operands[1]);
797 (define_expand "mov<mode>"
798 [(set (match_operand:GPF 0 "nonimmediate_operand" "")
799 (match_operand:GPF 1 "general_operand" ""))]
804 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
808 if (GET_CODE (operands[0]) == MEM)
809 operands[1] = force_reg (<MODE>mode, operands[1]);
813 (define_insn "*movsf_aarch64"
814 [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
815 (match_operand:SF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
816 "TARGET_FLOAT && (register_operand (operands[0], SFmode)
817 || register_operand (operands[1], SFmode))"
828 [(set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
829 f_loads,f_stores,f_loads,f_stores,mov_reg")]
832 (define_insn "*movdf_aarch64"
833 [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
834 (match_operand:DF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
835 "TARGET_FLOAT && (register_operand (operands[0], DFmode)
836 || register_operand (operands[1], DFmode))"
847 [(set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
848 f_loadd,f_stored,f_loadd,f_stored,mov_reg")]
851 (define_expand "movtf"
852 [(set (match_operand:TF 0 "nonimmediate_operand" "")
853 (match_operand:TF 1 "general_operand" ""))]
858 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
862 if (GET_CODE (operands[0]) == MEM)
863 operands[1] = force_reg (TFmode, operands[1]);
867 (define_insn "*movtf_aarch64"
868 [(set (match_operand:TF 0
869 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
871 "general_operand" " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
872 "TARGET_FLOAT && (register_operand (operands[0], TFmode)
873 || register_operand (operands[1], TFmode))"
875 orr\\t%0.16b, %1.16b, %1.16b
885 [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,fconstd,fconstd,\
886 f_loadd,f_stored,neon_load1_2reg,neon_store1_2reg")
887 (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
888 (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
889 (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
893 [(set (match_operand:TF 0 "register_operand" "")
894 (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
895 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
898 aarch64_split_128bit_move (operands[0], operands[1]);
905 ;; 2 is size of move in bytes
908 (define_expand "movmemdi"
909 [(match_operand:BLK 0 "memory_operand")
910 (match_operand:BLK 1 "memory_operand")
911 (match_operand:DI 2 "immediate_operand")
912 (match_operand:DI 3 "immediate_operand")]
915 if (aarch64_expand_movmem (operands))
921 ;; Operands 1 and 3 are tied together by the final condition; so we allow
922 ;; fairly lax checking on the second memory operation.
923 (define_insn "load_pair<mode>"
924 [(set (match_operand:GPI 0 "register_operand" "=r")
925 (match_operand:GPI 1 "aarch64_mem_pair_operand" "Ump"))
926 (set (match_operand:GPI 2 "register_operand" "=r")
927 (match_operand:GPI 3 "memory_operand" "m"))]
928 "rtx_equal_p (XEXP (operands[3], 0),
929 plus_constant (Pmode,
930 XEXP (operands[1], 0),
931 GET_MODE_SIZE (<MODE>mode)))"
932 "ldp\\t%<w>0, %<w>2, %1"
933 [(set_attr "type" "load2")]
936 ;; Operands 0 and 2 are tied together by the final condition; so we allow
937 ;; fairly lax checking on the second memory operation.
938 (define_insn "store_pair<mode>"
939 [(set (match_operand:GPI 0 "aarch64_mem_pair_operand" "=Ump")
940 (match_operand:GPI 1 "register_operand" "r"))
941 (set (match_operand:GPI 2 "memory_operand" "=m")
942 (match_operand:GPI 3 "register_operand" "r"))]
943 "rtx_equal_p (XEXP (operands[2], 0),
944 plus_constant (Pmode,
945 XEXP (operands[0], 0),
946 GET_MODE_SIZE (<MODE>mode)))"
947 "stp\\t%<w>1, %<w>3, %0"
948 [(set_attr "type" "store2")]
951 ;; Operands 1 and 3 are tied together by the final condition; so we allow
952 ;; fairly lax checking on the second memory operation.
953 (define_insn "load_pair<mode>"
954 [(set (match_operand:GPF 0 "register_operand" "=w")
955 (match_operand:GPF 1 "aarch64_mem_pair_operand" "Ump"))
956 (set (match_operand:GPF 2 "register_operand" "=w")
957 (match_operand:GPF 3 "memory_operand" "m"))]
958 "rtx_equal_p (XEXP (operands[3], 0),
959 plus_constant (Pmode,
960 XEXP (operands[1], 0),
961 GET_MODE_SIZE (<MODE>mode)))"
962 "ldp\\t%<w>0, %<w>2, %1"
963 [(set_attr "type" "neon_load1_2reg<q>")]
966 ;; Operands 0 and 2 are tied together by the final condition; so we allow
967 ;; fairly lax checking on the second memory operation.
968 (define_insn "store_pair<mode>"
969 [(set (match_operand:GPF 0 "aarch64_mem_pair_operand" "=Ump")
970 (match_operand:GPF 1 "register_operand" "w"))
971 (set (match_operand:GPF 2 "memory_operand" "=m")
972 (match_operand:GPF 3 "register_operand" "w"))]
973 "rtx_equal_p (XEXP (operands[2], 0),
974 plus_constant (Pmode,
975 XEXP (operands[0], 0),
976 GET_MODE_SIZE (<MODE>mode)))"
977 "stp\\t%<w>1, %<w>3, %0"
978 [(set_attr "type" "neon_store1_2reg<q>")]
981 ;; Load pair with post-index writeback. This is primarily used in function
983 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
985 [(set (match_operand:P 0 "register_operand" "=k")
986 (plus:P (match_operand:P 1 "register_operand" "0")
987 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
988 (set (match_operand:GPI 2 "register_operand" "=r")
989 (mem:GPI (match_dup 1)))
990 (set (match_operand:GPI 3 "register_operand" "=r")
991 (mem:GPI (plus:P (match_dup 1)
992 (match_operand:P 5 "const_int_operand" "n"))))])]
993 "INTVAL (operands[5]) == GET_MODE_SIZE (<GPI:MODE>mode)"
994 "ldp\\t%<w>2, %<w>3, [%1], %4"
995 [(set_attr "type" "load2")]
998 (define_insn "loadwb_pair<GPF:mode>_<P:mode>"
1000 [(set (match_operand:P 0 "register_operand" "=k")
1001 (plus:P (match_operand:P 1 "register_operand" "0")
1002 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1003 (set (match_operand:GPF 2 "register_operand" "=w")
1004 (mem:GPF (match_dup 1)))
1005 (set (match_operand:GPF 3 "register_operand" "=w")
1006 (mem:GPF (plus:P (match_dup 1)
1007 (match_operand:P 5 "const_int_operand" "n"))))])]
1008 "INTVAL (operands[5]) == GET_MODE_SIZE (<GPF:MODE>mode)"
1009 "ldp\\t%<w>2, %<w>3, [%1], %4"
1010 [(set_attr "type" "neon_load1_2reg")]
1013 ;; Store pair with pre-index writeback. This is primarily used in function
1015 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
1017 [(set (match_operand:P 0 "register_operand" "=&k")
1018 (plus:P (match_operand:P 1 "register_operand" "0")
1019 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1020 (set (mem:GPI (plus:P (match_dup 0)
1022 (match_operand:GPI 2 "register_operand" "r"))
1023 (set (mem:GPI (plus:P (match_dup 0)
1024 (match_operand:P 5 "const_int_operand" "n")))
1025 (match_operand:GPI 3 "register_operand" "r"))])]
1026 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1027 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1028 [(set_attr "type" "store2")]
1031 (define_insn "storewb_pair<GPF:mode>_<P:mode>"
1033 [(set (match_operand:P 0 "register_operand" "=&k")
1034 (plus:P (match_operand:P 1 "register_operand" "0")
1035 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1036 (set (mem:GPF (plus:P (match_dup 0)
1038 (match_operand:GPF 2 "register_operand" "w"))
1039 (set (mem:GPF (plus:P (match_dup 0)
1040 (match_operand:P 5 "const_int_operand" "n")))
1041 (match_operand:GPF 3 "register_operand" "w"))])]
1042 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPF:MODE>mode)"
1043 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1044 [(set_attr "type" "neon_store1_2reg<q>")]
1047 ;; -------------------------------------------------------------------
1048 ;; Sign/Zero extension
1049 ;; -------------------------------------------------------------------
1051 (define_expand "<optab>sidi2"
1052 [(set (match_operand:DI 0 "register_operand")
1053 (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1057 (define_insn "*extendsidi2_aarch64"
1058 [(set (match_operand:DI 0 "register_operand" "=r,r")
1059 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1064 [(set_attr "type" "extend,load1")]
1067 (define_insn "*zero_extendsidi2_aarch64"
1068 [(set (match_operand:DI 0 "register_operand" "=r,r")
1069 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1074 [(set_attr "type" "extend,load1")]
1077 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1078 [(set (match_operand:GPI 0 "register_operand")
1079 (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1083 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1084 [(set (match_operand:GPI 0 "register_operand" "=r,r")
1085 (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1088 sxt<SHORT:size>\t%<GPI:w>0, %w1
1089 ldrs<SHORT:size>\t%<GPI:w>0, %1"
1090 [(set_attr "type" "extend,load1")]
1093 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1094 [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1095 (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1098 uxt<SHORT:size>\t%<GPI:w>0, %w1
1099 ldr<SHORT:size>\t%w0, %1
1100 ldr\t%<SHORT:size>0, %1"
1101 [(set_attr "type" "extend,load1,load1")]
1104 (define_expand "<optab>qihi2"
1105 [(set (match_operand:HI 0 "register_operand")
1106 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1110 (define_insn "*<optab>qihi2_aarch64"
1111 [(set (match_operand:HI 0 "register_operand" "=r,r")
1112 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1117 [(set_attr "type" "extend,load1")]
1120 ;; -------------------------------------------------------------------
1121 ;; Simple arithmetic
1122 ;; -------------------------------------------------------------------
1124 (define_expand "add<mode>3"
1126 (match_operand:GPI 0 "register_operand" "")
1127 (plus:GPI (match_operand:GPI 1 "register_operand" "")
1128 (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1131 if (! aarch64_plus_operand (operands[2], VOIDmode))
1133 rtx subtarget = ((optimize && can_create_pseudo_p ())
1134 ? gen_reg_rtx (<MODE>mode) : operands[0]);
1135 HOST_WIDE_INT imm = INTVAL (operands[2]);
1138 imm = -(-imm & ~0xfff);
1142 emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1143 operands[1] = subtarget;
1144 operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1149 (define_insn "*addsi3_aarch64"
1151 (match_operand:SI 0 "register_operand" "=rk,rk,w,rk")
1153 (match_operand:SI 1 "register_operand" "%rk,rk,w,rk")
1154 (match_operand:SI 2 "aarch64_plus_operand" "I,r,w,J")))]
1159 add\\t%0.2s, %1.2s, %2.2s
1160 sub\\t%w0, %w1, #%n2"
1161 [(set_attr "type" "alu_imm,alu_reg,neon_add,alu_imm")
1162 (set_attr "simd" "*,*,yes,*")]
1165 ;; zero_extend version of above
1166 (define_insn "*addsi3_aarch64_uxtw"
1168 (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1170 (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1171 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1176 sub\\t%w0, %w1, #%n2"
1177 [(set_attr "type" "alu_imm,alu_reg,alu_imm")]
1180 (define_insn "*adddi3_aarch64"
1182 (match_operand:DI 0 "register_operand" "=rk,rk,rk,!w")
1184 (match_operand:DI 1 "register_operand" "%rk,rk,rk,!w")
1185 (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,!w")))]
1190 sub\\t%x0, %x1, #%n2
1191 add\\t%d0, %d1, %d2"
1192 [(set_attr "type" "alu_imm,alu_reg,alu_imm,alu_reg")
1193 (set_attr "simd" "*,*,*,yes")]
1196 (define_expand "addti3"
1197 [(set (match_operand:TI 0 "register_operand" "")
1198 (plus:TI (match_operand:TI 1 "register_operand" "")
1199 (match_operand:TI 2 "register_operand" "")))]
1202 rtx low = gen_reg_rtx (DImode);
1203 emit_insn (gen_adddi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1204 gen_lowpart (DImode, operands[2])));
1206 rtx high = gen_reg_rtx (DImode);
1207 emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]),
1208 gen_highpart (DImode, operands[2])));
1210 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1211 emit_move_insn (gen_highpart (DImode, operands[0]), high);
1215 (define_insn "add<mode>3_compare0"
1216 [(set (reg:CC_NZ CC_REGNUM)
1218 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1219 (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1221 (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1222 (plus:GPI (match_dup 1) (match_dup 2)))]
1225 adds\\t%<w>0, %<w>1, %<w>2
1226 adds\\t%<w>0, %<w>1, %<w>2
1227 subs\\t%<w>0, %<w>1, #%n2"
1228 [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1231 ;; zero_extend version of above
1232 (define_insn "*addsi3_compare0_uxtw"
1233 [(set (reg:CC_NZ CC_REGNUM)
1235 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1236 (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1238 (set (match_operand:DI 0 "register_operand" "=r,r,r")
1239 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1242 adds\\t%w0, %w1, %w2
1243 adds\\t%w0, %w1, %w2
1244 subs\\t%w0, %w1, #%n2"
1245 [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1248 (define_insn "*adds_mul_imm_<mode>"
1249 [(set (reg:CC_NZ CC_REGNUM)
1252 (match_operand:GPI 1 "register_operand" "r")
1253 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1254 (match_operand:GPI 3 "register_operand" "r"))
1256 (set (match_operand:GPI 0 "register_operand" "=r")
1257 (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1260 "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1261 [(set_attr "type" "alus_shift_imm")]
1264 (define_insn "*subs_mul_imm_<mode>"
1265 [(set (reg:CC_NZ CC_REGNUM)
1267 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1269 (match_operand:GPI 2 "register_operand" "r")
1270 (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1272 (set (match_operand:GPI 0 "register_operand" "=r")
1273 (minus:GPI (match_dup 1)
1274 (mult:GPI (match_dup 2) (match_dup 3))))]
1276 "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1277 [(set_attr "type" "alus_shift_imm")]
1280 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1281 [(set (reg:CC_NZ CC_REGNUM)
1284 (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1285 (match_operand:GPI 2 "register_operand" "r"))
1287 (set (match_operand:GPI 0 "register_operand" "=r")
1288 (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1290 "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1291 [(set_attr "type" "alus_ext")]
1294 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1295 [(set (reg:CC_NZ CC_REGNUM)
1297 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1299 (match_operand:ALLX 2 "register_operand" "r")))
1301 (set (match_operand:GPI 0 "register_operand" "=r")
1302 (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1304 "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1305 [(set_attr "type" "alus_ext")]
1308 (define_insn "*adds_<optab><mode>_multp2"
1309 [(set (reg:CC_NZ CC_REGNUM)
1311 (plus:GPI (ANY_EXTRACT:GPI
1312 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1313 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1314 (match_operand 3 "const_int_operand" "n")
1316 (match_operand:GPI 4 "register_operand" "r"))
1318 (set (match_operand:GPI 0 "register_operand" "=r")
1319 (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1323 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1324 "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1325 [(set_attr "type" "alus_ext")]
1328 (define_insn "*subs_<optab><mode>_multp2"
1329 [(set (reg:CC_NZ CC_REGNUM)
1331 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1333 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1334 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1335 (match_operand 3 "const_int_operand" "n")
1338 (set (match_operand:GPI 0 "register_operand" "=r")
1339 (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1340 (mult:GPI (match_dup 1) (match_dup 2))
1343 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1344 "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1345 [(set_attr "type" "alus_ext")]
1348 (define_insn "*add<mode>3nr_compare0"
1349 [(set (reg:CC_NZ CC_REGNUM)
1351 (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1352 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1359 [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1362 (define_insn "*compare_neg<mode>"
1363 [(set (reg:CC_Z CC_REGNUM)
1365 (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1366 (match_operand:GPI 1 "register_operand" "r")))]
1368 "cmn\\t%<w>1, %<w>0"
1369 [(set_attr "type" "alus_reg")]
1372 (define_insn "*add_<shift>_<mode>"
1373 [(set (match_operand:GPI 0 "register_operand" "=r")
1374 (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1375 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1376 (match_operand:GPI 3 "register_operand" "r")))]
1378 "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1379 [(set_attr "type" "alu_shift_imm")]
1382 ;; zero_extend version of above
1383 (define_insn "*add_<shift>_si_uxtw"
1384 [(set (match_operand:DI 0 "register_operand" "=r")
1386 (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1387 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1388 (match_operand:SI 3 "register_operand" "r"))))]
1390 "add\\t%w0, %w3, %w1, <shift> %2"
1391 [(set_attr "type" "alu_shift_imm")]
1394 (define_insn "*add_mul_imm_<mode>"
1395 [(set (match_operand:GPI 0 "register_operand" "=r")
1396 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1397 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1398 (match_operand:GPI 3 "register_operand" "r")))]
1400 "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1401 [(set_attr "type" "alu_shift_imm")]
1404 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1405 [(set (match_operand:GPI 0 "register_operand" "=rk")
1406 (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1407 (match_operand:GPI 2 "register_operand" "r")))]
1409 "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1410 [(set_attr "type" "alu_ext")]
1413 ;; zero_extend version of above
1414 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1415 [(set (match_operand:DI 0 "register_operand" "=rk")
1417 (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1418 (match_operand:GPI 2 "register_operand" "r"))))]
1420 "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1421 [(set_attr "type" "alu_ext")]
1424 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1425 [(set (match_operand:GPI 0 "register_operand" "=rk")
1426 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1427 (match_operand:ALLX 1 "register_operand" "r"))
1428 (match_operand 2 "aarch64_imm3" "Ui3"))
1429 (match_operand:GPI 3 "register_operand" "r")))]
1431 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1432 [(set_attr "type" "alu_ext")]
1435 ;; zero_extend version of above
1436 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1437 [(set (match_operand:DI 0 "register_operand" "=rk")
1439 (plus:SI (ashift:SI (ANY_EXTEND:SI
1440 (match_operand:SHORT 1 "register_operand" "r"))
1441 (match_operand 2 "aarch64_imm3" "Ui3"))
1442 (match_operand:SI 3 "register_operand" "r"))))]
1444 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1445 [(set_attr "type" "alu_ext")]
1448 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1449 [(set (match_operand:GPI 0 "register_operand" "=rk")
1450 (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1451 (match_operand:ALLX 1 "register_operand" "r"))
1452 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1453 (match_operand:GPI 3 "register_operand" "r")))]
1455 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1456 [(set_attr "type" "alu_ext")]
1459 ;; zero_extend version of above
1460 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1461 [(set (match_operand:DI 0 "register_operand" "=rk")
1462 (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1463 (match_operand:SHORT 1 "register_operand" "r"))
1464 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1465 (match_operand:SI 3 "register_operand" "r"))))]
1467 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1468 [(set_attr "type" "alu_ext")]
1471 (define_insn "*add_<optab><mode>_multp2"
1472 [(set (match_operand:GPI 0 "register_operand" "=rk")
1473 (plus:GPI (ANY_EXTRACT:GPI
1474 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1475 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1476 (match_operand 3 "const_int_operand" "n")
1478 (match_operand:GPI 4 "register_operand" "r")))]
1479 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1480 "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1481 [(set_attr "type" "alu_ext")]
1484 ;; zero_extend version of above
1485 (define_insn "*add_<optab>si_multp2_uxtw"
1486 [(set (match_operand:DI 0 "register_operand" "=rk")
1488 (plus:SI (ANY_EXTRACT:SI
1489 (mult:SI (match_operand:SI 1 "register_operand" "r")
1490 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1491 (match_operand 3 "const_int_operand" "n")
1493 (match_operand:SI 4 "register_operand" "r"))))]
1494 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1495 "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1496 [(set_attr "type" "alu_ext")]
1499 (define_insn "add<mode>3_carryin"
1501 (match_operand:GPI 0 "register_operand" "=r")
1502 (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1504 (match_operand:GPI 1 "register_operand" "r")
1505 (match_operand:GPI 2 "register_operand" "r"))))]
1507 "adc\\t%<w>0, %<w>1, %<w>2"
1508 [(set_attr "type" "adc_reg")]
1511 ;; zero_extend version of above
1512 (define_insn "*addsi3_carryin_uxtw"
1514 (match_operand:DI 0 "register_operand" "=r")
1516 (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1518 (match_operand:SI 1 "register_operand" "r")
1519 (match_operand:SI 2 "register_operand" "r")))))]
1521 "adc\\t%w0, %w1, %w2"
1522 [(set_attr "type" "adc_reg")]
1525 (define_insn "*add<mode>3_carryin_alt1"
1527 (match_operand:GPI 0 "register_operand" "=r")
1529 (match_operand:GPI 1 "register_operand" "r")
1530 (match_operand:GPI 2 "register_operand" "r"))
1531 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1533 "adc\\t%<w>0, %<w>1, %<w>2"
1534 [(set_attr "type" "adc_reg")]
1537 ;; zero_extend version of above
1538 (define_insn "*addsi3_carryin_alt1_uxtw"
1540 (match_operand:DI 0 "register_operand" "=r")
1543 (match_operand:SI 1 "register_operand" "r")
1544 (match_operand:SI 2 "register_operand" "r"))
1545 (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1547 "adc\\t%w0, %w1, %w2"
1548 [(set_attr "type" "adc_reg")]
1551 (define_insn "*add<mode>3_carryin_alt2"
1553 (match_operand:GPI 0 "register_operand" "=r")
1555 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1556 (match_operand:GPI 1 "register_operand" "r"))
1557 (match_operand:GPI 2 "register_operand" "r")))]
1559 "adc\\t%<w>0, %<w>1, %<w>2"
1560 [(set_attr "type" "adc_reg")]
1563 ;; zero_extend version of above
1564 (define_insn "*addsi3_carryin_alt2_uxtw"
1566 (match_operand:DI 0 "register_operand" "=r")
1569 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1570 (match_operand:SI 1 "register_operand" "r"))
1571 (match_operand:SI 2 "register_operand" "r"))))]
1573 "adc\\t%w0, %w1, %w2"
1574 [(set_attr "type" "adc_reg")]
1577 (define_insn "*add<mode>3_carryin_alt3"
1579 (match_operand:GPI 0 "register_operand" "=r")
1581 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1582 (match_operand:GPI 2 "register_operand" "r"))
1583 (match_operand:GPI 1 "register_operand" "r")))]
1585 "adc\\t%<w>0, %<w>1, %<w>2"
1586 [(set_attr "type" "adc_reg")]
1589 ;; zero_extend version of above
1590 (define_insn "*addsi3_carryin_alt3_uxtw"
1592 (match_operand:DI 0 "register_operand" "=r")
1595 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1596 (match_operand:SI 2 "register_operand" "r"))
1597 (match_operand:SI 1 "register_operand" "r"))))]
1599 "adc\\t%w0, %w1, %w2"
1600 [(set_attr "type" "adc_reg")]
1603 (define_insn "*add_uxt<mode>_multp2"
1604 [(set (match_operand:GPI 0 "register_operand" "=rk")
1606 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1607 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1608 (match_operand 3 "const_int_operand" "n"))
1609 (match_operand:GPI 4 "register_operand" "r")))]
1610 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1612 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1613 INTVAL (operands[3])));
1614 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1615 [(set_attr "type" "alu_ext")]
1618 ;; zero_extend version of above
1619 (define_insn "*add_uxtsi_multp2_uxtw"
1620 [(set (match_operand:DI 0 "register_operand" "=rk")
1623 (mult:SI (match_operand:SI 1 "register_operand" "r")
1624 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1625 (match_operand 3 "const_int_operand" "n"))
1626 (match_operand:SI 4 "register_operand" "r"))))]
1627 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1629 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1630 INTVAL (operands[3])));
1631 return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1632 [(set_attr "type" "alu_ext")]
1635 (define_insn "subsi3"
1636 [(set (match_operand:SI 0 "register_operand" "=rk")
1637 (minus:SI (match_operand:SI 1 "register_operand" "r")
1638 (match_operand:SI 2 "register_operand" "r")))]
1640 "sub\\t%w0, %w1, %w2"
1641 [(set_attr "type" "alu_reg")]
1644 ;; zero_extend version of above
1645 (define_insn "*subsi3_uxtw"
1646 [(set (match_operand:DI 0 "register_operand" "=rk")
1648 (minus:SI (match_operand:SI 1 "register_operand" "r")
1649 (match_operand:SI 2 "register_operand" "r"))))]
1651 "sub\\t%w0, %w1, %w2"
1652 [(set_attr "type" "alu_reg")]
1655 (define_insn "subdi3"
1656 [(set (match_operand:DI 0 "register_operand" "=rk,!w")
1657 (minus:DI (match_operand:DI 1 "register_operand" "r,!w")
1658 (match_operand:DI 2 "register_operand" "r,!w")))]
1662 sub\\t%d0, %d1, %d2"
1663 [(set_attr "type" "alu_reg, neon_sub")
1664 (set_attr "simd" "*,yes")]
1667 (define_expand "subti3"
1668 [(set (match_operand:TI 0 "register_operand" "")
1669 (minus:TI (match_operand:TI 1 "register_operand" "")
1670 (match_operand:TI 2 "register_operand" "")))]
1673 rtx low = gen_reg_rtx (DImode);
1674 emit_insn (gen_subdi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1675 gen_lowpart (DImode, operands[2])));
1677 rtx high = gen_reg_rtx (DImode);
1678 emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]),
1679 gen_highpart (DImode, operands[2])));
1681 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1682 emit_move_insn (gen_highpart (DImode, operands[0]), high);
1686 (define_insn "sub<mode>3_compare0"
1687 [(set (reg:CC_NZ CC_REGNUM)
1688 (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1689 (match_operand:GPI 2 "register_operand" "r"))
1691 (set (match_operand:GPI 0 "register_operand" "=r")
1692 (minus:GPI (match_dup 1) (match_dup 2)))]
1694 "subs\\t%<w>0, %<w>1, %<w>2"
1695 [(set_attr "type" "alus_reg")]
1698 ;; zero_extend version of above
1699 (define_insn "*subsi3_compare0_uxtw"
1700 [(set (reg:CC_NZ CC_REGNUM)
1701 (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1702 (match_operand:SI 2 "register_operand" "r"))
1704 (set (match_operand:DI 0 "register_operand" "=r")
1705 (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1707 "subs\\t%w0, %w1, %w2"
1708 [(set_attr "type" "alus_reg")]
1711 (define_insn "*sub_<shift>_<mode>"
1712 [(set (match_operand:GPI 0 "register_operand" "=r")
1713 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1715 (match_operand:GPI 1 "register_operand" "r")
1716 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1718 "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1719 [(set_attr "type" "alu_shift_imm")]
1722 ;; zero_extend version of above
1723 (define_insn "*sub_<shift>_si_uxtw"
1724 [(set (match_operand:DI 0 "register_operand" "=r")
1726 (minus:SI (match_operand:SI 3 "register_operand" "r")
1728 (match_operand:SI 1 "register_operand" "r")
1729 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1731 "sub\\t%w0, %w3, %w1, <shift> %2"
1732 [(set_attr "type" "alu_shift_imm")]
1735 (define_insn "*sub_mul_imm_<mode>"
1736 [(set (match_operand:GPI 0 "register_operand" "=r")
1737 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1739 (match_operand:GPI 1 "register_operand" "r")
1740 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1742 "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1743 [(set_attr "type" "alu_shift_imm")]
1746 ;; zero_extend version of above
1747 (define_insn "*sub_mul_imm_si_uxtw"
1748 [(set (match_operand:DI 0 "register_operand" "=r")
1750 (minus:SI (match_operand:SI 3 "register_operand" "r")
1752 (match_operand:SI 1 "register_operand" "r")
1753 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
1755 "sub\\t%w0, %w3, %w1, lsl %p2"
1756 [(set_attr "type" "alu_shift_imm")]
1759 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
1760 [(set (match_operand:GPI 0 "register_operand" "=rk")
1761 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1763 (match_operand:ALLX 2 "register_operand" "r"))))]
1765 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1766 [(set_attr "type" "alu_ext")]
1769 ;; zero_extend version of above
1770 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
1771 [(set (match_operand:DI 0 "register_operand" "=rk")
1773 (minus:SI (match_operand:SI 1 "register_operand" "r")
1775 (match_operand:SHORT 2 "register_operand" "r")))))]
1777 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
1778 [(set_attr "type" "alu_ext")]
1781 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
1782 [(set (match_operand:GPI 0 "register_operand" "=rk")
1783 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1784 (ashift:GPI (ANY_EXTEND:GPI
1785 (match_operand:ALLX 2 "register_operand" "r"))
1786 (match_operand 3 "aarch64_imm3" "Ui3"))))]
1788 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1789 [(set_attr "type" "alu_ext")]
1792 ;; zero_extend version of above
1793 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
1794 [(set (match_operand:DI 0 "register_operand" "=rk")
1796 (minus:SI (match_operand:SI 1 "register_operand" "r")
1797 (ashift:SI (ANY_EXTEND:SI
1798 (match_operand:SHORT 2 "register_operand" "r"))
1799 (match_operand 3 "aarch64_imm3" "Ui3")))))]
1801 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
1802 [(set_attr "type" "alu_ext")]
1805 (define_insn "*sub_<optab><mode>_multp2"
1806 [(set (match_operand:GPI 0 "register_operand" "=rk")
1807 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1809 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1810 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1811 (match_operand 3 "const_int_operand" "n")
1813 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1814 "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1815 [(set_attr "type" "alu_ext")]
1818 ;; zero_extend version of above
1819 (define_insn "*sub_<optab>si_multp2_uxtw"
1820 [(set (match_operand:DI 0 "register_operand" "=rk")
1822 (minus:SI (match_operand:SI 4 "register_operand" "r")
1824 (mult:SI (match_operand:SI 1 "register_operand" "r")
1825 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1826 (match_operand 3 "const_int_operand" "n")
1828 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1829 "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1830 [(set_attr "type" "alu_ext")]
1833 (define_insn "sub<mode>3_carryin"
1835 (match_operand:GPI 0 "register_operand" "=r")
1836 (minus:GPI (minus:GPI
1837 (match_operand:GPI 1 "register_operand" "r")
1838 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
1839 (match_operand:GPI 2 "register_operand" "r")))]
1841 "sbc\\t%<w>0, %<w>1, %<w>2"
1842 [(set_attr "type" "adc_reg")]
1845 ;; zero_extend version of the above
1846 (define_insn "*subsi3_carryin_uxtw"
1848 (match_operand:DI 0 "register_operand" "=r")
1851 (match_operand:SI 1 "register_operand" "r")
1852 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
1853 (match_operand:SI 2 "register_operand" "r"))))]
1855 "sbc\\t%w0, %w1, %w2"
1856 [(set_attr "type" "adc_reg")]
1859 (define_insn "*sub_uxt<mode>_multp2"
1860 [(set (match_operand:GPI 0 "register_operand" "=rk")
1861 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1863 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1864 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1865 (match_operand 3 "const_int_operand" "n"))))]
1866 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1868 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1869 INTVAL (operands[3])));
1870 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1871 [(set_attr "type" "alu_ext")]
1874 ;; zero_extend version of above
1875 (define_insn "*sub_uxtsi_multp2_uxtw"
1876 [(set (match_operand:DI 0 "register_operand" "=rk")
1878 (minus:SI (match_operand:SI 4 "register_operand" "r")
1880 (mult:SI (match_operand:SI 1 "register_operand" "r")
1881 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1882 (match_operand 3 "const_int_operand" "n")))))]
1883 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1885 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1886 INTVAL (operands[3])));
1887 return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
1888 [(set_attr "type" "alu_ext")]
1891 (define_insn_and_split "absdi2"
1892 [(set (match_operand:DI 0 "register_operand" "=r,w")
1893 (abs:DI (match_operand:DI 1 "register_operand" "r,w")))
1894 (clobber (match_scratch:DI 2 "=&r,X"))]
1900 && GP_REGNUM_P (REGNO (operands[0]))
1901 && GP_REGNUM_P (REGNO (operands[1]))"
1904 emit_insn (gen_rtx_SET (VOIDmode, operands[2],
1905 gen_rtx_XOR (DImode,
1906 gen_rtx_ASHIFTRT (DImode,
1910 emit_insn (gen_rtx_SET (VOIDmode,
1912 gen_rtx_MINUS (DImode,
1914 gen_rtx_ASHIFTRT (DImode,
1919 [(set_attr "type" "alu_sreg")
1920 (set_attr "simd" "no,yes")]
1923 (define_insn "neg<mode>2"
1924 [(set (match_operand:GPI 0 "register_operand" "=r,w")
1925 (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
1929 neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
1930 [(set_attr "type" "alu_reg, neon_neg<q>")
1931 (set_attr "simd" "*,yes")]
1934 ;; zero_extend version of above
1935 (define_insn "*negsi2_uxtw"
1936 [(set (match_operand:DI 0 "register_operand" "=r")
1937 (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
1940 [(set_attr "type" "alu_reg")]
1943 (define_insn "*ngc<mode>"
1944 [(set (match_operand:GPI 0 "register_operand" "=r")
1945 (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
1946 (match_operand:GPI 1 "register_operand" "r")))]
1948 "ngc\\t%<w>0, %<w>1"
1949 [(set_attr "type" "adc_reg")]
1952 (define_insn "*ngcsi_uxtw"
1953 [(set (match_operand:DI 0 "register_operand" "=r")
1955 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
1956 (match_operand:SI 1 "register_operand" "r"))))]
1959 [(set_attr "type" "adc_reg")]
1962 (define_insn "*neg<mode>2_compare0"
1963 [(set (reg:CC_NZ CC_REGNUM)
1964 (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
1966 (set (match_operand:GPI 0 "register_operand" "=r")
1967 (neg:GPI (match_dup 1)))]
1969 "negs\\t%<w>0, %<w>1"
1970 [(set_attr "type" "alus_reg")]
1973 ;; zero_extend version of above
1974 (define_insn "*negsi2_compare0_uxtw"
1975 [(set (reg:CC_NZ CC_REGNUM)
1976 (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
1978 (set (match_operand:DI 0 "register_operand" "=r")
1979 (zero_extend:DI (neg:SI (match_dup 1))))]
1982 [(set_attr "type" "alus_reg")]
1985 (define_insn "*neg_<shift><mode>3_compare0"
1986 [(set (reg:CC_NZ CC_REGNUM)
1988 (neg:GPI (ASHIFT:GPI
1989 (match_operand:GPI 1 "register_operand" "r")
1990 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
1992 (set (match_operand:GPI 0 "register_operand" "=r")
1993 (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
1995 "negs\\t%<w>0, %<w>1, <shift> %2"
1996 [(set_attr "type" "alus_shift_imm")]
1999 (define_insn "*neg_<shift>_<mode>2"
2000 [(set (match_operand:GPI 0 "register_operand" "=r")
2001 (neg:GPI (ASHIFT:GPI
2002 (match_operand:GPI 1 "register_operand" "r")
2003 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2005 "neg\\t%<w>0, %<w>1, <shift> %2"
2006 [(set_attr "type" "alu_shift_imm")]
2009 ;; zero_extend version of above
2010 (define_insn "*neg_<shift>_si2_uxtw"
2011 [(set (match_operand:DI 0 "register_operand" "=r")
2014 (match_operand:SI 1 "register_operand" "r")
2015 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2017 "neg\\t%w0, %w1, <shift> %2"
2018 [(set_attr "type" "alu_shift_imm")]
2021 (define_insn "*neg_mul_imm_<mode>2"
2022 [(set (match_operand:GPI 0 "register_operand" "=r")
2024 (match_operand:GPI 1 "register_operand" "r")
2025 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2027 "neg\\t%<w>0, %<w>1, lsl %p2"
2028 [(set_attr "type" "alu_shift_imm")]
2031 ;; zero_extend version of above
2032 (define_insn "*neg_mul_imm_si2_uxtw"
2033 [(set (match_operand:DI 0 "register_operand" "=r")
2036 (match_operand:SI 1 "register_operand" "r")
2037 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2039 "neg\\t%w0, %w1, lsl %p2"
2040 [(set_attr "type" "alu_shift_imm")]
2043 (define_insn "mul<mode>3"
2044 [(set (match_operand:GPI 0 "register_operand" "=r")
2045 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2046 (match_operand:GPI 2 "register_operand" "r")))]
2048 "mul\\t%<w>0, %<w>1, %<w>2"
2049 [(set_attr "type" "mul")]
2052 ;; zero_extend version of above
2053 (define_insn "*mulsi3_uxtw"
2054 [(set (match_operand:DI 0 "register_operand" "=r")
2056 (mult:SI (match_operand:SI 1 "register_operand" "r")
2057 (match_operand:SI 2 "register_operand" "r"))))]
2059 "mul\\t%w0, %w1, %w2"
2060 [(set_attr "type" "mul")]
2063 (define_insn "madd<mode>"
2064 [(set (match_operand:GPI 0 "register_operand" "=r")
2065 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2066 (match_operand:GPI 2 "register_operand" "r"))
2067 (match_operand:GPI 3 "register_operand" "r")))]
2069 "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2070 [(set_attr "type" "mla")]
2073 ;; zero_extend version of above
2074 (define_insn "*maddsi_uxtw"
2075 [(set (match_operand:DI 0 "register_operand" "=r")
2077 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2078 (match_operand:SI 2 "register_operand" "r"))
2079 (match_operand:SI 3 "register_operand" "r"))))]
2081 "madd\\t%w0, %w1, %w2, %w3"
2082 [(set_attr "type" "mla")]
2085 (define_insn "*msub<mode>"
2086 [(set (match_operand:GPI 0 "register_operand" "=r")
2087 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2088 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2089 (match_operand:GPI 2 "register_operand" "r"))))]
2092 "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2093 [(set_attr "type" "mla")]
2096 ;; zero_extend version of above
2097 (define_insn "*msubsi_uxtw"
2098 [(set (match_operand:DI 0 "register_operand" "=r")
2100 (minus:SI (match_operand:SI 3 "register_operand" "r")
2101 (mult:SI (match_operand:SI 1 "register_operand" "r")
2102 (match_operand:SI 2 "register_operand" "r")))))]
2105 "msub\\t%w0, %w1, %w2, %w3"
2106 [(set_attr "type" "mla")]
2109 (define_insn "*mul<mode>_neg"
2110 [(set (match_operand:GPI 0 "register_operand" "=r")
2111 (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2112 (match_operand:GPI 2 "register_operand" "r")))]
2115 "mneg\\t%<w>0, %<w>1, %<w>2"
2116 [(set_attr "type" "mul")]
2119 ;; zero_extend version of above
2120 (define_insn "*mulsi_neg_uxtw"
2121 [(set (match_operand:DI 0 "register_operand" "=r")
2123 (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2124 (match_operand:SI 2 "register_operand" "r"))))]
2127 "mneg\\t%w0, %w1, %w2"
2128 [(set_attr "type" "mul")]
2131 (define_insn "<su_optab>mulsidi3"
2132 [(set (match_operand:DI 0 "register_operand" "=r")
2133 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2134 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2136 "<su>mull\\t%0, %w1, %w2"
2137 [(set_attr "type" "<su>mull")]
2140 (define_insn "<su_optab>maddsidi4"
2141 [(set (match_operand:DI 0 "register_operand" "=r")
2143 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2144 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2145 (match_operand:DI 3 "register_operand" "r")))]
2147 "<su>maddl\\t%0, %w1, %w2, %3"
2148 [(set_attr "type" "<su>mlal")]
2151 (define_insn "<su_optab>msubsidi4"
2152 [(set (match_operand:DI 0 "register_operand" "=r")
2154 (match_operand:DI 3 "register_operand" "r")
2155 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2157 (match_operand:SI 2 "register_operand" "r")))))]
2159 "<su>msubl\\t%0, %w1, %w2, %3"
2160 [(set_attr "type" "<su>mlal")]
2163 (define_insn "*<su_optab>mulsidi_neg"
2164 [(set (match_operand:DI 0 "register_operand" "=r")
2166 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2167 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2169 "<su>mnegl\\t%0, %w1, %w2"
2170 [(set_attr "type" "<su>mull")]
2173 (define_expand "<su_optab>mulditi3"
2174 [(set (match_operand:TI 0 "register_operand")
2175 (mult:TI (ANY_EXTEND:TI (match_operand:DI 1 "register_operand"))
2176 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand"))))]
2179 rtx low = gen_reg_rtx (DImode);
2180 emit_insn (gen_muldi3 (low, operands[1], operands[2]));
2182 rtx high = gen_reg_rtx (DImode);
2183 emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2]));
2185 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2186 emit_move_insn (gen_highpart (DImode, operands[0]), high);
2190 ;; The default expansion of multi3 using umuldi3_highpart will perform
2191 ;; the additions in an order that fails to combine into two madd insns.
2192 (define_expand "multi3"
2193 [(set (match_operand:TI 0 "register_operand")
2194 (mult:TI (match_operand:TI 1 "register_operand")
2195 (match_operand:TI 2 "register_operand")))]
2198 rtx l0 = gen_reg_rtx (DImode);
2199 rtx l1 = gen_lowpart (DImode, operands[1]);
2200 rtx l2 = gen_lowpart (DImode, operands[2]);
2201 rtx h0 = gen_reg_rtx (DImode);
2202 rtx h1 = gen_highpart (DImode, operands[1]);
2203 rtx h2 = gen_highpart (DImode, operands[2]);
2205 emit_insn (gen_muldi3 (l0, l1, l2));
2206 emit_insn (gen_umuldi3_highpart (h0, l1, l2));
2207 emit_insn (gen_madddi (h0, h1, l2, h0));
2208 emit_insn (gen_madddi (h0, l1, h2, h0));
2210 emit_move_insn (gen_lowpart (DImode, operands[0]), l0);
2211 emit_move_insn (gen_highpart (DImode, operands[0]), h0);
2215 (define_insn "<su>muldi3_highpart"
2216 [(set (match_operand:DI 0 "register_operand" "=r")
2220 (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2221 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2224 "<su>mulh\\t%0, %1, %2"
2225 [(set_attr "type" "<su>mull")]
2228 (define_insn "<su_optab>div<mode>3"
2229 [(set (match_operand:GPI 0 "register_operand" "=r")
2230 (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2231 (match_operand:GPI 2 "register_operand" "r")))]
2233 "<su>div\\t%<w>0, %<w>1, %<w>2"
2234 [(set_attr "type" "<su>div")]
2237 ;; zero_extend version of above
2238 (define_insn "*<su_optab>divsi3_uxtw"
2239 [(set (match_operand:DI 0 "register_operand" "=r")
2241 (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2242 (match_operand:SI 2 "register_operand" "r"))))]
2244 "<su>div\\t%w0, %w1, %w2"
2245 [(set_attr "type" "<su>div")]
2248 ;; -------------------------------------------------------------------
2250 ;; -------------------------------------------------------------------
2252 (define_insn "*cmp<mode>"
2253 [(set (reg:CC CC_REGNUM)
2254 (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2255 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2261 [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
2264 (define_insn "*cmp<mode>"
2265 [(set (reg:CCFP CC_REGNUM)
2266 (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2267 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2271 fcmp\\t%<s>0, %<s>1"
2272 [(set_attr "type" "fcmp<s>")]
2275 (define_insn "*cmpe<mode>"
2276 [(set (reg:CCFPE CC_REGNUM)
2277 (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2278 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2282 fcmpe\\t%<s>0, %<s>1"
2283 [(set_attr "type" "fcmp<s>")]
2286 (define_insn "*cmp_swp_<shift>_reg<mode>"
2287 [(set (reg:CC_SWP CC_REGNUM)
2288 (compare:CC_SWP (ASHIFT:GPI
2289 (match_operand:GPI 0 "register_operand" "r")
2290 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2291 (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2293 "cmp\\t%<w>2, %<w>0, <shift> %1"
2294 [(set_attr "type" "alus_shift_imm")]
2297 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2298 [(set (reg:CC_SWP CC_REGNUM)
2299 (compare:CC_SWP (ANY_EXTEND:GPI
2300 (match_operand:ALLX 0 "register_operand" "r"))
2301 (match_operand:GPI 1 "register_operand" "r")))]
2303 "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2304 [(set_attr "type" "alus_ext")]
2307 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2308 [(set (reg:CC_SWP CC_REGNUM)
2309 (compare:CC_SWP (ashift:GPI
2311 (match_operand:ALLX 0 "register_operand" "r"))
2312 (match_operand 1 "aarch64_imm3" "Ui3"))
2313 (match_operand:GPI 2 "register_operand" "r")))]
2315 "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2316 [(set_attr "type" "alus_ext")]
2319 ;; -------------------------------------------------------------------
2320 ;; Store-flag and conditional select insns
2321 ;; -------------------------------------------------------------------
2323 (define_expand "cstore<mode>4"
2324 [(set (match_operand:SI 0 "register_operand" "")
2325 (match_operator:SI 1 "aarch64_comparison_operator"
2326 [(match_operand:GPI 2 "register_operand" "")
2327 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2330 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2332 operands[3] = const0_rtx;
2336 (define_expand "cstore<mode>4"
2337 [(set (match_operand:SI 0 "register_operand" "")
2338 (match_operator:SI 1 "aarch64_comparison_operator"
2339 [(match_operand:GPF 2 "register_operand" "")
2340 (match_operand:GPF 3 "register_operand" "")]))]
2343 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2345 operands[3] = const0_rtx;
2349 (define_insn "*cstore<mode>_insn"
2350 [(set (match_operand:ALLI 0 "register_operand" "=r")
2351 (match_operator:ALLI 1 "aarch64_comparison_operator"
2352 [(match_operand 2 "cc_register" "") (const_int 0)]))]
2355 [(set_attr "type" "csel")]
2358 ;; zero_extend version of the above
2359 (define_insn "*cstoresi_insn_uxtw"
2360 [(set (match_operand:DI 0 "register_operand" "=r")
2362 (match_operator:SI 1 "aarch64_comparison_operator"
2363 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2366 [(set_attr "type" "csel")]
2369 (define_insn "cstore<mode>_neg"
2370 [(set (match_operand:ALLI 0 "register_operand" "=r")
2371 (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2372 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2374 "csetm\\t%<w>0, %m1"
2375 [(set_attr "type" "csel")]
2378 ;; zero_extend version of the above
2379 (define_insn "*cstoresi_neg_uxtw"
2380 [(set (match_operand:DI 0 "register_operand" "=r")
2382 (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2383 [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2386 [(set_attr "type" "csel")]
2389 (define_expand "cmov<mode>6"
2390 [(set (match_operand:GPI 0 "register_operand" "")
2392 (match_operator 1 "aarch64_comparison_operator"
2393 [(match_operand:GPI 2 "register_operand" "")
2394 (match_operand:GPI 3 "aarch64_plus_operand" "")])
2395 (match_operand:GPI 4 "register_operand" "")
2396 (match_operand:GPI 5 "register_operand" "")))]
2399 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2401 operands[3] = const0_rtx;
2405 (define_expand "cmov<mode>6"
2406 [(set (match_operand:GPF 0 "register_operand" "")
2408 (match_operator 1 "aarch64_comparison_operator"
2409 [(match_operand:GPF 2 "register_operand" "")
2410 (match_operand:GPF 3 "register_operand" "")])
2411 (match_operand:GPF 4 "register_operand" "")
2412 (match_operand:GPF 5 "register_operand" "")))]
2415 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2417 operands[3] = const0_rtx;
2421 (define_insn "*cmov<mode>_insn"
2422 [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2424 (match_operator 1 "aarch64_comparison_operator"
2425 [(match_operand 2 "cc_register" "") (const_int 0)])
2426 (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2427 (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2428 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2429 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2430 ;; Final two alternatives should be unreachable, but included for completeness
2432 csel\\t%<w>0, %<w>3, %<w>4, %m1
2433 csinv\\t%<w>0, %<w>3, <w>zr, %m1
2434 csinv\\t%<w>0, %<w>4, <w>zr, %M1
2435 csinc\\t%<w>0, %<w>3, <w>zr, %m1
2436 csinc\\t%<w>0, %<w>4, <w>zr, %M1
2439 [(set_attr "type" "csel")]
2442 ;; zero_extend version of above
2443 (define_insn "*cmovsi_insn_uxtw"
2444 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2447 (match_operator 1 "aarch64_comparison_operator"
2448 [(match_operand 2 "cc_register" "") (const_int 0)])
2449 (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2450 (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2451 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2452 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2453 ;; Final two alternatives should be unreachable, but included for completeness
2455 csel\\t%w0, %w3, %w4, %m1
2456 csinv\\t%w0, %w3, wzr, %m1
2457 csinv\\t%w0, %w4, wzr, %M1
2458 csinc\\t%w0, %w3, wzr, %m1
2459 csinc\\t%w0, %w4, wzr, %M1
2462 [(set_attr "type" "csel")]
2465 (define_insn "*cmov<mode>_insn"
2466 [(set (match_operand:GPF 0 "register_operand" "=w")
2468 (match_operator 1 "aarch64_comparison_operator"
2469 [(match_operand 2 "cc_register" "") (const_int 0)])
2470 (match_operand:GPF 3 "register_operand" "w")
2471 (match_operand:GPF 4 "register_operand" "w")))]
2473 "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2474 [(set_attr "type" "fcsel")]
2477 (define_expand "mov<mode>cc"
2478 [(set (match_operand:ALLI 0 "register_operand" "")
2479 (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2480 (match_operand:ALLI 2 "register_operand" "")
2481 (match_operand:ALLI 3 "register_operand" "")))]
2485 enum rtx_code code = GET_CODE (operands[1]);
2487 if (code == UNEQ || code == LTGT)
2490 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2491 XEXP (operands[1], 1));
2492 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2496 (define_expand "mov<GPF:mode><GPI:mode>cc"
2497 [(set (match_operand:GPI 0 "register_operand" "")
2498 (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2499 (match_operand:GPF 2 "register_operand" "")
2500 (match_operand:GPF 3 "register_operand" "")))]
2504 enum rtx_code code = GET_CODE (operands[1]);
2506 if (code == UNEQ || code == LTGT)
2509 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2510 XEXP (operands[1], 1));
2511 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2515 (define_expand "mov<mode>cc"
2516 [(set (match_operand:GPF 0 "register_operand" "")
2517 (if_then_else:GPF (match_operand 1 "aarch64_comparison_operator" "")
2518 (match_operand:GPF 2 "register_operand" "")
2519 (match_operand:GPF 3 "register_operand" "")))]
2523 enum rtx_code code = GET_CODE (operands[1]);
2525 if (code == UNEQ || code == LTGT)
2528 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2529 XEXP (operands[1], 1));
2530 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2535 ;; CRC32 instructions.
2536 (define_insn "aarch64_<crc_variant>"
2537 [(set (match_operand:SI 0 "register_operand" "=r")
2538 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2539 (match_operand:<crc_mode> 2 "register_operand" "r")]
2543 if (GET_MODE_BITSIZE (GET_MODE (operands[2])) >= 64)
2544 return "<crc_variant>\\t%w0, %w1, %x2";
2546 return "<crc_variant>\\t%w0, %w1, %w2";
2548 [(set_attr "type" "crc")]
2551 (define_insn "*csinc2<mode>_insn"
2552 [(set (match_operand:GPI 0 "register_operand" "=r")
2553 (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator"
2554 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
2555 (match_operand:GPI 1 "register_operand" "r")))]
2557 "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2558 [(set_attr "type" "csel")]
2561 (define_insn "csinc3<mode>_insn"
2562 [(set (match_operand:GPI 0 "register_operand" "=r")
2564 (match_operator:GPI 1 "aarch64_comparison_operator"
2565 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2566 (plus:GPI (match_operand:GPI 3 "register_operand" "r")
2568 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2570 "csinc\\t%<w>0, %<w>4, %<w>3, %M1"
2571 [(set_attr "type" "csel")]
2574 (define_insn "*csinv3<mode>_insn"
2575 [(set (match_operand:GPI 0 "register_operand" "=r")
2577 (match_operator:GPI 1 "aarch64_comparison_operator"
2578 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2579 (not:GPI (match_operand:GPI 3 "register_operand" "r"))
2580 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2582 "csinv\\t%<w>0, %<w>4, %<w>3, %M1"
2583 [(set_attr "type" "csel")]
2586 (define_insn "*csneg3<mode>_insn"
2587 [(set (match_operand:GPI 0 "register_operand" "=r")
2589 (match_operator:GPI 1 "aarch64_comparison_operator"
2590 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2591 (neg:GPI (match_operand:GPI 3 "register_operand" "r"))
2592 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2594 "csneg\\t%<w>0, %<w>4, %<w>3, %M1"
2595 [(set_attr "type" "csel")]
2598 ;; -------------------------------------------------------------------
2599 ;; Logical operations
2600 ;; -------------------------------------------------------------------
2602 (define_insn "<optab><mode>3"
2603 [(set (match_operand:GPI 0 "register_operand" "=r,rk")
2604 (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2605 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
2607 "<logical>\\t%<w>0, %<w>1, %<w>2"
2608 [(set_attr "type" "logic_reg,logic_imm")]
2611 ;; zero_extend version of above
2612 (define_insn "*<optab>si3_uxtw"
2613 [(set (match_operand:DI 0 "register_operand" "=r,rk")
2615 (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2616 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2618 "<logical>\\t%w0, %w1, %w2"
2619 [(set_attr "type" "logic_reg,logic_imm")]
2622 (define_insn "*and<mode>3_compare0"
2623 [(set (reg:CC_NZ CC_REGNUM)
2625 (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2626 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2628 (set (match_operand:GPI 0 "register_operand" "=r,r")
2629 (and:GPI (match_dup 1) (match_dup 2)))]
2631 "ands\\t%<w>0, %<w>1, %<w>2"
2632 [(set_attr "type" "logics_reg,logics_imm")]
2635 ;; zero_extend version of above
2636 (define_insn "*andsi3_compare0_uxtw"
2637 [(set (reg:CC_NZ CC_REGNUM)
2639 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2640 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2642 (set (match_operand:DI 0 "register_operand" "=r,r")
2643 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2645 "ands\\t%w0, %w1, %w2"
2646 [(set_attr "type" "logics_reg,logics_imm")]
2649 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2650 [(set (reg:CC_NZ CC_REGNUM)
2653 (match_operand:GPI 1 "register_operand" "r")
2654 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2655 (match_operand:GPI 3 "register_operand" "r"))
2657 (set (match_operand:GPI 0 "register_operand" "=r")
2658 (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2660 "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2661 [(set_attr "type" "logics_shift_imm")]
2664 ;; zero_extend version of above
2665 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2666 [(set (reg:CC_NZ CC_REGNUM)
2669 (match_operand:SI 1 "register_operand" "r")
2670 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2671 (match_operand:SI 3 "register_operand" "r"))
2673 (set (match_operand:DI 0 "register_operand" "=r")
2674 (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2677 "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2678 [(set_attr "type" "logics_shift_imm")]
2681 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2682 [(set (match_operand:GPI 0 "register_operand" "=r")
2683 (LOGICAL:GPI (SHIFT:GPI
2684 (match_operand:GPI 1 "register_operand" "r")
2685 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2686 (match_operand:GPI 3 "register_operand" "r")))]
2688 "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2689 [(set_attr "type" "logic_shift_imm")]
2692 (define_insn "*<optab>_rol<mode>3"
2693 [(set (match_operand:GPI 0 "register_operand" "=r")
2694 (LOGICAL:GPI (rotate:GPI
2695 (match_operand:GPI 1 "register_operand" "r")
2696 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2697 (match_operand:GPI 3 "register_operand" "r")))]
2699 "<logical>\\t%<w>0, %<w>3, %<w>1, ror (<sizen> - %2)"
2700 [(set_attr "type" "logic_shift_imm")]
2703 ;; zero_extend versions of above
2704 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
2705 [(set (match_operand:DI 0 "register_operand" "=r")
2707 (LOGICAL:SI (SHIFT:SI
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 "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2713 [(set_attr "type" "logic_shift_imm")]
2716 (define_insn "*<optab>_rolsi3_uxtw"
2717 [(set (match_operand:DI 0 "register_operand" "=r")
2719 (LOGICAL:SI (rotate:SI
2720 (match_operand:SI 1 "register_operand" "r")
2721 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2722 (match_operand:SI 3 "register_operand" "r"))))]
2724 "<logical>\\t%w0, %w3, %w1, ror (32 - %2)"
2725 [(set_attr "type" "logic_shift_imm")]
2728 (define_insn "one_cmpl<mode>2"
2729 [(set (match_operand:GPI 0 "register_operand" "=r")
2730 (not:GPI (match_operand:GPI 1 "register_operand" "r")))]
2732 "mvn\\t%<w>0, %<w>1"
2733 [(set_attr "type" "logic_reg")]
2736 (define_insn "*one_cmpl_<optab><mode>2"
2737 [(set (match_operand:GPI 0 "register_operand" "=r")
2738 (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
2739 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2741 "mvn\\t%<w>0, %<w>1, <shift> %2"
2742 [(set_attr "type" "logic_shift_imm")]
2745 (define_insn "*<LOGICAL:optab>_one_cmpl<mode>3"
2746 [(set (match_operand:GPI 0 "register_operand" "=r")
2747 (LOGICAL:GPI (not:GPI
2748 (match_operand:GPI 1 "register_operand" "r"))
2749 (match_operand:GPI 2 "register_operand" "r")))]
2751 "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1"
2752 [(set_attr "type" "logic_reg")]
2755 (define_insn "*and_one_cmpl<mode>3_compare0"
2756 [(set (reg:CC_NZ CC_REGNUM)
2759 (match_operand:GPI 1 "register_operand" "r"))
2760 (match_operand:GPI 2 "register_operand" "r"))
2762 (set (match_operand:GPI 0 "register_operand" "=r")
2763 (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
2765 "bics\\t%<w>0, %<w>2, %<w>1"
2766 [(set_attr "type" "logics_reg")]
2769 ;; zero_extend version of above
2770 (define_insn "*and_one_cmplsi3_compare0_uxtw"
2771 [(set (reg:CC_NZ CC_REGNUM)
2774 (match_operand:SI 1 "register_operand" "r"))
2775 (match_operand:SI 2 "register_operand" "r"))
2777 (set (match_operand:DI 0 "register_operand" "=r")
2778 (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
2780 "bics\\t%w0, %w2, %w1"
2781 [(set_attr "type" "logics_reg")]
2784 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
2785 [(set (match_operand:GPI 0 "register_operand" "=r")
2786 (LOGICAL:GPI (not:GPI
2788 (match_operand:GPI 1 "register_operand" "r")
2789 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2790 (match_operand:GPI 3 "register_operand" "r")))]
2792 "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2793 [(set_attr "type" "logics_shift_imm")]
2796 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
2797 [(set (reg:CC_NZ CC_REGNUM)
2801 (match_operand:GPI 1 "register_operand" "r")
2802 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2803 (match_operand:GPI 3 "register_operand" "r"))
2805 (set (match_operand:GPI 0 "register_operand" "=r")
2808 (match_dup 1) (match_dup 2))) (match_dup 3)))]
2810 "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2811 [(set_attr "type" "logics_shift_imm")]
2814 ;; zero_extend version of above
2815 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
2816 [(set (reg:CC_NZ CC_REGNUM)
2820 (match_operand:SI 1 "register_operand" "r")
2821 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
2822 (match_operand:SI 3 "register_operand" "r"))
2824 (set (match_operand:DI 0 "register_operand" "=r")
2825 (zero_extend:DI (and:SI
2827 (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
2829 "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2830 [(set_attr "type" "logics_shift_imm")]
2833 (define_insn "clz<mode>2"
2834 [(set (match_operand:GPI 0 "register_operand" "=r")
2835 (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
2837 "clz\\t%<w>0, %<w>1"
2838 [(set_attr "type" "clz")]
2841 (define_expand "ffs<mode>2"
2842 [(match_operand:GPI 0 "register_operand")
2843 (match_operand:GPI 1 "register_operand")]
2846 rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
2847 rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
2849 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2850 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2851 emit_insn (gen_csinc3<mode>_insn (operands[0], x, ccreg, operands[0], const0_rtx));
2856 (define_insn "clrsb<mode>2"
2857 [(set (match_operand:GPI 0 "register_operand" "=r")
2858 (clrsb:GPI (match_operand:GPI 1 "register_operand" "r")))]
2860 "cls\\t%<w>0, %<w>1"
2861 [(set_attr "type" "clz")]
2864 (define_insn "rbit<mode>2"
2865 [(set (match_operand:GPI 0 "register_operand" "=r")
2866 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
2868 "rbit\\t%<w>0, %<w>1"
2869 [(set_attr "type" "rbit")]
2872 (define_expand "ctz<mode>2"
2873 [(match_operand:GPI 0 "register_operand")
2874 (match_operand:GPI 1 "register_operand")]
2877 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2878 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2883 (define_insn "*and<mode>3nr_compare0"
2884 [(set (reg:CC_NZ CC_REGNUM)
2886 (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
2887 (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
2890 "tst\\t%<w>0, %<w>1"
2891 [(set_attr "type" "logics_reg")]
2894 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
2895 [(set (reg:CC_NZ CC_REGNUM)
2898 (match_operand:GPI 0 "register_operand" "r")
2899 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2900 (match_operand:GPI 2 "register_operand" "r"))
2903 "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
2904 [(set_attr "type" "logics_shift_imm")]
2907 ;; -------------------------------------------------------------------
2909 ;; -------------------------------------------------------------------
2911 (define_expand "<optab><mode>3"
2912 [(set (match_operand:GPI 0 "register_operand")
2913 (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
2914 (match_operand:QI 2 "nonmemory_operand")))]
2917 if (CONST_INT_P (operands[2]))
2919 operands[2] = GEN_INT (INTVAL (operands[2])
2920 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2922 if (operands[2] == const0_rtx)
2924 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2931 (define_expand "ashl<mode>3"
2932 [(set (match_operand:SHORT 0 "register_operand")
2933 (ashift:SHORT (match_operand:SHORT 1 "register_operand")
2934 (match_operand:QI 2 "nonmemory_operand")))]
2937 if (CONST_INT_P (operands[2]))
2939 operands[2] = GEN_INT (INTVAL (operands[2])
2940 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2942 if (operands[2] == const0_rtx)
2944 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2951 (define_expand "rotr<mode>3"
2952 [(set (match_operand:GPI 0 "register_operand")
2953 (rotatert:GPI (match_operand:GPI 1 "register_operand")
2954 (match_operand:QI 2 "nonmemory_operand")))]
2957 if (CONST_INT_P (operands[2]))
2959 operands[2] = GEN_INT (INTVAL (operands[2])
2960 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2962 if (operands[2] == const0_rtx)
2964 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2971 (define_expand "rotl<mode>3"
2972 [(set (match_operand:GPI 0 "register_operand")
2973 (rotatert:GPI (match_operand:GPI 1 "register_operand")
2974 (match_operand:QI 2 "nonmemory_operand")))]
2977 /* (SZ - cnt) % SZ == -cnt % SZ */
2978 if (CONST_INT_P (operands[2]))
2980 operands[2] = GEN_INT ((-INTVAL (operands[2]))
2981 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2982 if (operands[2] == const0_rtx)
2984 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2989 operands[2] = expand_simple_unop (QImode, NEG, operands[2],
2994 ;; Logical left shift using SISD or Integer instruction
2995 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
2996 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
2998 (match_operand:GPI 1 "register_operand" "w,w,r")
2999 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3002 shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3003 ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
3004 lsl\t%<w>0, %<w>1, %<w>2"
3005 [(set_attr "simd" "yes,yes,no")
3006 (set_attr "type" "neon_shift_imm<q>, neon_shift_reg<q>,shift_reg")]
3009 ;; Logical right shift using SISD or Integer instruction
3010 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3011 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3013 (match_operand:GPI 1 "register_operand" "w,w,r")
3014 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3017 ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3019 lsr\t%<w>0, %<w>1, %<w>2"
3020 [(set_attr "simd" "yes,yes,no")
3021 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")]
3025 [(set (match_operand:DI 0 "aarch64_simd_register")
3027 (match_operand:DI 1 "aarch64_simd_register")
3028 (match_operand:QI 2 "aarch64_simd_register")))]
3029 "TARGET_SIMD && reload_completed"
3031 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3033 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_USHL))]
3038 [(set (match_operand:SI 0 "aarch64_simd_register")
3040 (match_operand:SI 1 "aarch64_simd_register")
3041 (match_operand:QI 2 "aarch64_simd_register")))]
3042 "TARGET_SIMD && reload_completed"
3044 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3046 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_USHL_2S))]
3050 ;; Arithmetic right shift using SISD or Integer instruction
3051 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3052 [(set (match_operand:GPI 0 "register_operand" "=w,&w,&w,r")
3054 (match_operand:GPI 1 "register_operand" "w,w,w,r")
3055 (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,0,rUs<cmode>")))]
3058 sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3061 asr\t%<w>0, %<w>1, %<w>2"
3062 [(set_attr "simd" "yes,yes,yes,no")
3063 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>,shift_reg")]
3067 [(set (match_operand:DI 0 "aarch64_simd_register")
3069 (match_operand:DI 1 "aarch64_simd_register")
3070 (match_operand:QI 2 "aarch64_simd_register")))]
3071 "TARGET_SIMD && reload_completed"
3073 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3075 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_SSHL))]
3077 operands[3] = gen_lowpart (QImode, operands[0]);
3082 [(set (match_operand:SI 0 "aarch64_simd_register")
3084 (match_operand:SI 1 "aarch64_simd_register")
3085 (match_operand:QI 2 "aarch64_simd_register")))]
3086 "TARGET_SIMD && reload_completed"
3088 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3090 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_SSHL_2S))]
3092 operands[3] = gen_lowpart (QImode, operands[0]);
3096 (define_insn "*aarch64_sisd_ushl"
3097 [(set (match_operand:DI 0 "register_operand" "=w")
3098 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3099 (match_operand:QI 2 "register_operand" "w")]
3102 "ushl\t%d0, %d1, %d2"
3103 [(set_attr "simd" "yes")
3104 (set_attr "type" "neon_shift_reg")]
3107 (define_insn "*aarch64_ushl_2s"
3108 [(set (match_operand:SI 0 "register_operand" "=w")
3109 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3110 (match_operand:QI 2 "register_operand" "w")]
3113 "ushl\t%0.2s, %1.2s, %2.2s"
3114 [(set_attr "simd" "yes")
3115 (set_attr "type" "neon_shift_reg")]
3118 (define_insn "*aarch64_sisd_sshl"
3119 [(set (match_operand:DI 0 "register_operand" "=w")
3120 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3121 (match_operand:QI 2 "register_operand" "w")]
3124 "sshl\t%d0, %d1, %d2"
3125 [(set_attr "simd" "yes")
3126 (set_attr "type" "neon_shift_reg")]
3129 (define_insn "*aarch64_sshl_2s"
3130 [(set (match_operand:SI 0 "register_operand" "=w")
3131 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3132 (match_operand:QI 2 "register_operand" "w")]
3135 "sshl\t%0.2s, %1.2s, %2.2s"
3136 [(set_attr "simd" "yes")
3137 (set_attr "type" "neon_shift_reg")]
3140 (define_insn "*aarch64_sisd_neg_qi"
3141 [(set (match_operand:QI 0 "register_operand" "=w")
3142 (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3146 [(set_attr "simd" "yes")
3147 (set_attr "type" "neon_neg")]
3151 (define_insn "*ror<mode>3_insn"
3152 [(set (match_operand:GPI 0 "register_operand" "=r")
3154 (match_operand:GPI 1 "register_operand" "r")
3155 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3157 "ror\\t%<w>0, %<w>1, %<w>2"
3158 [(set_attr "type" "shift_reg")]
3161 ;; zero_extend version of above
3162 (define_insn "*<optab>si3_insn_uxtw"
3163 [(set (match_operand:DI 0 "register_operand" "=r")
3164 (zero_extend:DI (SHIFT:SI
3165 (match_operand:SI 1 "register_operand" "r")
3166 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3168 "<shift>\\t%w0, %w1, %w2"
3169 [(set_attr "type" "shift_reg")]
3172 (define_insn "*ashl<mode>3_insn"
3173 [(set (match_operand:SHORT 0 "register_operand" "=r")
3174 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3175 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
3177 "lsl\\t%<w>0, %<w>1, %<w>2"
3178 [(set_attr "type" "shift_reg")]
3181 (define_insn "*<optab><mode>3_insn"
3182 [(set (match_operand:SHORT 0 "register_operand" "=r")
3183 (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3184 (match_operand 2 "const_int_operand" "n")))]
3185 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3187 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3188 return "<bfshift>\t%w0, %w1, %2, %3";
3190 [(set_attr "type" "bfm")]
3193 (define_insn "*extr<mode>5_insn"
3194 [(set (match_operand:GPI 0 "register_operand" "=r")
3195 (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3196 (match_operand 3 "const_int_operand" "n"))
3197 (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3198 (match_operand 4 "const_int_operand" "n"))))]
3199 "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3200 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3201 "extr\\t%<w>0, %<w>1, %<w>2, %4"
3202 [(set_attr "type" "shift_imm")]
3205 ;; zero_extend version of the above
3206 (define_insn "*extrsi5_insn_uxtw"
3207 [(set (match_operand:DI 0 "register_operand" "=r")
3209 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3210 (match_operand 3 "const_int_operand" "n"))
3211 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3212 (match_operand 4 "const_int_operand" "n")))))]
3213 "UINTVAL (operands[3]) < 32 &&
3214 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3215 "extr\\t%w0, %w1, %w2, %4"
3216 [(set_attr "type" "shift_imm")]
3219 (define_insn "*ror<mode>3_insn"
3220 [(set (match_operand:GPI 0 "register_operand" "=r")
3221 (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3222 (match_operand 2 "const_int_operand" "n")))]
3223 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3225 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3226 return "ror\\t%<w>0, %<w>1, %3";
3228 [(set_attr "type" "shift_imm")]
3231 ;; zero_extend version of the above
3232 (define_insn "*rorsi3_insn_uxtw"
3233 [(set (match_operand:DI 0 "register_operand" "=r")
3235 (rotate:SI (match_operand:SI 1 "register_operand" "r")
3236 (match_operand 2 "const_int_operand" "n"))))]
3237 "UINTVAL (operands[2]) < 32"
3239 operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3240 return "ror\\t%w0, %w1, %3";
3242 [(set_attr "type" "shift_imm")]
3245 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3246 [(set (match_operand:GPI 0 "register_operand" "=r")
3248 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3249 (match_operand 2 "const_int_operand" "n"))))]
3250 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3252 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3253 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3255 [(set_attr "type" "bfm")]
3258 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3259 [(set (match_operand:GPI 0 "register_operand" "=r")
3261 (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3262 (match_operand 2 "const_int_operand" "n"))))]
3263 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3265 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3266 return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3268 [(set_attr "type" "bfm")]
3271 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3272 [(set (match_operand:GPI 0 "register_operand" "=r")
3274 (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3275 (match_operand 2 "const_int_operand" "n"))))]
3276 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3278 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3279 return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3281 [(set_attr "type" "bfm")]
3284 ;; -------------------------------------------------------------------
3286 ;; -------------------------------------------------------------------
3288 (define_expand "<optab>"
3289 [(set (match_operand:DI 0 "register_operand" "=r")
3290 (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3291 (match_operand 2 "const_int_operand" "n")
3292 (match_operand 3 "const_int_operand" "n")))]
3297 (define_insn "*<optab><mode>"
3298 [(set (match_operand:GPI 0 "register_operand" "=r")
3299 (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3300 (match_operand 2 "const_int_operand" "n")
3301 (match_operand 3 "const_int_operand" "n")))]
3303 "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3304 [(set_attr "type" "bfm")]
3307 ;; Bitfield Insert (insv)
3308 (define_expand "insv<mode>"
3309 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3310 (match_operand 1 "const_int_operand")
3311 (match_operand 2 "const_int_operand"))
3312 (match_operand:GPI 3 "general_operand"))]
3315 unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3316 unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3317 rtx value = operands[3];
3319 if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3322 if (CONST_INT_P (value))
3324 unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3326 /* Prefer AND/OR for inserting all zeros or all ones. */
3327 if ((UINTVAL (value) & mask) == 0
3328 || (UINTVAL (value) & mask) == mask)
3331 /* 16-bit aligned 16-bit wide insert is handled by insv_imm. */
3332 if (width == 16 && (pos % 16) == 0)
3335 operands[3] = force_reg (<MODE>mode, value);
3338 (define_insn "*insv_reg<mode>"
3339 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3340 (match_operand 1 "const_int_operand" "n")
3341 (match_operand 2 "const_int_operand" "n"))
3342 (match_operand:GPI 3 "register_operand" "r"))]
3343 "!(UINTVAL (operands[1]) == 0
3344 || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3345 > GET_MODE_BITSIZE (<MODE>mode)))"
3346 "bfi\\t%<w>0, %<w>3, %2, %1"
3347 [(set_attr "type" "bfm")]
3350 (define_insn "*extr_insv_lower_reg<mode>"
3351 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3352 (match_operand 1 "const_int_operand" "n")
3354 (zero_extract:GPI (match_operand:GPI 2 "register_operand" "+r")
3356 (match_operand 3 "const_int_operand" "n")))]
3357 "!(UINTVAL (operands[1]) == 0
3358 || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3359 > GET_MODE_BITSIZE (<MODE>mode)))"
3360 "bfxil\\t%<w>0, %<w>2, %3, %1"
3361 [(set_attr "type" "bfm")]
3364 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3365 [(set (match_operand:GPI 0 "register_operand" "=r")
3366 (ashift:GPI (ANY_EXTEND:GPI
3367 (match_operand:ALLX 1 "register_operand" "r"))
3368 (match_operand 2 "const_int_operand" "n")))]
3369 "UINTVAL (operands[2]) < <GPI:sizen>"
3371 operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3372 ? GEN_INT (<ALLX:sizen>)
3373 : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3374 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3376 [(set_attr "type" "bfm")]
3379 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3381 (define_insn "*andim_ashift<mode>_bfiz"
3382 [(set (match_operand:GPI 0 "register_operand" "=r")
3383 (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3384 (match_operand 2 "const_int_operand" "n"))
3385 (match_operand 3 "const_int_operand" "n")))]
3386 "exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3387 && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3388 "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3389 [(set_attr "type" "bfm")]
3392 (define_insn "bswap<mode>2"
3393 [(set (match_operand:GPI 0 "register_operand" "=r")
3394 (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3396 "rev\\t%<w>0, %<w>1"
3397 [(set_attr "type" "rev")]
3400 (define_insn "bswaphi2"
3401 [(set (match_operand:HI 0 "register_operand" "=r")
3402 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3405 [(set_attr "type" "rev")]
3408 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
3409 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
3410 ;; each valid permutation.
3412 (define_insn "rev16<mode>2"
3413 [(set (match_operand:GPI 0 "register_operand" "=r")
3414 (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3416 (match_operand:GPI 3 "const_int_operand" "n"))
3417 (and:GPI (lshiftrt:GPI (match_dup 1)
3419 (match_operand:GPI 2 "const_int_operand" "n"))))]
3420 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3421 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3422 "rev16\\t%<w>0, %<w>1"
3423 [(set_attr "type" "rev")]
3426 (define_insn "rev16<mode>2_alt"
3427 [(set (match_operand:GPI 0 "register_operand" "=r")
3428 (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r")
3430 (match_operand:GPI 2 "const_int_operand" "n"))
3431 (and:GPI (ashift:GPI (match_dup 1)
3433 (match_operand:GPI 3 "const_int_operand" "n"))))]
3434 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3435 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3436 "rev16\\t%<w>0, %<w>1"
3437 [(set_attr "type" "rev")]
3440 ;; zero_extend version of above
3441 (define_insn "*bswapsi2_uxtw"
3442 [(set (match_operand:DI 0 "register_operand" "=r")
3443 (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3446 [(set_attr "type" "rev")]
3449 ;; -------------------------------------------------------------------
3450 ;; Floating-point intrinsics
3451 ;; -------------------------------------------------------------------
3453 ;; frint floating-point round to integral standard patterns.
3454 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round, frintn.
3456 (define_insn "<frint_pattern><mode>2"
3457 [(set (match_operand:GPF 0 "register_operand" "=w")
3458 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3461 "frint<frint_suffix>\\t%<s>0, %<s>1"
3462 [(set_attr "type" "f_rint<s>")]
3465 ;; frcvt floating-point round to integer and convert standard patterns.
3466 ;; Expands to lbtrunc, lceil, lfloor, lround.
3467 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3468 [(set (match_operand:GPI 0 "register_operand" "=r")
3469 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3472 "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3473 [(set_attr "type" "f_cvtf2i")]
3478 (define_insn "fma<mode>4"
3479 [(set (match_operand:GPF 0 "register_operand" "=w")
3480 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3481 (match_operand:GPF 2 "register_operand" "w")
3482 (match_operand:GPF 3 "register_operand" "w")))]
3484 "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3485 [(set_attr "type" "fmac<s>")]
3488 (define_insn "fnma<mode>4"
3489 [(set (match_operand:GPF 0 "register_operand" "=w")
3490 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3491 (match_operand:GPF 2 "register_operand" "w")
3492 (match_operand:GPF 3 "register_operand" "w")))]
3494 "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3495 [(set_attr "type" "fmac<s>")]
3498 (define_insn "fms<mode>4"
3499 [(set (match_operand:GPF 0 "register_operand" "=w")
3500 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3501 (match_operand:GPF 2 "register_operand" "w")
3502 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3504 "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3505 [(set_attr "type" "fmac<s>")]
3508 (define_insn "fnms<mode>4"
3509 [(set (match_operand:GPF 0 "register_operand" "=w")
3510 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3511 (match_operand:GPF 2 "register_operand" "w")
3512 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3514 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3515 [(set_attr "type" "fmac<s>")]
3518 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3519 (define_insn "*fnmadd<mode>4"
3520 [(set (match_operand:GPF 0 "register_operand" "=w")
3521 (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3522 (match_operand:GPF 2 "register_operand" "w")
3523 (match_operand:GPF 3 "register_operand" "w"))))]
3524 "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3525 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3526 [(set_attr "type" "fmac<s>")]
3529 ;; -------------------------------------------------------------------
3530 ;; Floating-point conversions
3531 ;; -------------------------------------------------------------------
3533 (define_insn "extendsfdf2"
3534 [(set (match_operand:DF 0 "register_operand" "=w")
3535 (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3538 [(set_attr "type" "f_cvt")]
3541 (define_insn "truncdfsf2"
3542 [(set (match_operand:SF 0 "register_operand" "=w")
3543 (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3546 [(set_attr "type" "f_cvt")]
3549 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3550 [(set (match_operand:GPI 0 "register_operand" "=r")
3551 (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3553 "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3554 [(set_attr "type" "f_cvtf2i")]
3557 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3558 [(set (match_operand:GPI 0 "register_operand" "=r")
3559 (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3561 "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3562 [(set_attr "type" "f_cvtf2i")]
3565 (define_insn "float<GPI:mode><GPF:mode>2"
3566 [(set (match_operand:GPF 0 "register_operand" "=w")
3567 (float:GPF (match_operand:GPI 1 "register_operand" "r")))]
3569 "scvtf\\t%<GPF:s>0, %<GPI:w>1"
3570 [(set_attr "type" "f_cvti2f")]
3573 (define_insn "floatuns<GPI:mode><GPF:mode>2"
3574 [(set (match_operand:GPF 0 "register_operand" "=w")
3575 (unsigned_float:GPF (match_operand:GPI 1 "register_operand" "r")))]
3577 "ucvtf\\t%<GPF:s>0, %<GPI:w>1"
3578 [(set_attr "type" "f_cvt")]
3581 ;; -------------------------------------------------------------------
3582 ;; Floating-point arithmetic
3583 ;; -------------------------------------------------------------------
3585 (define_insn "add<mode>3"
3586 [(set (match_operand:GPF 0 "register_operand" "=w")
3588 (match_operand:GPF 1 "register_operand" "w")
3589 (match_operand:GPF 2 "register_operand" "w")))]
3591 "fadd\\t%<s>0, %<s>1, %<s>2"
3592 [(set_attr "type" "fadd<s>")]
3595 (define_insn "sub<mode>3"
3596 [(set (match_operand:GPF 0 "register_operand" "=w")
3598 (match_operand:GPF 1 "register_operand" "w")
3599 (match_operand:GPF 2 "register_operand" "w")))]
3601 "fsub\\t%<s>0, %<s>1, %<s>2"
3602 [(set_attr "type" "fadd<s>")]
3605 (define_insn "mul<mode>3"
3606 [(set (match_operand:GPF 0 "register_operand" "=w")
3608 (match_operand:GPF 1 "register_operand" "w")
3609 (match_operand:GPF 2 "register_operand" "w")))]
3611 "fmul\\t%<s>0, %<s>1, %<s>2"
3612 [(set_attr "type" "fmul<s>")]
3615 (define_insn "*fnmul<mode>3"
3616 [(set (match_operand:GPF 0 "register_operand" "=w")
3618 (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3619 (match_operand:GPF 2 "register_operand" "w")))]
3621 "fnmul\\t%<s>0, %<s>1, %<s>2"
3622 [(set_attr "type" "fmul<s>")]
3625 (define_insn "div<mode>3"
3626 [(set (match_operand:GPF 0 "register_operand" "=w")
3628 (match_operand:GPF 1 "register_operand" "w")
3629 (match_operand:GPF 2 "register_operand" "w")))]
3631 "fdiv\\t%<s>0, %<s>1, %<s>2"
3632 [(set_attr "type" "fdiv<s>")]
3635 (define_insn "neg<mode>2"
3636 [(set (match_operand:GPF 0 "register_operand" "=w")
3637 (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
3639 "fneg\\t%<s>0, %<s>1"
3640 [(set_attr "type" "ffarith<s>")]
3643 (define_insn "sqrt<mode>2"
3644 [(set (match_operand:GPF 0 "register_operand" "=w")
3645 (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
3647 "fsqrt\\t%<s>0, %<s>1"
3648 [(set_attr "type" "fsqrt<s>")]
3651 (define_insn "abs<mode>2"
3652 [(set (match_operand:GPF 0 "register_operand" "=w")
3653 (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
3655 "fabs\\t%<s>0, %<s>1"
3656 [(set_attr "type" "ffarith<s>")]
3659 ;; Given that smax/smin do not specify the result when either input is NaN,
3660 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
3663 (define_insn "smax<mode>3"
3664 [(set (match_operand:GPF 0 "register_operand" "=w")
3665 (smax:GPF (match_operand:GPF 1 "register_operand" "w")
3666 (match_operand:GPF 2 "register_operand" "w")))]
3668 "fmaxnm\\t%<s>0, %<s>1, %<s>2"
3669 [(set_attr "type" "f_minmax<s>")]
3672 (define_insn "smin<mode>3"
3673 [(set (match_operand:GPF 0 "register_operand" "=w")
3674 (smin:GPF (match_operand:GPF 1 "register_operand" "w")
3675 (match_operand:GPF 2 "register_operand" "w")))]
3677 "fminnm\\t%<s>0, %<s>1, %<s>2"
3678 [(set_attr "type" "f_minmax<s>")]
3681 ;; -------------------------------------------------------------------
3683 ;; -------------------------------------------------------------------
3685 (define_expand "aarch64_reload_mov<mode>"
3686 [(set (match_operand:TX 0 "register_operand" "=w")
3687 (match_operand:TX 1 "register_operand" "w"))
3688 (clobber (match_operand:DI 2 "register_operand" "=&r"))
3692 rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
3693 rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
3694 gen_aarch64_movtilow_tilow (op0, op1);
3695 gen_aarch64_movdi_tihigh (operands[2], op1);
3696 gen_aarch64_movtihigh_di (op0, operands[2]);
3701 ;; The following secondary reload helpers patterns are invoked
3702 ;; after or during reload as we don't want these patterns to start
3703 ;; kicking in during the combiner.
3705 (define_insn "aarch64_movdi_<mode>low"
3706 [(set (match_operand:DI 0 "register_operand" "=r")
3707 (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
3708 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
3710 [(set_attr "type" "f_mrc")
3711 (set_attr "length" "4")
3714 (define_insn "aarch64_movdi_<mode>high"
3715 [(set (match_operand:DI 0 "register_operand" "=r")
3717 (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
3719 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
3720 "fmov\\t%x0, %1.d[1]"
3721 [(set_attr "type" "f_mrc")
3722 (set_attr "length" "4")
3725 (define_insn "aarch64_mov<mode>high_di"
3726 [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
3727 (const_int 64) (const_int 64))
3728 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
3729 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
3730 "fmov\\t%0.d[1], %x1"
3731 [(set_attr "type" "f_mcr")
3732 (set_attr "length" "4")
3735 (define_insn "aarch64_mov<mode>low_di"
3736 [(set (match_operand:TX 0 "register_operand" "=w")
3737 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
3738 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
3740 [(set_attr "type" "f_mcr")
3741 (set_attr "length" "4")
3744 (define_insn "aarch64_movtilow_tilow"
3745 [(set (match_operand:TI 0 "register_operand" "=w")
3747 (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
3748 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
3750 [(set_attr "type" "fmov")
3751 (set_attr "length" "4")
3754 ;; There is a deliberate reason why the parameters of high and lo_sum's
3755 ;; don't have modes for ADRP and ADD instructions. This is to allow high
3756 ;; and lo_sum's to be used with the labels defining the jump tables in
3759 (define_expand "add_losym"
3760 [(set (match_operand 0 "register_operand" "=r")
3761 (lo_sum (match_operand 1 "register_operand" "r")
3762 (match_operand 2 "aarch64_valid_symref" "S")))]
3765 enum machine_mode mode = GET_MODE (operands[0]);
3767 emit_insn ((mode == DImode
3769 : gen_add_losym_si) (operands[0],
3775 (define_insn "add_losym_<mode>"
3776 [(set (match_operand:P 0 "register_operand" "=r")
3777 (lo_sum:P (match_operand:P 1 "register_operand" "r")
3778 (match_operand 2 "aarch64_valid_symref" "S")))]
3780 "add\\t%<w>0, %<w>1, :lo12:%a2"
3781 [(set_attr "type" "alu_reg")]
3784 (define_insn "ldr_got_small_<mode>"
3785 [(set (match_operand:PTR 0 "register_operand" "=r")
3786 (unspec:PTR [(mem:PTR (lo_sum:PTR
3787 (match_operand:PTR 1 "register_operand" "r")
3788 (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
3789 UNSPEC_GOTSMALLPIC))]
3791 "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
3792 [(set_attr "type" "load1")]
3795 (define_insn "ldr_got_small_sidi"
3796 [(set (match_operand:DI 0 "register_operand" "=r")
3798 (unspec:SI [(mem:SI (lo_sum:DI
3799 (match_operand:DI 1 "register_operand" "r")
3800 (match_operand:DI 2 "aarch64_valid_symref" "S")))]
3801 UNSPEC_GOTSMALLPIC)))]
3803 "ldr\\t%w0, [%1, #:got_lo12:%a2]"
3804 [(set_attr "type" "load1")]
3807 (define_insn "ldr_got_tiny"
3808 [(set (match_operand:DI 0 "register_operand" "=r")
3809 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
3810 UNSPEC_GOTTINYPIC))]
3813 [(set_attr "type" "load1")]
3816 (define_insn "aarch64_load_tp_hard"
3817 [(set (match_operand:DI 0 "register_operand" "=r")
3818 (unspec:DI [(const_int 0)] UNSPEC_TLS))]
3820 "mrs\\t%0, tpidr_el0"
3821 [(set_attr "type" "mrs")]
3824 ;; The TLS ABI specifically requires that the compiler does not schedule
3825 ;; instructions in the TLS stubs, in order to enable linker relaxation.
3826 ;; Therefore we treat the stubs as an atomic sequence.
3827 (define_expand "tlsgd_small"
3828 [(parallel [(set (match_operand 0 "register_operand" "")
3829 (call (mem:DI (match_dup 2)) (const_int 1)))
3830 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
3831 (clobber (reg:DI LR_REGNUM))])]
3834 operands[2] = aarch64_tls_get_addr ();
3837 (define_insn "*tlsgd_small"
3838 [(set (match_operand 0 "register_operand" "")
3839 (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
3840 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
3841 (clobber (reg:DI LR_REGNUM))
3844 "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
3845 [(set_attr "type" "call")
3846 (set_attr "length" "16")])
3848 (define_insn "tlsie_small_<mode>"
3849 [(set (match_operand:PTR 0 "register_operand" "=r")
3850 (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
3851 UNSPEC_GOTSMALLTLS))]
3853 "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
3854 [(set_attr "type" "load1")
3855 (set_attr "length" "8")]
3858 (define_insn "tlsie_small_sidi"
3859 [(set (match_operand:DI 0 "register_operand" "=r")
3861 (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")]
3862 UNSPEC_GOTSMALLTLS)))]
3864 "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
3865 [(set_attr "type" "load1")
3866 (set_attr "length" "8")]
3869 (define_expand "tlsle_small"
3870 [(set (match_operand 0 "register_operand" "=r")
3871 (unspec [(match_operand 1 "register_operand" "r")
3872 (match_operand 2 "aarch64_tls_le_symref" "S")]
3873 UNSPEC_GOTSMALLTLS))]
3876 enum machine_mode mode = GET_MODE (operands[0]);
3877 emit_insn ((mode == DImode
3878 ? gen_tlsle_small_di
3879 : gen_tlsle_small_si) (operands[0],
3885 (define_insn "tlsle_small_<mode>"
3886 [(set (match_operand:P 0 "register_operand" "=r")
3887 (unspec:P [(match_operand:P 1 "register_operand" "r")
3888 (match_operand 2 "aarch64_tls_le_symref" "S")]
3889 UNSPEC_GOTSMALLTLS))]
3891 "add\\t%<w>0, %<w>1, #%G2\;add\\t%<w>0, %<w>0, #%L2"
3892 [(set_attr "type" "alu_reg")
3893 (set_attr "length" "8")]
3896 (define_insn "tlsdesc_small_<mode>"
3897 [(set (reg:PTR R0_REGNUM)
3898 (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
3900 (clobber (reg:DI LR_REGNUM))
3901 (clobber (reg:CC CC_REGNUM))
3902 (clobber (match_scratch:DI 1 "=r"))]
3904 "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
3905 [(set_attr "type" "call")
3906 (set_attr "length" "16")])
3908 (define_insn "stack_tie"
3909 [(set (mem:BLK (scratch))
3910 (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
3911 (match_operand:DI 1 "register_operand" "rk")]
3915 [(set_attr "length" "0")]
3918 ;; Named pattern for expanding thread pointer reference.
3919 (define_expand "get_thread_pointerdi"
3920 [(match_operand:DI 0 "register_operand" "=r")]
3923 rtx tmp = aarch64_load_tp (operands[0]);
3924 if (tmp != operands[0])
3925 emit_move_insn (operands[0], tmp);
3929 ;; Named patterns for stack smashing protection.
3930 (define_expand "stack_protect_set"
3931 [(match_operand 0 "memory_operand")
3932 (match_operand 1 "memory_operand")]
3935 enum machine_mode mode = GET_MODE (operands[0]);
3937 emit_insn ((mode == DImode
3938 ? gen_stack_protect_set_di
3939 : gen_stack_protect_set_si) (operands[0], operands[1]));
3943 (define_insn "stack_protect_set_<mode>"
3944 [(set (match_operand:PTR 0 "memory_operand" "=m")
3945 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
3947 (set (match_scratch:PTR 2 "=&r") (const_int 0))]
3949 "ldr\\t%<w>2, %1\;str\\t%<w>2, %0\;mov\t%<w>2,0"
3950 [(set_attr "length" "12")
3951 (set_attr "type" "multiple")])
3953 (define_expand "stack_protect_test"
3954 [(match_operand 0 "memory_operand")
3955 (match_operand 1 "memory_operand")
3960 enum machine_mode mode = GET_MODE (operands[0]);
3962 result = gen_reg_rtx(mode);
3964 emit_insn ((mode == DImode
3965 ? gen_stack_protect_test_di
3966 : gen_stack_protect_test_si) (result,
3971 emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
3972 result, const0_rtx, operands[2]));
3974 emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
3975 result, const0_rtx, operands[2]));
3979 (define_insn "stack_protect_test_<mode>"
3980 [(set (match_operand:PTR 0 "register_operand")
3981 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
3982 (match_operand:PTR 2 "memory_operand" "m")]
3984 (clobber (match_scratch:PTR 3 "=&r"))]
3986 "ldr\t%<w>3, %x1\;ldr\t%<w>0, %x2\;eor\t%<w>0, %<w>3, %<w>0"
3987 [(set_attr "length" "12")
3988 (set_attr "type" "multiple")])
3990 ;; Write Floating-point Control Register.
3991 (define_insn "set_fpcr"
3992 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
3995 [(set_attr "type" "mrs")])
3997 ;; Read Floating-point Control Register.
3998 (define_insn "get_fpcr"
3999 [(set (match_operand:SI 0 "register_operand" "=r")
4000 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
4003 [(set_attr "type" "mrs")])
4005 ;; Write Floating-point Status Register.
4006 (define_insn "set_fpsr"
4007 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
4010 [(set_attr "type" "mrs")])
4012 ;; Read Floating-point Status Register.
4013 (define_insn "get_fpsr"
4014 [(set (match_operand:SI 0 "register_operand" "=r")
4015 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
4018 [(set_attr "type" "mrs")])
4022 (include "aarch64-simd.md")
4024 ;; Atomic Operations
4025 (include "atomics.md")