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" [
121 (define_c_enum "unspecv" [
122 UNSPECV_EH_RETURN ; Represent EH_RETURN
123 UNSPECV_GET_FPCR ; Represent fetch of FPCR content.
124 UNSPECV_SET_FPCR ; Represent assign of FPCR content.
125 UNSPECV_GET_FPSR ; Represent fetch of FPSR content.
126 UNSPECV_SET_FPSR ; Represent assign of FPSR content.
130 ;; If further include files are added the defintion of MD_INCLUDES
133 (include "constraints.md")
134 (include "predicates.md")
135 (include "iterators.md")
137 ;; -------------------------------------------------------------------
138 ;; Instruction types and attributes
139 ;; -------------------------------------------------------------------
141 ; The "type" attribute is is included here from AArch32 backend to be able
142 ; to share pipeline descriptions.
143 (include "../arm/types.md")
145 ;; Attribute that specifies whether or not the instruction touches fp
147 (define_attr "fp" "no,yes" (const_string "no"))
149 ;; Attribute that specifies whether or not the instruction touches simd
151 (define_attr "simd" "no,yes" (const_string "no"))
153 (define_attr "length" ""
156 ;; Attribute that controls whether an alternative is enabled or not.
157 ;; Currently it is only used to disable alternatives which touch fp or simd
158 ;; registers when -mgeneral-regs-only is specified.
159 (define_attr "enabled" "no,yes"
161 (and (eq_attr "fp" "yes")
162 (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
163 (and (eq_attr "simd" "yes")
164 (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
166 ] (const_string "yes")))
168 ;; -------------------------------------------------------------------
169 ;; Pipeline descriptions and scheduling
170 ;; -------------------------------------------------------------------
173 (include "aarch64-tune.md")
175 ;; True if the generic scheduling description should be used.
177 (define_attr "generic_sched" "yes,no"
179 (eq_attr "tune" "cortexa53,cortexa15")
181 (const_string "yes"))))
184 (include "../arm/cortex-a53.md")
185 (include "../arm/cortex-a15.md")
187 ;; -------------------------------------------------------------------
188 ;; Jumps and other miscellaneous insns
189 ;; -------------------------------------------------------------------
191 (define_insn "indirect_jump"
192 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
195 [(set_attr "type" "branch")]
199 [(set (pc) (label_ref (match_operand 0 "" "")))]
202 [(set_attr "type" "branch")]
205 (define_expand "cbranch<mode>4"
206 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
207 [(match_operand:GPI 1 "register_operand" "")
208 (match_operand:GPI 2 "aarch64_plus_operand" "")])
209 (label_ref (match_operand 3 "" ""))
213 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
215 operands[2] = const0_rtx;
219 (define_expand "cbranch<mode>4"
220 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
221 [(match_operand:GPF 1 "register_operand" "")
222 (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
223 (label_ref (match_operand 3 "" ""))
227 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
229 operands[2] = const0_rtx;
233 (define_insn "*condjump"
234 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
235 [(match_operand 1 "cc_register" "") (const_int 0)])
236 (label_ref (match_operand 2 "" ""))
240 [(set_attr "type" "branch")]
243 (define_expand "casesi"
244 [(match_operand:SI 0 "register_operand" "") ; Index
245 (match_operand:SI 1 "const_int_operand" "") ; Lower bound
246 (match_operand:SI 2 "const_int_operand" "") ; Total range
247 (match_operand:DI 3 "" "") ; Table label
248 (match_operand:DI 4 "" "")] ; Out of range label
251 if (operands[1] != const0_rtx)
253 rtx reg = gen_reg_rtx (SImode);
255 /* Canonical RTL says that if you have:
259 then this should be emitted as:
263 The use of trunc_int_for_mode ensures that the resulting
264 constant can be represented in SImode, this is important
265 for the corner case where operand[1] is INT_MIN. */
267 operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
269 if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
270 (operands[1], SImode))
271 operands[1] = force_reg (SImode, operands[1]);
272 emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
276 if (!aarch64_plus_operand (operands[2], SImode))
277 operands[2] = force_reg (SImode, operands[2]);
278 emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
280 operands[0], operands[2], operands[4]));
282 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
283 emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
289 (define_insn "casesi_dispatch"
292 (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
293 (match_operand:SI 1 "register_operand" "r")]
295 (clobber (reg:CC CC_REGNUM))
296 (clobber (match_scratch:DI 3 "=r"))
297 (clobber (match_scratch:DI 4 "=r"))
298 (use (label_ref (match_operand 2 "" "")))])]
301 return aarch64_output_casesi (operands);
303 [(set_attr "length" "16")
304 (set_attr "type" "branch")]
308 [(unspec[(const_int 0)] UNSPEC_NOP)]
311 [(set_attr "type" "no_insn")]
315 [(trap_if (const_int 1) (const_int 8))]
318 [(set_attr "type" "trap")])
320 (define_expand "prologue"
321 [(clobber (const_int 0))]
324 aarch64_expand_prologue ();
329 (define_expand "epilogue"
330 [(clobber (const_int 0))]
333 aarch64_expand_epilogue (false);
338 (define_expand "sibcall_epilogue"
339 [(clobber (const_int 0))]
342 aarch64_expand_epilogue (true);
347 (define_insn "*do_return"
351 [(set_attr "type" "branch")]
354 (define_insn "eh_return"
355 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
359 [(set_attr "type" "branch")]
364 [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
367 [(set (match_dup 1) (match_dup 0))]
369 operands[1] = aarch64_final_eh_return_addr ();
373 (define_insn "*cb<optab><mode>1"
374 [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
376 (label_ref (match_operand 1 "" ""))
380 [(set_attr "type" "branch")]
384 (define_insn "*tb<optab><mode>1"
385 [(set (pc) (if_then_else
386 (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
388 (match_operand 1 "const_int_operand" "n"))
390 (label_ref (match_operand 2 "" ""))
392 (clobber (match_scratch:DI 3 "=r"))]
395 if (get_attr_length (insn) == 8)
396 return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
397 return \"<tbz>\\t%<w>0, %1, %l2\";
399 [(set_attr "type" "branch")
401 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
402 (lt (minus (match_dup 2) (pc)) (const_int 32764)))
407 (define_insn "*cb<optab><mode>1"
408 [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
410 (label_ref (match_operand 1 "" ""))
412 (clobber (match_scratch:DI 2 "=r"))]
415 if (get_attr_length (insn) == 8)
416 return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
417 return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
419 [(set_attr "type" "branch")
421 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
422 (lt (minus (match_dup 1) (pc)) (const_int 32764)))
427 ;; -------------------------------------------------------------------
428 ;; Subroutine calls and sibcalls
429 ;; -------------------------------------------------------------------
431 (define_expand "call_internal"
432 [(parallel [(call (match_operand 0 "memory_operand" "")
433 (match_operand 1 "general_operand" ""))
434 (use (match_operand 2 "" ""))
435 (clobber (reg:DI LR_REGNUM))])])
437 (define_expand "call"
438 [(parallel [(call (match_operand 0 "memory_operand" "")
439 (match_operand 1 "general_operand" ""))
440 (use (match_operand 2 "" ""))
441 (clobber (reg:DI LR_REGNUM))])]
447 /* In an untyped call, we can get NULL for operand 2. */
448 if (operands[2] == NULL)
449 operands[2] = const0_rtx;
451 /* Decide if we should generate indirect calls by loading the
452 64-bit address of the callee into a register before performing
453 the branch-and-link. */
454 callee = XEXP (operands[0], 0);
455 if (GET_CODE (callee) == SYMBOL_REF
456 ? aarch64_is_long_call_p (callee)
458 XEXP (operands[0], 0) = force_reg (Pmode, callee);
460 pat = gen_call_internal (operands[0], operands[1], operands[2]);
461 aarch64_emit_call_insn (pat);
466 (define_insn "*call_reg"
467 [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
468 (match_operand 1 "" ""))
469 (use (match_operand 2 "" ""))
470 (clobber (reg:DI LR_REGNUM))]
473 [(set_attr "type" "call")]
476 (define_insn "*call_symbol"
477 [(call (mem:DI (match_operand:DI 0 "" ""))
478 (match_operand 1 "" ""))
479 (use (match_operand 2 "" ""))
480 (clobber (reg:DI LR_REGNUM))]
481 "GET_CODE (operands[0]) == SYMBOL_REF
482 && !aarch64_is_long_call_p (operands[0])"
484 [(set_attr "type" "call")]
487 (define_expand "call_value_internal"
488 [(parallel [(set (match_operand 0 "" "")
489 (call (match_operand 1 "memory_operand" "")
490 (match_operand 2 "general_operand" "")))
491 (use (match_operand 3 "" ""))
492 (clobber (reg:DI LR_REGNUM))])])
494 (define_expand "call_value"
495 [(parallel [(set (match_operand 0 "" "")
496 (call (match_operand 1 "memory_operand" "")
497 (match_operand 2 "general_operand" "")))
498 (use (match_operand 3 "" ""))
499 (clobber (reg:DI LR_REGNUM))])]
505 /* In an untyped call, we can get NULL for operand 3. */
506 if (operands[3] == NULL)
507 operands[3] = const0_rtx;
509 /* Decide if we should generate indirect calls by loading the
510 64-bit address of the callee into a register before performing
511 the branch-and-link. */
512 callee = XEXP (operands[1], 0);
513 if (GET_CODE (callee) == SYMBOL_REF
514 ? aarch64_is_long_call_p (callee)
516 XEXP (operands[1], 0) = force_reg (Pmode, callee);
518 pat = gen_call_value_internal (operands[0], operands[1], operands[2],
520 aarch64_emit_call_insn (pat);
525 (define_insn "*call_value_reg"
526 [(set (match_operand 0 "" "")
527 (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
528 (match_operand 2 "" "")))
529 (use (match_operand 3 "" ""))
530 (clobber (reg:DI LR_REGNUM))]
533 [(set_attr "type" "call")]
537 (define_insn "*call_value_symbol"
538 [(set (match_operand 0 "" "")
539 (call (mem:DI (match_operand:DI 1 "" ""))
540 (match_operand 2 "" "")))
541 (use (match_operand 3 "" ""))
542 (clobber (reg:DI LR_REGNUM))]
543 "GET_CODE (operands[1]) == SYMBOL_REF
544 && !aarch64_is_long_call_p (operands[1])"
546 [(set_attr "type" "call")]
549 (define_expand "sibcall_internal"
550 [(parallel [(call (match_operand 0 "memory_operand" "")
551 (match_operand 1 "general_operand" ""))
553 (use (match_operand 2 "" ""))])])
555 (define_expand "sibcall"
556 [(parallel [(call (match_operand 0 "memory_operand" "")
557 (match_operand 1 "general_operand" ""))
559 (use (match_operand 2 "" ""))])]
564 if (!REG_P (XEXP (operands[0], 0))
565 && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
566 XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
568 if (operands[2] == NULL_RTX)
569 operands[2] = const0_rtx;
571 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
572 aarch64_emit_call_insn (pat);
577 (define_expand "sibcall_value_internal"
578 [(parallel [(set (match_operand 0 "" "")
579 (call (match_operand 1 "memory_operand" "")
580 (match_operand 2 "general_operand" "")))
582 (use (match_operand 3 "" ""))])])
584 (define_expand "sibcall_value"
585 [(parallel [(set (match_operand 0 "" "")
586 (call (match_operand 1 "memory_operand" "")
587 (match_operand 2 "general_operand" "")))
589 (use (match_operand 3 "" ""))])]
594 if (!REG_P (XEXP (operands[1], 0))
595 && (GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF))
596 XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
598 if (operands[3] == NULL_RTX)
599 operands[3] = const0_rtx;
601 pat = gen_sibcall_value_internal (operands[0], operands[1], operands[2],
603 aarch64_emit_call_insn (pat);
608 (define_insn "*sibcall_insn"
609 [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucs, Usf"))
610 (match_operand 1 "" ""))
612 (use (match_operand 2 "" ""))]
613 "SIBLING_CALL_P (insn)"
617 [(set_attr "type" "branch, branch")]
620 (define_insn "*sibcall_value_insn"
621 [(set (match_operand 0 "" "")
622 (call (mem:DI (match_operand 1 "aarch64_call_insn_operand" "Ucs, Usf"))
623 (match_operand 2 "" "")))
625 (use (match_operand 3 "" ""))]
626 "SIBLING_CALL_P (insn)"
630 [(set_attr "type" "branch, branch")]
633 ;; Call subroutine returning any type.
635 (define_expand "untyped_call"
636 [(parallel [(call (match_operand 0 "")
639 (match_operand 2 "")])]
644 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
646 for (i = 0; i < XVECLEN (operands[2], 0); i++)
648 rtx set = XVECEXP (operands[2], 0, i);
649 emit_move_insn (SET_DEST (set), SET_SRC (set));
652 /* The optimizer does not know that the call sets the function value
653 registers we stored in the result block. We avoid problems by
654 claiming that all hard registers are used and clobbered at this
656 emit_insn (gen_blockage ());
660 ;; -------------------------------------------------------------------
662 ;; -------------------------------------------------------------------
664 (define_expand "mov<mode>"
665 [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
666 (match_operand:SHORT 1 "general_operand" ""))]
669 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
670 operands[1] = force_reg (<MODE>mode, operands[1]);
674 (define_insn "*mov<mode>_aarch64"
675 [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r, *w,r,*w, m, m, r,*w,*w")
676 (match_operand:SHORT 1 "general_operand" " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
677 "(register_operand (operands[0], <MODE>mode)
678 || aarch64_reg_or_zero (operands[1], <MODE>mode))"
680 switch (which_alternative)
683 return "mov\t%w0, %w1";
685 return "mov\t%w0, %1";
687 return aarch64_output_scalar_simd_mov_immediate (operands[1],
690 return "ldr<size>\t%w0, %1";
692 return "ldr\t%<size>0, %1";
694 return "str<size>\t%w1, %0";
696 return "str\t%<size>1, %0";
698 return "umov\t%w0, %1.<v>[0]";
700 return "dup\t%0.<Vallxd>, %w1";
702 return "dup\t%<Vetype>0, %1.<v>[0]";
707 [(set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
708 neon_from_gp<q>,neon_from_gp<q>, neon_dup")
709 (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")]
712 (define_expand "mov<mode>"
713 [(set (match_operand:GPI 0 "nonimmediate_operand" "")
714 (match_operand:GPI 1 "general_operand" ""))]
717 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
718 operands[1] = force_reg (<MODE>mode, operands[1]);
720 if (CONSTANT_P (operands[1]))
722 aarch64_expand_mov_immediate (operands[0], operands[1]);
728 (define_insn "*movsi_aarch64"
729 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m, m,r,r ,*w, r,*w")
730 (match_operand:SI 1 "aarch64_mov_operand" " r,r,k,M,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
731 "(register_operand (operands[0], SImode)
732 || aarch64_reg_or_zero (operands[1], SImode))"
747 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
748 adr,adr,f_mcr,f_mrc,fmov")
749 (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
752 (define_insn "*movdi_aarch64"
753 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m, m,r,r, *w, r,*w,w")
754 (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))]
755 "(register_operand (operands[0], DImode)
756 || aarch64_reg_or_zero (operands[1], DImode))"
772 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
773 adr,adr,f_mcr,f_mrc,fmov,fmov")
774 (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
775 (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
778 (define_insn "insv_imm<mode>"
779 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
781 (match_operand:GPI 1 "const_int_operand" "n"))
782 (match_operand:GPI 2 "const_int_operand" "n"))]
783 "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
784 && UINTVAL (operands[1]) % 16 == 0"
785 "movk\\t%<w>0, %X2, lsl %1"
786 [(set_attr "type" "mov_imm")]
789 (define_expand "movti"
790 [(set (match_operand:TI 0 "nonimmediate_operand" "")
791 (match_operand:TI 1 "general_operand" ""))]
794 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
795 operands[1] = force_reg (TImode, operands[1]);
799 (define_insn "*movti_aarch64"
800 [(set (match_operand:TI 0
801 "nonimmediate_operand" "=r, *w,r ,*w,r ,Ump,Ump,*w,m")
803 "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r ,Z , m,*w"))]
804 "(register_operand (operands[0], TImode)
805 || aarch64_reg_or_zero (operands[1], TImode))"
810 orr\\t%0.16b, %1.16b, %1.16b
816 [(set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \
817 load2,store2,store2,f_loadd,f_stored")
818 (set_attr "length" "8,8,8,4,4,4,4,4,4")
819 (set_attr "simd" "*,*,*,yes,*,*,*,*,*")
820 (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
823 ;; Split a TImode register-register or register-immediate move into
824 ;; its component DImode pieces, taking care to handle overlapping
825 ;; source and dest registers.
827 [(set (match_operand:TI 0 "register_operand" "")
828 (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
829 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
832 aarch64_split_128bit_move (operands[0], operands[1]);
836 (define_expand "mov<mode>"
837 [(set (match_operand:GPF 0 "nonimmediate_operand" "")
838 (match_operand:GPF 1 "general_operand" ""))]
843 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
847 if (GET_CODE (operands[0]) == MEM)
848 operands[1] = force_reg (<MODE>mode, operands[1]);
852 (define_insn "*movsf_aarch64"
853 [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
854 (match_operand:SF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
855 "TARGET_FLOAT && (register_operand (operands[0], SFmode)
856 || register_operand (operands[1], SFmode))"
867 [(set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
868 f_loads,f_stores,f_loads,f_stores,mov_reg")]
871 (define_insn "*movdf_aarch64"
872 [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
873 (match_operand:DF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
874 "TARGET_FLOAT && (register_operand (operands[0], DFmode)
875 || register_operand (operands[1], DFmode))"
886 [(set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
887 f_loadd,f_stored,f_loadd,f_stored,mov_reg")]
890 (define_expand "movtf"
891 [(set (match_operand:TF 0 "nonimmediate_operand" "")
892 (match_operand:TF 1 "general_operand" ""))]
897 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
901 if (GET_CODE (operands[0]) == MEM)
902 operands[1] = force_reg (TFmode, operands[1]);
906 (define_insn "*movtf_aarch64"
907 [(set (match_operand:TF 0
908 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
910 "general_operand" " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
911 "TARGET_FLOAT && (register_operand (operands[0], TFmode)
912 || register_operand (operands[1], TFmode))"
914 orr\\t%0.16b, %1.16b, %1.16b
924 [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,fconstd,fconstd,\
925 f_loadd,f_stored,neon_load1_2reg,neon_store1_2reg")
926 (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
927 (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
928 (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
932 [(set (match_operand:TF 0 "register_operand" "")
933 (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
934 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
937 aarch64_split_128bit_move (operands[0], operands[1]);
944 ;; 2 is size of move in bytes
947 (define_expand "movmemdi"
948 [(match_operand:BLK 0 "memory_operand")
949 (match_operand:BLK 1 "memory_operand")
950 (match_operand:DI 2 "immediate_operand")
951 (match_operand:DI 3 "immediate_operand")]
954 if (aarch64_expand_movmem (operands))
960 ;; Operands 1 and 3 are tied together by the final condition; so we allow
961 ;; fairly lax checking on the second memory operation.
962 (define_insn "load_pair<mode>"
963 [(set (match_operand:GPI 0 "register_operand" "=r")
964 (match_operand:GPI 1 "aarch64_mem_pair_operand" "Ump"))
965 (set (match_operand:GPI 2 "register_operand" "=r")
966 (match_operand:GPI 3 "memory_operand" "m"))]
967 "rtx_equal_p (XEXP (operands[3], 0),
968 plus_constant (Pmode,
969 XEXP (operands[1], 0),
970 GET_MODE_SIZE (<MODE>mode)))"
971 "ldp\\t%<w>0, %<w>2, %1"
972 [(set_attr "type" "load2")]
975 ;; Operands 0 and 2 are tied together by the final condition; so we allow
976 ;; fairly lax checking on the second memory operation.
977 (define_insn "store_pair<mode>"
978 [(set (match_operand:GPI 0 "aarch64_mem_pair_operand" "=Ump")
979 (match_operand:GPI 1 "register_operand" "r"))
980 (set (match_operand:GPI 2 "memory_operand" "=m")
981 (match_operand:GPI 3 "register_operand" "r"))]
982 "rtx_equal_p (XEXP (operands[2], 0),
983 plus_constant (Pmode,
984 XEXP (operands[0], 0),
985 GET_MODE_SIZE (<MODE>mode)))"
986 "stp\\t%<w>1, %<w>3, %0"
987 [(set_attr "type" "store2")]
990 ;; Operands 1 and 3 are tied together by the final condition; so we allow
991 ;; fairly lax checking on the second memory operation.
992 (define_insn "load_pair<mode>"
993 [(set (match_operand:GPF 0 "register_operand" "=w")
994 (match_operand:GPF 1 "aarch64_mem_pair_operand" "Ump"))
995 (set (match_operand:GPF 2 "register_operand" "=w")
996 (match_operand:GPF 3 "memory_operand" "m"))]
997 "rtx_equal_p (XEXP (operands[3], 0),
998 plus_constant (Pmode,
999 XEXP (operands[1], 0),
1000 GET_MODE_SIZE (<MODE>mode)))"
1001 "ldp\\t%<w>0, %<w>2, %1"
1002 [(set_attr "type" "neon_load1_2reg<q>")]
1005 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1006 ;; fairly lax checking on the second memory operation.
1007 (define_insn "store_pair<mode>"
1008 [(set (match_operand:GPF 0 "aarch64_mem_pair_operand" "=Ump")
1009 (match_operand:GPF 1 "register_operand" "w"))
1010 (set (match_operand:GPF 2 "memory_operand" "=m")
1011 (match_operand:GPF 3 "register_operand" "w"))]
1012 "rtx_equal_p (XEXP (operands[2], 0),
1013 plus_constant (Pmode,
1014 XEXP (operands[0], 0),
1015 GET_MODE_SIZE (<MODE>mode)))"
1016 "stp\\t%<w>1, %<w>3, %0"
1017 [(set_attr "type" "neon_store1_2reg<q>")]
1020 ;; Load pair with writeback. This is primarily used in function epilogues
1021 ;; when restoring [fp,lr]
1022 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
1024 [(set (match_operand:P 0 "register_operand" "=k")
1025 (plus:P (match_operand:P 1 "register_operand" "0")
1026 (match_operand:P 4 "const_int_operand" "n")))
1027 (set (match_operand:GPI 2 "register_operand" "=r")
1028 (mem:GPI (plus:P (match_dup 1)
1030 (set (match_operand:GPI 3 "register_operand" "=r")
1031 (mem:GPI (plus:P (match_dup 1)
1032 (match_operand:P 5 "const_int_operand" "n"))))])]
1033 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1034 "ldp\\t%<w>2, %<w>3, [%1], %4"
1035 [(set_attr "type" "load2")]
1038 ;; Store pair with writeback. This is primarily used in function prologues
1039 ;; when saving [fp,lr]
1040 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
1042 [(set (match_operand:P 0 "register_operand" "=&k")
1043 (plus:P (match_operand:P 1 "register_operand" "0")
1044 (match_operand:P 4 "const_int_operand" "n")))
1045 (set (mem:GPI (plus:P (match_dup 0)
1047 (match_operand:GPI 2 "register_operand" "r"))
1048 (set (mem:GPI (plus:P (match_dup 0)
1049 (match_operand:P 5 "const_int_operand" "n")))
1050 (match_operand:GPI 3 "register_operand" "r"))])]
1051 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1052 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1053 [(set_attr "type" "store2")]
1056 ;; -------------------------------------------------------------------
1057 ;; Sign/Zero extension
1058 ;; -------------------------------------------------------------------
1060 (define_expand "<optab>sidi2"
1061 [(set (match_operand:DI 0 "register_operand")
1062 (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1066 (define_insn "*extendsidi2_aarch64"
1067 [(set (match_operand:DI 0 "register_operand" "=r,r")
1068 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1073 [(set_attr "type" "extend,load1")]
1076 (define_insn "*zero_extendsidi2_aarch64"
1077 [(set (match_operand:DI 0 "register_operand" "=r,r")
1078 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1083 [(set_attr "type" "extend,load1")]
1086 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1087 [(set (match_operand:GPI 0 "register_operand")
1088 (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1092 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1093 [(set (match_operand:GPI 0 "register_operand" "=r,r")
1094 (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1097 sxt<SHORT:size>\t%<GPI:w>0, %w1
1098 ldrs<SHORT:size>\t%<GPI:w>0, %1"
1099 [(set_attr "type" "extend,load1")]
1102 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1103 [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1104 (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1107 uxt<SHORT:size>\t%<GPI:w>0, %w1
1108 ldr<SHORT:size>\t%w0, %1
1109 ldr\t%<SHORT:size>0, %1"
1110 [(set_attr "type" "extend,load1,load1")]
1113 (define_expand "<optab>qihi2"
1114 [(set (match_operand:HI 0 "register_operand")
1115 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1119 (define_insn "*<optab>qihi2_aarch64"
1120 [(set (match_operand:HI 0 "register_operand" "=r,r")
1121 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1126 [(set_attr "type" "extend,load1")]
1129 ;; -------------------------------------------------------------------
1130 ;; Simple arithmetic
1131 ;; -------------------------------------------------------------------
1133 (define_expand "add<mode>3"
1135 (match_operand:GPI 0 "register_operand" "")
1136 (plus:GPI (match_operand:GPI 1 "register_operand" "")
1137 (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1140 if (! aarch64_plus_operand (operands[2], VOIDmode))
1142 rtx subtarget = ((optimize && can_create_pseudo_p ())
1143 ? gen_reg_rtx (<MODE>mode) : operands[0]);
1144 HOST_WIDE_INT imm = INTVAL (operands[2]);
1147 imm = -(-imm & ~0xfff);
1151 emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1152 operands[1] = subtarget;
1153 operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1158 (define_insn "*addsi3_aarch64"
1160 (match_operand:SI 0 "register_operand" "=rk,rk,w,rk")
1162 (match_operand:SI 1 "register_operand" "%rk,rk,w,rk")
1163 (match_operand:SI 2 "aarch64_plus_operand" "I,r,w,J")))]
1168 add\\t%0.2s, %1.2s, %2.2s
1169 sub\\t%w0, %w1, #%n2"
1170 [(set_attr "type" "alu_imm,alu_reg,neon_add,alu_imm")
1171 (set_attr "simd" "*,*,yes,*")]
1174 ;; zero_extend version of above
1175 (define_insn "*addsi3_aarch64_uxtw"
1177 (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1179 (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1180 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1185 sub\\t%w0, %w1, #%n2"
1186 [(set_attr "type" "alu_imm,alu_reg,alu_imm")]
1189 (define_insn "*adddi3_aarch64"
1191 (match_operand:DI 0 "register_operand" "=rk,rk,rk,!w")
1193 (match_operand:DI 1 "register_operand" "%rk,rk,rk,!w")
1194 (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,!w")))]
1199 sub\\t%x0, %x1, #%n2
1200 add\\t%d0, %d1, %d2"
1201 [(set_attr "type" "alu_imm,alu_reg,alu_imm,alu_reg")
1202 (set_attr "simd" "*,*,*,yes")]
1205 (define_expand "addti3"
1206 [(set (match_operand:TI 0 "register_operand" "")
1207 (plus:TI (match_operand:TI 1 "register_operand" "")
1208 (match_operand:TI 2 "register_operand" "")))]
1211 rtx low = gen_reg_rtx (DImode);
1212 emit_insn (gen_adddi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1213 gen_lowpart (DImode, operands[2])));
1215 rtx high = gen_reg_rtx (DImode);
1216 emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]),
1217 gen_highpart (DImode, operands[2])));
1219 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1220 emit_move_insn (gen_highpart (DImode, operands[0]), high);
1224 (define_insn "add<mode>3_compare0"
1225 [(set (reg:CC_NZ CC_REGNUM)
1227 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1228 (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1230 (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1231 (plus:GPI (match_dup 1) (match_dup 2)))]
1234 adds\\t%<w>0, %<w>1, %<w>2
1235 adds\\t%<w>0, %<w>1, %<w>2
1236 subs\\t%<w>0, %<w>1, #%n2"
1237 [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1240 ;; zero_extend version of above
1241 (define_insn "*addsi3_compare0_uxtw"
1242 [(set (reg:CC_NZ CC_REGNUM)
1244 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1245 (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1247 (set (match_operand:DI 0 "register_operand" "=r,r,r")
1248 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1251 adds\\t%w0, %w1, %w2
1252 adds\\t%w0, %w1, %w2
1253 subs\\t%w0, %w1, #%n2"
1254 [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1257 (define_insn "*adds_mul_imm_<mode>"
1258 [(set (reg:CC_NZ CC_REGNUM)
1261 (match_operand:GPI 1 "register_operand" "r")
1262 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1263 (match_operand:GPI 3 "register_operand" "r"))
1265 (set (match_operand:GPI 0 "register_operand" "=r")
1266 (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1269 "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1270 [(set_attr "type" "alus_shift_imm")]
1273 (define_insn "*subs_mul_imm_<mode>"
1274 [(set (reg:CC_NZ CC_REGNUM)
1276 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1278 (match_operand:GPI 2 "register_operand" "r")
1279 (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1281 (set (match_operand:GPI 0 "register_operand" "=r")
1282 (minus:GPI (match_dup 1)
1283 (mult:GPI (match_dup 2) (match_dup 3))))]
1285 "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1286 [(set_attr "type" "alus_shift_imm")]
1289 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1290 [(set (reg:CC_NZ CC_REGNUM)
1293 (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1294 (match_operand:GPI 2 "register_operand" "r"))
1296 (set (match_operand:GPI 0 "register_operand" "=r")
1297 (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1299 "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1300 [(set_attr "type" "alus_ext")]
1303 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1304 [(set (reg:CC_NZ CC_REGNUM)
1306 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1308 (match_operand:ALLX 2 "register_operand" "r")))
1310 (set (match_operand:GPI 0 "register_operand" "=r")
1311 (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1313 "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1314 [(set_attr "type" "alus_ext")]
1317 (define_insn "*adds_<optab><mode>_multp2"
1318 [(set (reg:CC_NZ CC_REGNUM)
1320 (plus:GPI (ANY_EXTRACT:GPI
1321 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1322 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1323 (match_operand 3 "const_int_operand" "n")
1325 (match_operand:GPI 4 "register_operand" "r"))
1327 (set (match_operand:GPI 0 "register_operand" "=r")
1328 (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1332 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1333 "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1334 [(set_attr "type" "alus_ext")]
1337 (define_insn "*subs_<optab><mode>_multp2"
1338 [(set (reg:CC_NZ CC_REGNUM)
1340 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1342 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1343 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1344 (match_operand 3 "const_int_operand" "n")
1347 (set (match_operand:GPI 0 "register_operand" "=r")
1348 (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1349 (mult:GPI (match_dup 1) (match_dup 2))
1352 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1353 "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1354 [(set_attr "type" "alus_ext")]
1357 (define_insn "*add<mode>3nr_compare0"
1358 [(set (reg:CC_NZ CC_REGNUM)
1360 (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1361 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1368 [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1371 (define_insn "*compare_neg<mode>"
1372 [(set (reg:CC_Z CC_REGNUM)
1374 (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1375 (match_operand:GPI 1 "register_operand" "r")))]
1377 "cmn\\t%<w>1, %<w>0"
1378 [(set_attr "type" "alus_reg")]
1381 (define_insn "*add_<shift>_<mode>"
1382 [(set (match_operand:GPI 0 "register_operand" "=r")
1383 (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1384 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1385 (match_operand:GPI 3 "register_operand" "r")))]
1387 "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1388 [(set_attr "type" "alu_shift_imm")]
1391 ;; zero_extend version of above
1392 (define_insn "*add_<shift>_si_uxtw"
1393 [(set (match_operand:DI 0 "register_operand" "=r")
1395 (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1396 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1397 (match_operand:SI 3 "register_operand" "r"))))]
1399 "add\\t%w0, %w3, %w1, <shift> %2"
1400 [(set_attr "type" "alu_shift_imm")]
1403 (define_insn "*add_mul_imm_<mode>"
1404 [(set (match_operand:GPI 0 "register_operand" "=r")
1405 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1406 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1407 (match_operand:GPI 3 "register_operand" "r")))]
1409 "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1410 [(set_attr "type" "alu_shift_imm")]
1413 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1414 [(set (match_operand:GPI 0 "register_operand" "=rk")
1415 (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1416 (match_operand:GPI 2 "register_operand" "r")))]
1418 "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1419 [(set_attr "type" "alu_ext")]
1422 ;; zero_extend version of above
1423 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1424 [(set (match_operand:DI 0 "register_operand" "=rk")
1426 (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1427 (match_operand:GPI 2 "register_operand" "r"))))]
1429 "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1430 [(set_attr "type" "alu_ext")]
1433 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1434 [(set (match_operand:GPI 0 "register_operand" "=rk")
1435 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1436 (match_operand:ALLX 1 "register_operand" "r"))
1437 (match_operand 2 "aarch64_imm3" "Ui3"))
1438 (match_operand:GPI 3 "register_operand" "r")))]
1440 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1441 [(set_attr "type" "alu_ext")]
1444 ;; zero_extend version of above
1445 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1446 [(set (match_operand:DI 0 "register_operand" "=rk")
1448 (plus:SI (ashift:SI (ANY_EXTEND:SI
1449 (match_operand:SHORT 1 "register_operand" "r"))
1450 (match_operand 2 "aarch64_imm3" "Ui3"))
1451 (match_operand:SI 3 "register_operand" "r"))))]
1453 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1454 [(set_attr "type" "alu_ext")]
1457 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1458 [(set (match_operand:GPI 0 "register_operand" "=rk")
1459 (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1460 (match_operand:ALLX 1 "register_operand" "r"))
1461 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1462 (match_operand:GPI 3 "register_operand" "r")))]
1464 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1465 [(set_attr "type" "alu_ext")]
1468 ;; zero_extend version of above
1469 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1470 [(set (match_operand:DI 0 "register_operand" "=rk")
1471 (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1472 (match_operand:SHORT 1 "register_operand" "r"))
1473 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1474 (match_operand:SI 3 "register_operand" "r"))))]
1476 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1477 [(set_attr "type" "alu_ext")]
1480 (define_insn "*add_<optab><mode>_multp2"
1481 [(set (match_operand:GPI 0 "register_operand" "=rk")
1482 (plus:GPI (ANY_EXTRACT:GPI
1483 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1484 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1485 (match_operand 3 "const_int_operand" "n")
1487 (match_operand:GPI 4 "register_operand" "r")))]
1488 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1489 "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1490 [(set_attr "type" "alu_ext")]
1493 ;; zero_extend version of above
1494 (define_insn "*add_<optab>si_multp2_uxtw"
1495 [(set (match_operand:DI 0 "register_operand" "=rk")
1497 (plus:SI (ANY_EXTRACT:SI
1498 (mult:SI (match_operand:SI 1 "register_operand" "r")
1499 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1500 (match_operand 3 "const_int_operand" "n")
1502 (match_operand:SI 4 "register_operand" "r"))))]
1503 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1504 "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1505 [(set_attr "type" "alu_ext")]
1508 (define_insn "add<mode>3_carryin"
1510 (match_operand:GPI 0 "register_operand" "=r")
1511 (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1513 (match_operand:GPI 1 "register_operand" "r")
1514 (match_operand:GPI 2 "register_operand" "r"))))]
1516 "adc\\t%<w>0, %<w>1, %<w>2"
1517 [(set_attr "type" "adc_reg")]
1520 ;; zero_extend version of above
1521 (define_insn "*addsi3_carryin_uxtw"
1523 (match_operand:DI 0 "register_operand" "=r")
1525 (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1527 (match_operand:SI 1 "register_operand" "r")
1528 (match_operand:SI 2 "register_operand" "r")))))]
1530 "adc\\t%w0, %w1, %w2"
1531 [(set_attr "type" "adc_reg")]
1534 (define_insn "*add<mode>3_carryin_alt1"
1536 (match_operand:GPI 0 "register_operand" "=r")
1538 (match_operand:GPI 1 "register_operand" "r")
1539 (match_operand:GPI 2 "register_operand" "r"))
1540 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1542 "adc\\t%<w>0, %<w>1, %<w>2"
1543 [(set_attr "type" "adc_reg")]
1546 ;; zero_extend version of above
1547 (define_insn "*addsi3_carryin_alt1_uxtw"
1549 (match_operand:DI 0 "register_operand" "=r")
1552 (match_operand:SI 1 "register_operand" "r")
1553 (match_operand:SI 2 "register_operand" "r"))
1554 (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1556 "adc\\t%w0, %w1, %w2"
1557 [(set_attr "type" "adc_reg")]
1560 (define_insn "*add<mode>3_carryin_alt2"
1562 (match_operand:GPI 0 "register_operand" "=r")
1564 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1565 (match_operand:GPI 1 "register_operand" "r"))
1566 (match_operand:GPI 2 "register_operand" "r")))]
1568 "adc\\t%<w>0, %<w>1, %<w>2"
1569 [(set_attr "type" "adc_reg")]
1572 ;; zero_extend version of above
1573 (define_insn "*addsi3_carryin_alt2_uxtw"
1575 (match_operand:DI 0 "register_operand" "=r")
1578 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1579 (match_operand:SI 1 "register_operand" "r"))
1580 (match_operand:SI 2 "register_operand" "r"))))]
1582 "adc\\t%w0, %w1, %w2"
1583 [(set_attr "type" "adc_reg")]
1586 (define_insn "*add<mode>3_carryin_alt3"
1588 (match_operand:GPI 0 "register_operand" "=r")
1590 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1591 (match_operand:GPI 2 "register_operand" "r"))
1592 (match_operand:GPI 1 "register_operand" "r")))]
1594 "adc\\t%<w>0, %<w>1, %<w>2"
1595 [(set_attr "type" "adc_reg")]
1598 ;; zero_extend version of above
1599 (define_insn "*addsi3_carryin_alt3_uxtw"
1601 (match_operand:DI 0 "register_operand" "=r")
1604 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1605 (match_operand:SI 2 "register_operand" "r"))
1606 (match_operand:SI 1 "register_operand" "r"))))]
1608 "adc\\t%w0, %w1, %w2"
1609 [(set_attr "type" "adc_reg")]
1612 (define_insn "*add_uxt<mode>_multp2"
1613 [(set (match_operand:GPI 0 "register_operand" "=rk")
1615 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1616 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1617 (match_operand 3 "const_int_operand" "n"))
1618 (match_operand:GPI 4 "register_operand" "r")))]
1619 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1621 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1622 INTVAL (operands[3])));
1623 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1624 [(set_attr "type" "alu_ext")]
1627 ;; zero_extend version of above
1628 (define_insn "*add_uxtsi_multp2_uxtw"
1629 [(set (match_operand:DI 0 "register_operand" "=rk")
1632 (mult:SI (match_operand:SI 1 "register_operand" "r")
1633 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1634 (match_operand 3 "const_int_operand" "n"))
1635 (match_operand:SI 4 "register_operand" "r"))))]
1636 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1638 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1639 INTVAL (operands[3])));
1640 return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1641 [(set_attr "type" "alu_ext")]
1644 (define_insn "subsi3"
1645 [(set (match_operand:SI 0 "register_operand" "=rk")
1646 (minus:SI (match_operand:SI 1 "register_operand" "r")
1647 (match_operand:SI 2 "register_operand" "r")))]
1649 "sub\\t%w0, %w1, %w2"
1650 [(set_attr "type" "alu_reg")]
1653 ;; zero_extend version of above
1654 (define_insn "*subsi3_uxtw"
1655 [(set (match_operand:DI 0 "register_operand" "=rk")
1657 (minus:SI (match_operand:SI 1 "register_operand" "r")
1658 (match_operand:SI 2 "register_operand" "r"))))]
1660 "sub\\t%w0, %w1, %w2"
1661 [(set_attr "type" "alu_reg")]
1664 (define_insn "subdi3"
1665 [(set (match_operand:DI 0 "register_operand" "=rk,!w")
1666 (minus:DI (match_operand:DI 1 "register_operand" "r,!w")
1667 (match_operand:DI 2 "register_operand" "r,!w")))]
1671 sub\\t%d0, %d1, %d2"
1672 [(set_attr "type" "alu_reg, neon_sub")
1673 (set_attr "simd" "*,yes")]
1676 (define_expand "subti3"
1677 [(set (match_operand:TI 0 "register_operand" "")
1678 (minus:TI (match_operand:TI 1 "register_operand" "")
1679 (match_operand:TI 2 "register_operand" "")))]
1682 rtx low = gen_reg_rtx (DImode);
1683 emit_insn (gen_subdi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1684 gen_lowpart (DImode, operands[2])));
1686 rtx high = gen_reg_rtx (DImode);
1687 emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]),
1688 gen_highpart (DImode, operands[2])));
1690 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1691 emit_move_insn (gen_highpart (DImode, operands[0]), high);
1695 (define_insn "sub<mode>3_compare0"
1696 [(set (reg:CC_NZ CC_REGNUM)
1697 (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1698 (match_operand:GPI 2 "register_operand" "r"))
1700 (set (match_operand:GPI 0 "register_operand" "=r")
1701 (minus:GPI (match_dup 1) (match_dup 2)))]
1703 "subs\\t%<w>0, %<w>1, %<w>2"
1704 [(set_attr "type" "alus_reg")]
1707 ;; zero_extend version of above
1708 (define_insn "*subsi3_compare0_uxtw"
1709 [(set (reg:CC_NZ CC_REGNUM)
1710 (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1711 (match_operand:SI 2 "register_operand" "r"))
1713 (set (match_operand:DI 0 "register_operand" "=r")
1714 (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1716 "subs\\t%w0, %w1, %w2"
1717 [(set_attr "type" "alus_reg")]
1720 (define_insn "*sub_<shift>_<mode>"
1721 [(set (match_operand:GPI 0 "register_operand" "=r")
1722 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1724 (match_operand:GPI 1 "register_operand" "r")
1725 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1727 "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1728 [(set_attr "type" "alu_shift_imm")]
1731 ;; zero_extend version of above
1732 (define_insn "*sub_<shift>_si_uxtw"
1733 [(set (match_operand:DI 0 "register_operand" "=r")
1735 (minus:SI (match_operand:SI 3 "register_operand" "r")
1737 (match_operand:SI 1 "register_operand" "r")
1738 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1740 "sub\\t%w0, %w3, %w1, <shift> %2"
1741 [(set_attr "type" "alu_shift_imm")]
1744 (define_insn "*sub_mul_imm_<mode>"
1745 [(set (match_operand:GPI 0 "register_operand" "=r")
1746 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1748 (match_operand:GPI 1 "register_operand" "r")
1749 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1751 "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1752 [(set_attr "type" "alu_shift_imm")]
1755 ;; zero_extend version of above
1756 (define_insn "*sub_mul_imm_si_uxtw"
1757 [(set (match_operand:DI 0 "register_operand" "=r")
1759 (minus:SI (match_operand:SI 3 "register_operand" "r")
1761 (match_operand:SI 1 "register_operand" "r")
1762 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
1764 "sub\\t%w0, %w3, %w1, lsl %p2"
1765 [(set_attr "type" "alu_shift_imm")]
1768 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
1769 [(set (match_operand:GPI 0 "register_operand" "=rk")
1770 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1772 (match_operand:ALLX 2 "register_operand" "r"))))]
1774 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1775 [(set_attr "type" "alu_ext")]
1778 ;; zero_extend version of above
1779 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
1780 [(set (match_operand:DI 0 "register_operand" "=rk")
1782 (minus:SI (match_operand:SI 1 "register_operand" "r")
1784 (match_operand:SHORT 2 "register_operand" "r")))))]
1786 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
1787 [(set_attr "type" "alu_ext")]
1790 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
1791 [(set (match_operand:GPI 0 "register_operand" "=rk")
1792 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1793 (ashift:GPI (ANY_EXTEND:GPI
1794 (match_operand:ALLX 2 "register_operand" "r"))
1795 (match_operand 3 "aarch64_imm3" "Ui3"))))]
1797 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1798 [(set_attr "type" "alu_ext")]
1801 ;; zero_extend version of above
1802 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
1803 [(set (match_operand:DI 0 "register_operand" "=rk")
1805 (minus:SI (match_operand:SI 1 "register_operand" "r")
1806 (ashift:SI (ANY_EXTEND:SI
1807 (match_operand:SHORT 2 "register_operand" "r"))
1808 (match_operand 3 "aarch64_imm3" "Ui3")))))]
1810 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
1811 [(set_attr "type" "alu_ext")]
1814 (define_insn "*sub_<optab><mode>_multp2"
1815 [(set (match_operand:GPI 0 "register_operand" "=rk")
1816 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1818 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1819 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1820 (match_operand 3 "const_int_operand" "n")
1822 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1823 "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1824 [(set_attr "type" "alu_ext")]
1827 ;; zero_extend version of above
1828 (define_insn "*sub_<optab>si_multp2_uxtw"
1829 [(set (match_operand:DI 0 "register_operand" "=rk")
1831 (minus:SI (match_operand:SI 4 "register_operand" "r")
1833 (mult:SI (match_operand:SI 1 "register_operand" "r")
1834 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1835 (match_operand 3 "const_int_operand" "n")
1837 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1838 "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1839 [(set_attr "type" "alu_ext")]
1842 (define_insn "sub<mode>3_carryin"
1844 (match_operand:GPI 0 "register_operand" "=r")
1845 (minus:GPI (minus:GPI
1846 (match_operand:GPI 1 "register_operand" "r")
1847 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
1848 (match_operand:GPI 2 "register_operand" "r")))]
1850 "sbc\\t%<w>0, %<w>1, %<w>2"
1851 [(set_attr "type" "adc_reg")]
1854 ;; zero_extend version of the above
1855 (define_insn "*subsi3_carryin_uxtw"
1857 (match_operand:DI 0 "register_operand" "=r")
1860 (match_operand:SI 1 "register_operand" "r")
1861 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
1862 (match_operand:SI 2 "register_operand" "r"))))]
1864 "sbc\\t%w0, %w1, %w2"
1865 [(set_attr "type" "adc_reg")]
1868 (define_insn "*sub_uxt<mode>_multp2"
1869 [(set (match_operand:GPI 0 "register_operand" "=rk")
1870 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1872 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1873 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1874 (match_operand 3 "const_int_operand" "n"))))]
1875 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1877 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1878 INTVAL (operands[3])));
1879 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1880 [(set_attr "type" "alu_ext")]
1883 ;; zero_extend version of above
1884 (define_insn "*sub_uxtsi_multp2_uxtw"
1885 [(set (match_operand:DI 0 "register_operand" "=rk")
1887 (minus:SI (match_operand:SI 4 "register_operand" "r")
1889 (mult:SI (match_operand:SI 1 "register_operand" "r")
1890 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1891 (match_operand 3 "const_int_operand" "n")))))]
1892 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1894 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1895 INTVAL (operands[3])));
1896 return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
1897 [(set_attr "type" "alu_ext")]
1900 (define_insn_and_split "absdi2"
1901 [(set (match_operand:DI 0 "register_operand" "=r,w")
1902 (abs:DI (match_operand:DI 1 "register_operand" "r,w")))
1903 (clobber (match_scratch:DI 2 "=&r,X"))]
1909 && GP_REGNUM_P (REGNO (operands[0]))
1910 && GP_REGNUM_P (REGNO (operands[1]))"
1913 emit_insn (gen_rtx_SET (VOIDmode, operands[2],
1914 gen_rtx_XOR (DImode,
1915 gen_rtx_ASHIFTRT (DImode,
1919 emit_insn (gen_rtx_SET (VOIDmode,
1921 gen_rtx_MINUS (DImode,
1923 gen_rtx_ASHIFTRT (DImode,
1928 [(set_attr "type" "alu_reg")]
1931 (define_insn "neg<mode>2"
1932 [(set (match_operand:GPI 0 "register_operand" "=r,w")
1933 (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
1937 neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
1938 [(set_attr "type" "alu_reg, neon_neg<q>")
1939 (set_attr "simd" "*,yes")]
1942 ;; zero_extend version of above
1943 (define_insn "*negsi2_uxtw"
1944 [(set (match_operand:DI 0 "register_operand" "=r")
1945 (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
1948 [(set_attr "type" "alu_reg")]
1951 (define_insn "*ngc<mode>"
1952 [(set (match_operand:GPI 0 "register_operand" "=r")
1953 (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
1954 (match_operand:GPI 1 "register_operand" "r")))]
1956 "ngc\\t%<w>0, %<w>1"
1957 [(set_attr "type" "adc_reg")]
1960 (define_insn "*ngcsi_uxtw"
1961 [(set (match_operand:DI 0 "register_operand" "=r")
1963 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
1964 (match_operand:SI 1 "register_operand" "r"))))]
1967 [(set_attr "type" "adc_reg")]
1970 (define_insn "*neg<mode>2_compare0"
1971 [(set (reg:CC_NZ CC_REGNUM)
1972 (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
1974 (set (match_operand:GPI 0 "register_operand" "=r")
1975 (neg:GPI (match_dup 1)))]
1977 "negs\\t%<w>0, %<w>1"
1978 [(set_attr "type" "alus_reg")]
1981 ;; zero_extend version of above
1982 (define_insn "*negsi2_compare0_uxtw"
1983 [(set (reg:CC_NZ CC_REGNUM)
1984 (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
1986 (set (match_operand:DI 0 "register_operand" "=r")
1987 (zero_extend:DI (neg:SI (match_dup 1))))]
1990 [(set_attr "type" "alus_reg")]
1993 (define_insn "*neg_<shift><mode>3_compare0"
1994 [(set (reg:CC_NZ CC_REGNUM)
1996 (neg:GPI (ASHIFT:GPI
1997 (match_operand:GPI 1 "register_operand" "r")
1998 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2000 (set (match_operand:GPI 0 "register_operand" "=r")
2001 (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2003 "negs\\t%<w>0, %<w>1, <shift> %2"
2004 [(set_attr "type" "alus_shift_imm")]
2007 (define_insn "*neg_<shift>_<mode>2"
2008 [(set (match_operand:GPI 0 "register_operand" "=r")
2009 (neg:GPI (ASHIFT:GPI
2010 (match_operand:GPI 1 "register_operand" "r")
2011 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2013 "neg\\t%<w>0, %<w>1, <shift> %2"
2014 [(set_attr "type" "alu_shift_imm")]
2017 ;; zero_extend version of above
2018 (define_insn "*neg_<shift>_si2_uxtw"
2019 [(set (match_operand:DI 0 "register_operand" "=r")
2022 (match_operand:SI 1 "register_operand" "r")
2023 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2025 "neg\\t%w0, %w1, <shift> %2"
2026 [(set_attr "type" "alu_shift_imm")]
2029 (define_insn "*neg_mul_imm_<mode>2"
2030 [(set (match_operand:GPI 0 "register_operand" "=r")
2032 (match_operand:GPI 1 "register_operand" "r")
2033 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2035 "neg\\t%<w>0, %<w>1, lsl %p2"
2036 [(set_attr "type" "alu_shift_imm")]
2039 ;; zero_extend version of above
2040 (define_insn "*neg_mul_imm_si2_uxtw"
2041 [(set (match_operand:DI 0 "register_operand" "=r")
2044 (match_operand:SI 1 "register_operand" "r")
2045 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2047 "neg\\t%w0, %w1, lsl %p2"
2048 [(set_attr "type" "alu_shift_imm")]
2051 (define_insn "mul<mode>3"
2052 [(set (match_operand:GPI 0 "register_operand" "=r")
2053 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2054 (match_operand:GPI 2 "register_operand" "r")))]
2056 "mul\\t%<w>0, %<w>1, %<w>2"
2057 [(set_attr "type" "mul")]
2060 ;; zero_extend version of above
2061 (define_insn "*mulsi3_uxtw"
2062 [(set (match_operand:DI 0 "register_operand" "=r")
2064 (mult:SI (match_operand:SI 1 "register_operand" "r")
2065 (match_operand:SI 2 "register_operand" "r"))))]
2067 "mul\\t%w0, %w1, %w2"
2068 [(set_attr "type" "mul")]
2071 (define_insn "madd<mode>"
2072 [(set (match_operand:GPI 0 "register_operand" "=r")
2073 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2074 (match_operand:GPI 2 "register_operand" "r"))
2075 (match_operand:GPI 3 "register_operand" "r")))]
2077 "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2078 [(set_attr "type" "mla")]
2081 ;; zero_extend version of above
2082 (define_insn "*maddsi_uxtw"
2083 [(set (match_operand:DI 0 "register_operand" "=r")
2085 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2086 (match_operand:SI 2 "register_operand" "r"))
2087 (match_operand:SI 3 "register_operand" "r"))))]
2089 "madd\\t%w0, %w1, %w2, %w3"
2090 [(set_attr "type" "mla")]
2093 (define_insn "*msub<mode>"
2094 [(set (match_operand:GPI 0 "register_operand" "=r")
2095 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2096 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2097 (match_operand:GPI 2 "register_operand" "r"))))]
2100 "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2101 [(set_attr "type" "mla")]
2104 ;; zero_extend version of above
2105 (define_insn "*msubsi_uxtw"
2106 [(set (match_operand:DI 0 "register_operand" "=r")
2108 (minus:SI (match_operand:SI 3 "register_operand" "r")
2109 (mult:SI (match_operand:SI 1 "register_operand" "r")
2110 (match_operand:SI 2 "register_operand" "r")))))]
2113 "msub\\t%w0, %w1, %w2, %w3"
2114 [(set_attr "type" "mla")]
2117 (define_insn "*mul<mode>_neg"
2118 [(set (match_operand:GPI 0 "register_operand" "=r")
2119 (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2120 (match_operand:GPI 2 "register_operand" "r")))]
2123 "mneg\\t%<w>0, %<w>1, %<w>2"
2124 [(set_attr "type" "mul")]
2127 ;; zero_extend version of above
2128 (define_insn "*mulsi_neg_uxtw"
2129 [(set (match_operand:DI 0 "register_operand" "=r")
2131 (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2132 (match_operand:SI 2 "register_operand" "r"))))]
2135 "mneg\\t%w0, %w1, %w2"
2136 [(set_attr "type" "mul")]
2139 (define_insn "<su_optab>mulsidi3"
2140 [(set (match_operand:DI 0 "register_operand" "=r")
2141 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2142 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2144 "<su>mull\\t%0, %w1, %w2"
2145 [(set_attr "type" "<su>mull")]
2148 (define_insn "<su_optab>maddsidi4"
2149 [(set (match_operand:DI 0 "register_operand" "=r")
2151 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2152 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2153 (match_operand:DI 3 "register_operand" "r")))]
2155 "<su>maddl\\t%0, %w1, %w2, %3"
2156 [(set_attr "type" "<su>mlal")]
2159 (define_insn "<su_optab>msubsidi4"
2160 [(set (match_operand:DI 0 "register_operand" "=r")
2162 (match_operand:DI 3 "register_operand" "r")
2163 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2165 (match_operand:SI 2 "register_operand" "r")))))]
2167 "<su>msubl\\t%0, %w1, %w2, %3"
2168 [(set_attr "type" "<su>mlal")]
2171 (define_insn "*<su_optab>mulsidi_neg"
2172 [(set (match_operand:DI 0 "register_operand" "=r")
2174 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2175 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2177 "<su>mnegl\\t%0, %w1, %w2"
2178 [(set_attr "type" "<su>mull")]
2181 (define_expand "<su_optab>mulditi3"
2182 [(set (match_operand:TI 0 "register_operand")
2183 (mult:TI (ANY_EXTEND:TI (match_operand:DI 1 "register_operand"))
2184 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand"))))]
2187 rtx low = gen_reg_rtx (DImode);
2188 emit_insn (gen_muldi3 (low, operands[1], operands[2]));
2190 rtx high = gen_reg_rtx (DImode);
2191 emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2]));
2193 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2194 emit_move_insn (gen_highpart (DImode, operands[0]), high);
2198 ;; The default expansion of multi3 using umuldi3_highpart will perform
2199 ;; the additions in an order that fails to combine into two madd insns.
2200 (define_expand "multi3"
2201 [(set (match_operand:TI 0 "register_operand")
2202 (mult:TI (match_operand:TI 1 "register_operand")
2203 (match_operand:TI 2 "register_operand")))]
2206 rtx l0 = gen_reg_rtx (DImode);
2207 rtx l1 = gen_lowpart (DImode, operands[1]);
2208 rtx l2 = gen_lowpart (DImode, operands[2]);
2209 rtx h0 = gen_reg_rtx (DImode);
2210 rtx h1 = gen_highpart (DImode, operands[1]);
2211 rtx h2 = gen_highpart (DImode, operands[2]);
2213 emit_insn (gen_muldi3 (l0, l1, l2));
2214 emit_insn (gen_umuldi3_highpart (h0, l1, l2));
2215 emit_insn (gen_madddi (h0, h1, l2, h0));
2216 emit_insn (gen_madddi (h0, l1, h2, h0));
2218 emit_move_insn (gen_lowpart (DImode, operands[0]), l0);
2219 emit_move_insn (gen_highpart (DImode, operands[0]), h0);
2223 (define_insn "<su>muldi3_highpart"
2224 [(set (match_operand:DI 0 "register_operand" "=r")
2228 (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2229 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2232 "<su>mulh\\t%0, %1, %2"
2233 [(set_attr "type" "<su>mull")]
2236 (define_insn "<su_optab>div<mode>3"
2237 [(set (match_operand:GPI 0 "register_operand" "=r")
2238 (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2239 (match_operand:GPI 2 "register_operand" "r")))]
2241 "<su>div\\t%<w>0, %<w>1, %<w>2"
2242 [(set_attr "type" "<su>div")]
2245 ;; zero_extend version of above
2246 (define_insn "*<su_optab>divsi3_uxtw"
2247 [(set (match_operand:DI 0 "register_operand" "=r")
2249 (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2250 (match_operand:SI 2 "register_operand" "r"))))]
2252 "<su>div\\t%w0, %w1, %w2"
2253 [(set_attr "type" "<su>div")]
2256 ;; -------------------------------------------------------------------
2258 ;; -------------------------------------------------------------------
2260 (define_insn "*cmp<mode>"
2261 [(set (reg:CC CC_REGNUM)
2262 (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2263 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2269 [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
2272 (define_insn "*cmp<mode>"
2273 [(set (reg:CCFP CC_REGNUM)
2274 (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2275 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2279 fcmp\\t%<s>0, %<s>1"
2280 [(set_attr "type" "fcmp<s>")]
2283 (define_insn "*cmpe<mode>"
2284 [(set (reg:CCFPE CC_REGNUM)
2285 (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2286 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2290 fcmpe\\t%<s>0, %<s>1"
2291 [(set_attr "type" "fcmp<s>")]
2294 (define_insn "*cmp_swp_<shift>_reg<mode>"
2295 [(set (reg:CC_SWP CC_REGNUM)
2296 (compare:CC_SWP (ASHIFT:GPI
2297 (match_operand:GPI 0 "register_operand" "r")
2298 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2299 (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2301 "cmp\\t%<w>2, %<w>0, <shift> %1"
2302 [(set_attr "type" "alus_shift_imm")]
2305 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2306 [(set (reg:CC_SWP CC_REGNUM)
2307 (compare:CC_SWP (ANY_EXTEND:GPI
2308 (match_operand:ALLX 0 "register_operand" "r"))
2309 (match_operand:GPI 1 "register_operand" "r")))]
2311 "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2312 [(set_attr "type" "alus_ext")]
2315 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2316 [(set (reg:CC_SWP CC_REGNUM)
2317 (compare:CC_SWP (ashift:GPI
2319 (match_operand:ALLX 0 "register_operand" "r"))
2320 (match_operand 1 "aarch64_imm3" "Ui3"))
2321 (match_operand:GPI 2 "register_operand" "r")))]
2323 "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2324 [(set_attr "type" "alus_ext")]
2327 ;; -------------------------------------------------------------------
2328 ;; Store-flag and conditional select insns
2329 ;; -------------------------------------------------------------------
2331 (define_expand "cstore<mode>4"
2332 [(set (match_operand:SI 0 "register_operand" "")
2333 (match_operator:SI 1 "aarch64_comparison_operator"
2334 [(match_operand:GPI 2 "register_operand" "")
2335 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2338 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2340 operands[3] = const0_rtx;
2344 (define_expand "cstore<mode>4"
2345 [(set (match_operand:SI 0 "register_operand" "")
2346 (match_operator:SI 1 "aarch64_comparison_operator"
2347 [(match_operand:GPF 2 "register_operand" "")
2348 (match_operand:GPF 3 "register_operand" "")]))]
2351 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2353 operands[3] = const0_rtx;
2357 (define_insn "*cstore<mode>_insn"
2358 [(set (match_operand:ALLI 0 "register_operand" "=r")
2359 (match_operator:ALLI 1 "aarch64_comparison_operator"
2360 [(match_operand 2 "cc_register" "") (const_int 0)]))]
2363 [(set_attr "type" "csel")]
2366 ;; zero_extend version of the above
2367 (define_insn "*cstoresi_insn_uxtw"
2368 [(set (match_operand:DI 0 "register_operand" "=r")
2370 (match_operator:SI 1 "aarch64_comparison_operator"
2371 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2374 [(set_attr "type" "csel")]
2377 (define_insn "cstore<mode>_neg"
2378 [(set (match_operand:ALLI 0 "register_operand" "=r")
2379 (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2380 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2382 "csetm\\t%<w>0, %m1"
2383 [(set_attr "type" "csel")]
2386 ;; zero_extend version of the above
2387 (define_insn "*cstoresi_neg_uxtw"
2388 [(set (match_operand:DI 0 "register_operand" "=r")
2390 (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2391 [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2394 [(set_attr "type" "csel")]
2397 (define_expand "cmov<mode>6"
2398 [(set (match_operand:GPI 0 "register_operand" "")
2400 (match_operator 1 "aarch64_comparison_operator"
2401 [(match_operand:GPI 2 "register_operand" "")
2402 (match_operand:GPI 3 "aarch64_plus_operand" "")])
2403 (match_operand:GPI 4 "register_operand" "")
2404 (match_operand:GPI 5 "register_operand" "")))]
2407 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2409 operands[3] = const0_rtx;
2413 (define_expand "cmov<mode>6"
2414 [(set (match_operand:GPF 0 "register_operand" "")
2416 (match_operator 1 "aarch64_comparison_operator"
2417 [(match_operand:GPF 2 "register_operand" "")
2418 (match_operand:GPF 3 "register_operand" "")])
2419 (match_operand:GPF 4 "register_operand" "")
2420 (match_operand:GPF 5 "register_operand" "")))]
2423 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2425 operands[3] = const0_rtx;
2429 (define_insn "*cmov<mode>_insn"
2430 [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2432 (match_operator 1 "aarch64_comparison_operator"
2433 [(match_operand 2 "cc_register" "") (const_int 0)])
2434 (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2435 (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2436 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2437 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2438 ;; Final two alternatives should be unreachable, but included for completeness
2440 csel\\t%<w>0, %<w>3, %<w>4, %m1
2441 csinv\\t%<w>0, %<w>3, <w>zr, %m1
2442 csinv\\t%<w>0, %<w>4, <w>zr, %M1
2443 csinc\\t%<w>0, %<w>3, <w>zr, %m1
2444 csinc\\t%<w>0, %<w>4, <w>zr, %M1
2447 [(set_attr "type" "csel")]
2450 ;; zero_extend version of above
2451 (define_insn "*cmovsi_insn_uxtw"
2452 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2455 (match_operator 1 "aarch64_comparison_operator"
2456 [(match_operand 2 "cc_register" "") (const_int 0)])
2457 (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2458 (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2459 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2460 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2461 ;; Final two alternatives should be unreachable, but included for completeness
2463 csel\\t%w0, %w3, %w4, %m1
2464 csinv\\t%w0, %w3, wzr, %m1
2465 csinv\\t%w0, %w4, wzr, %M1
2466 csinc\\t%w0, %w3, wzr, %m1
2467 csinc\\t%w0, %w4, wzr, %M1
2470 [(set_attr "type" "csel")]
2473 (define_insn "*cmov<mode>_insn"
2474 [(set (match_operand:GPF 0 "register_operand" "=w")
2476 (match_operator 1 "aarch64_comparison_operator"
2477 [(match_operand 2 "cc_register" "") (const_int 0)])
2478 (match_operand:GPF 3 "register_operand" "w")
2479 (match_operand:GPF 4 "register_operand" "w")))]
2481 "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2482 [(set_attr "type" "fcsel")]
2485 (define_expand "mov<mode>cc"
2486 [(set (match_operand:ALLI 0 "register_operand" "")
2487 (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2488 (match_operand:ALLI 2 "register_operand" "")
2489 (match_operand:ALLI 3 "register_operand" "")))]
2493 enum rtx_code code = GET_CODE (operands[1]);
2495 if (code == UNEQ || code == LTGT)
2498 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2499 XEXP (operands[1], 1));
2500 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2504 (define_expand "mov<GPF:mode><GPI:mode>cc"
2505 [(set (match_operand:GPI 0 "register_operand" "")
2506 (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2507 (match_operand:GPF 2 "register_operand" "")
2508 (match_operand:GPF 3 "register_operand" "")))]
2512 enum rtx_code code = GET_CODE (operands[1]);
2514 if (code == UNEQ || code == LTGT)
2517 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2518 XEXP (operands[1], 1));
2519 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2523 (define_expand "mov<mode>cc"
2524 [(set (match_operand:GPF 0 "register_operand" "")
2525 (if_then_else:GPF (match_operand 1 "aarch64_comparison_operator" "")
2526 (match_operand:GPF 2 "register_operand" "")
2527 (match_operand:GPF 3 "register_operand" "")))]
2531 enum rtx_code code = GET_CODE (operands[1]);
2533 if (code == UNEQ || code == LTGT)
2536 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2537 XEXP (operands[1], 1));
2538 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2543 ;; CRC32 instructions.
2544 (define_insn "aarch64_<crc_variant>"
2545 [(set (match_operand:SI 0 "register_operand" "=r")
2546 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2547 (match_operand:<crc_mode> 2 "register_operand" "r")]
2551 if (GET_MODE_BITSIZE (GET_MODE (operands[2])) >= 64)
2552 return "<crc_variant>\\t%w0, %w1, %x2";
2554 return "<crc_variant>\\t%w0, %w1, %w2";
2556 [(set_attr "type" "crc")]
2559 (define_insn "*csinc2<mode>_insn"
2560 [(set (match_operand:GPI 0 "register_operand" "=r")
2561 (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator"
2562 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
2563 (match_operand:GPI 1 "register_operand" "r")))]
2565 "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2566 [(set_attr "type" "csel")]
2569 (define_insn "csinc3<mode>_insn"
2570 [(set (match_operand:GPI 0 "register_operand" "=r")
2572 (match_operator:GPI 1 "aarch64_comparison_operator"
2573 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2574 (plus:GPI (match_operand:GPI 3 "register_operand" "r")
2576 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2578 "csinc\\t%<w>0, %<w>4, %<w>3, %M1"
2579 [(set_attr "type" "csel")]
2582 (define_insn "*csinv3<mode>_insn"
2583 [(set (match_operand:GPI 0 "register_operand" "=r")
2585 (match_operator:GPI 1 "aarch64_comparison_operator"
2586 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2587 (not:GPI (match_operand:GPI 3 "register_operand" "r"))
2588 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2590 "csinv\\t%<w>0, %<w>4, %<w>3, %M1"
2591 [(set_attr "type" "csel")]
2594 (define_insn "*csneg3<mode>_insn"
2595 [(set (match_operand:GPI 0 "register_operand" "=r")
2597 (match_operator:GPI 1 "aarch64_comparison_operator"
2598 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2599 (neg:GPI (match_operand:GPI 3 "register_operand" "r"))
2600 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2602 "csneg\\t%<w>0, %<w>4, %<w>3, %M1"
2603 [(set_attr "type" "csel")]
2606 ;; -------------------------------------------------------------------
2607 ;; Logical operations
2608 ;; -------------------------------------------------------------------
2610 (define_insn "<optab><mode>3"
2611 [(set (match_operand:GPI 0 "register_operand" "=r,rk")
2612 (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2613 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
2615 "<logical>\\t%<w>0, %<w>1, %<w>2"
2616 [(set_attr "type" "logic_reg,logic_imm")]
2619 ;; zero_extend version of above
2620 (define_insn "*<optab>si3_uxtw"
2621 [(set (match_operand:DI 0 "register_operand" "=r,rk")
2623 (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2624 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2626 "<logical>\\t%w0, %w1, %w2"
2627 [(set_attr "type" "logic_reg,logic_imm")]
2630 (define_insn "*and<mode>3_compare0"
2631 [(set (reg:CC_NZ CC_REGNUM)
2633 (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2634 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2636 (set (match_operand:GPI 0 "register_operand" "=r,r")
2637 (and:GPI (match_dup 1) (match_dup 2)))]
2639 "ands\\t%<w>0, %<w>1, %<w>2"
2640 [(set_attr "type" "logics_reg,logics_imm")]
2643 ;; zero_extend version of above
2644 (define_insn "*andsi3_compare0_uxtw"
2645 [(set (reg:CC_NZ CC_REGNUM)
2647 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2648 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2650 (set (match_operand:DI 0 "register_operand" "=r,r")
2651 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2653 "ands\\t%w0, %w1, %w2"
2654 [(set_attr "type" "logics_reg,logics_imm")]
2657 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2658 [(set (reg:CC_NZ CC_REGNUM)
2661 (match_operand:GPI 1 "register_operand" "r")
2662 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2663 (match_operand:GPI 3 "register_operand" "r"))
2665 (set (match_operand:GPI 0 "register_operand" "=r")
2666 (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2668 "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2669 [(set_attr "type" "logics_shift_imm")]
2672 ;; zero_extend version of above
2673 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2674 [(set (reg:CC_NZ CC_REGNUM)
2677 (match_operand:SI 1 "register_operand" "r")
2678 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2679 (match_operand:SI 3 "register_operand" "r"))
2681 (set (match_operand:DI 0 "register_operand" "=r")
2682 (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2685 "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2686 [(set_attr "type" "logics_shift_imm")]
2689 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2690 [(set (match_operand:GPI 0 "register_operand" "=r")
2691 (LOGICAL:GPI (SHIFT:GPI
2692 (match_operand:GPI 1 "register_operand" "r")
2693 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2694 (match_operand:GPI 3 "register_operand" "r")))]
2696 "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2697 [(set_attr "type" "logic_shift_imm")]
2700 (define_insn "*<optab>_rol<mode>3"
2701 [(set (match_operand:GPI 0 "register_operand" "=r")
2702 (LOGICAL:GPI (rotate:GPI
2703 (match_operand:GPI 1 "register_operand" "r")
2704 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2705 (match_operand:GPI 3 "register_operand" "r")))]
2707 "<logical>\\t%<w>0, %<w>3, %<w>1, ror (<sizen> - %2)"
2708 [(set_attr "type" "logic_shift_imm")]
2711 ;; zero_extend versions of above
2712 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
2713 [(set (match_operand:DI 0 "register_operand" "=r")
2715 (LOGICAL:SI (SHIFT:SI
2716 (match_operand:SI 1 "register_operand" "r")
2717 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2718 (match_operand:SI 3 "register_operand" "r"))))]
2720 "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2721 [(set_attr "type" "logic_shift_imm")]
2724 (define_insn "*<optab>_rolsi3_uxtw"
2725 [(set (match_operand:DI 0 "register_operand" "=r")
2727 (LOGICAL:SI (rotate:SI
2728 (match_operand:SI 1 "register_operand" "r")
2729 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2730 (match_operand:SI 3 "register_operand" "r"))))]
2732 "<logical>\\t%w0, %w3, %w1, ror (32 - %2)"
2733 [(set_attr "type" "logic_shift_imm")]
2736 (define_insn "one_cmpl<mode>2"
2737 [(set (match_operand:GPI 0 "register_operand" "=r")
2738 (not:GPI (match_operand:GPI 1 "register_operand" "r")))]
2740 "mvn\\t%<w>0, %<w>1"
2741 [(set_attr "type" "logic_reg")]
2744 (define_insn "*one_cmpl_<optab><mode>2"
2745 [(set (match_operand:GPI 0 "register_operand" "=r")
2746 (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
2747 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2749 "mvn\\t%<w>0, %<w>1, <shift> %2"
2750 [(set_attr "type" "logic_shift_imm")]
2753 (define_insn "*<LOGICAL:optab>_one_cmpl<mode>3"
2754 [(set (match_operand:GPI 0 "register_operand" "=r")
2755 (LOGICAL:GPI (not:GPI
2756 (match_operand:GPI 1 "register_operand" "r"))
2757 (match_operand:GPI 2 "register_operand" "r")))]
2759 "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1"
2760 [(set_attr "type" "logic_reg")]
2763 (define_insn "*and_one_cmpl<mode>3_compare0"
2764 [(set (reg:CC_NZ CC_REGNUM)
2767 (match_operand:GPI 1 "register_operand" "r"))
2768 (match_operand:GPI 2 "register_operand" "r"))
2770 (set (match_operand:GPI 0 "register_operand" "=r")
2771 (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
2773 "bics\\t%<w>0, %<w>2, %<w>1"
2774 [(set_attr "type" "logics_reg")]
2777 ;; zero_extend version of above
2778 (define_insn "*and_one_cmplsi3_compare0_uxtw"
2779 [(set (reg:CC_NZ CC_REGNUM)
2782 (match_operand:SI 1 "register_operand" "r"))
2783 (match_operand:SI 2 "register_operand" "r"))
2785 (set (match_operand:DI 0 "register_operand" "=r")
2786 (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
2788 "bics\\t%w0, %w2, %w1"
2789 [(set_attr "type" "logics_reg")]
2792 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
2793 [(set (match_operand:GPI 0 "register_operand" "=r")
2794 (LOGICAL:GPI (not:GPI
2796 (match_operand:GPI 1 "register_operand" "r")
2797 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2798 (match_operand:GPI 3 "register_operand" "r")))]
2800 "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2801 [(set_attr "type" "logics_shift_imm")]
2804 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
2805 [(set (reg:CC_NZ CC_REGNUM)
2809 (match_operand:GPI 1 "register_operand" "r")
2810 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2811 (match_operand:GPI 3 "register_operand" "r"))
2813 (set (match_operand:GPI 0 "register_operand" "=r")
2816 (match_dup 1) (match_dup 2))) (match_dup 3)))]
2818 "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2819 [(set_attr "type" "logics_shift_imm")]
2822 ;; zero_extend version of above
2823 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
2824 [(set (reg:CC_NZ CC_REGNUM)
2828 (match_operand:SI 1 "register_operand" "r")
2829 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
2830 (match_operand:SI 3 "register_operand" "r"))
2832 (set (match_operand:DI 0 "register_operand" "=r")
2833 (zero_extend:DI (and:SI
2835 (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
2837 "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2838 [(set_attr "type" "logics_shift_imm")]
2841 (define_insn "clz<mode>2"
2842 [(set (match_operand:GPI 0 "register_operand" "=r")
2843 (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
2845 "clz\\t%<w>0, %<w>1"
2846 [(set_attr "type" "clz")]
2849 (define_expand "ffs<mode>2"
2850 [(match_operand:GPI 0 "register_operand")
2851 (match_operand:GPI 1 "register_operand")]
2854 rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
2855 rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
2857 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2858 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2859 emit_insn (gen_csinc3<mode>_insn (operands[0], x, ccreg, operands[0], const0_rtx));
2864 (define_insn "clrsb<mode>2"
2865 [(set (match_operand:GPI 0 "register_operand" "=r")
2866 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_CLS))]
2868 "cls\\t%<w>0, %<w>1"
2869 [(set_attr "type" "clz")]
2872 (define_insn "rbit<mode>2"
2873 [(set (match_operand:GPI 0 "register_operand" "=r")
2874 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
2876 "rbit\\t%<w>0, %<w>1"
2877 [(set_attr "type" "rbit")]
2880 (define_expand "ctz<mode>2"
2881 [(match_operand:GPI 0 "register_operand")
2882 (match_operand:GPI 1 "register_operand")]
2885 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2886 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2891 (define_insn "*and<mode>3nr_compare0"
2892 [(set (reg:CC_NZ CC_REGNUM)
2894 (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
2895 (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
2898 "tst\\t%<w>0, %<w>1"
2899 [(set_attr "type" "logics_reg")]
2902 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
2903 [(set (reg:CC_NZ CC_REGNUM)
2906 (match_operand:GPI 0 "register_operand" "r")
2907 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2908 (match_operand:GPI 2 "register_operand" "r"))
2911 "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
2912 [(set_attr "type" "logics_shift_imm")]
2915 ;; -------------------------------------------------------------------
2917 ;; -------------------------------------------------------------------
2919 (define_expand "<optab><mode>3"
2920 [(set (match_operand:GPI 0 "register_operand")
2921 (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
2922 (match_operand:QI 2 "nonmemory_operand")))]
2925 if (CONST_INT_P (operands[2]))
2927 operands[2] = GEN_INT (INTVAL (operands[2])
2928 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2930 if (operands[2] == const0_rtx)
2932 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2939 (define_expand "ashl<mode>3"
2940 [(set (match_operand:SHORT 0 "register_operand")
2941 (ashift:SHORT (match_operand:SHORT 1 "register_operand")
2942 (match_operand:QI 2 "nonmemory_operand")))]
2945 if (CONST_INT_P (operands[2]))
2947 operands[2] = GEN_INT (INTVAL (operands[2])
2948 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2950 if (operands[2] == const0_rtx)
2952 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2959 (define_expand "rotr<mode>3"
2960 [(set (match_operand:GPI 0 "register_operand")
2961 (rotatert:GPI (match_operand:GPI 1 "register_operand")
2962 (match_operand:QI 2 "nonmemory_operand")))]
2965 if (CONST_INT_P (operands[2]))
2967 operands[2] = GEN_INT (INTVAL (operands[2])
2968 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2970 if (operands[2] == const0_rtx)
2972 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2979 (define_expand "rotl<mode>3"
2980 [(set (match_operand:GPI 0 "register_operand")
2981 (rotatert:GPI (match_operand:GPI 1 "register_operand")
2982 (match_operand:QI 2 "nonmemory_operand")))]
2985 /* (SZ - cnt) % SZ == -cnt % SZ */
2986 if (CONST_INT_P (operands[2]))
2988 operands[2] = GEN_INT ((-INTVAL (operands[2]))
2989 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2990 if (operands[2] == const0_rtx)
2992 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2997 operands[2] = expand_simple_unop (QImode, NEG, operands[2],
3002 ;; Logical left shift using SISD or Integer instruction
3003 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
3004 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3006 (match_operand:GPI 1 "register_operand" "w,w,r")
3007 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3010 shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3011 ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
3012 lsl\t%<w>0, %<w>1, %<w>2"
3013 [(set_attr "simd" "yes,yes,no")
3014 (set_attr "type" "neon_shift_imm<q>, neon_shift_reg<q>,shift_reg")]
3017 ;; Logical right shift using SISD or Integer instruction
3018 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3019 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3021 (match_operand:GPI 1 "register_operand" "w,w,r")
3022 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3025 ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3027 lsr\t%<w>0, %<w>1, %<w>2"
3028 [(set_attr "simd" "yes,yes,no")
3029 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")]
3033 [(set (match_operand:DI 0 "aarch64_simd_register")
3035 (match_operand:DI 1 "aarch64_simd_register")
3036 (match_operand:QI 2 "aarch64_simd_register")))]
3037 "TARGET_SIMD && reload_completed"
3039 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3041 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_USHL))]
3046 [(set (match_operand:SI 0 "aarch64_simd_register")
3048 (match_operand:SI 1 "aarch64_simd_register")
3049 (match_operand:QI 2 "aarch64_simd_register")))]
3050 "TARGET_SIMD && reload_completed"
3052 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3054 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_USHL_2S))]
3058 ;; Arithmetic right shift using SISD or Integer instruction
3059 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3060 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3062 (match_operand:GPI 1 "register_operand" "w,w,r")
3063 (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,rUs<cmode>")))]
3066 sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3068 asr\t%<w>0, %<w>1, %<w>2"
3069 [(set_attr "simd" "yes,yes,no")
3070 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")]
3074 [(set (match_operand:DI 0 "aarch64_simd_register")
3076 (match_operand:DI 1 "aarch64_simd_register")
3077 (match_operand:QI 2 "aarch64_simd_register")))]
3078 "TARGET_SIMD && reload_completed"
3080 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3082 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_SSHL))]
3087 [(set (match_operand:SI 0 "aarch64_simd_register")
3089 (match_operand:SI 1 "aarch64_simd_register")
3090 (match_operand:QI 2 "aarch64_simd_register")))]
3091 "TARGET_SIMD && reload_completed"
3093 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3095 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_SSHL_2S))]
3099 (define_insn "*aarch64_sisd_ushl"
3100 [(set (match_operand:DI 0 "register_operand" "=w")
3101 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3102 (match_operand:QI 2 "register_operand" "w")]
3105 "ushl\t%d0, %d1, %d2"
3106 [(set_attr "simd" "yes")
3107 (set_attr "type" "neon_shift_reg")]
3110 (define_insn "*aarch64_ushl_2s"
3111 [(set (match_operand:SI 0 "register_operand" "=w")
3112 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3113 (match_operand:QI 2 "register_operand" "w")]
3116 "ushl\t%0.2s, %1.2s, %2.2s"
3117 [(set_attr "simd" "yes")
3118 (set_attr "type" "neon_shift_reg")]
3121 (define_insn "*aarch64_sisd_sshl"
3122 [(set (match_operand:DI 0 "register_operand" "=w")
3123 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3124 (match_operand:QI 2 "register_operand" "w")]
3127 "sshl\t%d0, %d1, %d2"
3128 [(set_attr "simd" "yes")
3129 (set_attr "type" "neon_shift_reg")]
3132 (define_insn "*aarch64_sshl_2s"
3133 [(set (match_operand:SI 0 "register_operand" "=w")
3134 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3135 (match_operand:QI 2 "register_operand" "w")]
3138 "sshl\t%0.2s, %1.2s, %2.2s"
3139 [(set_attr "simd" "yes")
3140 (set_attr "type" "neon_shift_reg")]
3143 (define_insn "*aarch64_sisd_neg_qi"
3144 [(set (match_operand:QI 0 "register_operand" "=w")
3145 (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3149 [(set_attr "simd" "yes")
3150 (set_attr "type" "neon_neg")]
3154 (define_insn "*ror<mode>3_insn"
3155 [(set (match_operand:GPI 0 "register_operand" "=r")
3157 (match_operand:GPI 1 "register_operand" "r")
3158 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3160 "ror\\t%<w>0, %<w>1, %<w>2"
3161 [(set_attr "type" "shift_reg")]
3164 ;; zero_extend version of above
3165 (define_insn "*<optab>si3_insn_uxtw"
3166 [(set (match_operand:DI 0 "register_operand" "=r")
3167 (zero_extend:DI (SHIFT:SI
3168 (match_operand:SI 1 "register_operand" "r")
3169 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3171 "<shift>\\t%w0, %w1, %w2"
3172 [(set_attr "type" "shift_reg")]
3175 (define_insn "*ashl<mode>3_insn"
3176 [(set (match_operand:SHORT 0 "register_operand" "=r")
3177 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3178 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
3180 "lsl\\t%<w>0, %<w>1, %<w>2"
3181 [(set_attr "type" "shift_reg")]
3184 (define_insn "*<optab><mode>3_insn"
3185 [(set (match_operand:SHORT 0 "register_operand" "=r")
3186 (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3187 (match_operand 2 "const_int_operand" "n")))]
3188 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3190 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3191 return "<bfshift>\t%w0, %w1, %2, %3";
3193 [(set_attr "type" "bfm")]
3196 (define_insn "*extr<mode>5_insn"
3197 [(set (match_operand:GPI 0 "register_operand" "=r")
3198 (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3199 (match_operand 3 "const_int_operand" "n"))
3200 (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3201 (match_operand 4 "const_int_operand" "n"))))]
3202 "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3203 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3204 "extr\\t%<w>0, %<w>1, %<w>2, %4"
3205 [(set_attr "type" "shift_imm")]
3208 ;; zero_extend version of the above
3209 (define_insn "*extrsi5_insn_uxtw"
3210 [(set (match_operand:DI 0 "register_operand" "=r")
3212 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3213 (match_operand 3 "const_int_operand" "n"))
3214 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3215 (match_operand 4 "const_int_operand" "n")))))]
3216 "UINTVAL (operands[3]) < 32 &&
3217 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3218 "extr\\t%w0, %w1, %w2, %4"
3219 [(set_attr "type" "shift_imm")]
3222 (define_insn "*ror<mode>3_insn"
3223 [(set (match_operand:GPI 0 "register_operand" "=r")
3224 (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3225 (match_operand 2 "const_int_operand" "n")))]
3226 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3228 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3229 return "ror\\t%<w>0, %<w>1, %3";
3231 [(set_attr "type" "shift_imm")]
3234 ;; zero_extend version of the above
3235 (define_insn "*rorsi3_insn_uxtw"
3236 [(set (match_operand:DI 0 "register_operand" "=r")
3238 (rotate:SI (match_operand:SI 1 "register_operand" "r")
3239 (match_operand 2 "const_int_operand" "n"))))]
3240 "UINTVAL (operands[2]) < 32"
3242 operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3243 return "ror\\t%w0, %w1, %3";
3245 [(set_attr "type" "shift_imm")]
3248 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3249 [(set (match_operand:GPI 0 "register_operand" "=r")
3251 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3252 (match_operand 2 "const_int_operand" "n"))))]
3253 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3255 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3256 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3258 [(set_attr "type" "bfm")]
3261 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3262 [(set (match_operand:GPI 0 "register_operand" "=r")
3264 (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3265 (match_operand 2 "const_int_operand" "n"))))]
3266 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3268 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3269 return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3271 [(set_attr "type" "bfm")]
3274 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3275 [(set (match_operand:GPI 0 "register_operand" "=r")
3277 (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3278 (match_operand 2 "const_int_operand" "n"))))]
3279 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3281 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3282 return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3284 [(set_attr "type" "bfm")]
3287 ;; -------------------------------------------------------------------
3289 ;; -------------------------------------------------------------------
3291 (define_expand "<optab>"
3292 [(set (match_operand:DI 0 "register_operand" "=r")
3293 (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3294 (match_operand 2 "const_int_operand" "n")
3295 (match_operand 3 "const_int_operand" "n")))]
3300 (define_insn "*<optab><mode>"
3301 [(set (match_operand:GPI 0 "register_operand" "=r")
3302 (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3303 (match_operand 2 "const_int_operand" "n")
3304 (match_operand 3 "const_int_operand" "n")))]
3306 "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3307 [(set_attr "type" "bfm")]
3310 ;; Bitfield Insert (insv)
3311 (define_expand "insv<mode>"
3312 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3313 (match_operand 1 "const_int_operand")
3314 (match_operand 2 "const_int_operand"))
3315 (match_operand:GPI 3 "general_operand"))]
3318 unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3319 unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3320 rtx value = operands[3];
3322 if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3325 if (CONST_INT_P (value))
3327 unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3329 /* Prefer AND/OR for inserting all zeros or all ones. */
3330 if ((UINTVAL (value) & mask) == 0
3331 || (UINTVAL (value) & mask) == mask)
3334 /* 16-bit aligned 16-bit wide insert is handled by insv_imm. */
3335 if (width == 16 && (pos % 16) == 0)
3338 operands[3] = force_reg (<MODE>mode, value);
3341 (define_insn "*insv_reg<mode>"
3342 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3343 (match_operand 1 "const_int_operand" "n")
3344 (match_operand 2 "const_int_operand" "n"))
3345 (match_operand:GPI 3 "register_operand" "r"))]
3346 "!(UINTVAL (operands[1]) == 0
3347 || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3348 > GET_MODE_BITSIZE (<MODE>mode)))"
3349 "bfi\\t%<w>0, %<w>3, %2, %1"
3350 [(set_attr "type" "bfm")]
3353 (define_insn "*extr_insv_lower_reg<mode>"
3354 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3355 (match_operand 1 "const_int_operand" "n")
3357 (zero_extract:GPI (match_operand:GPI 2 "register_operand" "+r")
3359 (match_operand 3 "const_int_operand" "n")))]
3360 "!(UINTVAL (operands[1]) == 0
3361 || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3362 > GET_MODE_BITSIZE (<MODE>mode)))"
3363 "bfxil\\t%<w>0, %<w>2, %3, %1"
3364 [(set_attr "type" "bfm")]
3367 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3368 [(set (match_operand:GPI 0 "register_operand" "=r")
3369 (ashift:GPI (ANY_EXTEND:GPI
3370 (match_operand:ALLX 1 "register_operand" "r"))
3371 (match_operand 2 "const_int_operand" "n")))]
3372 "UINTVAL (operands[2]) < <GPI:sizen>"
3374 operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3375 ? GEN_INT (<ALLX:sizen>)
3376 : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3377 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3379 [(set_attr "type" "bfm")]
3382 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3384 (define_insn "*andim_ashift<mode>_bfiz"
3385 [(set (match_operand:GPI 0 "register_operand" "=r")
3386 (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3387 (match_operand 2 "const_int_operand" "n"))
3388 (match_operand 3 "const_int_operand" "n")))]
3389 "exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3390 && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3391 "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3392 [(set_attr "type" "bfm")]
3395 (define_insn "bswap<mode>2"
3396 [(set (match_operand:GPI 0 "register_operand" "=r")
3397 (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3399 "rev\\t%<w>0, %<w>1"
3400 [(set_attr "type" "rev")]
3403 (define_insn "bswaphi2"
3404 [(set (match_operand:HI 0 "register_operand" "=r")
3405 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3408 [(set_attr "type" "rev")]
3411 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
3412 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
3413 ;; each valid permutation.
3415 (define_insn "rev16<mode>2"
3416 [(set (match_operand:GPI 0 "register_operand" "=r")
3417 (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3419 (match_operand:GPI 3 "const_int_operand" "n"))
3420 (and:GPI (lshiftrt:GPI (match_dup 1)
3422 (match_operand:GPI 2 "const_int_operand" "n"))))]
3423 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3424 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3425 "rev16\\t%<w>0, %<w>1"
3426 [(set_attr "type" "rev")]
3429 (define_insn "rev16<mode>2_alt"
3430 [(set (match_operand:GPI 0 "register_operand" "=r")
3431 (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r")
3433 (match_operand:GPI 2 "const_int_operand" "n"))
3434 (and:GPI (ashift:GPI (match_dup 1)
3436 (match_operand:GPI 3 "const_int_operand" "n"))))]
3437 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3438 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3439 "rev16\\t%<w>0, %<w>1"
3440 [(set_attr "type" "rev")]
3443 ;; zero_extend version of above
3444 (define_insn "*bswapsi2_uxtw"
3445 [(set (match_operand:DI 0 "register_operand" "=r")
3446 (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3449 [(set_attr "type" "rev")]
3452 ;; -------------------------------------------------------------------
3453 ;; Floating-point intrinsics
3454 ;; -------------------------------------------------------------------
3456 ;; frint floating-point round to integral standard patterns.
3457 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round, frintn.
3459 (define_insn "<frint_pattern><mode>2"
3460 [(set (match_operand:GPF 0 "register_operand" "=w")
3461 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3464 "frint<frint_suffix>\\t%<s>0, %<s>1"
3465 [(set_attr "type" "f_rint<s>")]
3468 ;; frcvt floating-point round to integer and convert standard patterns.
3469 ;; Expands to lbtrunc, lceil, lfloor, lround.
3470 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3471 [(set (match_operand:GPI 0 "register_operand" "=r")
3472 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3475 "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3476 [(set_attr "type" "f_cvtf2i")]
3481 (define_insn "fma<mode>4"
3482 [(set (match_operand:GPF 0 "register_operand" "=w")
3483 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3484 (match_operand:GPF 2 "register_operand" "w")
3485 (match_operand:GPF 3 "register_operand" "w")))]
3487 "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3488 [(set_attr "type" "fmac<s>")]
3491 (define_insn "fnma<mode>4"
3492 [(set (match_operand:GPF 0 "register_operand" "=w")
3493 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3494 (match_operand:GPF 2 "register_operand" "w")
3495 (match_operand:GPF 3 "register_operand" "w")))]
3497 "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3498 [(set_attr "type" "fmac<s>")]
3501 (define_insn "fms<mode>4"
3502 [(set (match_operand:GPF 0 "register_operand" "=w")
3503 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3504 (match_operand:GPF 2 "register_operand" "w")
3505 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3507 "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3508 [(set_attr "type" "fmac<s>")]
3511 (define_insn "fnms<mode>4"
3512 [(set (match_operand:GPF 0 "register_operand" "=w")
3513 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3514 (match_operand:GPF 2 "register_operand" "w")
3515 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3517 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3518 [(set_attr "type" "fmac<s>")]
3521 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3522 (define_insn "*fnmadd<mode>4"
3523 [(set (match_operand:GPF 0 "register_operand" "=w")
3524 (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3525 (match_operand:GPF 2 "register_operand" "w")
3526 (match_operand:GPF 3 "register_operand" "w"))))]
3527 "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3528 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3529 [(set_attr "type" "fmac<s>")]
3532 ;; -------------------------------------------------------------------
3533 ;; Floating-point conversions
3534 ;; -------------------------------------------------------------------
3536 (define_insn "extendsfdf2"
3537 [(set (match_operand:DF 0 "register_operand" "=w")
3538 (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3541 [(set_attr "type" "f_cvt")]
3544 (define_insn "truncdfsf2"
3545 [(set (match_operand:SF 0 "register_operand" "=w")
3546 (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3549 [(set_attr "type" "f_cvt")]
3552 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3553 [(set (match_operand:GPI 0 "register_operand" "=r")
3554 (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3556 "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3557 [(set_attr "type" "f_cvtf2i")]
3560 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3561 [(set (match_operand:GPI 0 "register_operand" "=r")
3562 (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3564 "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3565 [(set_attr "type" "f_cvtf2i")]
3568 (define_insn "<optab><fcvt_target><GPF:mode>2"
3569 [(set (match_operand:GPF 0 "register_operand" "=w,w")
3570 (FLOATUORS:GPF (match_operand:<FCVT_TARGET> 1 "register_operand" "w,r")))]
3573 <su_optab>cvtf\t%<GPF:s>0, %<s>1
3574 <su_optab>cvtf\t%<GPF:s>0, %<w1>1"
3575 [(set_attr "simd" "yes,no")
3576 (set_attr "fp" "no,yes")
3577 (set_attr "type" "neon_int_to_fp_<Vetype>,f_cvti2f")]
3580 (define_insn "<optab><fcvt_iesize><GPF:mode>2"
3581 [(set (match_operand:GPF 0 "register_operand" "=w")
3582 (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand" "r")))]
3584 "<su_optab>cvtf\t%<GPF:s>0, %<w2>1"
3585 [(set_attr "type" "f_cvti2f")]
3588 ;; -------------------------------------------------------------------
3589 ;; Floating-point arithmetic
3590 ;; -------------------------------------------------------------------
3592 (define_insn "add<mode>3"
3593 [(set (match_operand:GPF 0 "register_operand" "=w")
3595 (match_operand:GPF 1 "register_operand" "w")
3596 (match_operand:GPF 2 "register_operand" "w")))]
3598 "fadd\\t%<s>0, %<s>1, %<s>2"
3599 [(set_attr "type" "fadd<s>")]
3602 (define_insn "sub<mode>3"
3603 [(set (match_operand:GPF 0 "register_operand" "=w")
3605 (match_operand:GPF 1 "register_operand" "w")
3606 (match_operand:GPF 2 "register_operand" "w")))]
3608 "fsub\\t%<s>0, %<s>1, %<s>2"
3609 [(set_attr "type" "fadd<s>")]
3612 (define_insn "mul<mode>3"
3613 [(set (match_operand:GPF 0 "register_operand" "=w")
3615 (match_operand:GPF 1 "register_operand" "w")
3616 (match_operand:GPF 2 "register_operand" "w")))]
3618 "fmul\\t%<s>0, %<s>1, %<s>2"
3619 [(set_attr "type" "fmul<s>")]
3622 (define_insn "*fnmul<mode>3"
3623 [(set (match_operand:GPF 0 "register_operand" "=w")
3625 (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3626 (match_operand:GPF 2 "register_operand" "w")))]
3628 "fnmul\\t%<s>0, %<s>1, %<s>2"
3629 [(set_attr "type" "fmul<s>")]
3632 (define_insn "div<mode>3"
3633 [(set (match_operand:GPF 0 "register_operand" "=w")
3635 (match_operand:GPF 1 "register_operand" "w")
3636 (match_operand:GPF 2 "register_operand" "w")))]
3638 "fdiv\\t%<s>0, %<s>1, %<s>2"
3639 [(set_attr "type" "fdiv<s>")]
3642 (define_insn "neg<mode>2"
3643 [(set (match_operand:GPF 0 "register_operand" "=w")
3644 (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
3646 "fneg\\t%<s>0, %<s>1"
3647 [(set_attr "type" "ffarith<s>")]
3650 (define_insn "sqrt<mode>2"
3651 [(set (match_operand:GPF 0 "register_operand" "=w")
3652 (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
3654 "fsqrt\\t%<s>0, %<s>1"
3655 [(set_attr "type" "fsqrt<s>")]
3658 (define_insn "abs<mode>2"
3659 [(set (match_operand:GPF 0 "register_operand" "=w")
3660 (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
3662 "fabs\\t%<s>0, %<s>1"
3663 [(set_attr "type" "ffarith<s>")]
3666 ;; Given that smax/smin do not specify the result when either input is NaN,
3667 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
3670 (define_insn "smax<mode>3"
3671 [(set (match_operand:GPF 0 "register_operand" "=w")
3672 (smax:GPF (match_operand:GPF 1 "register_operand" "w")
3673 (match_operand:GPF 2 "register_operand" "w")))]
3675 "fmaxnm\\t%<s>0, %<s>1, %<s>2"
3676 [(set_attr "type" "f_minmax<s>")]
3679 (define_insn "smin<mode>3"
3680 [(set (match_operand:GPF 0 "register_operand" "=w")
3681 (smin:GPF (match_operand:GPF 1 "register_operand" "w")
3682 (match_operand:GPF 2 "register_operand" "w")))]
3684 "fminnm\\t%<s>0, %<s>1, %<s>2"
3685 [(set_attr "type" "f_minmax<s>")]
3688 ;; -------------------------------------------------------------------
3690 ;; -------------------------------------------------------------------
3692 (define_expand "aarch64_reload_mov<mode>"
3693 [(set (match_operand:TX 0 "register_operand" "=w")
3694 (match_operand:TX 1 "register_operand" "w"))
3695 (clobber (match_operand:DI 2 "register_operand" "=&r"))
3699 rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
3700 rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
3701 gen_aarch64_movtilow_tilow (op0, op1);
3702 gen_aarch64_movdi_tihigh (operands[2], op1);
3703 gen_aarch64_movtihigh_di (op0, operands[2]);
3708 ;; The following secondary reload helpers patterns are invoked
3709 ;; after or during reload as we don't want these patterns to start
3710 ;; kicking in during the combiner.
3712 (define_insn "aarch64_movdi_<mode>low"
3713 [(set (match_operand:DI 0 "register_operand" "=r")
3714 (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
3715 "reload_completed || reload_in_progress"
3717 [(set_attr "type" "f_mrc")
3718 (set_attr "length" "4")
3721 (define_insn "aarch64_movdi_<mode>high"
3722 [(set (match_operand:DI 0 "register_operand" "=r")
3724 (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
3726 "reload_completed || reload_in_progress"
3727 "fmov\\t%x0, %1.d[1]"
3728 [(set_attr "type" "f_mrc")
3729 (set_attr "length" "4")
3732 (define_insn "aarch64_mov<mode>high_di"
3733 [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
3734 (const_int 64) (const_int 64))
3735 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
3736 "reload_completed || reload_in_progress"
3737 "fmov\\t%0.d[1], %x1"
3738 [(set_attr "type" "f_mcr")
3739 (set_attr "length" "4")
3742 (define_insn "aarch64_mov<mode>low_di"
3743 [(set (match_operand:TX 0 "register_operand" "=w")
3744 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
3745 "reload_completed || reload_in_progress"
3747 [(set_attr "type" "f_mcr")
3748 (set_attr "length" "4")
3751 (define_insn "aarch64_movtilow_tilow"
3752 [(set (match_operand:TI 0 "register_operand" "=w")
3754 (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
3755 "reload_completed || reload_in_progress"
3757 [(set_attr "type" "fmov")
3758 (set_attr "length" "4")
3761 ;; There is a deliberate reason why the parameters of high and lo_sum's
3762 ;; don't have modes for ADRP and ADD instructions. This is to allow high
3763 ;; and lo_sum's to be used with the labels defining the jump tables in
3766 (define_expand "add_losym"
3767 [(set (match_operand 0 "register_operand" "=r")
3768 (lo_sum (match_operand 1 "register_operand" "r")
3769 (match_operand 2 "aarch64_valid_symref" "S")))]
3772 enum machine_mode mode = GET_MODE (operands[0]);
3774 emit_insn ((mode == DImode
3776 : gen_add_losym_si) (operands[0],
3782 (define_insn "add_losym_<mode>"
3783 [(set (match_operand:P 0 "register_operand" "=r")
3784 (lo_sum:P (match_operand:P 1 "register_operand" "r")
3785 (match_operand 2 "aarch64_valid_symref" "S")))]
3787 "add\\t%<w>0, %<w>1, :lo12:%a2"
3788 [(set_attr "type" "alu_reg")]
3791 (define_insn "ldr_got_small_<mode>"
3792 [(set (match_operand:PTR 0 "register_operand" "=r")
3793 (unspec:PTR [(mem:PTR (lo_sum:PTR
3794 (match_operand:PTR 1 "register_operand" "r")
3795 (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
3796 UNSPEC_GOTSMALLPIC))]
3798 "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
3799 [(set_attr "type" "load1")]
3802 (define_insn "ldr_got_small_sidi"
3803 [(set (match_operand:DI 0 "register_operand" "=r")
3805 (unspec:SI [(mem:SI (lo_sum:DI
3806 (match_operand:DI 1 "register_operand" "r")
3807 (match_operand:DI 2 "aarch64_valid_symref" "S")))]
3808 UNSPEC_GOTSMALLPIC)))]
3810 "ldr\\t%w0, [%1, #:got_lo12:%a2]"
3811 [(set_attr "type" "load1")]
3814 (define_insn "ldr_got_tiny"
3815 [(set (match_operand:DI 0 "register_operand" "=r")
3816 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
3817 UNSPEC_GOTTINYPIC))]
3820 [(set_attr "type" "load1")]
3823 (define_insn "aarch64_load_tp_hard"
3824 [(set (match_operand:DI 0 "register_operand" "=r")
3825 (unspec:DI [(const_int 0)] UNSPEC_TLS))]
3827 "mrs\\t%0, tpidr_el0"
3828 [(set_attr "type" "mrs")]
3831 ;; The TLS ABI specifically requires that the compiler does not schedule
3832 ;; instructions in the TLS stubs, in order to enable linker relaxation.
3833 ;; Therefore we treat the stubs as an atomic sequence.
3834 (define_expand "tlsgd_small"
3835 [(parallel [(set (match_operand 0 "register_operand" "")
3836 (call (mem:DI (match_dup 2)) (const_int 1)))
3837 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
3838 (clobber (reg:DI LR_REGNUM))])]
3841 operands[2] = aarch64_tls_get_addr ();
3844 (define_insn "*tlsgd_small"
3845 [(set (match_operand 0 "register_operand" "")
3846 (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
3847 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
3848 (clobber (reg:DI LR_REGNUM))
3851 "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
3852 [(set_attr "type" "call")
3853 (set_attr "length" "16")])
3855 (define_insn "tlsie_small_<mode>"
3856 [(set (match_operand:PTR 0 "register_operand" "=r")
3857 (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
3858 UNSPEC_GOTSMALLTLS))]
3860 "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
3861 [(set_attr "type" "load1")
3862 (set_attr "length" "8")]
3865 (define_insn "tlsie_small_sidi"
3866 [(set (match_operand:DI 0 "register_operand" "=r")
3868 (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")]
3869 UNSPEC_GOTSMALLTLS)))]
3871 "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
3872 [(set_attr "type" "load1")
3873 (set_attr "length" "8")]
3876 (define_expand "tlsle_small"
3877 [(set (match_operand 0 "register_operand" "=r")
3878 (unspec [(match_operand 1 "register_operand" "r")
3879 (match_operand 2 "aarch64_tls_le_symref" "S")]
3880 UNSPEC_GOTSMALLTLS))]
3883 enum machine_mode mode = GET_MODE (operands[0]);
3884 emit_insn ((mode == DImode
3885 ? gen_tlsle_small_di
3886 : gen_tlsle_small_si) (operands[0],
3892 (define_insn "tlsle_small_<mode>"
3893 [(set (match_operand:P 0 "register_operand" "=r")
3894 (unspec:P [(match_operand:P 1 "register_operand" "r")
3895 (match_operand 2 "aarch64_tls_le_symref" "S")]
3896 UNSPEC_GOTSMALLTLS))]
3898 "add\\t%<w>0, %<w>1, #%G2\;add\\t%<w>0, %<w>0, #%L2"
3899 [(set_attr "type" "alu_reg")
3900 (set_attr "length" "8")]
3903 (define_insn "tlsdesc_small_<mode>"
3904 [(set (reg:PTR R0_REGNUM)
3905 (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
3907 (clobber (reg:DI LR_REGNUM))
3908 (clobber (reg:CC CC_REGNUM))
3909 (clobber (match_scratch:DI 1 "=r"))]
3911 "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
3912 [(set_attr "type" "call")
3913 (set_attr "length" "16")])
3915 (define_insn "stack_tie"
3916 [(set (mem:BLK (scratch))
3917 (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
3918 (match_operand:DI 1 "register_operand" "rk")]
3922 [(set_attr "length" "0")]
3925 ;; Named pattern for expanding thread pointer reference.
3926 (define_expand "get_thread_pointerdi"
3927 [(match_operand:DI 0 "register_operand" "=r")]
3930 rtx tmp = aarch64_load_tp (operands[0]);
3931 if (tmp != operands[0])
3932 emit_move_insn (operands[0], tmp);
3936 ;; Named patterns for stack smashing protection.
3937 (define_expand "stack_protect_set"
3938 [(match_operand 0 "memory_operand")
3939 (match_operand 1 "memory_operand")]
3942 enum machine_mode mode = GET_MODE (operands[0]);
3944 emit_insn ((mode == DImode
3945 ? gen_stack_protect_set_di
3946 : gen_stack_protect_set_si) (operands[0], operands[1]));
3950 (define_insn "stack_protect_set_<mode>"
3951 [(set (match_operand:PTR 0 "memory_operand" "=m")
3952 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
3954 (set (match_scratch:PTR 2 "=&r") (const_int 0))]
3956 "ldr\\t%<w>2, %1\;str\\t%<w>2, %0\;mov\t%<w>2,0"
3957 [(set_attr "length" "12")
3958 (set_attr "type" "multiple")])
3960 (define_expand "stack_protect_test"
3961 [(match_operand 0 "memory_operand")
3962 (match_operand 1 "memory_operand")
3967 enum machine_mode mode = GET_MODE (operands[0]);
3969 result = gen_reg_rtx(mode);
3971 emit_insn ((mode == DImode
3972 ? gen_stack_protect_test_di
3973 : gen_stack_protect_test_si) (result,
3978 emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
3979 result, const0_rtx, operands[2]));
3981 emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
3982 result, const0_rtx, operands[2]));
3986 (define_insn "stack_protect_test_<mode>"
3987 [(set (match_operand:PTR 0 "register_operand")
3988 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
3989 (match_operand:PTR 2 "memory_operand" "m")]
3991 (clobber (match_scratch:PTR 3 "=&r"))]
3993 "ldr\t%<w>3, %x1\;ldr\t%<w>0, %x2\;eor\t%<w>0, %<w>3, %<w>0"
3994 [(set_attr "length" "12")
3995 (set_attr "type" "multiple")])
3997 ;; Write Floating-point Control Register.
3998 (define_insn "set_fpcr"
3999 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
4002 [(set_attr "type" "mrs")])
4004 ;; Read Floating-point Control Register.
4005 (define_insn "get_fpcr"
4006 [(set (match_operand:SI 0 "register_operand" "=r")
4007 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
4010 [(set_attr "type" "mrs")])
4012 ;; Write Floating-point Status Register.
4013 (define_insn "set_fpsr"
4014 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
4017 [(set_attr "type" "mrs")])
4019 ;; Read Floating-point Status Register.
4020 (define_insn "get_fpsr"
4021 [(set (match_operand:SI 0 "register_operand" "=r")
4022 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
4025 [(set_attr "type" "mrs")])
4029 (include "aarch64-simd.md")
4031 ;; Atomic Operations
4032 (include "atomics.md")