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"
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))])]
441 /* In an untyped call, we can get NULL for operand 2. */
442 if (operands[2] == NULL)
443 operands[2] = const0_rtx;
445 /* Decide if we should generate indirect calls by loading the
446 64-bit address of the callee into a register before performing
447 the branch-and-link. */
448 callee = XEXP (operands[0], 0);
449 if (GET_CODE (callee) == SYMBOL_REF
450 ? aarch64_is_long_call_p (callee)
452 XEXP (operands[0], 0) = force_reg (Pmode, callee);
456 (define_insn "*call_reg"
457 [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
458 (match_operand 1 "" ""))
459 (use (match_operand 2 "" ""))
460 (clobber (reg:DI LR_REGNUM))]
463 [(set_attr "type" "call")]
466 (define_insn "*call_symbol"
467 [(call (mem:DI (match_operand:DI 0 "" ""))
468 (match_operand 1 "" ""))
469 (use (match_operand 2 "" ""))
470 (clobber (reg:DI LR_REGNUM))]
471 "GET_CODE (operands[0]) == SYMBOL_REF
472 && !aarch64_is_long_call_p (operands[0])"
474 [(set_attr "type" "call")]
477 (define_expand "call_value"
478 [(parallel [(set (match_operand 0 "" "")
479 (call (match_operand 1 "memory_operand" "")
480 (match_operand 2 "general_operand" "")))
481 (use (match_operand 3 "" ""))
482 (clobber (reg:DI LR_REGNUM))])]
488 /* In an untyped call, we can get NULL for operand 3. */
489 if (operands[3] == NULL)
490 operands[3] = const0_rtx;
492 /* Decide if we should generate indirect calls by loading the
493 64-bit address of the callee into a register before performing
494 the branch-and-link. */
495 callee = XEXP (operands[1], 0);
496 if (GET_CODE (callee) == SYMBOL_REF
497 ? aarch64_is_long_call_p (callee)
499 XEXP (operands[1], 0) = force_reg (Pmode, callee);
503 (define_insn "*call_value_reg"
504 [(set (match_operand 0 "" "")
505 (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
506 (match_operand 2 "" "")))
507 (use (match_operand 3 "" ""))
508 (clobber (reg:DI LR_REGNUM))]
511 [(set_attr "type" "call")]
515 (define_insn "*call_value_symbol"
516 [(set (match_operand 0 "" "")
517 (call (mem:DI (match_operand:DI 1 "" ""))
518 (match_operand 2 "" "")))
519 (use (match_operand 3 "" ""))
520 (clobber (reg:DI LR_REGNUM))]
521 "GET_CODE (operands[1]) == SYMBOL_REF
522 && !aarch64_is_long_call_p (operands[1])"
524 [(set_attr "type" "call")]
527 (define_expand "sibcall"
528 [(parallel [(call (match_operand 0 "memory_operand" "")
529 (match_operand 1 "general_operand" ""))
531 (use (match_operand 2 "" ""))])]
534 if (!REG_P (XEXP (operands[0], 0))
535 && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
536 XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
538 if (operands[2] == NULL_RTX)
539 operands[2] = const0_rtx;
543 (define_expand "sibcall_value"
544 [(parallel [(set (match_operand 0 "" "")
545 (call (match_operand 1 "memory_operand" "")
546 (match_operand 2 "general_operand" "")))
548 (use (match_operand 3 "" ""))])]
551 if (!REG_P (XEXP (operands[1], 0))
552 && (GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF))
553 XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
555 if (operands[3] == NULL_RTX)
556 operands[3] = const0_rtx;
560 (define_insn "*sibcall_insn"
561 [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucs, Usf"))
562 (match_operand 1 "" ""))
564 (use (match_operand 2 "" ""))]
565 "SIBLING_CALL_P (insn)"
569 [(set_attr "type" "branch, branch")]
572 (define_insn "*sibcall_value_insn"
573 [(set (match_operand 0 "" "")
574 (call (mem:DI (match_operand 1 "aarch64_call_insn_operand" "Ucs, Usf"))
575 (match_operand 2 "" "")))
577 (use (match_operand 3 "" ""))]
578 "SIBLING_CALL_P (insn)"
582 [(set_attr "type" "branch, branch")]
585 ;; Call subroutine returning any type.
587 (define_expand "untyped_call"
588 [(parallel [(call (match_operand 0 "")
591 (match_operand 2 "")])]
596 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
598 for (i = 0; i < XVECLEN (operands[2], 0); i++)
600 rtx set = XVECEXP (operands[2], 0, i);
601 emit_move_insn (SET_DEST (set), SET_SRC (set));
604 /* The optimizer does not know that the call sets the function value
605 registers we stored in the result block. We avoid problems by
606 claiming that all hard registers are used and clobbered at this
608 emit_insn (gen_blockage ());
612 ;; -------------------------------------------------------------------
614 ;; -------------------------------------------------------------------
616 (define_expand "mov<mode>"
617 [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
618 (match_operand:SHORT 1 "general_operand" ""))]
621 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
622 operands[1] = force_reg (<MODE>mode, operands[1]);
626 (define_insn "*mov<mode>_aarch64"
627 [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r, *w,r,*w, m, m, r,*w,*w")
628 (match_operand:SHORT 1 "general_operand" " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
629 "(register_operand (operands[0], <MODE>mode)
630 || aarch64_reg_or_zero (operands[1], <MODE>mode))"
632 switch (which_alternative)
635 return "mov\t%w0, %w1";
637 return "mov\t%w0, %1";
639 return aarch64_output_scalar_simd_mov_immediate (operands[1],
642 return "ldr<size>\t%w0, %1";
644 return "ldr\t%<size>0, %1";
646 return "str<size>\t%w1, %0";
648 return "str\t%<size>1, %0";
650 return "umov\t%w0, %1.<v>[0]";
652 return "dup\t%0.<Vallxd>, %w1";
654 return "dup\t%<Vetype>0, %1.<v>[0]";
659 [(set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
660 neon_from_gp<q>,neon_from_gp<q>, neon_dup")
661 (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")]
664 (define_expand "mov<mode>"
665 [(set (match_operand:GPI 0 "nonimmediate_operand" "")
666 (match_operand:GPI 1 "general_operand" ""))]
669 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
670 operands[1] = force_reg (<MODE>mode, operands[1]);
672 if (CONSTANT_P (operands[1]))
674 aarch64_expand_mov_immediate (operands[0], operands[1]);
680 (define_insn "*movsi_aarch64"
681 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m, m,r,r ,*w, r,*w")
682 (match_operand:SI 1 "aarch64_mov_operand" " r,r,k,M,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
683 "(register_operand (operands[0], SImode)
684 || aarch64_reg_or_zero (operands[1], SImode))"
699 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
700 adr,adr,f_mcr,f_mrc,fmov")
701 (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
704 (define_insn "*movdi_aarch64"
705 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m, m,r,r, *w, r,*w,w")
706 (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))]
707 "(register_operand (operands[0], DImode)
708 || aarch64_reg_or_zero (operands[1], DImode))"
724 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
725 adr,adr,f_mcr,f_mrc,fmov,fmov")
726 (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
727 (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
730 (define_insn "insv_imm<mode>"
731 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
733 (match_operand:GPI 1 "const_int_operand" "n"))
734 (match_operand:GPI 2 "const_int_operand" "n"))]
735 "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
736 && UINTVAL (operands[1]) % 16 == 0"
737 "movk\\t%<w>0, %X2, lsl %1"
738 [(set_attr "type" "mov_imm")]
741 (define_expand "movti"
742 [(set (match_operand:TI 0 "nonimmediate_operand" "")
743 (match_operand:TI 1 "general_operand" ""))]
746 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
747 operands[1] = force_reg (TImode, operands[1]);
751 (define_insn "*movti_aarch64"
752 [(set (match_operand:TI 0
753 "nonimmediate_operand" "=r, *w,r ,*w,r ,Ump,Ump,*w,m")
755 "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r ,Z , m,*w"))]
756 "(register_operand (operands[0], TImode)
757 || aarch64_reg_or_zero (operands[1], TImode))"
762 orr\\t%0.16b, %1.16b, %1.16b
768 [(set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \
769 load2,store2,store2,f_loadd,f_stored")
770 (set_attr "length" "8,8,8,4,4,4,4,4,4")
771 (set_attr "simd" "*,*,*,yes,*,*,*,*,*")
772 (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
775 ;; Split a TImode register-register or register-immediate move into
776 ;; its component DImode pieces, taking care to handle overlapping
777 ;; source and dest registers.
779 [(set (match_operand:TI 0 "register_operand" "")
780 (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
781 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
784 aarch64_split_128bit_move (operands[0], operands[1]);
788 (define_expand "mov<mode>"
789 [(set (match_operand:GPF 0 "nonimmediate_operand" "")
790 (match_operand:GPF 1 "general_operand" ""))]
795 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
799 if (GET_CODE (operands[0]) == MEM)
800 operands[1] = force_reg (<MODE>mode, operands[1]);
804 (define_insn "*movsf_aarch64"
805 [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
806 (match_operand:SF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
807 "TARGET_FLOAT && (register_operand (operands[0], SFmode)
808 || register_operand (operands[1], SFmode))"
819 [(set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
820 f_loads,f_stores,f_loads,f_stores,mov_reg")]
823 (define_insn "*movdf_aarch64"
824 [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
825 (match_operand:DF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
826 "TARGET_FLOAT && (register_operand (operands[0], DFmode)
827 || register_operand (operands[1], DFmode))"
838 [(set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
839 f_loadd,f_stored,f_loadd,f_stored,mov_reg")]
842 (define_expand "movtf"
843 [(set (match_operand:TF 0 "nonimmediate_operand" "")
844 (match_operand:TF 1 "general_operand" ""))]
849 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
853 if (GET_CODE (operands[0]) == MEM)
854 operands[1] = force_reg (TFmode, operands[1]);
858 (define_insn "*movtf_aarch64"
859 [(set (match_operand:TF 0
860 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
862 "general_operand" " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
863 "TARGET_FLOAT && (register_operand (operands[0], TFmode)
864 || register_operand (operands[1], TFmode))"
866 orr\\t%0.16b, %1.16b, %1.16b
876 [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,fconstd,fconstd,\
877 f_loadd,f_stored,neon_load1_2reg,neon_store1_2reg")
878 (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
879 (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
880 (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
884 [(set (match_operand:TF 0 "register_operand" "")
885 (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
886 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
889 aarch64_split_128bit_move (operands[0], operands[1]);
896 ;; 2 is size of move in bytes
899 (define_expand "movmemdi"
900 [(match_operand:BLK 0 "memory_operand")
901 (match_operand:BLK 1 "memory_operand")
902 (match_operand:DI 2 "immediate_operand")
903 (match_operand:DI 3 "immediate_operand")]
906 if (aarch64_expand_movmem (operands))
912 ;; Operands 1 and 3 are tied together by the final condition; so we allow
913 ;; fairly lax checking on the second memory operation.
914 (define_insn "load_pair<mode>"
915 [(set (match_operand:GPI 0 "register_operand" "=r")
916 (match_operand:GPI 1 "aarch64_mem_pair_operand" "Ump"))
917 (set (match_operand:GPI 2 "register_operand" "=r")
918 (match_operand:GPI 3 "memory_operand" "m"))]
919 "rtx_equal_p (XEXP (operands[3], 0),
920 plus_constant (Pmode,
921 XEXP (operands[1], 0),
922 GET_MODE_SIZE (<MODE>mode)))"
923 "ldp\\t%<w>0, %<w>2, %1"
924 [(set_attr "type" "load2")]
927 ;; Operands 0 and 2 are tied together by the final condition; so we allow
928 ;; fairly lax checking on the second memory operation.
929 (define_insn "store_pair<mode>"
930 [(set (match_operand:GPI 0 "aarch64_mem_pair_operand" "=Ump")
931 (match_operand:GPI 1 "register_operand" "r"))
932 (set (match_operand:GPI 2 "memory_operand" "=m")
933 (match_operand:GPI 3 "register_operand" "r"))]
934 "rtx_equal_p (XEXP (operands[2], 0),
935 plus_constant (Pmode,
936 XEXP (operands[0], 0),
937 GET_MODE_SIZE (<MODE>mode)))"
938 "stp\\t%<w>1, %<w>3, %0"
939 [(set_attr "type" "store2")]
942 ;; Operands 1 and 3 are tied together by the final condition; so we allow
943 ;; fairly lax checking on the second memory operation.
944 (define_insn "load_pair<mode>"
945 [(set (match_operand:GPF 0 "register_operand" "=w")
946 (match_operand:GPF 1 "aarch64_mem_pair_operand" "Ump"))
947 (set (match_operand:GPF 2 "register_operand" "=w")
948 (match_operand:GPF 3 "memory_operand" "m"))]
949 "rtx_equal_p (XEXP (operands[3], 0),
950 plus_constant (Pmode,
951 XEXP (operands[1], 0),
952 GET_MODE_SIZE (<MODE>mode)))"
953 "ldp\\t%<w>0, %<w>2, %1"
954 [(set_attr "type" "neon_load1_2reg<q>")]
957 ;; Operands 0 and 2 are tied together by the final condition; so we allow
958 ;; fairly lax checking on the second memory operation.
959 (define_insn "store_pair<mode>"
960 [(set (match_operand:GPF 0 "aarch64_mem_pair_operand" "=Ump")
961 (match_operand:GPF 1 "register_operand" "w"))
962 (set (match_operand:GPF 2 "memory_operand" "=m")
963 (match_operand:GPF 3 "register_operand" "w"))]
964 "rtx_equal_p (XEXP (operands[2], 0),
965 plus_constant (Pmode,
966 XEXP (operands[0], 0),
967 GET_MODE_SIZE (<MODE>mode)))"
968 "stp\\t%<w>1, %<w>3, %0"
969 [(set_attr "type" "neon_store1_2reg<q>")]
972 ;; Load pair with writeback. This is primarily used in function epilogues
973 ;; when restoring [fp,lr]
974 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
976 [(set (match_operand:P 0 "register_operand" "=k")
977 (plus:P (match_operand:P 1 "register_operand" "0")
978 (match_operand:P 4 "const_int_operand" "n")))
979 (set (match_operand:GPI 2 "register_operand" "=r")
980 (mem:GPI (plus:P (match_dup 1)
982 (set (match_operand:GPI 3 "register_operand" "=r")
983 (mem:GPI (plus:P (match_dup 1)
984 (match_operand:P 5 "const_int_operand" "n"))))])]
985 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
986 "ldp\\t%<w>2, %<w>3, [%1], %4"
987 [(set_attr "type" "load2")]
990 ;; Store pair with writeback. This is primarily used in function prologues
991 ;; when saving [fp,lr]
992 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
994 [(set (match_operand:P 0 "register_operand" "=&k")
995 (plus:P (match_operand:P 1 "register_operand" "0")
996 (match_operand:P 4 "const_int_operand" "n")))
997 (set (mem:GPI (plus:P (match_dup 0)
999 (match_operand:GPI 2 "register_operand" "r"))
1000 (set (mem:GPI (plus:P (match_dup 0)
1001 (match_operand:P 5 "const_int_operand" "n")))
1002 (match_operand:GPI 3 "register_operand" "r"))])]
1003 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1004 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1005 [(set_attr "type" "store2")]
1008 ;; -------------------------------------------------------------------
1009 ;; Sign/Zero extension
1010 ;; -------------------------------------------------------------------
1012 (define_expand "<optab>sidi2"
1013 [(set (match_operand:DI 0 "register_operand")
1014 (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1018 (define_insn "*extendsidi2_aarch64"
1019 [(set (match_operand:DI 0 "register_operand" "=r,r")
1020 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1025 [(set_attr "type" "extend,load1")]
1028 (define_insn "*zero_extendsidi2_aarch64"
1029 [(set (match_operand:DI 0 "register_operand" "=r,r")
1030 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1035 [(set_attr "type" "extend,load1")]
1038 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1039 [(set (match_operand:GPI 0 "register_operand")
1040 (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1044 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1045 [(set (match_operand:GPI 0 "register_operand" "=r,r")
1046 (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1049 sxt<SHORT:size>\t%<GPI:w>0, %w1
1050 ldrs<SHORT:size>\t%<GPI:w>0, %1"
1051 [(set_attr "type" "extend,load1")]
1054 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1055 [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1056 (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1059 uxt<SHORT:size>\t%<GPI:w>0, %w1
1060 ldr<SHORT:size>\t%w0, %1
1061 ldr\t%<SHORT:size>0, %1"
1062 [(set_attr "type" "extend,load1,load1")]
1065 (define_expand "<optab>qihi2"
1066 [(set (match_operand:HI 0 "register_operand")
1067 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1071 (define_insn "*<optab>qihi2_aarch64"
1072 [(set (match_operand:HI 0 "register_operand" "=r,r")
1073 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1078 [(set_attr "type" "extend,load1")]
1081 ;; -------------------------------------------------------------------
1082 ;; Simple arithmetic
1083 ;; -------------------------------------------------------------------
1085 (define_expand "add<mode>3"
1087 (match_operand:GPI 0 "register_operand" "")
1088 (plus:GPI (match_operand:GPI 1 "register_operand" "")
1089 (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1092 if (! aarch64_plus_operand (operands[2], VOIDmode))
1094 rtx subtarget = ((optimize && can_create_pseudo_p ())
1095 ? gen_reg_rtx (<MODE>mode) : operands[0]);
1096 HOST_WIDE_INT imm = INTVAL (operands[2]);
1099 imm = -(-imm & ~0xfff);
1103 emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1104 operands[1] = subtarget;
1105 operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1110 (define_insn "*addsi3_aarch64"
1112 (match_operand:SI 0 "register_operand" "=rk,rk,rk")
1114 (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1115 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J")))]
1120 sub\\t%w0, %w1, #%n2"
1121 [(set_attr "type" "alu_imm,alu_reg,alu_imm")]
1124 ;; zero_extend version of above
1125 (define_insn "*addsi3_aarch64_uxtw"
1127 (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1129 (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1130 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1135 sub\\t%w0, %w1, #%n2"
1136 [(set_attr "type" "alu_imm,alu_reg,alu_imm")]
1139 (define_insn "*adddi3_aarch64"
1141 (match_operand:DI 0 "register_operand" "=rk,rk,rk,!w")
1143 (match_operand:DI 1 "register_operand" "%rk,rk,rk,!w")
1144 (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,!w")))]
1149 sub\\t%x0, %x1, #%n2
1150 add\\t%d0, %d1, %d2"
1151 [(set_attr "type" "alu_imm,alu_reg,alu_imm,alu_reg")
1152 (set_attr "simd" "*,*,*,yes")]
1155 (define_expand "addti3"
1156 [(set (match_operand:TI 0 "register_operand" "")
1157 (plus:TI (match_operand:TI 1 "register_operand" "")
1158 (match_operand:TI 2 "register_operand" "")))]
1161 rtx low = gen_reg_rtx (DImode);
1162 emit_insn (gen_adddi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1163 gen_lowpart (DImode, operands[2])));
1165 rtx high = gen_reg_rtx (DImode);
1166 emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]),
1167 gen_highpart (DImode, operands[2])));
1169 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1170 emit_move_insn (gen_highpart (DImode, operands[0]), high);
1174 (define_insn "add<mode>3_compare0"
1175 [(set (reg:CC_NZ CC_REGNUM)
1177 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1178 (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1180 (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1181 (plus:GPI (match_dup 1) (match_dup 2)))]
1184 adds\\t%<w>0, %<w>1, %<w>2
1185 adds\\t%<w>0, %<w>1, %<w>2
1186 subs\\t%<w>0, %<w>1, #%n2"
1187 [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1190 ;; zero_extend version of above
1191 (define_insn "*addsi3_compare0_uxtw"
1192 [(set (reg:CC_NZ CC_REGNUM)
1194 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1195 (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1197 (set (match_operand:DI 0 "register_operand" "=r,r,r")
1198 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1201 adds\\t%w0, %w1, %w2
1202 adds\\t%w0, %w1, %w2
1203 subs\\t%w0, %w1, #%n2"
1204 [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1207 (define_insn "*adds_mul_imm_<mode>"
1208 [(set (reg:CC_NZ CC_REGNUM)
1211 (match_operand:GPI 1 "register_operand" "r")
1212 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1213 (match_operand:GPI 3 "register_operand" "r"))
1215 (set (match_operand:GPI 0 "register_operand" "=r")
1216 (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1219 "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1220 [(set_attr "type" "alus_shift_imm")]
1223 (define_insn "*subs_mul_imm_<mode>"
1224 [(set (reg:CC_NZ CC_REGNUM)
1226 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1228 (match_operand:GPI 2 "register_operand" "r")
1229 (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1231 (set (match_operand:GPI 0 "register_operand" "=r")
1232 (minus:GPI (match_dup 1)
1233 (mult:GPI (match_dup 2) (match_dup 3))))]
1235 "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1236 [(set_attr "type" "alus_shift_imm")]
1239 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1240 [(set (reg:CC_NZ CC_REGNUM)
1243 (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1244 (match_operand:GPI 2 "register_operand" "r"))
1246 (set (match_operand:GPI 0 "register_operand" "=r")
1247 (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1249 "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1250 [(set_attr "type" "alus_ext")]
1253 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1254 [(set (reg:CC_NZ CC_REGNUM)
1256 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1258 (match_operand:ALLX 2 "register_operand" "r")))
1260 (set (match_operand:GPI 0 "register_operand" "=r")
1261 (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1263 "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1264 [(set_attr "type" "alus_ext")]
1267 (define_insn "*adds_<optab><mode>_multp2"
1268 [(set (reg:CC_NZ CC_REGNUM)
1270 (plus:GPI (ANY_EXTRACT:GPI
1271 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1272 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1273 (match_operand 3 "const_int_operand" "n")
1275 (match_operand:GPI 4 "register_operand" "r"))
1277 (set (match_operand:GPI 0 "register_operand" "=r")
1278 (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1282 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1283 "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1284 [(set_attr "type" "alus_ext")]
1287 (define_insn "*subs_<optab><mode>_multp2"
1288 [(set (reg:CC_NZ CC_REGNUM)
1290 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1292 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1293 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1294 (match_operand 3 "const_int_operand" "n")
1297 (set (match_operand:GPI 0 "register_operand" "=r")
1298 (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1299 (mult:GPI (match_dup 1) (match_dup 2))
1302 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1303 "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1304 [(set_attr "type" "alus_ext")]
1307 (define_insn "*add<mode>3nr_compare0"
1308 [(set (reg:CC_NZ CC_REGNUM)
1310 (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1311 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1318 [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1321 (define_insn "*compare_neg<mode>"
1322 [(set (reg:CC_Z CC_REGNUM)
1324 (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1325 (match_operand:GPI 1 "register_operand" "r")))]
1327 "cmn\\t%<w>1, %<w>0"
1328 [(set_attr "type" "alus_reg")]
1331 (define_insn "*add_<shift>_<mode>"
1332 [(set (match_operand:GPI 0 "register_operand" "=r")
1333 (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1334 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1335 (match_operand:GPI 3 "register_operand" "r")))]
1337 "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1338 [(set_attr "type" "alu_shift_imm")]
1341 ;; zero_extend version of above
1342 (define_insn "*add_<shift>_si_uxtw"
1343 [(set (match_operand:DI 0 "register_operand" "=r")
1345 (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1346 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1347 (match_operand:SI 3 "register_operand" "r"))))]
1349 "add\\t%w0, %w3, %w1, <shift> %2"
1350 [(set_attr "type" "alu_shift_imm")]
1353 (define_insn "*add_mul_imm_<mode>"
1354 [(set (match_operand:GPI 0 "register_operand" "=r")
1355 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1356 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1357 (match_operand:GPI 3 "register_operand" "r")))]
1359 "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1360 [(set_attr "type" "alu_shift_imm")]
1363 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1364 [(set (match_operand:GPI 0 "register_operand" "=rk")
1365 (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1366 (match_operand:GPI 2 "register_operand" "r")))]
1368 "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1369 [(set_attr "type" "alu_ext")]
1372 ;; zero_extend version of above
1373 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1374 [(set (match_operand:DI 0 "register_operand" "=rk")
1376 (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1377 (match_operand:GPI 2 "register_operand" "r"))))]
1379 "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1380 [(set_attr "type" "alu_ext")]
1383 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1384 [(set (match_operand:GPI 0 "register_operand" "=rk")
1385 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1386 (match_operand:ALLX 1 "register_operand" "r"))
1387 (match_operand 2 "aarch64_imm3" "Ui3"))
1388 (match_operand:GPI 3 "register_operand" "r")))]
1390 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1391 [(set_attr "type" "alu_ext")]
1394 ;; zero_extend version of above
1395 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1396 [(set (match_operand:DI 0 "register_operand" "=rk")
1398 (plus:SI (ashift:SI (ANY_EXTEND:SI
1399 (match_operand:SHORT 1 "register_operand" "r"))
1400 (match_operand 2 "aarch64_imm3" "Ui3"))
1401 (match_operand:SI 3 "register_operand" "r"))))]
1403 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1404 [(set_attr "type" "alu_ext")]
1407 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1408 [(set (match_operand:GPI 0 "register_operand" "=rk")
1409 (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1410 (match_operand:ALLX 1 "register_operand" "r"))
1411 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1412 (match_operand:GPI 3 "register_operand" "r")))]
1414 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1415 [(set_attr "type" "alu_ext")]
1418 ;; zero_extend version of above
1419 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1420 [(set (match_operand:DI 0 "register_operand" "=rk")
1421 (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1422 (match_operand:SHORT 1 "register_operand" "r"))
1423 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1424 (match_operand:SI 3 "register_operand" "r"))))]
1426 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1427 [(set_attr "type" "alu_ext")]
1430 (define_insn "*add_<optab><mode>_multp2"
1431 [(set (match_operand:GPI 0 "register_operand" "=rk")
1432 (plus:GPI (ANY_EXTRACT:GPI
1433 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1434 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1435 (match_operand 3 "const_int_operand" "n")
1437 (match_operand:GPI 4 "register_operand" "r")))]
1438 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1439 "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1440 [(set_attr "type" "alu_ext")]
1443 ;; zero_extend version of above
1444 (define_insn "*add_<optab>si_multp2_uxtw"
1445 [(set (match_operand:DI 0 "register_operand" "=rk")
1447 (plus:SI (ANY_EXTRACT:SI
1448 (mult:SI (match_operand:SI 1 "register_operand" "r")
1449 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1450 (match_operand 3 "const_int_operand" "n")
1452 (match_operand:SI 4 "register_operand" "r"))))]
1453 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1454 "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1455 [(set_attr "type" "alu_ext")]
1458 (define_insn "add<mode>3_carryin"
1460 (match_operand:GPI 0 "register_operand" "=r")
1461 (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1463 (match_operand:GPI 1 "register_operand" "r")
1464 (match_operand:GPI 2 "register_operand" "r"))))]
1466 "adc\\t%<w>0, %<w>1, %<w>2"
1467 [(set_attr "type" "adc_reg")]
1470 ;; zero_extend version of above
1471 (define_insn "*addsi3_carryin_uxtw"
1473 (match_operand:DI 0 "register_operand" "=r")
1475 (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1477 (match_operand:SI 1 "register_operand" "r")
1478 (match_operand:SI 2 "register_operand" "r")))))]
1480 "adc\\t%w0, %w1, %w2"
1481 [(set_attr "type" "adc_reg")]
1484 (define_insn "*add<mode>3_carryin_alt1"
1486 (match_operand:GPI 0 "register_operand" "=r")
1488 (match_operand:GPI 1 "register_operand" "r")
1489 (match_operand:GPI 2 "register_operand" "r"))
1490 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1492 "adc\\t%<w>0, %<w>1, %<w>2"
1493 [(set_attr "type" "adc_reg")]
1496 ;; zero_extend version of above
1497 (define_insn "*addsi3_carryin_alt1_uxtw"
1499 (match_operand:DI 0 "register_operand" "=r")
1502 (match_operand:SI 1 "register_operand" "r")
1503 (match_operand:SI 2 "register_operand" "r"))
1504 (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1506 "adc\\t%w0, %w1, %w2"
1507 [(set_attr "type" "adc_reg")]
1510 (define_insn "*add<mode>3_carryin_alt2"
1512 (match_operand:GPI 0 "register_operand" "=r")
1514 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1515 (match_operand:GPI 1 "register_operand" "r"))
1516 (match_operand:GPI 2 "register_operand" "r")))]
1518 "adc\\t%<w>0, %<w>1, %<w>2"
1519 [(set_attr "type" "adc_reg")]
1522 ;; zero_extend version of above
1523 (define_insn "*addsi3_carryin_alt2_uxtw"
1525 (match_operand:DI 0 "register_operand" "=r")
1528 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1529 (match_operand:SI 1 "register_operand" "r"))
1530 (match_operand:SI 2 "register_operand" "r"))))]
1532 "adc\\t%w0, %w1, %w2"
1533 [(set_attr "type" "adc_reg")]
1536 (define_insn "*add<mode>3_carryin_alt3"
1538 (match_operand:GPI 0 "register_operand" "=r")
1540 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1541 (match_operand:GPI 2 "register_operand" "r"))
1542 (match_operand:GPI 1 "register_operand" "r")))]
1544 "adc\\t%<w>0, %<w>1, %<w>2"
1545 [(set_attr "type" "adc_reg")]
1548 ;; zero_extend version of above
1549 (define_insn "*addsi3_carryin_alt3_uxtw"
1551 (match_operand:DI 0 "register_operand" "=r")
1554 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1555 (match_operand:SI 2 "register_operand" "r"))
1556 (match_operand:SI 1 "register_operand" "r"))))]
1558 "adc\\t%w0, %w1, %w2"
1559 [(set_attr "type" "adc_reg")]
1562 (define_insn "*add_uxt<mode>_multp2"
1563 [(set (match_operand:GPI 0 "register_operand" "=rk")
1565 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1566 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1567 (match_operand 3 "const_int_operand" "n"))
1568 (match_operand:GPI 4 "register_operand" "r")))]
1569 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1571 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1572 INTVAL (operands[3])));
1573 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1574 [(set_attr "type" "alu_ext")]
1577 ;; zero_extend version of above
1578 (define_insn "*add_uxtsi_multp2_uxtw"
1579 [(set (match_operand:DI 0 "register_operand" "=rk")
1582 (mult:SI (match_operand:SI 1 "register_operand" "r")
1583 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1584 (match_operand 3 "const_int_operand" "n"))
1585 (match_operand:SI 4 "register_operand" "r"))))]
1586 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1588 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1589 INTVAL (operands[3])));
1590 return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1591 [(set_attr "type" "alu_ext")]
1594 (define_insn "subsi3"
1595 [(set (match_operand:SI 0 "register_operand" "=rk")
1596 (minus:SI (match_operand:SI 1 "register_operand" "r")
1597 (match_operand:SI 2 "register_operand" "r")))]
1599 "sub\\t%w0, %w1, %w2"
1600 [(set_attr "type" "alu_reg")]
1603 ;; zero_extend version of above
1604 (define_insn "*subsi3_uxtw"
1605 [(set (match_operand:DI 0 "register_operand" "=rk")
1607 (minus:SI (match_operand:SI 1 "register_operand" "r")
1608 (match_operand:SI 2 "register_operand" "r"))))]
1610 "sub\\t%w0, %w1, %w2"
1611 [(set_attr "type" "alu_reg")]
1614 (define_insn "subdi3"
1615 [(set (match_operand:DI 0 "register_operand" "=rk,!w")
1616 (minus:DI (match_operand:DI 1 "register_operand" "r,!w")
1617 (match_operand:DI 2 "register_operand" "r,!w")))]
1621 sub\\t%d0, %d1, %d2"
1622 [(set_attr "type" "alu_reg, neon_sub")
1623 (set_attr "simd" "*,yes")]
1626 (define_expand "subti3"
1627 [(set (match_operand:TI 0 "register_operand" "")
1628 (minus:TI (match_operand:TI 1 "register_operand" "")
1629 (match_operand:TI 2 "register_operand" "")))]
1632 rtx low = gen_reg_rtx (DImode);
1633 emit_insn (gen_subdi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1634 gen_lowpart (DImode, operands[2])));
1636 rtx high = gen_reg_rtx (DImode);
1637 emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]),
1638 gen_highpart (DImode, operands[2])));
1640 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1641 emit_move_insn (gen_highpart (DImode, operands[0]), high);
1645 (define_insn "sub<mode>3_compare0"
1646 [(set (reg:CC_NZ CC_REGNUM)
1647 (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1648 (match_operand:GPI 2 "register_operand" "r"))
1650 (set (match_operand:GPI 0 "register_operand" "=r")
1651 (minus:GPI (match_dup 1) (match_dup 2)))]
1653 "subs\\t%<w>0, %<w>1, %<w>2"
1654 [(set_attr "type" "alus_reg")]
1657 ;; zero_extend version of above
1658 (define_insn "*subsi3_compare0_uxtw"
1659 [(set (reg:CC_NZ CC_REGNUM)
1660 (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1661 (match_operand:SI 2 "register_operand" "r"))
1663 (set (match_operand:DI 0 "register_operand" "=r")
1664 (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1666 "subs\\t%w0, %w1, %w2"
1667 [(set_attr "type" "alus_reg")]
1670 (define_insn "*sub_<shift>_<mode>"
1671 [(set (match_operand:GPI 0 "register_operand" "=r")
1672 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1674 (match_operand:GPI 1 "register_operand" "r")
1675 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1677 "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1678 [(set_attr "type" "alu_shift_imm")]
1681 ;; zero_extend version of above
1682 (define_insn "*sub_<shift>_si_uxtw"
1683 [(set (match_operand:DI 0 "register_operand" "=r")
1685 (minus:SI (match_operand:SI 3 "register_operand" "r")
1687 (match_operand:SI 1 "register_operand" "r")
1688 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1690 "sub\\t%w0, %w3, %w1, <shift> %2"
1691 [(set_attr "type" "alu_shift_imm")]
1694 (define_insn "*sub_mul_imm_<mode>"
1695 [(set (match_operand:GPI 0 "register_operand" "=r")
1696 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1698 (match_operand:GPI 1 "register_operand" "r")
1699 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1701 "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1702 [(set_attr "type" "alu_shift_imm")]
1705 ;; zero_extend version of above
1706 (define_insn "*sub_mul_imm_si_uxtw"
1707 [(set (match_operand:DI 0 "register_operand" "=r")
1709 (minus:SI (match_operand:SI 3 "register_operand" "r")
1711 (match_operand:SI 1 "register_operand" "r")
1712 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
1714 "sub\\t%w0, %w3, %w1, lsl %p2"
1715 [(set_attr "type" "alu_shift_imm")]
1718 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
1719 [(set (match_operand:GPI 0 "register_operand" "=rk")
1720 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1722 (match_operand:ALLX 2 "register_operand" "r"))))]
1724 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1725 [(set_attr "type" "alu_ext")]
1728 ;; zero_extend version of above
1729 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
1730 [(set (match_operand:DI 0 "register_operand" "=rk")
1732 (minus:SI (match_operand:SI 1 "register_operand" "r")
1734 (match_operand:SHORT 2 "register_operand" "r")))))]
1736 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
1737 [(set_attr "type" "alu_ext")]
1740 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
1741 [(set (match_operand:GPI 0 "register_operand" "=rk")
1742 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1743 (ashift:GPI (ANY_EXTEND:GPI
1744 (match_operand:ALLX 2 "register_operand" "r"))
1745 (match_operand 3 "aarch64_imm3" "Ui3"))))]
1747 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1748 [(set_attr "type" "alu_ext")]
1751 ;; zero_extend version of above
1752 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
1753 [(set (match_operand:DI 0 "register_operand" "=rk")
1755 (minus:SI (match_operand:SI 1 "register_operand" "r")
1756 (ashift:SI (ANY_EXTEND:SI
1757 (match_operand:SHORT 2 "register_operand" "r"))
1758 (match_operand 3 "aarch64_imm3" "Ui3")))))]
1760 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
1761 [(set_attr "type" "alu_ext")]
1764 (define_insn "*sub_<optab><mode>_multp2"
1765 [(set (match_operand:GPI 0 "register_operand" "=rk")
1766 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1768 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1769 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1770 (match_operand 3 "const_int_operand" "n")
1772 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1773 "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1774 [(set_attr "type" "alu_ext")]
1777 ;; zero_extend version of above
1778 (define_insn "*sub_<optab>si_multp2_uxtw"
1779 [(set (match_operand:DI 0 "register_operand" "=rk")
1781 (minus:SI (match_operand:SI 4 "register_operand" "r")
1783 (mult:SI (match_operand:SI 1 "register_operand" "r")
1784 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1785 (match_operand 3 "const_int_operand" "n")
1787 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1788 "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1789 [(set_attr "type" "alu_ext")]
1792 (define_insn "sub<mode>3_carryin"
1794 (match_operand:GPI 0 "register_operand" "=r")
1795 (minus:GPI (minus:GPI
1796 (match_operand:GPI 1 "register_operand" "r")
1797 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
1798 (match_operand:GPI 2 "register_operand" "r")))]
1800 "sbc\\t%<w>0, %<w>1, %<w>2"
1801 [(set_attr "type" "adc_reg")]
1804 ;; zero_extend version of the above
1805 (define_insn "*subsi3_carryin_uxtw"
1807 (match_operand:DI 0 "register_operand" "=r")
1810 (match_operand:SI 1 "register_operand" "r")
1811 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
1812 (match_operand:SI 2 "register_operand" "r"))))]
1814 "sbc\\t%w0, %w1, %w2"
1815 [(set_attr "type" "adc_reg")]
1818 (define_insn "*sub_uxt<mode>_multp2"
1819 [(set (match_operand:GPI 0 "register_operand" "=rk")
1820 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1822 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1823 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1824 (match_operand 3 "const_int_operand" "n"))))]
1825 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1827 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1828 INTVAL (operands[3])));
1829 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1830 [(set_attr "type" "alu_ext")]
1833 ;; zero_extend version of above
1834 (define_insn "*sub_uxtsi_multp2_uxtw"
1835 [(set (match_operand:DI 0 "register_operand" "=rk")
1837 (minus:SI (match_operand:SI 4 "register_operand" "r")
1839 (mult:SI (match_operand:SI 1 "register_operand" "r")
1840 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1841 (match_operand 3 "const_int_operand" "n")))))]
1842 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1844 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1845 INTVAL (operands[3])));
1846 return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
1847 [(set_attr "type" "alu_ext")]
1850 (define_insn_and_split "absdi2"
1851 [(set (match_operand:DI 0 "register_operand" "=r,w")
1852 (abs:DI (match_operand:DI 1 "register_operand" "r,w")))
1853 (clobber (match_scratch:DI 2 "=&r,X"))]
1859 && GP_REGNUM_P (REGNO (operands[0]))
1860 && GP_REGNUM_P (REGNO (operands[1]))"
1863 emit_insn (gen_rtx_SET (VOIDmode, operands[2],
1864 gen_rtx_XOR (DImode,
1865 gen_rtx_ASHIFTRT (DImode,
1869 emit_insn (gen_rtx_SET (VOIDmode,
1871 gen_rtx_MINUS (DImode,
1873 gen_rtx_ASHIFTRT (DImode,
1878 [(set_attr "type" "alu_reg")]
1881 (define_insn "neg<mode>2"
1882 [(set (match_operand:GPI 0 "register_operand" "=r,w")
1883 (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
1887 neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
1888 [(set_attr "type" "alu_reg, neon_neg<q>")
1889 (set_attr "simd" "*,yes")]
1892 ;; zero_extend version of above
1893 (define_insn "*negsi2_uxtw"
1894 [(set (match_operand:DI 0 "register_operand" "=r")
1895 (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
1898 [(set_attr "type" "alu_reg")]
1901 (define_insn "*ngc<mode>"
1902 [(set (match_operand:GPI 0 "register_operand" "=r")
1903 (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
1904 (match_operand:GPI 1 "register_operand" "r")))]
1906 "ngc\\t%<w>0, %<w>1"
1907 [(set_attr "type" "adc_reg")]
1910 (define_insn "*ngcsi_uxtw"
1911 [(set (match_operand:DI 0 "register_operand" "=r")
1913 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
1914 (match_operand:SI 1 "register_operand" "r"))))]
1917 [(set_attr "type" "adc_reg")]
1920 (define_insn "*neg<mode>2_compare0"
1921 [(set (reg:CC_NZ CC_REGNUM)
1922 (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
1924 (set (match_operand:GPI 0 "register_operand" "=r")
1925 (neg:GPI (match_dup 1)))]
1927 "negs\\t%<w>0, %<w>1"
1928 [(set_attr "type" "alus_reg")]
1931 ;; zero_extend version of above
1932 (define_insn "*negsi2_compare0_uxtw"
1933 [(set (reg:CC_NZ CC_REGNUM)
1934 (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
1936 (set (match_operand:DI 0 "register_operand" "=r")
1937 (zero_extend:DI (neg:SI (match_dup 1))))]
1940 [(set_attr "type" "alus_reg")]
1943 (define_insn "*neg_<shift><mode>3_compare0"
1944 [(set (reg:CC_NZ CC_REGNUM)
1946 (neg:GPI (ASHIFT:GPI
1947 (match_operand:GPI 1 "register_operand" "r")
1948 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
1950 (set (match_operand:GPI 0 "register_operand" "=r")
1951 (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
1953 "negs\\t%<w>0, %<w>1, <shift> %2"
1954 [(set_attr "type" "alus_shift_imm")]
1957 (define_insn "*neg_<shift>_<mode>2"
1958 [(set (match_operand:GPI 0 "register_operand" "=r")
1959 (neg:GPI (ASHIFT:GPI
1960 (match_operand:GPI 1 "register_operand" "r")
1961 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1963 "neg\\t%<w>0, %<w>1, <shift> %2"
1964 [(set_attr "type" "alu_shift_imm")]
1967 ;; zero_extend version of above
1968 (define_insn "*neg_<shift>_si2_uxtw"
1969 [(set (match_operand:DI 0 "register_operand" "=r")
1972 (match_operand:SI 1 "register_operand" "r")
1973 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1975 "neg\\t%w0, %w1, <shift> %2"
1976 [(set_attr "type" "alu_shift_imm")]
1979 (define_insn "*neg_mul_imm_<mode>2"
1980 [(set (match_operand:GPI 0 "register_operand" "=r")
1982 (match_operand:GPI 1 "register_operand" "r")
1983 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1985 "neg\\t%<w>0, %<w>1, lsl %p2"
1986 [(set_attr "type" "alu_shift_imm")]
1989 ;; zero_extend version of above
1990 (define_insn "*neg_mul_imm_si2_uxtw"
1991 [(set (match_operand:DI 0 "register_operand" "=r")
1994 (match_operand:SI 1 "register_operand" "r")
1995 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
1997 "neg\\t%w0, %w1, lsl %p2"
1998 [(set_attr "type" "alu_shift_imm")]
2001 (define_insn "mul<mode>3"
2002 [(set (match_operand:GPI 0 "register_operand" "=r")
2003 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2004 (match_operand:GPI 2 "register_operand" "r")))]
2006 "mul\\t%<w>0, %<w>1, %<w>2"
2007 [(set_attr "type" "mul")]
2010 ;; zero_extend version of above
2011 (define_insn "*mulsi3_uxtw"
2012 [(set (match_operand:DI 0 "register_operand" "=r")
2014 (mult:SI (match_operand:SI 1 "register_operand" "r")
2015 (match_operand:SI 2 "register_operand" "r"))))]
2017 "mul\\t%w0, %w1, %w2"
2018 [(set_attr "type" "mul")]
2021 (define_insn "madd<mode>"
2022 [(set (match_operand:GPI 0 "register_operand" "=r")
2023 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2024 (match_operand:GPI 2 "register_operand" "r"))
2025 (match_operand:GPI 3 "register_operand" "r")))]
2027 "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2028 [(set_attr "type" "mla")]
2031 ;; zero_extend version of above
2032 (define_insn "*maddsi_uxtw"
2033 [(set (match_operand:DI 0 "register_operand" "=r")
2035 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2036 (match_operand:SI 2 "register_operand" "r"))
2037 (match_operand:SI 3 "register_operand" "r"))))]
2039 "madd\\t%w0, %w1, %w2, %w3"
2040 [(set_attr "type" "mla")]
2043 (define_insn "*msub<mode>"
2044 [(set (match_operand:GPI 0 "register_operand" "=r")
2045 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2046 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2047 (match_operand:GPI 2 "register_operand" "r"))))]
2050 "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2051 [(set_attr "type" "mla")]
2054 ;; zero_extend version of above
2055 (define_insn "*msubsi_uxtw"
2056 [(set (match_operand:DI 0 "register_operand" "=r")
2058 (minus:SI (match_operand:SI 3 "register_operand" "r")
2059 (mult:SI (match_operand:SI 1 "register_operand" "r")
2060 (match_operand:SI 2 "register_operand" "r")))))]
2063 "msub\\t%w0, %w1, %w2, %w3"
2064 [(set_attr "type" "mla")]
2067 (define_insn "*mul<mode>_neg"
2068 [(set (match_operand:GPI 0 "register_operand" "=r")
2069 (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2070 (match_operand:GPI 2 "register_operand" "r")))]
2073 "mneg\\t%<w>0, %<w>1, %<w>2"
2074 [(set_attr "type" "mul")]
2077 ;; zero_extend version of above
2078 (define_insn "*mulsi_neg_uxtw"
2079 [(set (match_operand:DI 0 "register_operand" "=r")
2081 (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2082 (match_operand:SI 2 "register_operand" "r"))))]
2085 "mneg\\t%w0, %w1, %w2"
2086 [(set_attr "type" "mul")]
2089 (define_insn "<su_optab>mulsidi3"
2090 [(set (match_operand:DI 0 "register_operand" "=r")
2091 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2092 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2094 "<su>mull\\t%0, %w1, %w2"
2095 [(set_attr "type" "<su>mull")]
2098 (define_insn "<su_optab>maddsidi4"
2099 [(set (match_operand:DI 0 "register_operand" "=r")
2101 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2102 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2103 (match_operand:DI 3 "register_operand" "r")))]
2105 "<su>maddl\\t%0, %w1, %w2, %3"
2106 [(set_attr "type" "<su>mlal")]
2109 (define_insn "<su_optab>msubsidi4"
2110 [(set (match_operand:DI 0 "register_operand" "=r")
2112 (match_operand:DI 3 "register_operand" "r")
2113 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2115 (match_operand:SI 2 "register_operand" "r")))))]
2117 "<su>msubl\\t%0, %w1, %w2, %3"
2118 [(set_attr "type" "<su>mlal")]
2121 (define_insn "*<su_optab>mulsidi_neg"
2122 [(set (match_operand:DI 0 "register_operand" "=r")
2124 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2125 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2127 "<su>mnegl\\t%0, %w1, %w2"
2128 [(set_attr "type" "<su>mull")]
2131 (define_expand "<su_optab>mulditi3"
2132 [(set (match_operand:TI 0 "register_operand")
2133 (mult:TI (ANY_EXTEND:TI (match_operand:DI 1 "register_operand"))
2134 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand"))))]
2137 rtx low = gen_reg_rtx (DImode);
2138 emit_insn (gen_muldi3 (low, operands[1], operands[2]));
2140 rtx high = gen_reg_rtx (DImode);
2141 emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2]));
2143 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2144 emit_move_insn (gen_highpart (DImode, operands[0]), high);
2148 ;; The default expansion of multi3 using umuldi3_highpart will perform
2149 ;; the additions in an order that fails to combine into two madd insns.
2150 (define_expand "multi3"
2151 [(set (match_operand:TI 0 "register_operand")
2152 (mult:TI (match_operand:TI 1 "register_operand")
2153 (match_operand:TI 2 "register_operand")))]
2156 rtx l0 = gen_reg_rtx (DImode);
2157 rtx l1 = gen_lowpart (DImode, operands[1]);
2158 rtx l2 = gen_lowpart (DImode, operands[2]);
2159 rtx h0 = gen_reg_rtx (DImode);
2160 rtx h1 = gen_highpart (DImode, operands[1]);
2161 rtx h2 = gen_highpart (DImode, operands[2]);
2163 emit_insn (gen_muldi3 (l0, l1, l2));
2164 emit_insn (gen_umuldi3_highpart (h0, l1, l2));
2165 emit_insn (gen_madddi (h0, h1, l2, h0));
2166 emit_insn (gen_madddi (h0, l1, h2, h0));
2168 emit_move_insn (gen_lowpart (DImode, operands[0]), l0);
2169 emit_move_insn (gen_highpart (DImode, operands[0]), h0);
2173 (define_insn "<su>muldi3_highpart"
2174 [(set (match_operand:DI 0 "register_operand" "=r")
2178 (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2179 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2182 "<su>mulh\\t%0, %1, %2"
2183 [(set_attr "type" "<su>mull")]
2186 (define_insn "<su_optab>div<mode>3"
2187 [(set (match_operand:GPI 0 "register_operand" "=r")
2188 (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2189 (match_operand:GPI 2 "register_operand" "r")))]
2191 "<su>div\\t%<w>0, %<w>1, %<w>2"
2192 [(set_attr "type" "<su>div")]
2195 ;; zero_extend version of above
2196 (define_insn "*<su_optab>divsi3_uxtw"
2197 [(set (match_operand:DI 0 "register_operand" "=r")
2199 (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2200 (match_operand:SI 2 "register_operand" "r"))))]
2202 "<su>div\\t%w0, %w1, %w2"
2203 [(set_attr "type" "<su>div")]
2206 ;; -------------------------------------------------------------------
2208 ;; -------------------------------------------------------------------
2210 (define_insn "*cmp<mode>"
2211 [(set (reg:CC CC_REGNUM)
2212 (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2213 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2219 [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
2222 (define_insn "*cmp<mode>"
2223 [(set (reg:CCFP CC_REGNUM)
2224 (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2225 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2229 fcmp\\t%<s>0, %<s>1"
2230 [(set_attr "type" "fcmp<s>")]
2233 (define_insn "*cmpe<mode>"
2234 [(set (reg:CCFPE CC_REGNUM)
2235 (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2236 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2240 fcmpe\\t%<s>0, %<s>1"
2241 [(set_attr "type" "fcmp<s>")]
2244 (define_insn "*cmp_swp_<shift>_reg<mode>"
2245 [(set (reg:CC_SWP CC_REGNUM)
2246 (compare:CC_SWP (ASHIFT:GPI
2247 (match_operand:GPI 0 "register_operand" "r")
2248 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2249 (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2251 "cmp\\t%<w>2, %<w>0, <shift> %1"
2252 [(set_attr "type" "alus_shift_imm")]
2255 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2256 [(set (reg:CC_SWP CC_REGNUM)
2257 (compare:CC_SWP (ANY_EXTEND:GPI
2258 (match_operand:ALLX 0 "register_operand" "r"))
2259 (match_operand:GPI 1 "register_operand" "r")))]
2261 "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2262 [(set_attr "type" "alus_ext")]
2265 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2266 [(set (reg:CC_SWP CC_REGNUM)
2267 (compare:CC_SWP (ashift:GPI
2269 (match_operand:ALLX 0 "register_operand" "r"))
2270 (match_operand 1 "aarch64_imm3" "Ui3"))
2271 (match_operand:GPI 2 "register_operand" "r")))]
2273 "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2274 [(set_attr "type" "alus_ext")]
2277 ;; -------------------------------------------------------------------
2278 ;; Store-flag and conditional select insns
2279 ;; -------------------------------------------------------------------
2281 (define_expand "cstore<mode>4"
2282 [(set (match_operand:SI 0 "register_operand" "")
2283 (match_operator:SI 1 "aarch64_comparison_operator"
2284 [(match_operand:GPI 2 "register_operand" "")
2285 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2288 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2290 operands[3] = const0_rtx;
2294 (define_expand "cstore<mode>4"
2295 [(set (match_operand:SI 0 "register_operand" "")
2296 (match_operator:SI 1 "aarch64_comparison_operator"
2297 [(match_operand:GPF 2 "register_operand" "")
2298 (match_operand:GPF 3 "register_operand" "")]))]
2301 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2303 operands[3] = const0_rtx;
2307 (define_insn "*cstore<mode>_insn"
2308 [(set (match_operand:ALLI 0 "register_operand" "=r")
2309 (match_operator:ALLI 1 "aarch64_comparison_operator"
2310 [(match_operand 2 "cc_register" "") (const_int 0)]))]
2313 [(set_attr "type" "csel")]
2316 ;; zero_extend version of the above
2317 (define_insn "*cstoresi_insn_uxtw"
2318 [(set (match_operand:DI 0 "register_operand" "=r")
2320 (match_operator:SI 1 "aarch64_comparison_operator"
2321 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2324 [(set_attr "type" "csel")]
2327 (define_insn "cstore<mode>_neg"
2328 [(set (match_operand:ALLI 0 "register_operand" "=r")
2329 (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2330 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2332 "csetm\\t%<w>0, %m1"
2333 [(set_attr "type" "csel")]
2336 ;; zero_extend version of the above
2337 (define_insn "*cstoresi_neg_uxtw"
2338 [(set (match_operand:DI 0 "register_operand" "=r")
2340 (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2341 [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2344 [(set_attr "type" "csel")]
2347 (define_expand "cmov<mode>6"
2348 [(set (match_operand:GPI 0 "register_operand" "")
2350 (match_operator 1 "aarch64_comparison_operator"
2351 [(match_operand:GPI 2 "register_operand" "")
2352 (match_operand:GPI 3 "aarch64_plus_operand" "")])
2353 (match_operand:GPI 4 "register_operand" "")
2354 (match_operand:GPI 5 "register_operand" "")))]
2357 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2359 operands[3] = const0_rtx;
2363 (define_expand "cmov<mode>6"
2364 [(set (match_operand:GPF 0 "register_operand" "")
2366 (match_operator 1 "aarch64_comparison_operator"
2367 [(match_operand:GPF 2 "register_operand" "")
2368 (match_operand:GPF 3 "register_operand" "")])
2369 (match_operand:GPF 4 "register_operand" "")
2370 (match_operand:GPF 5 "register_operand" "")))]
2373 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2375 operands[3] = const0_rtx;
2379 (define_insn "*cmov<mode>_insn"
2380 [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2382 (match_operator 1 "aarch64_comparison_operator"
2383 [(match_operand 2 "cc_register" "") (const_int 0)])
2384 (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2385 (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2386 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2387 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2388 ;; Final two alternatives should be unreachable, but included for completeness
2390 csel\\t%<w>0, %<w>3, %<w>4, %m1
2391 csinv\\t%<w>0, %<w>3, <w>zr, %m1
2392 csinv\\t%<w>0, %<w>4, <w>zr, %M1
2393 csinc\\t%<w>0, %<w>3, <w>zr, %m1
2394 csinc\\t%<w>0, %<w>4, <w>zr, %M1
2397 [(set_attr "type" "csel")]
2400 ;; zero_extend version of above
2401 (define_insn "*cmovsi_insn_uxtw"
2402 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2405 (match_operator 1 "aarch64_comparison_operator"
2406 [(match_operand 2 "cc_register" "") (const_int 0)])
2407 (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2408 (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2409 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2410 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2411 ;; Final two alternatives should be unreachable, but included for completeness
2413 csel\\t%w0, %w3, %w4, %m1
2414 csinv\\t%w0, %w3, wzr, %m1
2415 csinv\\t%w0, %w4, wzr, %M1
2416 csinc\\t%w0, %w3, wzr, %m1
2417 csinc\\t%w0, %w4, wzr, %M1
2420 [(set_attr "type" "csel")]
2423 (define_insn "*cmov<mode>_insn"
2424 [(set (match_operand:GPF 0 "register_operand" "=w")
2426 (match_operator 1 "aarch64_comparison_operator"
2427 [(match_operand 2 "cc_register" "") (const_int 0)])
2428 (match_operand:GPF 3 "register_operand" "w")
2429 (match_operand:GPF 4 "register_operand" "w")))]
2431 "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2432 [(set_attr "type" "fcsel")]
2435 (define_expand "mov<mode>cc"
2436 [(set (match_operand:ALLI 0 "register_operand" "")
2437 (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2438 (match_operand:ALLI 2 "register_operand" "")
2439 (match_operand:ALLI 3 "register_operand" "")))]
2443 enum rtx_code code = GET_CODE (operands[1]);
2445 if (code == UNEQ || code == LTGT)
2448 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2449 XEXP (operands[1], 1));
2450 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2454 (define_expand "mov<GPF:mode><GPI:mode>cc"
2455 [(set (match_operand:GPI 0 "register_operand" "")
2456 (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2457 (match_operand:GPF 2 "register_operand" "")
2458 (match_operand:GPF 3 "register_operand" "")))]
2462 enum rtx_code code = GET_CODE (operands[1]);
2464 if (code == UNEQ || code == LTGT)
2467 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2468 XEXP (operands[1], 1));
2469 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2473 (define_expand "mov<mode>cc"
2474 [(set (match_operand:GPF 0 "register_operand" "")
2475 (if_then_else:GPF (match_operand 1 "aarch64_comparison_operator" "")
2476 (match_operand:GPF 2 "register_operand" "")
2477 (match_operand:GPF 3 "register_operand" "")))]
2481 enum rtx_code code = GET_CODE (operands[1]);
2483 if (code == UNEQ || code == LTGT)
2486 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2487 XEXP (operands[1], 1));
2488 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2493 ;; CRC32 instructions.
2494 (define_insn "aarch64_<crc_variant>"
2495 [(set (match_operand:SI 0 "register_operand" "=r")
2496 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2497 (match_operand:<crc_mode> 2 "register_operand" "r")]
2501 if (GET_MODE_BITSIZE (GET_MODE (operands[2])) >= 64)
2502 return "<crc_variant>\\t%w0, %w1, %x2";
2504 return "<crc_variant>\\t%w0, %w1, %w2";
2506 [(set_attr "type" "crc")]
2509 (define_insn "*csinc2<mode>_insn"
2510 [(set (match_operand:GPI 0 "register_operand" "=r")
2511 (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator"
2512 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
2513 (match_operand:GPI 1 "register_operand" "r")))]
2515 "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2516 [(set_attr "type" "csel")]
2519 (define_insn "csinc3<mode>_insn"
2520 [(set (match_operand:GPI 0 "register_operand" "=r")
2522 (match_operator:GPI 1 "aarch64_comparison_operator"
2523 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2524 (plus:GPI (match_operand:GPI 3 "register_operand" "r")
2526 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2528 "csinc\\t%<w>0, %<w>4, %<w>3, %M1"
2529 [(set_attr "type" "csel")]
2532 (define_insn "*csinv3<mode>_insn"
2533 [(set (match_operand:GPI 0 "register_operand" "=r")
2535 (match_operator:GPI 1 "aarch64_comparison_operator"
2536 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2537 (not:GPI (match_operand:GPI 3 "register_operand" "r"))
2538 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2540 "csinv\\t%<w>0, %<w>4, %<w>3, %M1"
2541 [(set_attr "type" "csel")]
2544 (define_insn "*csneg3<mode>_insn"
2545 [(set (match_operand:GPI 0 "register_operand" "=r")
2547 (match_operator:GPI 1 "aarch64_comparison_operator"
2548 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2549 (neg:GPI (match_operand:GPI 3 "register_operand" "r"))
2550 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2552 "csneg\\t%<w>0, %<w>4, %<w>3, %M1"
2553 [(set_attr "type" "csel")]
2556 ;; -------------------------------------------------------------------
2557 ;; Logical operations
2558 ;; -------------------------------------------------------------------
2560 (define_insn "<optab><mode>3"
2561 [(set (match_operand:GPI 0 "register_operand" "=r,rk")
2562 (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2563 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
2565 "<logical>\\t%<w>0, %<w>1, %<w>2"
2566 [(set_attr "type" "logic_reg,logic_imm")]
2569 ;; zero_extend version of above
2570 (define_insn "*<optab>si3_uxtw"
2571 [(set (match_operand:DI 0 "register_operand" "=r,rk")
2573 (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2574 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2576 "<logical>\\t%w0, %w1, %w2"
2577 [(set_attr "type" "logic_reg,logic_imm")]
2580 (define_insn "*and<mode>3_compare0"
2581 [(set (reg:CC_NZ CC_REGNUM)
2583 (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2584 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2586 (set (match_operand:GPI 0 "register_operand" "=r,r")
2587 (and:GPI (match_dup 1) (match_dup 2)))]
2589 "ands\\t%<w>0, %<w>1, %<w>2"
2590 [(set_attr "type" "logics_reg,logics_imm")]
2593 ;; zero_extend version of above
2594 (define_insn "*andsi3_compare0_uxtw"
2595 [(set (reg:CC_NZ CC_REGNUM)
2597 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2598 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2600 (set (match_operand:DI 0 "register_operand" "=r,r")
2601 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2603 "ands\\t%w0, %w1, %w2"
2604 [(set_attr "type" "logics_reg,logics_imm")]
2607 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2608 [(set (reg:CC_NZ CC_REGNUM)
2611 (match_operand:GPI 1 "register_operand" "r")
2612 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2613 (match_operand:GPI 3 "register_operand" "r"))
2615 (set (match_operand:GPI 0 "register_operand" "=r")
2616 (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2618 "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2619 [(set_attr "type" "logics_shift_imm")]
2622 ;; zero_extend version of above
2623 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2624 [(set (reg:CC_NZ CC_REGNUM)
2627 (match_operand:SI 1 "register_operand" "r")
2628 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2629 (match_operand:SI 3 "register_operand" "r"))
2631 (set (match_operand:DI 0 "register_operand" "=r")
2632 (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2635 "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2636 [(set_attr "type" "logics_shift_imm")]
2639 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2640 [(set (match_operand:GPI 0 "register_operand" "=r")
2641 (LOGICAL:GPI (SHIFT:GPI
2642 (match_operand:GPI 1 "register_operand" "r")
2643 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2644 (match_operand:GPI 3 "register_operand" "r")))]
2646 "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2647 [(set_attr "type" "logic_shift_imm")]
2650 (define_insn "*<optab>_rol<mode>3"
2651 [(set (match_operand:GPI 0 "register_operand" "=r")
2652 (LOGICAL:GPI (rotate:GPI
2653 (match_operand:GPI 1 "register_operand" "r")
2654 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2655 (match_operand:GPI 3 "register_operand" "r")))]
2657 "<logical>\\t%<w>0, %<w>3, %<w>1, ror (<sizen> - %2)"
2658 [(set_attr "type" "logic_shift_imm")]
2661 ;; zero_extend versions of above
2662 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
2663 [(set (match_operand:DI 0 "register_operand" "=r")
2665 (LOGICAL:SI (SHIFT:SI
2666 (match_operand:SI 1 "register_operand" "r")
2667 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2668 (match_operand:SI 3 "register_operand" "r"))))]
2670 "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2671 [(set_attr "type" "logic_shift_imm")]
2674 (define_insn "*<optab>_rolsi3_uxtw"
2675 [(set (match_operand:DI 0 "register_operand" "=r")
2677 (LOGICAL:SI (rotate:SI
2678 (match_operand:SI 1 "register_operand" "r")
2679 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2680 (match_operand:SI 3 "register_operand" "r"))))]
2682 "<logical>\\t%w0, %w3, %w1, ror (32 - %2)"
2683 [(set_attr "type" "logic_shift_imm")]
2686 (define_insn "one_cmpl<mode>2"
2687 [(set (match_operand:GPI 0 "register_operand" "=r")
2688 (not:GPI (match_operand:GPI 1 "register_operand" "r")))]
2690 "mvn\\t%<w>0, %<w>1"
2691 [(set_attr "type" "logic_reg")]
2694 (define_insn "*one_cmpl_<optab><mode>2"
2695 [(set (match_operand:GPI 0 "register_operand" "=r")
2696 (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
2697 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2699 "mvn\\t%<w>0, %<w>1, <shift> %2"
2700 [(set_attr "type" "logic_shift_imm")]
2703 (define_insn "*<LOGICAL:optab>_one_cmpl<mode>3"
2704 [(set (match_operand:GPI 0 "register_operand" "=r")
2705 (LOGICAL:GPI (not:GPI
2706 (match_operand:GPI 1 "register_operand" "r"))
2707 (match_operand:GPI 2 "register_operand" "r")))]
2709 "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1"
2710 [(set_attr "type" "logic_reg")]
2713 (define_insn "*and_one_cmpl<mode>3_compare0"
2714 [(set (reg:CC_NZ CC_REGNUM)
2717 (match_operand:GPI 1 "register_operand" "r"))
2718 (match_operand:GPI 2 "register_operand" "r"))
2720 (set (match_operand:GPI 0 "register_operand" "=r")
2721 (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
2723 "bics\\t%<w>0, %<w>2, %<w>1"
2724 [(set_attr "type" "logics_reg")]
2727 ;; zero_extend version of above
2728 (define_insn "*and_one_cmplsi3_compare0_uxtw"
2729 [(set (reg:CC_NZ CC_REGNUM)
2732 (match_operand:SI 1 "register_operand" "r"))
2733 (match_operand:SI 2 "register_operand" "r"))
2735 (set (match_operand:DI 0 "register_operand" "=r")
2736 (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
2738 "bics\\t%w0, %w2, %w1"
2739 [(set_attr "type" "logics_reg")]
2742 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
2743 [(set (match_operand:GPI 0 "register_operand" "=r")
2744 (LOGICAL:GPI (not:GPI
2746 (match_operand:GPI 1 "register_operand" "r")
2747 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2748 (match_operand:GPI 3 "register_operand" "r")))]
2750 "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2751 [(set_attr "type" "logics_shift_imm")]
2754 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
2755 [(set (reg:CC_NZ CC_REGNUM)
2759 (match_operand:GPI 1 "register_operand" "r")
2760 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2761 (match_operand:GPI 3 "register_operand" "r"))
2763 (set (match_operand:GPI 0 "register_operand" "=r")
2766 (match_dup 1) (match_dup 2))) (match_dup 3)))]
2768 "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2769 [(set_attr "type" "logics_shift_imm")]
2772 ;; zero_extend version of above
2773 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
2774 [(set (reg:CC_NZ CC_REGNUM)
2778 (match_operand:SI 1 "register_operand" "r")
2779 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
2780 (match_operand:SI 3 "register_operand" "r"))
2782 (set (match_operand:DI 0 "register_operand" "=r")
2783 (zero_extend:DI (and:SI
2785 (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
2787 "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2788 [(set_attr "type" "logics_shift_imm")]
2791 (define_insn "clz<mode>2"
2792 [(set (match_operand:GPI 0 "register_operand" "=r")
2793 (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
2795 "clz\\t%<w>0, %<w>1"
2796 [(set_attr "type" "clz")]
2799 (define_expand "ffs<mode>2"
2800 [(match_operand:GPI 0 "register_operand")
2801 (match_operand:GPI 1 "register_operand")]
2804 rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
2805 rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
2807 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2808 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2809 emit_insn (gen_csinc3<mode>_insn (operands[0], x, ccreg, operands[0], const0_rtx));
2814 (define_insn "clrsb<mode>2"
2815 [(set (match_operand:GPI 0 "register_operand" "=r")
2816 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_CLS))]
2818 "cls\\t%<w>0, %<w>1"
2819 [(set_attr "type" "clz")]
2822 (define_insn "rbit<mode>2"
2823 [(set (match_operand:GPI 0 "register_operand" "=r")
2824 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
2826 "rbit\\t%<w>0, %<w>1"
2827 [(set_attr "type" "rbit")]
2830 (define_expand "ctz<mode>2"
2831 [(match_operand:GPI 0 "register_operand")
2832 (match_operand:GPI 1 "register_operand")]
2835 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2836 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2841 (define_insn "*and<mode>3nr_compare0"
2842 [(set (reg:CC_NZ CC_REGNUM)
2844 (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
2845 (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
2848 "tst\\t%<w>0, %<w>1"
2849 [(set_attr "type" "logics_reg")]
2852 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
2853 [(set (reg:CC_NZ CC_REGNUM)
2856 (match_operand:GPI 0 "register_operand" "r")
2857 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2858 (match_operand:GPI 2 "register_operand" "r"))
2861 "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
2862 [(set_attr "type" "logics_shift_imm")]
2865 ;; -------------------------------------------------------------------
2867 ;; -------------------------------------------------------------------
2869 (define_expand "<optab><mode>3"
2870 [(set (match_operand:GPI 0 "register_operand")
2871 (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
2872 (match_operand:QI 2 "nonmemory_operand")))]
2875 if (CONST_INT_P (operands[2]))
2877 operands[2] = GEN_INT (INTVAL (operands[2])
2878 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2880 if (operands[2] == const0_rtx)
2882 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2889 (define_expand "ashl<mode>3"
2890 [(set (match_operand:SHORT 0 "register_operand")
2891 (ashift:SHORT (match_operand:SHORT 1 "register_operand")
2892 (match_operand:QI 2 "nonmemory_operand")))]
2895 if (CONST_INT_P (operands[2]))
2897 operands[2] = GEN_INT (INTVAL (operands[2])
2898 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2900 if (operands[2] == const0_rtx)
2902 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2909 (define_expand "rotr<mode>3"
2910 [(set (match_operand:GPI 0 "register_operand")
2911 (rotatert:GPI (match_operand:GPI 1 "register_operand")
2912 (match_operand:QI 2 "nonmemory_operand")))]
2915 if (CONST_INT_P (operands[2]))
2917 operands[2] = GEN_INT (INTVAL (operands[2])
2918 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2920 if (operands[2] == const0_rtx)
2922 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2929 (define_expand "rotl<mode>3"
2930 [(set (match_operand:GPI 0 "register_operand")
2931 (rotatert:GPI (match_operand:GPI 1 "register_operand")
2932 (match_operand:QI 2 "nonmemory_operand")))]
2935 /* (SZ - cnt) % SZ == -cnt % SZ */
2936 if (CONST_INT_P (operands[2]))
2938 operands[2] = GEN_INT ((-INTVAL (operands[2]))
2939 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2940 if (operands[2] == const0_rtx)
2942 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2947 operands[2] = expand_simple_unop (QImode, NEG, operands[2],
2952 ;; Logical left shift using SISD or Integer instruction
2953 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
2954 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
2956 (match_operand:GPI 1 "register_operand" "w,w,r")
2957 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
2960 shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
2961 ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
2962 lsl\t%<w>0, %<w>1, %<w>2"
2963 [(set_attr "simd" "yes,yes,no")
2964 (set_attr "type" "neon_shift_imm<q>, neon_shift_reg<q>,shift_reg")]
2967 ;; Logical right shift using SISD or Integer instruction
2968 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
2969 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
2971 (match_operand:GPI 1 "register_operand" "w,w,r")
2972 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
2975 ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
2977 lsr\t%<w>0, %<w>1, %<w>2"
2978 [(set_attr "simd" "yes,yes,no")
2979 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")]
2983 [(set (match_operand:DI 0 "aarch64_simd_register")
2985 (match_operand:DI 1 "aarch64_simd_register")
2986 (match_operand:QI 2 "aarch64_simd_register")))]
2987 "TARGET_SIMD && reload_completed"
2989 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
2991 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_USHL))]
2996 [(set (match_operand:SI 0 "aarch64_simd_register")
2998 (match_operand:SI 1 "aarch64_simd_register")
2999 (match_operand:QI 2 "aarch64_simd_register")))]
3000 "TARGET_SIMD && reload_completed"
3002 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3004 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_USHL_2S))]
3008 ;; Arithmetic right shift using SISD or Integer instruction
3009 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3010 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3012 (match_operand:GPI 1 "register_operand" "w,w,r")
3013 (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,rUs<cmode>")))]
3016 sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3018 asr\t%<w>0, %<w>1, %<w>2"
3019 [(set_attr "simd" "yes,yes,no")
3020 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")]
3024 [(set (match_operand:DI 0 "aarch64_simd_register")
3026 (match_operand:DI 1 "aarch64_simd_register")
3027 (match_operand:QI 2 "aarch64_simd_register")))]
3028 "TARGET_SIMD && reload_completed"
3030 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3032 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_SSHL))]
3037 [(set (match_operand:SI 0 "aarch64_simd_register")
3039 (match_operand:SI 1 "aarch64_simd_register")
3040 (match_operand:QI 2 "aarch64_simd_register")))]
3041 "TARGET_SIMD && reload_completed"
3043 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3045 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_SSHL_2S))]
3049 (define_insn "*aarch64_sisd_ushl"
3050 [(set (match_operand:DI 0 "register_operand" "=w")
3051 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3052 (match_operand:QI 2 "register_operand" "w")]
3055 "ushl\t%d0, %d1, %d2"
3056 [(set_attr "simd" "yes")
3057 (set_attr "type" "neon_shift_reg")]
3060 (define_insn "*aarch64_ushl_2s"
3061 [(set (match_operand:SI 0 "register_operand" "=w")
3062 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3063 (match_operand:QI 2 "register_operand" "w")]
3066 "ushl\t%0.2s, %1.2s, %2.2s"
3067 [(set_attr "simd" "yes")
3068 (set_attr "type" "neon_shift_reg")]
3071 (define_insn "*aarch64_sisd_sshl"
3072 [(set (match_operand:DI 0 "register_operand" "=w")
3073 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3074 (match_operand:QI 2 "register_operand" "w")]
3077 "sshl\t%d0, %d1, %d2"
3078 [(set_attr "simd" "yes")
3079 (set_attr "type" "neon_shift_reg")]
3082 (define_insn "*aarch64_sshl_2s"
3083 [(set (match_operand:SI 0 "register_operand" "=w")
3084 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3085 (match_operand:QI 2 "register_operand" "w")]
3088 "sshl\t%0.2s, %1.2s, %2.2s"
3089 [(set_attr "simd" "yes")
3090 (set_attr "type" "neon_shift_reg")]
3093 (define_insn "*aarch64_sisd_neg_qi"
3094 [(set (match_operand:QI 0 "register_operand" "=w")
3095 (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3099 [(set_attr "simd" "yes")
3100 (set_attr "type" "neon_neg")]
3104 (define_insn "*ror<mode>3_insn"
3105 [(set (match_operand:GPI 0 "register_operand" "=r")
3107 (match_operand:GPI 1 "register_operand" "r")
3108 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3110 "ror\\t%<w>0, %<w>1, %<w>2"
3111 [(set_attr "type" "shift_reg")]
3114 ;; zero_extend version of above
3115 (define_insn "*<optab>si3_insn_uxtw"
3116 [(set (match_operand:DI 0 "register_operand" "=r")
3117 (zero_extend:DI (SHIFT:SI
3118 (match_operand:SI 1 "register_operand" "r")
3119 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3121 "<shift>\\t%w0, %w1, %w2"
3122 [(set_attr "type" "shift_reg")]
3125 (define_insn "*ashl<mode>3_insn"
3126 [(set (match_operand:SHORT 0 "register_operand" "=r")
3127 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3128 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
3130 "lsl\\t%<w>0, %<w>1, %<w>2"
3131 [(set_attr "type" "shift_reg")]
3134 (define_insn "*<optab><mode>3_insn"
3135 [(set (match_operand:SHORT 0 "register_operand" "=r")
3136 (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3137 (match_operand 2 "const_int_operand" "n")))]
3138 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3140 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3141 return "<bfshift>\t%w0, %w1, %2, %3";
3143 [(set_attr "type" "bfm")]
3146 (define_insn "*extr<mode>5_insn"
3147 [(set (match_operand:GPI 0 "register_operand" "=r")
3148 (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3149 (match_operand 3 "const_int_operand" "n"))
3150 (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3151 (match_operand 4 "const_int_operand" "n"))))]
3152 "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3153 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3154 "extr\\t%<w>0, %<w>1, %<w>2, %4"
3155 [(set_attr "type" "shift_imm")]
3158 ;; zero_extend version of the above
3159 (define_insn "*extrsi5_insn_uxtw"
3160 [(set (match_operand:DI 0 "register_operand" "=r")
3162 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3163 (match_operand 3 "const_int_operand" "n"))
3164 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3165 (match_operand 4 "const_int_operand" "n")))))]
3166 "UINTVAL (operands[3]) < 32 &&
3167 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3168 "extr\\t%w0, %w1, %w2, %4"
3169 [(set_attr "type" "shift_imm")]
3172 (define_insn "*ror<mode>3_insn"
3173 [(set (match_operand:GPI 0 "register_operand" "=r")
3174 (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3175 (match_operand 2 "const_int_operand" "n")))]
3176 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3178 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3179 return "ror\\t%<w>0, %<w>1, %3";
3181 [(set_attr "type" "shift_imm")]
3184 ;; zero_extend version of the above
3185 (define_insn "*rorsi3_insn_uxtw"
3186 [(set (match_operand:DI 0 "register_operand" "=r")
3188 (rotate:SI (match_operand:SI 1 "register_operand" "r")
3189 (match_operand 2 "const_int_operand" "n"))))]
3190 "UINTVAL (operands[2]) < 32"
3192 operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3193 return "ror\\t%w0, %w1, %3";
3195 [(set_attr "type" "shift_imm")]
3198 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3199 [(set (match_operand:GPI 0 "register_operand" "=r")
3201 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3202 (match_operand 2 "const_int_operand" "n"))))]
3203 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3205 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3206 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3208 [(set_attr "type" "bfm")]
3211 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3212 [(set (match_operand:GPI 0 "register_operand" "=r")
3214 (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3215 (match_operand 2 "const_int_operand" "n"))))]
3216 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3218 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3219 return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3221 [(set_attr "type" "bfm")]
3224 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3225 [(set (match_operand:GPI 0 "register_operand" "=r")
3227 (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3228 (match_operand 2 "const_int_operand" "n"))))]
3229 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3231 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3232 return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3234 [(set_attr "type" "bfm")]
3237 ;; -------------------------------------------------------------------
3239 ;; -------------------------------------------------------------------
3241 (define_expand "<optab>"
3242 [(set (match_operand:DI 0 "register_operand" "=r")
3243 (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3244 (match_operand 2 "const_int_operand" "n")
3245 (match_operand 3 "const_int_operand" "n")))]
3250 (define_insn "*<optab><mode>"
3251 [(set (match_operand:GPI 0 "register_operand" "=r")
3252 (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3253 (match_operand 2 "const_int_operand" "n")
3254 (match_operand 3 "const_int_operand" "n")))]
3256 "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3257 [(set_attr "type" "bfm")]
3260 ;; Bitfield Insert (insv)
3261 (define_expand "insv<mode>"
3262 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3263 (match_operand 1 "const_int_operand")
3264 (match_operand 2 "const_int_operand"))
3265 (match_operand:GPI 3 "general_operand"))]
3268 unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3269 unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3270 rtx value = operands[3];
3272 if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3275 if (CONST_INT_P (value))
3277 unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3279 /* Prefer AND/OR for inserting all zeros or all ones. */
3280 if ((UINTVAL (value) & mask) == 0
3281 || (UINTVAL (value) & mask) == mask)
3284 /* 16-bit aligned 16-bit wide insert is handled by insv_imm. */
3285 if (width == 16 && (pos % 16) == 0)
3288 operands[3] = force_reg (<MODE>mode, value);
3291 (define_insn "*insv_reg<mode>"
3292 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3293 (match_operand 1 "const_int_operand" "n")
3294 (match_operand 2 "const_int_operand" "n"))
3295 (match_operand:GPI 3 "register_operand" "r"))]
3296 "!(UINTVAL (operands[1]) == 0
3297 || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3298 > GET_MODE_BITSIZE (<MODE>mode)))"
3299 "bfi\\t%<w>0, %<w>3, %2, %1"
3300 [(set_attr "type" "bfm")]
3303 (define_insn "*extr_insv_lower_reg<mode>"
3304 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3305 (match_operand 1 "const_int_operand" "n")
3307 (zero_extract:GPI (match_operand:GPI 2 "register_operand" "+r")
3309 (match_operand 3 "const_int_operand" "n")))]
3310 "!(UINTVAL (operands[1]) == 0
3311 || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3312 > GET_MODE_BITSIZE (<MODE>mode)))"
3313 "bfxil\\t%<w>0, %<w>2, %3, %1"
3314 [(set_attr "type" "bfm")]
3317 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3318 [(set (match_operand:GPI 0 "register_operand" "=r")
3319 (ashift:GPI (ANY_EXTEND:GPI
3320 (match_operand:ALLX 1 "register_operand" "r"))
3321 (match_operand 2 "const_int_operand" "n")))]
3322 "UINTVAL (operands[2]) < <GPI:sizen>"
3324 operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3325 ? GEN_INT (<ALLX:sizen>)
3326 : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3327 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3329 [(set_attr "type" "bfm")]
3332 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3334 (define_insn "*andim_ashift<mode>_bfiz"
3335 [(set (match_operand:GPI 0 "register_operand" "=r")
3336 (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3337 (match_operand 2 "const_int_operand" "n"))
3338 (match_operand 3 "const_int_operand" "n")))]
3339 "exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3340 && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3341 "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3342 [(set_attr "type" "bfm")]
3345 (define_insn "bswap<mode>2"
3346 [(set (match_operand:GPI 0 "register_operand" "=r")
3347 (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3349 "rev\\t%<w>0, %<w>1"
3350 [(set_attr "type" "rev")]
3353 (define_insn "bswaphi2"
3354 [(set (match_operand:HI 0 "register_operand" "=r")
3355 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3358 [(set_attr "type" "rev")]
3361 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
3362 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
3363 ;; each valid permutation.
3365 (define_insn "rev16<mode>2"
3366 [(set (match_operand:GPI 0 "register_operand" "=r")
3367 (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3369 (match_operand:GPI 3 "const_int_operand" "n"))
3370 (and:GPI (lshiftrt:GPI (match_dup 1)
3372 (match_operand:GPI 2 "const_int_operand" "n"))))]
3373 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3374 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3375 "rev16\\t%<w>0, %<w>1"
3376 [(set_attr "type" "rev")]
3379 (define_insn "rev16<mode>2_alt"
3380 [(set (match_operand:GPI 0 "register_operand" "=r")
3381 (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r")
3383 (match_operand:GPI 2 "const_int_operand" "n"))
3384 (and:GPI (ashift:GPI (match_dup 1)
3386 (match_operand:GPI 3 "const_int_operand" "n"))))]
3387 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3388 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3389 "rev16\\t%<w>0, %<w>1"
3390 [(set_attr "type" "rev")]
3393 ;; zero_extend version of above
3394 (define_insn "*bswapsi2_uxtw"
3395 [(set (match_operand:DI 0 "register_operand" "=r")
3396 (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3399 [(set_attr "type" "rev")]
3402 ;; -------------------------------------------------------------------
3403 ;; Floating-point intrinsics
3404 ;; -------------------------------------------------------------------
3406 ;; frint floating-point round to integral standard patterns.
3407 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round, frintn.
3409 (define_insn "<frint_pattern><mode>2"
3410 [(set (match_operand:GPF 0 "register_operand" "=w")
3411 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3414 "frint<frint_suffix>\\t%<s>0, %<s>1"
3415 [(set_attr "type" "f_rint<s>")]
3418 ;; frcvt floating-point round to integer and convert standard patterns.
3419 ;; Expands to lbtrunc, lceil, lfloor, lround.
3420 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3421 [(set (match_operand:GPI 0 "register_operand" "=r")
3422 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3425 "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3426 [(set_attr "type" "f_cvtf2i")]
3431 (define_insn "fma<mode>4"
3432 [(set (match_operand:GPF 0 "register_operand" "=w")
3433 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3434 (match_operand:GPF 2 "register_operand" "w")
3435 (match_operand:GPF 3 "register_operand" "w")))]
3437 "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3438 [(set_attr "type" "fmac<s>")]
3441 (define_insn "fnma<mode>4"
3442 [(set (match_operand:GPF 0 "register_operand" "=w")
3443 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3444 (match_operand:GPF 2 "register_operand" "w")
3445 (match_operand:GPF 3 "register_operand" "w")))]
3447 "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3448 [(set_attr "type" "fmac<s>")]
3451 (define_insn "fms<mode>4"
3452 [(set (match_operand:GPF 0 "register_operand" "=w")
3453 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3454 (match_operand:GPF 2 "register_operand" "w")
3455 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3457 "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3458 [(set_attr "type" "fmac<s>")]
3461 (define_insn "fnms<mode>4"
3462 [(set (match_operand:GPF 0 "register_operand" "=w")
3463 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3464 (match_operand:GPF 2 "register_operand" "w")
3465 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3467 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3468 [(set_attr "type" "fmac<s>")]
3471 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3472 (define_insn "*fnmadd<mode>4"
3473 [(set (match_operand:GPF 0 "register_operand" "=w")
3474 (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3475 (match_operand:GPF 2 "register_operand" "w")
3476 (match_operand:GPF 3 "register_operand" "w"))))]
3477 "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3478 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3479 [(set_attr "type" "fmac<s>")]
3482 ;; -------------------------------------------------------------------
3483 ;; Floating-point conversions
3484 ;; -------------------------------------------------------------------
3486 (define_insn "extendsfdf2"
3487 [(set (match_operand:DF 0 "register_operand" "=w")
3488 (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3491 [(set_attr "type" "f_cvt")]
3494 (define_insn "truncdfsf2"
3495 [(set (match_operand:SF 0 "register_operand" "=w")
3496 (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3499 [(set_attr "type" "f_cvt")]
3502 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3503 [(set (match_operand:GPI 0 "register_operand" "=r")
3504 (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3506 "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3507 [(set_attr "type" "f_cvtf2i")]
3510 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3511 [(set (match_operand:GPI 0 "register_operand" "=r")
3512 (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3514 "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3515 [(set_attr "type" "f_cvtf2i")]
3518 (define_insn "<optab><fcvt_target><GPF:mode>2"
3519 [(set (match_operand:GPF 0 "register_operand" "=w,w")
3520 (FLOATUORS:GPF (match_operand:<FCVT_TARGET> 1 "register_operand" "w,r")))]
3523 <su_optab>cvtf\t%<GPF:s>0, %<s>1
3524 <su_optab>cvtf\t%<GPF:s>0, %<w1>1"
3525 [(set_attr "simd" "yes,no")
3526 (set_attr "fp" "no,yes")
3527 (set_attr "type" "neon_int_to_fp_<Vetype>,f_cvti2f")]
3530 (define_insn "<optab><fcvt_iesize><GPF:mode>2"
3531 [(set (match_operand:GPF 0 "register_operand" "=w")
3532 (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand" "r")))]
3534 "<su_optab>cvtf\t%<GPF:s>0, %<w2>1"
3535 [(set_attr "type" "f_cvti2f")]
3538 ;; -------------------------------------------------------------------
3539 ;; Floating-point arithmetic
3540 ;; -------------------------------------------------------------------
3542 (define_insn "add<mode>3"
3543 [(set (match_operand:GPF 0 "register_operand" "=w")
3545 (match_operand:GPF 1 "register_operand" "w")
3546 (match_operand:GPF 2 "register_operand" "w")))]
3548 "fadd\\t%<s>0, %<s>1, %<s>2"
3549 [(set_attr "type" "fadd<s>")]
3552 (define_insn "sub<mode>3"
3553 [(set (match_operand:GPF 0 "register_operand" "=w")
3555 (match_operand:GPF 1 "register_operand" "w")
3556 (match_operand:GPF 2 "register_operand" "w")))]
3558 "fsub\\t%<s>0, %<s>1, %<s>2"
3559 [(set_attr "type" "fadd<s>")]
3562 (define_insn "mul<mode>3"
3563 [(set (match_operand:GPF 0 "register_operand" "=w")
3565 (match_operand:GPF 1 "register_operand" "w")
3566 (match_operand:GPF 2 "register_operand" "w")))]
3568 "fmul\\t%<s>0, %<s>1, %<s>2"
3569 [(set_attr "type" "fmul<s>")]
3572 (define_insn "*fnmul<mode>3"
3573 [(set (match_operand:GPF 0 "register_operand" "=w")
3575 (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3576 (match_operand:GPF 2 "register_operand" "w")))]
3578 "fnmul\\t%<s>0, %<s>1, %<s>2"
3579 [(set_attr "type" "fmul<s>")]
3582 (define_insn "div<mode>3"
3583 [(set (match_operand:GPF 0 "register_operand" "=w")
3585 (match_operand:GPF 1 "register_operand" "w")
3586 (match_operand:GPF 2 "register_operand" "w")))]
3588 "fdiv\\t%<s>0, %<s>1, %<s>2"
3589 [(set_attr "type" "fdiv<s>")]
3592 (define_insn "neg<mode>2"
3593 [(set (match_operand:GPF 0 "register_operand" "=w")
3594 (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
3596 "fneg\\t%<s>0, %<s>1"
3597 [(set_attr "type" "ffarith<s>")]
3600 (define_insn "sqrt<mode>2"
3601 [(set (match_operand:GPF 0 "register_operand" "=w")
3602 (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
3604 "fsqrt\\t%<s>0, %<s>1"
3605 [(set_attr "type" "fsqrt<s>")]
3608 (define_insn "abs<mode>2"
3609 [(set (match_operand:GPF 0 "register_operand" "=w")
3610 (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
3612 "fabs\\t%<s>0, %<s>1"
3613 [(set_attr "type" "ffarith<s>")]
3616 ;; Given that smax/smin do not specify the result when either input is NaN,
3617 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
3620 (define_insn "smax<mode>3"
3621 [(set (match_operand:GPF 0 "register_operand" "=w")
3622 (smax:GPF (match_operand:GPF 1 "register_operand" "w")
3623 (match_operand:GPF 2 "register_operand" "w")))]
3625 "fmaxnm\\t%<s>0, %<s>1, %<s>2"
3626 [(set_attr "type" "f_minmax<s>")]
3629 (define_insn "smin<mode>3"
3630 [(set (match_operand:GPF 0 "register_operand" "=w")
3631 (smin:GPF (match_operand:GPF 1 "register_operand" "w")
3632 (match_operand:GPF 2 "register_operand" "w")))]
3634 "fminnm\\t%<s>0, %<s>1, %<s>2"
3635 [(set_attr "type" "f_minmax<s>")]
3638 ;; -------------------------------------------------------------------
3640 ;; -------------------------------------------------------------------
3642 (define_expand "aarch64_reload_mov<mode>"
3643 [(set (match_operand:TX 0 "register_operand" "=w")
3644 (match_operand:TX 1 "register_operand" "w"))
3645 (clobber (match_operand:DI 2 "register_operand" "=&r"))
3649 rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
3650 rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
3651 gen_aarch64_movtilow_tilow (op0, op1);
3652 gen_aarch64_movdi_tihigh (operands[2], op1);
3653 gen_aarch64_movtihigh_di (op0, operands[2]);
3658 ;; The following secondary reload helpers patterns are invoked
3659 ;; after or during reload as we don't want these patterns to start
3660 ;; kicking in during the combiner.
3662 (define_insn "aarch64_movdi_<mode>low"
3663 [(set (match_operand:DI 0 "register_operand" "=r")
3664 (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
3665 "reload_completed || reload_in_progress"
3667 [(set_attr "type" "f_mrc")
3668 (set_attr "length" "4")
3671 (define_insn "aarch64_movdi_<mode>high"
3672 [(set (match_operand:DI 0 "register_operand" "=r")
3674 (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
3676 "reload_completed || reload_in_progress"
3677 "fmov\\t%x0, %1.d[1]"
3678 [(set_attr "type" "f_mrc")
3679 (set_attr "length" "4")
3682 (define_insn "aarch64_mov<mode>high_di"
3683 [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
3684 (const_int 64) (const_int 64))
3685 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
3686 "reload_completed || reload_in_progress"
3687 "fmov\\t%0.d[1], %x1"
3688 [(set_attr "type" "f_mcr")
3689 (set_attr "length" "4")
3692 (define_insn "aarch64_mov<mode>low_di"
3693 [(set (match_operand:TX 0 "register_operand" "=w")
3694 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
3695 "reload_completed || reload_in_progress"
3697 [(set_attr "type" "f_mcr")
3698 (set_attr "length" "4")
3701 (define_insn "aarch64_movtilow_tilow"
3702 [(set (match_operand:TI 0 "register_operand" "=w")
3704 (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
3705 "reload_completed || reload_in_progress"
3707 [(set_attr "type" "fmov")
3708 (set_attr "length" "4")
3711 ;; There is a deliberate reason why the parameters of high and lo_sum's
3712 ;; don't have modes for ADRP and ADD instructions. This is to allow high
3713 ;; and lo_sum's to be used with the labels defining the jump tables in
3716 (define_expand "add_losym"
3717 [(set (match_operand 0 "register_operand" "=r")
3718 (lo_sum (match_operand 1 "register_operand" "r")
3719 (match_operand 2 "aarch64_valid_symref" "S")))]
3722 enum machine_mode mode = GET_MODE (operands[0]);
3724 emit_insn ((mode == DImode
3726 : gen_add_losym_si) (operands[0],
3732 (define_insn "add_losym_<mode>"
3733 [(set (match_operand:P 0 "register_operand" "=r")
3734 (lo_sum:P (match_operand:P 1 "register_operand" "r")
3735 (match_operand 2 "aarch64_valid_symref" "S")))]
3737 "add\\t%<w>0, %<w>1, :lo12:%a2"
3738 [(set_attr "type" "alu_reg")]
3741 (define_insn "ldr_got_small_<mode>"
3742 [(set (match_operand:PTR 0 "register_operand" "=r")
3743 (unspec:PTR [(mem:PTR (lo_sum:PTR
3744 (match_operand:PTR 1 "register_operand" "r")
3745 (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
3746 UNSPEC_GOTSMALLPIC))]
3748 "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
3749 [(set_attr "type" "load1")]
3752 (define_insn "ldr_got_small_sidi"
3753 [(set (match_operand:DI 0 "register_operand" "=r")
3755 (unspec:SI [(mem:SI (lo_sum:DI
3756 (match_operand:DI 1 "register_operand" "r")
3757 (match_operand:DI 2 "aarch64_valid_symref" "S")))]
3758 UNSPEC_GOTSMALLPIC)))]
3760 "ldr\\t%w0, [%1, #:got_lo12:%a2]"
3761 [(set_attr "type" "load1")]
3764 (define_insn "ldr_got_tiny"
3765 [(set (match_operand:DI 0 "register_operand" "=r")
3766 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
3767 UNSPEC_GOTTINYPIC))]
3770 [(set_attr "type" "load1")]
3773 (define_insn "aarch64_load_tp_hard"
3774 [(set (match_operand:DI 0 "register_operand" "=r")
3775 (unspec:DI [(const_int 0)] UNSPEC_TLS))]
3777 "mrs\\t%0, tpidr_el0"
3778 [(set_attr "type" "mrs")]
3781 ;; The TLS ABI specifically requires that the compiler does not schedule
3782 ;; instructions in the TLS stubs, in order to enable linker relaxation.
3783 ;; Therefore we treat the stubs as an atomic sequence.
3784 (define_expand "tlsgd_small"
3785 [(parallel [(set (match_operand 0 "register_operand" "")
3786 (call (mem:DI (match_dup 2)) (const_int 1)))
3787 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
3788 (clobber (reg:DI LR_REGNUM))])]
3791 operands[2] = aarch64_tls_get_addr ();
3794 (define_insn "*tlsgd_small"
3795 [(set (match_operand 0 "register_operand" "")
3796 (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
3797 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
3798 (clobber (reg:DI LR_REGNUM))
3801 "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
3802 [(set_attr "type" "call")
3803 (set_attr "length" "16")])
3805 (define_insn "tlsie_small_<mode>"
3806 [(set (match_operand:PTR 0 "register_operand" "=r")
3807 (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
3808 UNSPEC_GOTSMALLTLS))]
3810 "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
3811 [(set_attr "type" "load1")
3812 (set_attr "length" "8")]
3815 (define_insn "tlsie_small_sidi"
3816 [(set (match_operand:DI 0 "register_operand" "=r")
3818 (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")]
3819 UNSPEC_GOTSMALLTLS)))]
3821 "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
3822 [(set_attr "type" "load1")
3823 (set_attr "length" "8")]
3826 (define_expand "tlsle_small"
3827 [(set (match_operand 0 "register_operand" "=r")
3828 (unspec [(match_operand 1 "register_operand" "r")
3829 (match_operand 2 "aarch64_tls_le_symref" "S")]
3830 UNSPEC_GOTSMALLTLS))]
3833 enum machine_mode mode = GET_MODE (operands[0]);
3834 emit_insn ((mode == DImode
3835 ? gen_tlsle_small_di
3836 : gen_tlsle_small_si) (operands[0],
3842 (define_insn "tlsle_small_<mode>"
3843 [(set (match_operand:P 0 "register_operand" "=r")
3844 (unspec:P [(match_operand:P 1 "register_operand" "r")
3845 (match_operand 2 "aarch64_tls_le_symref" "S")]
3846 UNSPEC_GOTSMALLTLS))]
3848 "add\\t%<w>0, %<w>1, #%G2\;add\\t%<w>0, %<w>0, #%L2"
3849 [(set_attr "type" "alu_reg")
3850 (set_attr "length" "8")]
3853 (define_insn "tlsdesc_small_<mode>"
3854 [(set (reg:PTR R0_REGNUM)
3855 (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
3857 (clobber (reg:DI LR_REGNUM))
3858 (clobber (match_scratch:DI 1 "=r"))]
3860 "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
3861 [(set_attr "type" "call")
3862 (set_attr "length" "16")])
3864 (define_insn "stack_tie"
3865 [(set (mem:BLK (scratch))
3866 (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
3867 (match_operand:DI 1 "register_operand" "rk")]
3871 [(set_attr "length" "0")]
3874 ;; Named pattern for expanding thread pointer reference.
3875 (define_expand "get_thread_pointerdi"
3876 [(match_operand:DI 0 "register_operand" "=r")]
3879 rtx tmp = aarch64_load_tp (operands[0]);
3880 if (tmp != operands[0])
3881 emit_move_insn (operands[0], tmp);
3885 ;; Named patterns for stack smashing protection.
3886 (define_expand "stack_protect_set"
3887 [(match_operand 0 "memory_operand")
3888 (match_operand 1 "memory_operand")]
3891 enum machine_mode mode = GET_MODE (operands[0]);
3893 emit_insn ((mode == DImode
3894 ? gen_stack_protect_set_di
3895 : gen_stack_protect_set_si) (operands[0], operands[1]));
3899 (define_insn "stack_protect_set_<mode>"
3900 [(set (match_operand:PTR 0 "memory_operand" "=m")
3901 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
3903 (set (match_scratch:PTR 2 "=&r") (const_int 0))]
3905 "ldr\\t%<w>2, %1\;str\\t%<w>2, %0\;mov\t%<w>2,0"
3906 [(set_attr "length" "12")
3907 (set_attr "type" "multiple")])
3909 (define_expand "stack_protect_test"
3910 [(match_operand 0 "memory_operand")
3911 (match_operand 1 "memory_operand")
3916 enum machine_mode mode = GET_MODE (operands[0]);
3918 result = gen_reg_rtx(mode);
3920 emit_insn ((mode == DImode
3921 ? gen_stack_protect_test_di
3922 : gen_stack_protect_test_si) (result,
3927 emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
3928 result, const0_rtx, operands[2]));
3930 emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
3931 result, const0_rtx, operands[2]));
3935 (define_insn "stack_protect_test_<mode>"
3936 [(set (match_operand:PTR 0 "register_operand")
3937 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
3938 (match_operand:PTR 2 "memory_operand" "m")]
3940 (clobber (match_scratch:PTR 3 "=&r"))]
3942 "ldr\t%<w>3, %x1\;ldr\t%<w>0, %x2\;eor\t%<w>0, %<w>3, %<w>0"
3943 [(set_attr "length" "12")
3944 (set_attr "type" "multiple")])
3946 ;; Write Floating-point Control Register.
3947 (define_insn "set_fpcr"
3948 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
3951 [(set_attr "type" "mrs")])
3953 ;; Read Floating-point Control Register.
3954 (define_insn "get_fpcr"
3955 [(set (match_operand:SI 0 "register_operand" "=r")
3956 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
3959 [(set_attr "type" "mrs")])
3961 ;; Write Floating-point Status Register.
3962 (define_insn "set_fpsr"
3963 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
3966 [(set_attr "type" "mrs")])
3968 ;; Read Floating-point Status Register.
3969 (define_insn "get_fpsr"
3970 [(set (match_operand:SI 0 "register_operand" "=r")
3971 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
3974 [(set_attr "type" "mrs")])
3978 (include "aarch64-simd.md")
3980 ;; Atomic Operations
3981 (include "atomics.md")