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" [
124 (define_c_enum "unspecv" [
125 UNSPECV_EH_RETURN ; Represent EH_RETURN
126 UNSPECV_GET_FPCR ; Represent fetch of FPCR content.
127 UNSPECV_SET_FPCR ; Represent assign of FPCR content.
128 UNSPECV_GET_FPSR ; Represent fetch of FPSR content.
129 UNSPECV_SET_FPSR ; Represent assign of FPSR content.
133 ;; If further include files are added the defintion of MD_INCLUDES
136 (include "constraints.md")
137 (include "predicates.md")
138 (include "iterators.md")
140 ;; -------------------------------------------------------------------
141 ;; Instruction types and attributes
142 ;; -------------------------------------------------------------------
144 ; The "type" attribute is is included here from AArch32 backend to be able
145 ; to share pipeline descriptions.
146 (include "../arm/types.md")
148 ;; Attribute that specifies whether or not the instruction touches fp
150 (define_attr "fp" "no,yes" (const_string "no"))
152 ;; Attribute that specifies whether or not the instruction touches simd
154 (define_attr "simd" "no,yes" (const_string "no"))
156 (define_attr "length" ""
159 ;; Attribute that controls whether an alternative is enabled or not.
160 ;; Currently it is only used to disable alternatives which touch fp or simd
161 ;; registers when -mgeneral-regs-only is specified.
162 (define_attr "enabled" "no,yes"
164 (and (eq_attr "fp" "yes")
165 (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
166 (and (eq_attr "simd" "yes")
167 (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
169 ] (const_string "yes")))
171 ;; -------------------------------------------------------------------
172 ;; Pipeline descriptions and scheduling
173 ;; -------------------------------------------------------------------
176 (include "aarch64-tune.md")
179 (include "../arm/cortex-a53.md")
180 (include "../arm/cortex-a57.md")
181 (include "thunderx.md")
182 (include "../arm/xgene1.md")
184 ;; -------------------------------------------------------------------
185 ;; Jumps and other miscellaneous insns
186 ;; -------------------------------------------------------------------
188 (define_insn "indirect_jump"
189 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
192 [(set_attr "type" "branch")]
196 [(set (pc) (label_ref (match_operand 0 "" "")))]
199 [(set_attr "type" "branch")]
202 (define_expand "cbranch<mode>4"
203 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
204 [(match_operand:GPI 1 "register_operand" "")
205 (match_operand:GPI 2 "aarch64_plus_operand" "")])
206 (label_ref (match_operand 3 "" ""))
210 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
212 operands[2] = const0_rtx;
216 (define_expand "cbranch<mode>4"
217 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
218 [(match_operand:GPF 1 "register_operand" "")
219 (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
220 (label_ref (match_operand 3 "" ""))
224 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
226 operands[2] = const0_rtx;
230 (define_insn "*condjump"
231 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
232 [(match_operand 1 "cc_register" "") (const_int 0)])
233 (label_ref (match_operand 2 "" ""))
237 [(set_attr "type" "branch")]
240 (define_expand "casesi"
241 [(match_operand:SI 0 "register_operand" "") ; Index
242 (match_operand:SI 1 "const_int_operand" "") ; Lower bound
243 (match_operand:SI 2 "const_int_operand" "") ; Total range
244 (match_operand:DI 3 "" "") ; Table label
245 (match_operand:DI 4 "" "")] ; Out of range label
248 if (operands[1] != const0_rtx)
250 rtx reg = gen_reg_rtx (SImode);
252 /* Canonical RTL says that if you have:
256 then this should be emitted as:
260 The use of trunc_int_for_mode ensures that the resulting
261 constant can be represented in SImode, this is important
262 for the corner case where operand[1] is INT_MIN. */
264 operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
266 if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
267 (operands[1], SImode))
268 operands[1] = force_reg (SImode, operands[1]);
269 emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
273 if (!aarch64_plus_operand (operands[2], SImode))
274 operands[2] = force_reg (SImode, operands[2]);
275 emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
277 operands[0], operands[2], operands[4]));
279 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
280 emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
286 (define_insn "casesi_dispatch"
289 (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
290 (match_operand:SI 1 "register_operand" "r")]
292 (clobber (reg:CC CC_REGNUM))
293 (clobber (match_scratch:DI 3 "=r"))
294 (clobber (match_scratch:DI 4 "=r"))
295 (use (label_ref (match_operand 2 "" "")))])]
298 return aarch64_output_casesi (operands);
300 [(set_attr "length" "16")
301 (set_attr "type" "branch")]
305 [(unspec[(const_int 0)] UNSPEC_NOP)]
308 [(set_attr "type" "no_insn")]
312 [(trap_if (const_int 1) (const_int 8))]
315 [(set_attr "type" "trap")])
317 (define_expand "prologue"
318 [(clobber (const_int 0))]
321 aarch64_expand_prologue ();
326 (define_expand "epilogue"
327 [(clobber (const_int 0))]
330 aarch64_expand_epilogue (false);
335 (define_expand "sibcall_epilogue"
336 [(clobber (const_int 0))]
339 aarch64_expand_epilogue (true);
344 (define_insn "*do_return"
348 [(set_attr "type" "branch")]
351 (define_insn "eh_return"
352 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
356 [(set_attr "type" "branch")]
361 [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
364 [(set (match_dup 1) (match_dup 0))]
366 operands[1] = aarch64_final_eh_return_addr ();
370 (define_insn "*cb<optab><mode>1"
371 [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
373 (label_ref (match_operand 1 "" ""))
377 [(set_attr "type" "branch")]
381 (define_insn "*tb<optab><mode>1"
382 [(set (pc) (if_then_else
383 (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
385 (match_operand 1 "const_int_operand" "n"))
387 (label_ref (match_operand 2 "" ""))
389 (clobber (match_scratch:DI 3 "=r"))]
392 if (get_attr_length (insn) == 8)
393 return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
394 return \"<tbz>\\t%<w>0, %1, %l2\";
396 [(set_attr "type" "branch")
398 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
399 (lt (minus (match_dup 2) (pc)) (const_int 32764)))
404 (define_insn "*cb<optab><mode>1"
405 [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
407 (label_ref (match_operand 1 "" ""))
409 (clobber (match_scratch:DI 2 "=r"))]
412 if (get_attr_length (insn) == 8)
413 return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
414 return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
416 [(set_attr "type" "branch")
418 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
419 (lt (minus (match_dup 1) (pc)) (const_int 32764)))
424 ;; -------------------------------------------------------------------
425 ;; Subroutine calls and sibcalls
426 ;; -------------------------------------------------------------------
428 (define_expand "call"
429 [(parallel [(call (match_operand 0 "memory_operand" "")
430 (match_operand 1 "general_operand" ""))
431 (use (match_operand 2 "" ""))
432 (clobber (reg:DI LR_REGNUM))])]
438 /* In an untyped call, we can get NULL for operand 2. */
439 if (operands[2] == NULL)
440 operands[2] = const0_rtx;
442 /* Decide if we should generate indirect calls by loading the
443 64-bit address of the callee into a register before performing
444 the branch-and-link. */
445 callee = XEXP (operands[0], 0);
446 if (GET_CODE (callee) == SYMBOL_REF
447 ? aarch64_is_long_call_p (callee)
449 XEXP (operands[0], 0) = force_reg (Pmode, callee);
453 (define_insn "*call_reg"
454 [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
455 (match_operand 1 "" ""))
456 (use (match_operand 2 "" ""))
457 (clobber (reg:DI LR_REGNUM))]
460 [(set_attr "type" "call")]
463 (define_insn "*call_symbol"
464 [(call (mem:DI (match_operand:DI 0 "" ""))
465 (match_operand 1 "" ""))
466 (use (match_operand 2 "" ""))
467 (clobber (reg:DI LR_REGNUM))]
468 "GET_CODE (operands[0]) == SYMBOL_REF
469 && !aarch64_is_long_call_p (operands[0])"
471 [(set_attr "type" "call")]
474 (define_expand "call_value"
475 [(parallel [(set (match_operand 0 "" "")
476 (call (match_operand 1 "memory_operand" "")
477 (match_operand 2 "general_operand" "")))
478 (use (match_operand 3 "" ""))
479 (clobber (reg:DI LR_REGNUM))])]
485 /* In an untyped call, we can get NULL for operand 3. */
486 if (operands[3] == NULL)
487 operands[3] = const0_rtx;
489 /* Decide if we should generate indirect calls by loading the
490 64-bit address of the callee into a register before performing
491 the branch-and-link. */
492 callee = XEXP (operands[1], 0);
493 if (GET_CODE (callee) == SYMBOL_REF
494 ? aarch64_is_long_call_p (callee)
496 XEXP (operands[1], 0) = force_reg (Pmode, callee);
500 (define_insn "*call_value_reg"
501 [(set (match_operand 0 "" "")
502 (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
503 (match_operand 2 "" "")))
504 (use (match_operand 3 "" ""))
505 (clobber (reg:DI LR_REGNUM))]
508 [(set_attr "type" "call")]
512 (define_insn "*call_value_symbol"
513 [(set (match_operand 0 "" "")
514 (call (mem:DI (match_operand:DI 1 "" ""))
515 (match_operand 2 "" "")))
516 (use (match_operand 3 "" ""))
517 (clobber (reg:DI LR_REGNUM))]
518 "GET_CODE (operands[1]) == SYMBOL_REF
519 && !aarch64_is_long_call_p (operands[1])"
521 [(set_attr "type" "call")]
524 (define_expand "sibcall"
525 [(parallel [(call (match_operand 0 "memory_operand" "")
526 (match_operand 1 "general_operand" ""))
528 (use (match_operand 2 "" ""))])]
531 if (!REG_P (XEXP (operands[0], 0))
532 && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
533 XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
535 if (operands[2] == NULL_RTX)
536 operands[2] = const0_rtx;
540 (define_expand "sibcall_value"
541 [(parallel [(set (match_operand 0 "" "")
542 (call (match_operand 1 "memory_operand" "")
543 (match_operand 2 "general_operand" "")))
545 (use (match_operand 3 "" ""))])]
548 if (!REG_P (XEXP (operands[1], 0))
549 && (GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF))
550 XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
552 if (operands[3] == NULL_RTX)
553 operands[3] = const0_rtx;
557 (define_insn "*sibcall_insn"
558 [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucs, Usf"))
559 (match_operand 1 "" ""))
561 (use (match_operand 2 "" ""))]
562 "SIBLING_CALL_P (insn)"
566 [(set_attr "type" "branch, branch")]
569 (define_insn "*sibcall_value_insn"
570 [(set (match_operand 0 "" "")
572 (match_operand:DI 1 "aarch64_call_insn_operand" "Ucs, Usf"))
573 (match_operand 2 "" "")))
575 (use (match_operand 3 "" ""))]
576 "SIBLING_CALL_P (insn)"
580 [(set_attr "type" "branch, branch")]
583 ;; Call subroutine returning any type.
585 (define_expand "untyped_call"
586 [(parallel [(call (match_operand 0 "")
589 (match_operand 2 "")])]
594 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
596 for (i = 0; i < XVECLEN (operands[2], 0); i++)
598 rtx set = XVECEXP (operands[2], 0, i);
599 emit_move_insn (SET_DEST (set), SET_SRC (set));
602 /* The optimizer does not know that the call sets the function value
603 registers we stored in the result block. We avoid problems by
604 claiming that all hard registers are used and clobbered at this
606 emit_insn (gen_blockage ());
610 ;; -------------------------------------------------------------------
612 ;; -------------------------------------------------------------------
614 (define_expand "mov<mode>"
615 [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
616 (match_operand:SHORT 1 "general_operand" ""))]
619 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
620 operands[1] = force_reg (<MODE>mode, operands[1]);
624 (define_insn "*mov<mode>_aarch64"
625 [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r, *w,r,*w, m, m, r,*w,*w")
626 (match_operand:SHORT 1 "general_operand" " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
627 "(register_operand (operands[0], <MODE>mode)
628 || aarch64_reg_or_zero (operands[1], <MODE>mode))"
630 switch (which_alternative)
633 return "mov\t%w0, %w1";
635 return "mov\t%w0, %1";
637 return aarch64_output_scalar_simd_mov_immediate (operands[1],
640 return "ldr<size>\t%w0, %1";
642 return "ldr\t%<size>0, %1";
644 return "str<size>\t%w1, %0";
646 return "str\t%<size>1, %0";
648 return "umov\t%w0, %1.<v>[0]";
650 return "dup\t%0.<Vallxd>, %w1";
652 return "dup\t%<Vetype>0, %1.<v>[0]";
657 [(set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
658 neon_from_gp<q>,neon_from_gp<q>, neon_dup")
659 (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")]
662 (define_expand "mov<mode>"
663 [(set (match_operand:GPI 0 "nonimmediate_operand" "")
664 (match_operand:GPI 1 "general_operand" ""))]
667 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
668 operands[1] = force_reg (<MODE>mode, operands[1]);
670 /* FIXME: RR we still need to fix up what we are doing with
671 symbol_refs and other types of constants. */
672 if (CONSTANT_P (operands[1])
673 && !CONST_INT_P (operands[1]))
675 aarch64_expand_mov_immediate (operands[0], operands[1]);
681 (define_insn_and_split "*movsi_aarch64"
682 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,r,*w,m, m,r,r ,*w, r,*w")
683 (match_operand:SI 1 "aarch64_mov_operand" " r,r,k,M,n,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
684 "(register_operand (operands[0], SImode)
685 || aarch64_reg_or_zero (operands[1], SImode))"
701 "CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), SImode)
702 && GP_REGNUM_P (REGNO (operands[0]))"
705 aarch64_expand_mov_immediate (operands[0], operands[1]);
708 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
709 adr,adr,f_mcr,f_mrc,fmov")
710 (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
713 (define_insn_and_split "*movdi_aarch64"
714 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,r,*w,m, m,r,r, *w, r,*w,w")
715 (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,n,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))]
716 "(register_operand (operands[0], DImode)
717 || aarch64_reg_or_zero (operands[1], DImode))"
734 "(CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), DImode))
735 && GP_REGNUM_P (REGNO (operands[0]))"
738 aarch64_expand_mov_immediate (operands[0], operands[1]);
741 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
742 adr,adr,f_mcr,f_mrc,fmov,fmov")
743 (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
744 (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
747 (define_insn "insv_imm<mode>"
748 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
750 (match_operand:GPI 1 "const_int_operand" "n"))
751 (match_operand:GPI 2 "const_int_operand" "n"))]
752 "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
753 && UINTVAL (operands[1]) % 16 == 0"
754 "movk\\t%<w>0, %X2, lsl %1"
755 [(set_attr "type" "mov_imm")]
758 (define_expand "movti"
759 [(set (match_operand:TI 0 "nonimmediate_operand" "")
760 (match_operand:TI 1 "general_operand" ""))]
763 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
764 operands[1] = force_reg (TImode, operands[1]);
768 (define_insn "*movti_aarch64"
769 [(set (match_operand:TI 0
770 "nonimmediate_operand" "=r, *w,r ,*w,r ,Ump,Ump,*w,m")
772 "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r ,Z , m,*w"))]
773 "(register_operand (operands[0], TImode)
774 || aarch64_reg_or_zero (operands[1], TImode))"
779 orr\\t%0.16b, %1.16b, %1.16b
785 [(set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \
786 load2,store2,store2,f_loadd,f_stored")
787 (set_attr "length" "8,8,8,4,4,4,4,4,4")
788 (set_attr "simd" "*,*,*,yes,*,*,*,*,*")
789 (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
792 ;; Split a TImode register-register or register-immediate move into
793 ;; its component DImode pieces, taking care to handle overlapping
794 ;; source and dest registers.
796 [(set (match_operand:TI 0 "register_operand" "")
797 (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
798 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
801 aarch64_split_128bit_move (operands[0], operands[1]);
805 (define_expand "mov<mode>"
806 [(set (match_operand:GPF 0 "nonimmediate_operand" "")
807 (match_operand:GPF 1 "general_operand" ""))]
812 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
816 if (GET_CODE (operands[0]) == MEM)
817 operands[1] = force_reg (<MODE>mode, operands[1]);
821 (define_insn "*movsf_aarch64"
822 [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
823 (match_operand:SF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
824 "TARGET_FLOAT && (register_operand (operands[0], SFmode)
825 || register_operand (operands[1], SFmode))"
836 [(set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
837 f_loads,f_stores,f_loads,f_stores,mov_reg")]
840 (define_insn "*movdf_aarch64"
841 [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
842 (match_operand:DF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
843 "TARGET_FLOAT && (register_operand (operands[0], DFmode)
844 || register_operand (operands[1], DFmode))"
855 [(set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
856 f_loadd,f_stored,f_loadd,f_stored,mov_reg")]
859 (define_expand "movtf"
860 [(set (match_operand:TF 0 "nonimmediate_operand" "")
861 (match_operand:TF 1 "general_operand" ""))]
866 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
870 if (GET_CODE (operands[0]) == MEM)
871 operands[1] = force_reg (TFmode, operands[1]);
875 (define_insn "*movtf_aarch64"
876 [(set (match_operand:TF 0
877 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
879 "general_operand" " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
880 "TARGET_FLOAT && (register_operand (operands[0], TFmode)
881 || register_operand (operands[1], TFmode))"
883 orr\\t%0.16b, %1.16b, %1.16b
893 [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,fconstd,fconstd,\
894 f_loadd,f_stored,neon_load1_2reg,neon_store1_2reg")
895 (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
896 (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
897 (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
901 [(set (match_operand:TF 0 "register_operand" "")
902 (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
903 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
906 aarch64_split_128bit_move (operands[0], operands[1]);
913 ;; 2 is size of move in bytes
916 (define_expand "movmemdi"
917 [(match_operand:BLK 0 "memory_operand")
918 (match_operand:BLK 1 "memory_operand")
919 (match_operand:DI 2 "immediate_operand")
920 (match_operand:DI 3 "immediate_operand")]
923 if (aarch64_expand_movmem (operands))
929 ;; Operands 1 and 3 are tied together by the final condition; so we allow
930 ;; fairly lax checking on the second memory operation.
931 (define_insn "load_pair<mode>"
932 [(set (match_operand:GPI 0 "register_operand" "=r")
933 (match_operand:GPI 1 "aarch64_mem_pair_operand" "Ump"))
934 (set (match_operand:GPI 2 "register_operand" "=r")
935 (match_operand:GPI 3 "memory_operand" "m"))]
936 "rtx_equal_p (XEXP (operands[3], 0),
937 plus_constant (Pmode,
938 XEXP (operands[1], 0),
939 GET_MODE_SIZE (<MODE>mode)))"
940 "ldp\\t%<w>0, %<w>2, %1"
941 [(set_attr "type" "load2")]
944 ;; Operands 0 and 2 are tied together by the final condition; so we allow
945 ;; fairly lax checking on the second memory operation.
946 (define_insn "store_pair<mode>"
947 [(set (match_operand:GPI 0 "aarch64_mem_pair_operand" "=Ump")
948 (match_operand:GPI 1 "register_operand" "r"))
949 (set (match_operand:GPI 2 "memory_operand" "=m")
950 (match_operand:GPI 3 "register_operand" "r"))]
951 "rtx_equal_p (XEXP (operands[2], 0),
952 plus_constant (Pmode,
953 XEXP (operands[0], 0),
954 GET_MODE_SIZE (<MODE>mode)))"
955 "stp\\t%<w>1, %<w>3, %0"
956 [(set_attr "type" "store2")]
959 ;; Operands 1 and 3 are tied together by the final condition; so we allow
960 ;; fairly lax checking on the second memory operation.
961 (define_insn "load_pair<mode>"
962 [(set (match_operand:GPF 0 "register_operand" "=w")
963 (match_operand:GPF 1 "aarch64_mem_pair_operand" "Ump"))
964 (set (match_operand:GPF 2 "register_operand" "=w")
965 (match_operand:GPF 3 "memory_operand" "m"))]
966 "rtx_equal_p (XEXP (operands[3], 0),
967 plus_constant (Pmode,
968 XEXP (operands[1], 0),
969 GET_MODE_SIZE (<MODE>mode)))"
970 "ldp\\t%<w>0, %<w>2, %1"
971 [(set_attr "type" "neon_load1_2reg<q>")]
974 ;; Operands 0 and 2 are tied together by the final condition; so we allow
975 ;; fairly lax checking on the second memory operation.
976 (define_insn "store_pair<mode>"
977 [(set (match_operand:GPF 0 "aarch64_mem_pair_operand" "=Ump")
978 (match_operand:GPF 1 "register_operand" "w"))
979 (set (match_operand:GPF 2 "memory_operand" "=m")
980 (match_operand:GPF 3 "register_operand" "w"))]
981 "rtx_equal_p (XEXP (operands[2], 0),
982 plus_constant (Pmode,
983 XEXP (operands[0], 0),
984 GET_MODE_SIZE (<MODE>mode)))"
985 "stp\\t%<w>1, %<w>3, %0"
986 [(set_attr "type" "neon_store1_2reg<q>")]
989 ;; Load pair with post-index writeback. This is primarily used in function
991 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
993 [(set (match_operand:P 0 "register_operand" "=k")
994 (plus:P (match_operand:P 1 "register_operand" "0")
995 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
996 (set (match_operand:GPI 2 "register_operand" "=r")
997 (mem:GPI (match_dup 1)))
998 (set (match_operand:GPI 3 "register_operand" "=r")
999 (mem:GPI (plus:P (match_dup 1)
1000 (match_operand:P 5 "const_int_operand" "n"))))])]
1001 "INTVAL (operands[5]) == GET_MODE_SIZE (<GPI:MODE>mode)"
1002 "ldp\\t%<w>2, %<w>3, [%1], %4"
1003 [(set_attr "type" "load2")]
1006 (define_insn "loadwb_pair<GPF:mode>_<P:mode>"
1008 [(set (match_operand:P 0 "register_operand" "=k")
1009 (plus:P (match_operand:P 1 "register_operand" "0")
1010 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1011 (set (match_operand:GPF 2 "register_operand" "=w")
1012 (mem:GPF (match_dup 1)))
1013 (set (match_operand:GPF 3 "register_operand" "=w")
1014 (mem:GPF (plus:P (match_dup 1)
1015 (match_operand:P 5 "const_int_operand" "n"))))])]
1016 "INTVAL (operands[5]) == GET_MODE_SIZE (<GPF:MODE>mode)"
1017 "ldp\\t%<w>2, %<w>3, [%1], %4"
1018 [(set_attr "type" "neon_load1_2reg")]
1021 ;; Store pair with pre-index writeback. This is primarily used in function
1023 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
1025 [(set (match_operand:P 0 "register_operand" "=&k")
1026 (plus:P (match_operand:P 1 "register_operand" "0")
1027 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1028 (set (mem:GPI (plus:P (match_dup 0)
1030 (match_operand:GPI 2 "register_operand" "r"))
1031 (set (mem:GPI (plus:P (match_dup 0)
1032 (match_operand:P 5 "const_int_operand" "n")))
1033 (match_operand:GPI 3 "register_operand" "r"))])]
1034 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1035 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1036 [(set_attr "type" "store2")]
1039 (define_insn "storewb_pair<GPF:mode>_<P:mode>"
1041 [(set (match_operand:P 0 "register_operand" "=&k")
1042 (plus:P (match_operand:P 1 "register_operand" "0")
1043 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1044 (set (mem:GPF (plus:P (match_dup 0)
1046 (match_operand:GPF 2 "register_operand" "w"))
1047 (set (mem:GPF (plus:P (match_dup 0)
1048 (match_operand:P 5 "const_int_operand" "n")))
1049 (match_operand:GPF 3 "register_operand" "w"))])]
1050 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPF:MODE>mode)"
1051 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1052 [(set_attr "type" "neon_store1_2reg<q>")]
1055 ;; -------------------------------------------------------------------
1056 ;; Sign/Zero extension
1057 ;; -------------------------------------------------------------------
1059 (define_expand "<optab>sidi2"
1060 [(set (match_operand:DI 0 "register_operand")
1061 (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1065 (define_insn "*extendsidi2_aarch64"
1066 [(set (match_operand:DI 0 "register_operand" "=r,r")
1067 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1072 [(set_attr "type" "extend,load1")]
1075 (define_insn "*zero_extendsidi2_aarch64"
1076 [(set (match_operand:DI 0 "register_operand" "=r,r")
1077 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1082 [(set_attr "type" "extend,load1")]
1085 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1086 [(set (match_operand:GPI 0 "register_operand")
1087 (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1091 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1092 [(set (match_operand:GPI 0 "register_operand" "=r,r")
1093 (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1096 sxt<SHORT:size>\t%<GPI:w>0, %w1
1097 ldrs<SHORT:size>\t%<GPI:w>0, %1"
1098 [(set_attr "type" "extend,load1")]
1101 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1102 [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1103 (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1106 uxt<SHORT:size>\t%<GPI:w>0, %w1
1107 ldr<SHORT:size>\t%w0, %1
1108 ldr\t%<SHORT:size>0, %1"
1109 [(set_attr "type" "extend,load1,load1")]
1112 (define_expand "<optab>qihi2"
1113 [(set (match_operand:HI 0 "register_operand")
1114 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1118 (define_insn "*<optab>qihi2_aarch64"
1119 [(set (match_operand:HI 0 "register_operand" "=r,r")
1120 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1125 [(set_attr "type" "extend,load1")]
1128 ;; -------------------------------------------------------------------
1129 ;; Simple arithmetic
1130 ;; -------------------------------------------------------------------
1132 (define_expand "add<mode>3"
1134 (match_operand:GPI 0 "register_operand" "")
1135 (plus:GPI (match_operand:GPI 1 "register_operand" "")
1136 (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1139 if (! aarch64_plus_operand (operands[2], VOIDmode))
1141 rtx subtarget = ((optimize && can_create_pseudo_p ())
1142 ? gen_reg_rtx (<MODE>mode) : operands[0]);
1143 HOST_WIDE_INT imm = INTVAL (operands[2]);
1146 imm = -(-imm & ~0xfff);
1150 emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1151 operands[1] = subtarget;
1152 operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1157 (define_insn "*addsi3_aarch64"
1159 (match_operand:SI 0 "register_operand" "=rk,rk,w,rk")
1161 (match_operand:SI 1 "register_operand" "%rk,rk,w,rk")
1162 (match_operand:SI 2 "aarch64_plus_operand" "I,r,w,J")))]
1167 add\\t%0.2s, %1.2s, %2.2s
1168 sub\\t%w0, %w1, #%n2"
1169 [(set_attr "type" "alu_imm,alu_reg,neon_add,alu_imm")
1170 (set_attr "simd" "*,*,yes,*")]
1173 ;; zero_extend version of above
1174 (define_insn "*addsi3_aarch64_uxtw"
1176 (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1178 (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1179 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1184 sub\\t%w0, %w1, #%n2"
1185 [(set_attr "type" "alu_imm,alu_reg,alu_imm")]
1188 (define_insn "*adddi3_aarch64"
1190 (match_operand:DI 0 "register_operand" "=rk,rk,rk,w")
1192 (match_operand:DI 1 "register_operand" "%rk,rk,rk,w")
1193 (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,w")))]
1198 sub\\t%x0, %x1, #%n2
1199 add\\t%d0, %d1, %d2"
1200 [(set_attr "type" "alu_imm,alu_reg,alu_imm,neon_add")
1201 (set_attr "simd" "*,*,*,yes")]
1204 (define_expand "addti3"
1205 [(set (match_operand:TI 0 "register_operand" "")
1206 (plus:TI (match_operand:TI 1 "register_operand" "")
1207 (match_operand:TI 2 "register_operand" "")))]
1210 rtx low = gen_reg_rtx (DImode);
1211 emit_insn (gen_adddi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1212 gen_lowpart (DImode, operands[2])));
1214 rtx high = gen_reg_rtx (DImode);
1215 emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]),
1216 gen_highpart (DImode, operands[2])));
1218 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1219 emit_move_insn (gen_highpart (DImode, operands[0]), high);
1223 (define_insn "add<mode>3_compare0"
1224 [(set (reg:CC_NZ CC_REGNUM)
1226 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1227 (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1229 (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1230 (plus:GPI (match_dup 1) (match_dup 2)))]
1233 adds\\t%<w>0, %<w>1, %<w>2
1234 adds\\t%<w>0, %<w>1, %<w>2
1235 subs\\t%<w>0, %<w>1, #%n2"
1236 [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1239 ;; zero_extend version of above
1240 (define_insn "*addsi3_compare0_uxtw"
1241 [(set (reg:CC_NZ CC_REGNUM)
1243 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1244 (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1246 (set (match_operand:DI 0 "register_operand" "=r,r,r")
1247 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1250 adds\\t%w0, %w1, %w2
1251 adds\\t%w0, %w1, %w2
1252 subs\\t%w0, %w1, #%n2"
1253 [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1256 (define_insn "*adds_mul_imm_<mode>"
1257 [(set (reg:CC_NZ CC_REGNUM)
1260 (match_operand:GPI 1 "register_operand" "r")
1261 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1262 (match_operand:GPI 3 "register_operand" "r"))
1264 (set (match_operand:GPI 0 "register_operand" "=r")
1265 (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1268 "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1269 [(set_attr "type" "alus_shift_imm")]
1272 (define_insn "*subs_mul_imm_<mode>"
1273 [(set (reg:CC_NZ CC_REGNUM)
1275 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1277 (match_operand:GPI 2 "register_operand" "r")
1278 (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1280 (set (match_operand:GPI 0 "register_operand" "=r")
1281 (minus:GPI (match_dup 1)
1282 (mult:GPI (match_dup 2) (match_dup 3))))]
1284 "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1285 [(set_attr "type" "alus_shift_imm")]
1288 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1289 [(set (reg:CC_NZ CC_REGNUM)
1292 (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1293 (match_operand:GPI 2 "register_operand" "r"))
1295 (set (match_operand:GPI 0 "register_operand" "=r")
1296 (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1298 "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1299 [(set_attr "type" "alus_ext")]
1302 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1303 [(set (reg:CC_NZ CC_REGNUM)
1305 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1307 (match_operand:ALLX 2 "register_operand" "r")))
1309 (set (match_operand:GPI 0 "register_operand" "=r")
1310 (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1312 "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1313 [(set_attr "type" "alus_ext")]
1316 (define_insn "*adds_<optab><mode>_multp2"
1317 [(set (reg:CC_NZ CC_REGNUM)
1319 (plus:GPI (ANY_EXTRACT:GPI
1320 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1321 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1322 (match_operand 3 "const_int_operand" "n")
1324 (match_operand:GPI 4 "register_operand" "r"))
1326 (set (match_operand:GPI 0 "register_operand" "=r")
1327 (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1331 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1332 "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1333 [(set_attr "type" "alus_ext")]
1336 (define_insn "*subs_<optab><mode>_multp2"
1337 [(set (reg:CC_NZ CC_REGNUM)
1339 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1341 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1342 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1343 (match_operand 3 "const_int_operand" "n")
1346 (set (match_operand:GPI 0 "register_operand" "=r")
1347 (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1348 (mult:GPI (match_dup 1) (match_dup 2))
1351 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1352 "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1353 [(set_attr "type" "alus_ext")]
1356 (define_insn "*add<mode>3nr_compare0"
1357 [(set (reg:CC_NZ CC_REGNUM)
1359 (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1360 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1367 [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
1370 (define_insn "*compare_neg<mode>"
1371 [(set (reg:CC_Z CC_REGNUM)
1373 (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1374 (match_operand:GPI 1 "register_operand" "r")))]
1376 "cmn\\t%<w>1, %<w>0"
1377 [(set_attr "type" "alus_reg")]
1380 (define_insn "*add_<shift>_<mode>"
1381 [(set (match_operand:GPI 0 "register_operand" "=r")
1382 (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1383 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1384 (match_operand:GPI 3 "register_operand" "r")))]
1386 "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1387 [(set_attr "type" "alu_shift_imm")]
1390 ;; zero_extend version of above
1391 (define_insn "*add_<shift>_si_uxtw"
1392 [(set (match_operand:DI 0 "register_operand" "=r")
1394 (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1395 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1396 (match_operand:SI 3 "register_operand" "r"))))]
1398 "add\\t%w0, %w3, %w1, <shift> %2"
1399 [(set_attr "type" "alu_shift_imm")]
1402 (define_insn "*add_mul_imm_<mode>"
1403 [(set (match_operand:GPI 0 "register_operand" "=r")
1404 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1405 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1406 (match_operand:GPI 3 "register_operand" "r")))]
1408 "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1409 [(set_attr "type" "alu_shift_imm")]
1412 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1413 [(set (match_operand:GPI 0 "register_operand" "=rk")
1414 (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1415 (match_operand:GPI 2 "register_operand" "r")))]
1417 "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1418 [(set_attr "type" "alu_ext")]
1421 ;; zero_extend version of above
1422 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1423 [(set (match_operand:DI 0 "register_operand" "=rk")
1425 (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1426 (match_operand:GPI 2 "register_operand" "r"))))]
1428 "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1429 [(set_attr "type" "alu_ext")]
1432 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1433 [(set (match_operand:GPI 0 "register_operand" "=rk")
1434 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1435 (match_operand:ALLX 1 "register_operand" "r"))
1436 (match_operand 2 "aarch64_imm3" "Ui3"))
1437 (match_operand:GPI 3 "register_operand" "r")))]
1439 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1440 [(set_attr "type" "alu_ext")]
1443 ;; zero_extend version of above
1444 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1445 [(set (match_operand:DI 0 "register_operand" "=rk")
1447 (plus:SI (ashift:SI (ANY_EXTEND:SI
1448 (match_operand:SHORT 1 "register_operand" "r"))
1449 (match_operand 2 "aarch64_imm3" "Ui3"))
1450 (match_operand:SI 3 "register_operand" "r"))))]
1452 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1453 [(set_attr "type" "alu_ext")]
1456 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1457 [(set (match_operand:GPI 0 "register_operand" "=rk")
1458 (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1459 (match_operand:ALLX 1 "register_operand" "r"))
1460 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1461 (match_operand:GPI 3 "register_operand" "r")))]
1463 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1464 [(set_attr "type" "alu_ext")]
1467 ;; zero_extend version of above
1468 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1469 [(set (match_operand:DI 0 "register_operand" "=rk")
1470 (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1471 (match_operand:SHORT 1 "register_operand" "r"))
1472 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1473 (match_operand:SI 3 "register_operand" "r"))))]
1475 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1476 [(set_attr "type" "alu_ext")]
1479 (define_insn "*add_<optab><mode>_multp2"
1480 [(set (match_operand:GPI 0 "register_operand" "=rk")
1481 (plus:GPI (ANY_EXTRACT:GPI
1482 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1483 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1484 (match_operand 3 "const_int_operand" "n")
1486 (match_operand:GPI 4 "register_operand" "r")))]
1487 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1488 "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1489 [(set_attr "type" "alu_ext")]
1492 ;; zero_extend version of above
1493 (define_insn "*add_<optab>si_multp2_uxtw"
1494 [(set (match_operand:DI 0 "register_operand" "=rk")
1496 (plus:SI (ANY_EXTRACT:SI
1497 (mult:SI (match_operand:SI 1 "register_operand" "r")
1498 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1499 (match_operand 3 "const_int_operand" "n")
1501 (match_operand:SI 4 "register_operand" "r"))))]
1502 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1503 "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1504 [(set_attr "type" "alu_ext")]
1507 (define_insn "add<mode>3_carryin"
1509 (match_operand:GPI 0 "register_operand" "=r")
1510 (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1512 (match_operand:GPI 1 "register_operand" "r")
1513 (match_operand:GPI 2 "register_operand" "r"))))]
1515 "adc\\t%<w>0, %<w>1, %<w>2"
1516 [(set_attr "type" "adc_reg")]
1519 ;; zero_extend version of above
1520 (define_insn "*addsi3_carryin_uxtw"
1522 (match_operand:DI 0 "register_operand" "=r")
1524 (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1526 (match_operand:SI 1 "register_operand" "r")
1527 (match_operand:SI 2 "register_operand" "r")))))]
1529 "adc\\t%w0, %w1, %w2"
1530 [(set_attr "type" "adc_reg")]
1533 (define_insn "*add<mode>3_carryin_alt1"
1535 (match_operand:GPI 0 "register_operand" "=r")
1537 (match_operand:GPI 1 "register_operand" "r")
1538 (match_operand:GPI 2 "register_operand" "r"))
1539 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1541 "adc\\t%<w>0, %<w>1, %<w>2"
1542 [(set_attr "type" "adc_reg")]
1545 ;; zero_extend version of above
1546 (define_insn "*addsi3_carryin_alt1_uxtw"
1548 (match_operand:DI 0 "register_operand" "=r")
1551 (match_operand:SI 1 "register_operand" "r")
1552 (match_operand:SI 2 "register_operand" "r"))
1553 (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1555 "adc\\t%w0, %w1, %w2"
1556 [(set_attr "type" "adc_reg")]
1559 (define_insn "*add<mode>3_carryin_alt2"
1561 (match_operand:GPI 0 "register_operand" "=r")
1563 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1564 (match_operand:GPI 1 "register_operand" "r"))
1565 (match_operand:GPI 2 "register_operand" "r")))]
1567 "adc\\t%<w>0, %<w>1, %<w>2"
1568 [(set_attr "type" "adc_reg")]
1571 ;; zero_extend version of above
1572 (define_insn "*addsi3_carryin_alt2_uxtw"
1574 (match_operand:DI 0 "register_operand" "=r")
1577 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1578 (match_operand:SI 1 "register_operand" "r"))
1579 (match_operand:SI 2 "register_operand" "r"))))]
1581 "adc\\t%w0, %w1, %w2"
1582 [(set_attr "type" "adc_reg")]
1585 (define_insn "*add<mode>3_carryin_alt3"
1587 (match_operand:GPI 0 "register_operand" "=r")
1589 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1590 (match_operand:GPI 2 "register_operand" "r"))
1591 (match_operand:GPI 1 "register_operand" "r")))]
1593 "adc\\t%<w>0, %<w>1, %<w>2"
1594 [(set_attr "type" "adc_reg")]
1597 ;; zero_extend version of above
1598 (define_insn "*addsi3_carryin_alt3_uxtw"
1600 (match_operand:DI 0 "register_operand" "=r")
1603 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1604 (match_operand:SI 2 "register_operand" "r"))
1605 (match_operand:SI 1 "register_operand" "r"))))]
1607 "adc\\t%w0, %w1, %w2"
1608 [(set_attr "type" "adc_reg")]
1611 (define_insn "*add_uxt<mode>_multp2"
1612 [(set (match_operand:GPI 0 "register_operand" "=rk")
1614 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1615 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1616 (match_operand 3 "const_int_operand" "n"))
1617 (match_operand:GPI 4 "register_operand" "r")))]
1618 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1620 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1621 INTVAL (operands[3])));
1622 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1623 [(set_attr "type" "alu_ext")]
1626 ;; zero_extend version of above
1627 (define_insn "*add_uxtsi_multp2_uxtw"
1628 [(set (match_operand:DI 0 "register_operand" "=rk")
1631 (mult:SI (match_operand:SI 1 "register_operand" "r")
1632 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1633 (match_operand 3 "const_int_operand" "n"))
1634 (match_operand:SI 4 "register_operand" "r"))))]
1635 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1637 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1638 INTVAL (operands[3])));
1639 return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1640 [(set_attr "type" "alu_ext")]
1643 (define_insn "subsi3"
1644 [(set (match_operand:SI 0 "register_operand" "=rk")
1645 (minus:SI (match_operand:SI 1 "register_operand" "r")
1646 (match_operand:SI 2 "register_operand" "r")))]
1648 "sub\\t%w0, %w1, %w2"
1649 [(set_attr "type" "alu_reg")]
1652 ;; zero_extend version of above
1653 (define_insn "*subsi3_uxtw"
1654 [(set (match_operand:DI 0 "register_operand" "=rk")
1656 (minus:SI (match_operand:SI 1 "register_operand" "r")
1657 (match_operand:SI 2 "register_operand" "r"))))]
1659 "sub\\t%w0, %w1, %w2"
1660 [(set_attr "type" "alu_reg")]
1663 (define_insn "subdi3"
1664 [(set (match_operand:DI 0 "register_operand" "=rk,w")
1665 (minus:DI (match_operand:DI 1 "register_operand" "r,w")
1666 (match_operand:DI 2 "register_operand" "r,w")))]
1670 sub\\t%d0, %d1, %d2"
1671 [(set_attr "type" "alu_reg, neon_sub")
1672 (set_attr "simd" "*,yes")]
1675 (define_expand "subti3"
1676 [(set (match_operand:TI 0 "register_operand" "")
1677 (minus:TI (match_operand:TI 1 "register_operand" "")
1678 (match_operand:TI 2 "register_operand" "")))]
1681 rtx low = gen_reg_rtx (DImode);
1682 emit_insn (gen_subdi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1683 gen_lowpart (DImode, operands[2])));
1685 rtx high = gen_reg_rtx (DImode);
1686 emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]),
1687 gen_highpart (DImode, operands[2])));
1689 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1690 emit_move_insn (gen_highpart (DImode, operands[0]), high);
1694 (define_insn "sub<mode>3_compare0"
1695 [(set (reg:CC_NZ CC_REGNUM)
1696 (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1697 (match_operand:GPI 2 "register_operand" "r"))
1699 (set (match_operand:GPI 0 "register_operand" "=r")
1700 (minus:GPI (match_dup 1) (match_dup 2)))]
1702 "subs\\t%<w>0, %<w>1, %<w>2"
1703 [(set_attr "type" "alus_reg")]
1706 ;; zero_extend version of above
1707 (define_insn "*subsi3_compare0_uxtw"
1708 [(set (reg:CC_NZ CC_REGNUM)
1709 (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1710 (match_operand:SI 2 "register_operand" "r"))
1712 (set (match_operand:DI 0 "register_operand" "=r")
1713 (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1715 "subs\\t%w0, %w1, %w2"
1716 [(set_attr "type" "alus_reg")]
1719 (define_insn "*sub_<shift>_<mode>"
1720 [(set (match_operand:GPI 0 "register_operand" "=r")
1721 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1723 (match_operand:GPI 1 "register_operand" "r")
1724 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1726 "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1727 [(set_attr "type" "alu_shift_imm")]
1730 ;; zero_extend version of above
1731 (define_insn "*sub_<shift>_si_uxtw"
1732 [(set (match_operand:DI 0 "register_operand" "=r")
1734 (minus:SI (match_operand:SI 3 "register_operand" "r")
1736 (match_operand:SI 1 "register_operand" "r")
1737 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1739 "sub\\t%w0, %w3, %w1, <shift> %2"
1740 [(set_attr "type" "alu_shift_imm")]
1743 (define_insn "*sub_mul_imm_<mode>"
1744 [(set (match_operand:GPI 0 "register_operand" "=r")
1745 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1747 (match_operand:GPI 1 "register_operand" "r")
1748 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1750 "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1751 [(set_attr "type" "alu_shift_imm")]
1754 ;; zero_extend version of above
1755 (define_insn "*sub_mul_imm_si_uxtw"
1756 [(set (match_operand:DI 0 "register_operand" "=r")
1758 (minus:SI (match_operand:SI 3 "register_operand" "r")
1760 (match_operand:SI 1 "register_operand" "r")
1761 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
1763 "sub\\t%w0, %w3, %w1, lsl %p2"
1764 [(set_attr "type" "alu_shift_imm")]
1767 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
1768 [(set (match_operand:GPI 0 "register_operand" "=rk")
1769 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1771 (match_operand:ALLX 2 "register_operand" "r"))))]
1773 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1774 [(set_attr "type" "alu_ext")]
1777 ;; zero_extend version of above
1778 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
1779 [(set (match_operand:DI 0 "register_operand" "=rk")
1781 (minus:SI (match_operand:SI 1 "register_operand" "r")
1783 (match_operand:SHORT 2 "register_operand" "r")))))]
1785 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
1786 [(set_attr "type" "alu_ext")]
1789 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
1790 [(set (match_operand:GPI 0 "register_operand" "=rk")
1791 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1792 (ashift:GPI (ANY_EXTEND:GPI
1793 (match_operand:ALLX 2 "register_operand" "r"))
1794 (match_operand 3 "aarch64_imm3" "Ui3"))))]
1796 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1797 [(set_attr "type" "alu_ext")]
1800 ;; zero_extend version of above
1801 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
1802 [(set (match_operand:DI 0 "register_operand" "=rk")
1804 (minus:SI (match_operand:SI 1 "register_operand" "r")
1805 (ashift:SI (ANY_EXTEND:SI
1806 (match_operand:SHORT 2 "register_operand" "r"))
1807 (match_operand 3 "aarch64_imm3" "Ui3")))))]
1809 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
1810 [(set_attr "type" "alu_ext")]
1813 (define_insn "*sub_<optab><mode>_multp2"
1814 [(set (match_operand:GPI 0 "register_operand" "=rk")
1815 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1817 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1818 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1819 (match_operand 3 "const_int_operand" "n")
1821 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1822 "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1823 [(set_attr "type" "alu_ext")]
1826 ;; zero_extend version of above
1827 (define_insn "*sub_<optab>si_multp2_uxtw"
1828 [(set (match_operand:DI 0 "register_operand" "=rk")
1830 (minus:SI (match_operand:SI 4 "register_operand" "r")
1832 (mult:SI (match_operand:SI 1 "register_operand" "r")
1833 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1834 (match_operand 3 "const_int_operand" "n")
1836 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1837 "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1838 [(set_attr "type" "alu_ext")]
1841 (define_insn "sub<mode>3_carryin"
1843 (match_operand:GPI 0 "register_operand" "=r")
1844 (minus:GPI (minus:GPI
1845 (match_operand:GPI 1 "register_operand" "r")
1846 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
1847 (match_operand:GPI 2 "register_operand" "r")))]
1849 "sbc\\t%<w>0, %<w>1, %<w>2"
1850 [(set_attr "type" "adc_reg")]
1853 ;; zero_extend version of the above
1854 (define_insn "*subsi3_carryin_uxtw"
1856 (match_operand:DI 0 "register_operand" "=r")
1859 (match_operand:SI 1 "register_operand" "r")
1860 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
1861 (match_operand:SI 2 "register_operand" "r"))))]
1863 "sbc\\t%w0, %w1, %w2"
1864 [(set_attr "type" "adc_reg")]
1867 (define_insn "*sub_uxt<mode>_multp2"
1868 [(set (match_operand:GPI 0 "register_operand" "=rk")
1869 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1871 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1872 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1873 (match_operand 3 "const_int_operand" "n"))))]
1874 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1876 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1877 INTVAL (operands[3])));
1878 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1879 [(set_attr "type" "alu_ext")]
1882 ;; zero_extend version of above
1883 (define_insn "*sub_uxtsi_multp2_uxtw"
1884 [(set (match_operand:DI 0 "register_operand" "=rk")
1886 (minus:SI (match_operand:SI 4 "register_operand" "r")
1888 (mult:SI (match_operand:SI 1 "register_operand" "r")
1889 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1890 (match_operand 3 "const_int_operand" "n")))))]
1891 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1893 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1894 INTVAL (operands[3])));
1895 return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
1896 [(set_attr "type" "alu_ext")]
1899 (define_insn_and_split "absdi2"
1900 [(set (match_operand:DI 0 "register_operand" "=&r,w")
1901 (abs:DI (match_operand:DI 1 "register_operand" "r,w")))]
1907 && GP_REGNUM_P (REGNO (operands[0]))
1908 && GP_REGNUM_P (REGNO (operands[1]))"
1911 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
1912 gen_rtx_XOR (DImode,
1913 gen_rtx_ASHIFTRT (DImode,
1917 emit_insn (gen_rtx_SET (VOIDmode,
1919 gen_rtx_MINUS (DImode,
1921 gen_rtx_ASHIFTRT (DImode,
1926 [(set_attr "type" "alu_reg")]
1929 (define_insn "neg<mode>2"
1930 [(set (match_operand:GPI 0 "register_operand" "=r,w")
1931 (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
1935 neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
1936 [(set_attr "type" "alu_reg, neon_neg<q>")
1937 (set_attr "simd" "*,yes")]
1940 ;; zero_extend version of above
1941 (define_insn "*negsi2_uxtw"
1942 [(set (match_operand:DI 0 "register_operand" "=r")
1943 (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
1946 [(set_attr "type" "alu_reg")]
1949 (define_insn "*ngc<mode>"
1950 [(set (match_operand:GPI 0 "register_operand" "=r")
1951 (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
1952 (match_operand:GPI 1 "register_operand" "r")))]
1954 "ngc\\t%<w>0, %<w>1"
1955 [(set_attr "type" "adc_reg")]
1958 (define_insn "*ngcsi_uxtw"
1959 [(set (match_operand:DI 0 "register_operand" "=r")
1961 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
1962 (match_operand:SI 1 "register_operand" "r"))))]
1965 [(set_attr "type" "adc_reg")]
1968 (define_insn "*neg<mode>2_compare0"
1969 [(set (reg:CC_NZ CC_REGNUM)
1970 (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
1972 (set (match_operand:GPI 0 "register_operand" "=r")
1973 (neg:GPI (match_dup 1)))]
1975 "negs\\t%<w>0, %<w>1"
1976 [(set_attr "type" "alus_reg")]
1979 ;; zero_extend version of above
1980 (define_insn "*negsi2_compare0_uxtw"
1981 [(set (reg:CC_NZ CC_REGNUM)
1982 (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
1984 (set (match_operand:DI 0 "register_operand" "=r")
1985 (zero_extend:DI (neg:SI (match_dup 1))))]
1988 [(set_attr "type" "alus_reg")]
1991 (define_insn "*neg_<shift><mode>3_compare0"
1992 [(set (reg:CC_NZ CC_REGNUM)
1994 (neg:GPI (ASHIFT:GPI
1995 (match_operand:GPI 1 "register_operand" "r")
1996 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
1998 (set (match_operand:GPI 0 "register_operand" "=r")
1999 (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2001 "negs\\t%<w>0, %<w>1, <shift> %2"
2002 [(set_attr "type" "alus_shift_imm")]
2005 (define_insn "*neg_<shift>_<mode>2"
2006 [(set (match_operand:GPI 0 "register_operand" "=r")
2007 (neg:GPI (ASHIFT:GPI
2008 (match_operand:GPI 1 "register_operand" "r")
2009 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2011 "neg\\t%<w>0, %<w>1, <shift> %2"
2012 [(set_attr "type" "alu_shift_imm")]
2015 ;; zero_extend version of above
2016 (define_insn "*neg_<shift>_si2_uxtw"
2017 [(set (match_operand:DI 0 "register_operand" "=r")
2020 (match_operand:SI 1 "register_operand" "r")
2021 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2023 "neg\\t%w0, %w1, <shift> %2"
2024 [(set_attr "type" "alu_shift_imm")]
2027 (define_insn "*neg_mul_imm_<mode>2"
2028 [(set (match_operand:GPI 0 "register_operand" "=r")
2030 (match_operand:GPI 1 "register_operand" "r")
2031 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2033 "neg\\t%<w>0, %<w>1, lsl %p2"
2034 [(set_attr "type" "alu_shift_imm")]
2037 ;; zero_extend version of above
2038 (define_insn "*neg_mul_imm_si2_uxtw"
2039 [(set (match_operand:DI 0 "register_operand" "=r")
2042 (match_operand:SI 1 "register_operand" "r")
2043 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2045 "neg\\t%w0, %w1, lsl %p2"
2046 [(set_attr "type" "alu_shift_imm")]
2049 (define_insn "mul<mode>3"
2050 [(set (match_operand:GPI 0 "register_operand" "=r")
2051 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2052 (match_operand:GPI 2 "register_operand" "r")))]
2054 "mul\\t%<w>0, %<w>1, %<w>2"
2055 [(set_attr "type" "mul")]
2058 ;; zero_extend version of above
2059 (define_insn "*mulsi3_uxtw"
2060 [(set (match_operand:DI 0 "register_operand" "=r")
2062 (mult:SI (match_operand:SI 1 "register_operand" "r")
2063 (match_operand:SI 2 "register_operand" "r"))))]
2065 "mul\\t%w0, %w1, %w2"
2066 [(set_attr "type" "mul")]
2069 (define_insn "madd<mode>"
2070 [(set (match_operand:GPI 0 "register_operand" "=r")
2071 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2072 (match_operand:GPI 2 "register_operand" "r"))
2073 (match_operand:GPI 3 "register_operand" "r")))]
2075 "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2076 [(set_attr "type" "mla")]
2079 ;; zero_extend version of above
2080 (define_insn "*maddsi_uxtw"
2081 [(set (match_operand:DI 0 "register_operand" "=r")
2083 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2084 (match_operand:SI 2 "register_operand" "r"))
2085 (match_operand:SI 3 "register_operand" "r"))))]
2087 "madd\\t%w0, %w1, %w2, %w3"
2088 [(set_attr "type" "mla")]
2091 (define_insn "*msub<mode>"
2092 [(set (match_operand:GPI 0 "register_operand" "=r")
2093 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2094 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2095 (match_operand:GPI 2 "register_operand" "r"))))]
2098 "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2099 [(set_attr "type" "mla")]
2102 ;; zero_extend version of above
2103 (define_insn "*msubsi_uxtw"
2104 [(set (match_operand:DI 0 "register_operand" "=r")
2106 (minus:SI (match_operand:SI 3 "register_operand" "r")
2107 (mult:SI (match_operand:SI 1 "register_operand" "r")
2108 (match_operand:SI 2 "register_operand" "r")))))]
2111 "msub\\t%w0, %w1, %w2, %w3"
2112 [(set_attr "type" "mla")]
2115 (define_insn "*mul<mode>_neg"
2116 [(set (match_operand:GPI 0 "register_operand" "=r")
2117 (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2118 (match_operand:GPI 2 "register_operand" "r")))]
2121 "mneg\\t%<w>0, %<w>1, %<w>2"
2122 [(set_attr "type" "mul")]
2125 ;; zero_extend version of above
2126 (define_insn "*mulsi_neg_uxtw"
2127 [(set (match_operand:DI 0 "register_operand" "=r")
2129 (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2130 (match_operand:SI 2 "register_operand" "r"))))]
2133 "mneg\\t%w0, %w1, %w2"
2134 [(set_attr "type" "mul")]
2137 (define_insn "<su_optab>mulsidi3"
2138 [(set (match_operand:DI 0 "register_operand" "=r")
2139 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2140 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2142 "<su>mull\\t%0, %w1, %w2"
2143 [(set_attr "type" "<su>mull")]
2146 (define_insn "<su_optab>maddsidi4"
2147 [(set (match_operand:DI 0 "register_operand" "=r")
2149 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2150 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2151 (match_operand:DI 3 "register_operand" "r")))]
2153 "<su>maddl\\t%0, %w1, %w2, %3"
2154 [(set_attr "type" "<su>mlal")]
2157 (define_insn "<su_optab>msubsidi4"
2158 [(set (match_operand:DI 0 "register_operand" "=r")
2160 (match_operand:DI 3 "register_operand" "r")
2161 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2163 (match_operand:SI 2 "register_operand" "r")))))]
2165 "<su>msubl\\t%0, %w1, %w2, %3"
2166 [(set_attr "type" "<su>mlal")]
2169 (define_insn "*<su_optab>mulsidi_neg"
2170 [(set (match_operand:DI 0 "register_operand" "=r")
2172 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2173 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2175 "<su>mnegl\\t%0, %w1, %w2"
2176 [(set_attr "type" "<su>mull")]
2179 (define_expand "<su_optab>mulditi3"
2180 [(set (match_operand:TI 0 "register_operand")
2181 (mult:TI (ANY_EXTEND:TI (match_operand:DI 1 "register_operand"))
2182 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand"))))]
2185 rtx low = gen_reg_rtx (DImode);
2186 emit_insn (gen_muldi3 (low, operands[1], operands[2]));
2188 rtx high = gen_reg_rtx (DImode);
2189 emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2]));
2191 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2192 emit_move_insn (gen_highpart (DImode, operands[0]), high);
2196 ;; The default expansion of multi3 using umuldi3_highpart will perform
2197 ;; the additions in an order that fails to combine into two madd insns.
2198 (define_expand "multi3"
2199 [(set (match_operand:TI 0 "register_operand")
2200 (mult:TI (match_operand:TI 1 "register_operand")
2201 (match_operand:TI 2 "register_operand")))]
2204 rtx l0 = gen_reg_rtx (DImode);
2205 rtx l1 = gen_lowpart (DImode, operands[1]);
2206 rtx l2 = gen_lowpart (DImode, operands[2]);
2207 rtx h0 = gen_reg_rtx (DImode);
2208 rtx h1 = gen_highpart (DImode, operands[1]);
2209 rtx h2 = gen_highpart (DImode, operands[2]);
2211 emit_insn (gen_muldi3 (l0, l1, l2));
2212 emit_insn (gen_umuldi3_highpart (h0, l1, l2));
2213 emit_insn (gen_madddi (h0, h1, l2, h0));
2214 emit_insn (gen_madddi (h0, l1, h2, h0));
2216 emit_move_insn (gen_lowpart (DImode, operands[0]), l0);
2217 emit_move_insn (gen_highpart (DImode, operands[0]), h0);
2221 (define_insn "<su>muldi3_highpart"
2222 [(set (match_operand:DI 0 "register_operand" "=r")
2226 (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2227 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2230 "<su>mulh\\t%0, %1, %2"
2231 [(set_attr "type" "<su>mull")]
2234 (define_insn "<su_optab>div<mode>3"
2235 [(set (match_operand:GPI 0 "register_operand" "=r")
2236 (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2237 (match_operand:GPI 2 "register_operand" "r")))]
2239 "<su>div\\t%<w>0, %<w>1, %<w>2"
2240 [(set_attr "type" "<su>div")]
2243 ;; zero_extend version of above
2244 (define_insn "*<su_optab>divsi3_uxtw"
2245 [(set (match_operand:DI 0 "register_operand" "=r")
2247 (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2248 (match_operand:SI 2 "register_operand" "r"))))]
2250 "<su>div\\t%w0, %w1, %w2"
2251 [(set_attr "type" "<su>div")]
2254 ;; -------------------------------------------------------------------
2256 ;; -------------------------------------------------------------------
2258 (define_insn "*cmp<mode>"
2259 [(set (reg:CC CC_REGNUM)
2260 (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2261 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2267 [(set_attr "type" "alus_reg,alus_imm,alus_imm")]
2270 (define_insn "*cmp<mode>"
2271 [(set (reg:CCFP CC_REGNUM)
2272 (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2273 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2277 fcmp\\t%<s>0, %<s>1"
2278 [(set_attr "type" "fcmp<s>")]
2281 (define_insn "*cmpe<mode>"
2282 [(set (reg:CCFPE CC_REGNUM)
2283 (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2284 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2288 fcmpe\\t%<s>0, %<s>1"
2289 [(set_attr "type" "fcmp<s>")]
2292 (define_insn "*cmp_swp_<shift>_reg<mode>"
2293 [(set (reg:CC_SWP CC_REGNUM)
2294 (compare:CC_SWP (ASHIFT:GPI
2295 (match_operand:GPI 0 "register_operand" "r")
2296 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2297 (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2299 "cmp\\t%<w>2, %<w>0, <shift> %1"
2300 [(set_attr "type" "alus_shift_imm")]
2303 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2304 [(set (reg:CC_SWP CC_REGNUM)
2305 (compare:CC_SWP (ANY_EXTEND:GPI
2306 (match_operand:ALLX 0 "register_operand" "r"))
2307 (match_operand:GPI 1 "register_operand" "r")))]
2309 "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2310 [(set_attr "type" "alus_ext")]
2313 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2314 [(set (reg:CC_SWP CC_REGNUM)
2315 (compare:CC_SWP (ashift:GPI
2317 (match_operand:ALLX 0 "register_operand" "r"))
2318 (match_operand 1 "aarch64_imm3" "Ui3"))
2319 (match_operand:GPI 2 "register_operand" "r")))]
2321 "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2322 [(set_attr "type" "alus_ext")]
2325 ;; -------------------------------------------------------------------
2326 ;; Store-flag and conditional select insns
2327 ;; -------------------------------------------------------------------
2329 (define_expand "cstore<mode>4"
2330 [(set (match_operand:SI 0 "register_operand" "")
2331 (match_operator:SI 1 "aarch64_comparison_operator"
2332 [(match_operand:GPI 2 "register_operand" "")
2333 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2336 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2338 operands[3] = const0_rtx;
2342 (define_expand "cstore<mode>4"
2343 [(set (match_operand:SI 0 "register_operand" "")
2344 (match_operator:SI 1 "aarch64_comparison_operator"
2345 [(match_operand:GPF 2 "register_operand" "")
2346 (match_operand:GPF 3 "register_operand" "")]))]
2349 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2351 operands[3] = const0_rtx;
2355 (define_insn "*cstore<mode>_insn"
2356 [(set (match_operand:ALLI 0 "register_operand" "=r")
2357 (match_operator:ALLI 1 "aarch64_comparison_operator"
2358 [(match_operand 2 "cc_register" "") (const_int 0)]))]
2361 [(set_attr "type" "csel")]
2364 ;; zero_extend version of the above
2365 (define_insn "*cstoresi_insn_uxtw"
2366 [(set (match_operand:DI 0 "register_operand" "=r")
2368 (match_operator:SI 1 "aarch64_comparison_operator"
2369 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2372 [(set_attr "type" "csel")]
2375 (define_insn "cstore<mode>_neg"
2376 [(set (match_operand:ALLI 0 "register_operand" "=r")
2377 (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2378 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2380 "csetm\\t%<w>0, %m1"
2381 [(set_attr "type" "csel")]
2384 ;; zero_extend version of the above
2385 (define_insn "*cstoresi_neg_uxtw"
2386 [(set (match_operand:DI 0 "register_operand" "=r")
2388 (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2389 [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2392 [(set_attr "type" "csel")]
2395 (define_expand "cmov<mode>6"
2396 [(set (match_operand:GPI 0 "register_operand" "")
2398 (match_operator 1 "aarch64_comparison_operator"
2399 [(match_operand:GPI 2 "register_operand" "")
2400 (match_operand:GPI 3 "aarch64_plus_operand" "")])
2401 (match_operand:GPI 4 "register_operand" "")
2402 (match_operand:GPI 5 "register_operand" "")))]
2405 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2407 operands[3] = const0_rtx;
2411 (define_expand "cmov<mode>6"
2412 [(set (match_operand:GPF 0 "register_operand" "")
2414 (match_operator 1 "aarch64_comparison_operator"
2415 [(match_operand:GPF 2 "register_operand" "")
2416 (match_operand:GPF 3 "register_operand" "")])
2417 (match_operand:GPF 4 "register_operand" "")
2418 (match_operand:GPF 5 "register_operand" "")))]
2421 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2423 operands[3] = const0_rtx;
2427 (define_insn "*cmov<mode>_insn"
2428 [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2430 (match_operator 1 "aarch64_comparison_operator"
2431 [(match_operand 2 "cc_register" "") (const_int 0)])
2432 (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2433 (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2434 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2435 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2436 ;; Final two alternatives should be unreachable, but included for completeness
2438 csel\\t%<w>0, %<w>3, %<w>4, %m1
2439 csinv\\t%<w>0, %<w>3, <w>zr, %m1
2440 csinv\\t%<w>0, %<w>4, <w>zr, %M1
2441 csinc\\t%<w>0, %<w>3, <w>zr, %m1
2442 csinc\\t%<w>0, %<w>4, <w>zr, %M1
2445 [(set_attr "type" "csel")]
2448 ;; zero_extend version of above
2449 (define_insn "*cmovsi_insn_uxtw"
2450 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2453 (match_operator 1 "aarch64_comparison_operator"
2454 [(match_operand 2 "cc_register" "") (const_int 0)])
2455 (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2456 (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2457 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2458 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2459 ;; Final two alternatives should be unreachable, but included for completeness
2461 csel\\t%w0, %w3, %w4, %m1
2462 csinv\\t%w0, %w3, wzr, %m1
2463 csinv\\t%w0, %w4, wzr, %M1
2464 csinc\\t%w0, %w3, wzr, %m1
2465 csinc\\t%w0, %w4, wzr, %M1
2468 [(set_attr "type" "csel")]
2471 (define_insn "*cmov<mode>_insn"
2472 [(set (match_operand:GPF 0 "register_operand" "=w")
2474 (match_operator 1 "aarch64_comparison_operator"
2475 [(match_operand 2 "cc_register" "") (const_int 0)])
2476 (match_operand:GPF 3 "register_operand" "w")
2477 (match_operand:GPF 4 "register_operand" "w")))]
2479 "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2480 [(set_attr "type" "fcsel")]
2483 (define_expand "mov<mode>cc"
2484 [(set (match_operand:ALLI 0 "register_operand" "")
2485 (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2486 (match_operand:ALLI 2 "register_operand" "")
2487 (match_operand:ALLI 3 "register_operand" "")))]
2491 enum rtx_code code = GET_CODE (operands[1]);
2493 if (code == UNEQ || code == LTGT)
2496 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2497 XEXP (operands[1], 1));
2498 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2502 (define_expand "mov<GPF:mode><GPI:mode>cc"
2503 [(set (match_operand:GPI 0 "register_operand" "")
2504 (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2505 (match_operand:GPF 2 "register_operand" "")
2506 (match_operand:GPF 3 "register_operand" "")))]
2510 enum rtx_code code = GET_CODE (operands[1]);
2512 if (code == UNEQ || code == LTGT)
2515 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2516 XEXP (operands[1], 1));
2517 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2521 (define_expand "mov<mode>cc"
2522 [(set (match_operand:GPF 0 "register_operand" "")
2523 (if_then_else:GPF (match_operand 1 "aarch64_comparison_operator" "")
2524 (match_operand:GPF 2 "register_operand" "")
2525 (match_operand:GPF 3 "register_operand" "")))]
2529 enum rtx_code code = GET_CODE (operands[1]);
2531 if (code == UNEQ || code == LTGT)
2534 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2535 XEXP (operands[1], 1));
2536 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2541 ;; CRC32 instructions.
2542 (define_insn "aarch64_<crc_variant>"
2543 [(set (match_operand:SI 0 "register_operand" "=r")
2544 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2545 (match_operand:<crc_mode> 2 "register_operand" "r")]
2549 if (GET_MODE_BITSIZE (GET_MODE (operands[2])) >= 64)
2550 return "<crc_variant>\\t%w0, %w1, %x2";
2552 return "<crc_variant>\\t%w0, %w1, %w2";
2554 [(set_attr "type" "crc")]
2557 (define_insn "*csinc2<mode>_insn"
2558 [(set (match_operand:GPI 0 "register_operand" "=r")
2559 (plus:GPI (match_operand 2 "aarch64_comparison_operation" "")
2560 (match_operand:GPI 1 "register_operand" "r")))]
2562 "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2563 [(set_attr "type" "csel")]
2566 (define_insn "csinc3<mode>_insn"
2567 [(set (match_operand:GPI 0 "register_operand" "=r")
2569 (match_operand 1 "aarch64_comparison_operation" "")
2570 (plus:GPI (match_operand:GPI 2 "register_operand" "r")
2572 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2574 "csinc\\t%<w>0, %<w>3, %<w>2, %M1"
2575 [(set_attr "type" "csel")]
2578 (define_insn "*csinv3<mode>_insn"
2579 [(set (match_operand:GPI 0 "register_operand" "=r")
2581 (match_operand 1 "aarch64_comparison_operation" "")
2582 (not:GPI (match_operand:GPI 2 "register_operand" "r"))
2583 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2585 "csinv\\t%<w>0, %<w>3, %<w>2, %M1"
2586 [(set_attr "type" "csel")]
2589 (define_insn "*csneg3<mode>_insn"
2590 [(set (match_operand:GPI 0 "register_operand" "=r")
2592 (match_operand 1 "aarch64_comparison_operation" "")
2593 (neg:GPI (match_operand:GPI 2 "register_operand" "r"))
2594 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2596 "csneg\\t%<w>0, %<w>3, %<w>2, %M1"
2597 [(set_attr "type" "csel")]
2600 ;; -------------------------------------------------------------------
2601 ;; Logical operations
2602 ;; -------------------------------------------------------------------
2604 (define_insn "<optab><mode>3"
2605 [(set (match_operand:GPI 0 "register_operand" "=r,rk,w")
2606 (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r,w")
2607 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>,w")))]
2610 <logical>\\t%<w>0, %<w>1, %<w>2
2611 <logical>\\t%<w>0, %<w>1, %<w>2
2612 <logical>\\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
2613 [(set_attr "type" "logic_reg,logic_imm,neon_logic")
2614 (set_attr "simd" "*,*,yes")]
2617 ;; zero_extend version of above
2618 (define_insn "*<optab>si3_uxtw"
2619 [(set (match_operand:DI 0 "register_operand" "=r,rk")
2621 (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2622 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2624 "<logical>\\t%w0, %w1, %w2"
2625 [(set_attr "type" "logic_reg,logic_imm")]
2628 (define_insn "*and<mode>3_compare0"
2629 [(set (reg:CC_NZ CC_REGNUM)
2631 (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2632 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2634 (set (match_operand:GPI 0 "register_operand" "=r,r")
2635 (and:GPI (match_dup 1) (match_dup 2)))]
2637 "ands\\t%<w>0, %<w>1, %<w>2"
2638 [(set_attr "type" "logics_reg,logics_imm")]
2641 ;; zero_extend version of above
2642 (define_insn "*andsi3_compare0_uxtw"
2643 [(set (reg:CC_NZ CC_REGNUM)
2645 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2646 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2648 (set (match_operand:DI 0 "register_operand" "=r,r")
2649 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2651 "ands\\t%w0, %w1, %w2"
2652 [(set_attr "type" "logics_reg,logics_imm")]
2655 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2656 [(set (reg:CC_NZ CC_REGNUM)
2659 (match_operand:GPI 1 "register_operand" "r")
2660 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2661 (match_operand:GPI 3 "register_operand" "r"))
2663 (set (match_operand:GPI 0 "register_operand" "=r")
2664 (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2666 "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2667 [(set_attr "type" "logics_shift_imm")]
2670 ;; zero_extend version of above
2671 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2672 [(set (reg:CC_NZ CC_REGNUM)
2675 (match_operand:SI 1 "register_operand" "r")
2676 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2677 (match_operand:SI 3 "register_operand" "r"))
2679 (set (match_operand:DI 0 "register_operand" "=r")
2680 (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2683 "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2684 [(set_attr "type" "logics_shift_imm")]
2687 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2688 [(set (match_operand:GPI 0 "register_operand" "=r")
2689 (LOGICAL:GPI (SHIFT:GPI
2690 (match_operand:GPI 1 "register_operand" "r")
2691 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2692 (match_operand:GPI 3 "register_operand" "r")))]
2694 "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2695 [(set_attr "type" "logic_shift_imm")]
2698 (define_insn "*<optab>_rol<mode>3"
2699 [(set (match_operand:GPI 0 "register_operand" "=r")
2700 (LOGICAL:GPI (rotate:GPI
2701 (match_operand:GPI 1 "register_operand" "r")
2702 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2703 (match_operand:GPI 3 "register_operand" "r")))]
2705 "<logical>\\t%<w>0, %<w>3, %<w>1, ror (<sizen> - %2)"
2706 [(set_attr "type" "logic_shift_imm")]
2709 ;; zero_extend versions of above
2710 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
2711 [(set (match_operand:DI 0 "register_operand" "=r")
2713 (LOGICAL:SI (SHIFT:SI
2714 (match_operand:SI 1 "register_operand" "r")
2715 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2716 (match_operand:SI 3 "register_operand" "r"))))]
2718 "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2719 [(set_attr "type" "logic_shift_imm")]
2722 (define_insn "*<optab>_rolsi3_uxtw"
2723 [(set (match_operand:DI 0 "register_operand" "=r")
2725 (LOGICAL:SI (rotate:SI
2726 (match_operand:SI 1 "register_operand" "r")
2727 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2728 (match_operand:SI 3 "register_operand" "r"))))]
2730 "<logical>\\t%w0, %w3, %w1, ror (32 - %2)"
2731 [(set_attr "type" "logic_shift_imm")]
2734 (define_insn "one_cmpl<mode>2"
2735 [(set (match_operand:GPI 0 "register_operand" "=r,w")
2736 (not:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
2741 [(set_attr "type" "logic_reg,neon_logic")
2742 (set_attr "simd" "*,yes")]
2745 (define_insn "*one_cmpl_<optab><mode>2"
2746 [(set (match_operand:GPI 0 "register_operand" "=r")
2747 (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
2748 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2750 "mvn\\t%<w>0, %<w>1, <shift> %2"
2751 [(set_attr "type" "logic_shift_imm")]
2754 ;; Binary logical operators negating one operand, i.e. (a & !b), (a | !b).
2756 (define_insn "*<NLOGICAL:optab>_one_cmpl<mode>3"
2757 [(set (match_operand:GPI 0 "register_operand" "=r,w")
2758 (NLOGICAL:GPI (not:GPI (match_operand:GPI 1 "register_operand" "r,w"))
2759 (match_operand:GPI 2 "register_operand" "r,w")))]
2762 <NLOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1
2763 <NLOGICAL:nlogical>\\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>"
2764 [(set_attr "type" "logic_reg,neon_logic")
2765 (set_attr "simd" "*,yes")]
2768 ;; (xor (not a) b) is simplify_rtx-ed down to (not (xor a b)).
2769 ;; eon does not operate on SIMD registers so the vector variant must be split.
2770 (define_insn_and_split "*xor_one_cmpl<mode>3"
2771 [(set (match_operand:GPI 0 "register_operand" "=r,w")
2772 (not:GPI (xor:GPI (match_operand:GPI 1 "register_operand" "r,?w")
2773 (match_operand:GPI 2 "register_operand" "r,w"))))]
2775 "eon\\t%<w>0, %<w>1, %<w>2" ;; For GPR registers (only).
2776 "reload_completed && (which_alternative == 1)" ;; For SIMD registers.
2777 [(set (match_operand:GPI 0 "register_operand" "=w")
2778 (xor:GPI (match_operand:GPI 1 "register_operand" "w")
2779 (match_operand:GPI 2 "register_operand" "w")))
2780 (set (match_dup 0) (not:GPI (match_dup 0)))]
2782 [(set_attr "type" "logic_reg,multiple")
2783 (set_attr "simd" "*,yes")]
2786 (define_insn "*and_one_cmpl<mode>3_compare0"
2787 [(set (reg:CC_NZ CC_REGNUM)
2790 (match_operand:GPI 1 "register_operand" "r"))
2791 (match_operand:GPI 2 "register_operand" "r"))
2793 (set (match_operand:GPI 0 "register_operand" "=r")
2794 (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
2796 "bics\\t%<w>0, %<w>2, %<w>1"
2797 [(set_attr "type" "logics_reg")]
2800 ;; zero_extend version of above
2801 (define_insn "*and_one_cmplsi3_compare0_uxtw"
2802 [(set (reg:CC_NZ CC_REGNUM)
2805 (match_operand:SI 1 "register_operand" "r"))
2806 (match_operand:SI 2 "register_operand" "r"))
2808 (set (match_operand:DI 0 "register_operand" "=r")
2809 (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
2811 "bics\\t%w0, %w2, %w1"
2812 [(set_attr "type" "logics_reg")]
2815 (define_insn "*and_one_cmpl<mode>3_compare0_no_reuse"
2816 [(set (reg:CC_NZ CC_REGNUM)
2819 (match_operand:GPI 0 "register_operand" "r"))
2820 (match_operand:GPI 1 "register_operand" "r"))
2823 "bics\\t<w>zr, %<w>1, %<w>0"
2824 [(set_attr "type" "logics_reg")]
2827 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
2828 [(set (match_operand:GPI 0 "register_operand" "=r")
2829 (LOGICAL:GPI (not:GPI
2831 (match_operand:GPI 1 "register_operand" "r")
2832 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2833 (match_operand:GPI 3 "register_operand" "r")))]
2835 "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2836 [(set_attr "type" "logics_shift_imm")]
2839 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
2840 [(set (reg:CC_NZ CC_REGNUM)
2844 (match_operand:GPI 1 "register_operand" "r")
2845 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2846 (match_operand:GPI 3 "register_operand" "r"))
2848 (set (match_operand:GPI 0 "register_operand" "=r")
2851 (match_dup 1) (match_dup 2))) (match_dup 3)))]
2853 "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2854 [(set_attr "type" "logics_shift_imm")]
2857 ;; zero_extend version of above
2858 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
2859 [(set (reg:CC_NZ CC_REGNUM)
2863 (match_operand:SI 1 "register_operand" "r")
2864 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
2865 (match_operand:SI 3 "register_operand" "r"))
2867 (set (match_operand:DI 0 "register_operand" "=r")
2868 (zero_extend:DI (and:SI
2870 (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
2872 "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2873 [(set_attr "type" "logics_shift_imm")]
2876 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0_no_reuse"
2877 [(set (reg:CC_NZ CC_REGNUM)
2881 (match_operand:GPI 0 "register_operand" "r")
2882 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n")))
2883 (match_operand:GPI 2 "register_operand" "r"))
2886 "bics\\t<w>zr, %<w>2, %<w>0, <SHIFT:shift> %1"
2887 [(set_attr "type" "logics_shift_imm")]
2890 (define_insn "clz<mode>2"
2891 [(set (match_operand:GPI 0 "register_operand" "=r")
2892 (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
2894 "clz\\t%<w>0, %<w>1"
2895 [(set_attr "type" "clz")]
2898 (define_expand "ffs<mode>2"
2899 [(match_operand:GPI 0 "register_operand")
2900 (match_operand:GPI 1 "register_operand")]
2903 rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
2904 rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
2906 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2907 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2908 emit_insn (gen_csinc3<mode>_insn (operands[0], x, operands[0], const0_rtx));
2913 (define_insn "clrsb<mode>2"
2914 [(set (match_operand:GPI 0 "register_operand" "=r")
2915 (clrsb:GPI (match_operand:GPI 1 "register_operand" "r")))]
2917 "cls\\t%<w>0, %<w>1"
2918 [(set_attr "type" "clz")]
2921 (define_insn "rbit<mode>2"
2922 [(set (match_operand:GPI 0 "register_operand" "=r")
2923 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
2925 "rbit\\t%<w>0, %<w>1"
2926 [(set_attr "type" "rbit")]
2929 (define_expand "ctz<mode>2"
2930 [(match_operand:GPI 0 "register_operand")
2931 (match_operand:GPI 1 "register_operand")]
2934 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2935 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2940 (define_insn "*and<mode>3nr_compare0"
2941 [(set (reg:CC_NZ CC_REGNUM)
2943 (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
2944 (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
2947 "tst\\t%<w>0, %<w>1"
2948 [(set_attr "type" "logics_reg")]
2951 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
2952 [(set (reg:CC_NZ CC_REGNUM)
2955 (match_operand:GPI 0 "register_operand" "r")
2956 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2957 (match_operand:GPI 2 "register_operand" "r"))
2960 "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
2961 [(set_attr "type" "logics_shift_imm")]
2964 ;; -------------------------------------------------------------------
2966 ;; -------------------------------------------------------------------
2968 (define_expand "<optab><mode>3"
2969 [(set (match_operand:GPI 0 "register_operand")
2970 (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
2971 (match_operand:QI 2 "nonmemory_operand")))]
2974 if (CONST_INT_P (operands[2]))
2976 operands[2] = GEN_INT (INTVAL (operands[2])
2977 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2979 if (operands[2] == const0_rtx)
2981 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2988 (define_expand "ashl<mode>3"
2989 [(set (match_operand:SHORT 0 "register_operand")
2990 (ashift:SHORT (match_operand:SHORT 1 "register_operand")
2991 (match_operand:QI 2 "nonmemory_operand")))]
2994 if (CONST_INT_P (operands[2]))
2996 operands[2] = GEN_INT (INTVAL (operands[2])
2997 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2999 if (operands[2] == const0_rtx)
3001 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3010 (define_expand "rotr<mode>3"
3011 [(set (match_operand:GPI 0 "register_operand")
3012 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3013 (match_operand:QI 2 "nonmemory_operand")))]
3016 if (CONST_INT_P (operands[2]))
3018 operands[2] = GEN_INT (INTVAL (operands[2])
3019 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3021 if (operands[2] == const0_rtx)
3023 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3030 (define_expand "rotl<mode>3"
3031 [(set (match_operand:GPI 0 "register_operand")
3032 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3033 (match_operand:QI 2 "nonmemory_operand")))]
3036 /* (SZ - cnt) % SZ == -cnt % SZ */
3037 if (CONST_INT_P (operands[2]))
3039 operands[2] = GEN_INT ((-INTVAL (operands[2]))
3040 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3041 if (operands[2] == const0_rtx)
3043 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3048 operands[2] = expand_simple_unop (QImode, NEG, operands[2],
3053 ;; Logical left shift using SISD or Integer instruction
3054 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
3055 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3057 (match_operand:GPI 1 "register_operand" "w,w,r")
3058 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3061 shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3062 ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
3063 lsl\t%<w>0, %<w>1, %<w>2"
3064 [(set_attr "simd" "yes,yes,no")
3065 (set_attr "type" "neon_shift_imm<q>, neon_shift_reg<q>,shift_reg")]
3068 ;; Logical right shift using SISD or Integer instruction
3069 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3070 [(set (match_operand:GPI 0 "register_operand" "=w,&w,r")
3072 (match_operand:GPI 1 "register_operand" "w,w,r")
3073 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3076 ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3078 lsr\t%<w>0, %<w>1, %<w>2"
3079 [(set_attr "simd" "yes,yes,no")
3080 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")]
3084 [(set (match_operand:DI 0 "aarch64_simd_register")
3086 (match_operand:DI 1 "aarch64_simd_register")
3087 (match_operand:QI 2 "aarch64_simd_register")))]
3088 "TARGET_SIMD && reload_completed"
3090 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3092 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_USHL))]
3094 operands[3] = gen_lowpart (QImode, operands[0]);
3099 [(set (match_operand:SI 0 "aarch64_simd_register")
3101 (match_operand:SI 1 "aarch64_simd_register")
3102 (match_operand:QI 2 "aarch64_simd_register")))]
3103 "TARGET_SIMD && reload_completed"
3105 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3107 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_USHL_2S))]
3109 operands[3] = gen_lowpart (QImode, operands[0]);
3113 ;; Arithmetic right shift using SISD or Integer instruction
3114 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3115 [(set (match_operand:GPI 0 "register_operand" "=w,&w,&w,r")
3117 (match_operand:GPI 1 "register_operand" "w,w,w,r")
3118 (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,0,rUs<cmode>")))]
3121 sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3124 asr\t%<w>0, %<w>1, %<w>2"
3125 [(set_attr "simd" "yes,yes,yes,no")
3126 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>,shift_reg")]
3130 [(set (match_operand:DI 0 "aarch64_simd_register")
3132 (match_operand:DI 1 "aarch64_simd_register")
3133 (match_operand:QI 2 "aarch64_simd_register")))]
3134 "TARGET_SIMD && reload_completed"
3136 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3138 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_SSHL))]
3140 operands[3] = gen_lowpart (QImode, operands[0]);
3145 [(set (match_operand:SI 0 "aarch64_simd_register")
3147 (match_operand:SI 1 "aarch64_simd_register")
3148 (match_operand:QI 2 "aarch64_simd_register")))]
3149 "TARGET_SIMD && reload_completed"
3151 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3153 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_SSHL_2S))]
3155 operands[3] = gen_lowpart (QImode, operands[0]);
3159 (define_insn "*aarch64_sisd_ushl"
3160 [(set (match_operand:DI 0 "register_operand" "=w")
3161 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3162 (match_operand:QI 2 "register_operand" "w")]
3165 "ushl\t%d0, %d1, %d2"
3166 [(set_attr "simd" "yes")
3167 (set_attr "type" "neon_shift_reg")]
3170 (define_insn "*aarch64_ushl_2s"
3171 [(set (match_operand:SI 0 "register_operand" "=w")
3172 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3173 (match_operand:QI 2 "register_operand" "w")]
3176 "ushl\t%0.2s, %1.2s, %2.2s"
3177 [(set_attr "simd" "yes")
3178 (set_attr "type" "neon_shift_reg")]
3181 (define_insn "*aarch64_sisd_sshl"
3182 [(set (match_operand:DI 0 "register_operand" "=w")
3183 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3184 (match_operand:QI 2 "register_operand" "w")]
3187 "sshl\t%d0, %d1, %d2"
3188 [(set_attr "simd" "yes")
3189 (set_attr "type" "neon_shift_reg")]
3192 (define_insn "*aarch64_sshl_2s"
3193 [(set (match_operand:SI 0 "register_operand" "=w")
3194 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3195 (match_operand:QI 2 "register_operand" "w")]
3198 "sshl\t%0.2s, %1.2s, %2.2s"
3199 [(set_attr "simd" "yes")
3200 (set_attr "type" "neon_shift_reg")]
3203 (define_insn "*aarch64_sisd_neg_qi"
3204 [(set (match_operand:QI 0 "register_operand" "=w")
3205 (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3209 [(set_attr "simd" "yes")
3210 (set_attr "type" "neon_neg")]
3214 (define_insn "*ror<mode>3_insn"
3215 [(set (match_operand:GPI 0 "register_operand" "=r")
3217 (match_operand:GPI 1 "register_operand" "r")
3218 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3220 "ror\\t%<w>0, %<w>1, %<w>2"
3221 [(set_attr "type" "shift_reg")]
3224 ;; zero_extend version of above
3225 (define_insn "*<optab>si3_insn_uxtw"
3226 [(set (match_operand:DI 0 "register_operand" "=r")
3227 (zero_extend:DI (SHIFT:SI
3228 (match_operand:SI 1 "register_operand" "r")
3229 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3231 "<shift>\\t%w0, %w1, %w2"
3232 [(set_attr "type" "shift_reg")]
3235 (define_insn "*<optab><mode>3_insn"
3236 [(set (match_operand:SHORT 0 "register_operand" "=r")
3237 (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3238 (match_operand 2 "const_int_operand" "n")))]
3239 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3241 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3242 return "<bfshift>\t%w0, %w1, %2, %3";
3244 [(set_attr "type" "bfm")]
3247 (define_insn "*extr<mode>5_insn"
3248 [(set (match_operand:GPI 0 "register_operand" "=r")
3249 (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3250 (match_operand 3 "const_int_operand" "n"))
3251 (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3252 (match_operand 4 "const_int_operand" "n"))))]
3253 "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3254 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3255 "extr\\t%<w>0, %<w>1, %<w>2, %4"
3256 [(set_attr "type" "shift_imm")]
3259 ;; zero_extend version of the above
3260 (define_insn "*extrsi5_insn_uxtw"
3261 [(set (match_operand:DI 0 "register_operand" "=r")
3263 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3264 (match_operand 3 "const_int_operand" "n"))
3265 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3266 (match_operand 4 "const_int_operand" "n")))))]
3267 "UINTVAL (operands[3]) < 32 &&
3268 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3269 "extr\\t%w0, %w1, %w2, %4"
3270 [(set_attr "type" "shift_imm")]
3273 (define_insn "*ror<mode>3_insn"
3274 [(set (match_operand:GPI 0 "register_operand" "=r")
3275 (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3276 (match_operand 2 "const_int_operand" "n")))]
3277 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3279 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3280 return "ror\\t%<w>0, %<w>1, %3";
3282 [(set_attr "type" "shift_imm")]
3285 ;; zero_extend version of the above
3286 (define_insn "*rorsi3_insn_uxtw"
3287 [(set (match_operand:DI 0 "register_operand" "=r")
3289 (rotate:SI (match_operand:SI 1 "register_operand" "r")
3290 (match_operand 2 "const_int_operand" "n"))))]
3291 "UINTVAL (operands[2]) < 32"
3293 operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3294 return "ror\\t%w0, %w1, %3";
3296 [(set_attr "type" "shift_imm")]
3299 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3300 [(set (match_operand:GPI 0 "register_operand" "=r")
3302 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3303 (match_operand 2 "const_int_operand" "n"))))]
3304 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3306 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3307 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3309 [(set_attr "type" "bfm")]
3312 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3313 [(set (match_operand:GPI 0 "register_operand" "=r")
3315 (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3316 (match_operand 2 "const_int_operand" "n"))))]
3317 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3319 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3320 return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3322 [(set_attr "type" "bfm")]
3325 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3326 [(set (match_operand:GPI 0 "register_operand" "=r")
3328 (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3329 (match_operand 2 "const_int_operand" "n"))))]
3330 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3332 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3333 return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3335 [(set_attr "type" "bfm")]
3338 ;; -------------------------------------------------------------------
3340 ;; -------------------------------------------------------------------
3342 (define_expand "<optab>"
3343 [(set (match_operand:DI 0 "register_operand" "=r")
3344 (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3345 (match_operand 2 "const_int_operand" "n")
3346 (match_operand 3 "const_int_operand" "n")))]
3351 (define_insn "*<optab><mode>"
3352 [(set (match_operand:GPI 0 "register_operand" "=r")
3353 (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3354 (match_operand 2 "const_int_operand" "n")
3355 (match_operand 3 "const_int_operand" "n")))]
3357 "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3358 [(set_attr "type" "bfm")]
3361 ;; Bitfield Insert (insv)
3362 (define_expand "insv<mode>"
3363 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3364 (match_operand 1 "const_int_operand")
3365 (match_operand 2 "const_int_operand"))
3366 (match_operand:GPI 3 "general_operand"))]
3369 unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3370 unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3371 rtx value = operands[3];
3373 if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3376 if (CONST_INT_P (value))
3378 unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3380 /* Prefer AND/OR for inserting all zeros or all ones. */
3381 if ((UINTVAL (value) & mask) == 0
3382 || (UINTVAL (value) & mask) == mask)
3385 /* 16-bit aligned 16-bit wide insert is handled by insv_imm. */
3386 if (width == 16 && (pos % 16) == 0)
3389 operands[3] = force_reg (<MODE>mode, value);
3392 (define_insn "*insv_reg<mode>"
3393 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3394 (match_operand 1 "const_int_operand" "n")
3395 (match_operand 2 "const_int_operand" "n"))
3396 (match_operand:GPI 3 "register_operand" "r"))]
3397 "!(UINTVAL (operands[1]) == 0
3398 || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3399 > GET_MODE_BITSIZE (<MODE>mode)))"
3400 "bfi\\t%<w>0, %<w>3, %2, %1"
3401 [(set_attr "type" "bfm")]
3404 (define_insn "*extr_insv_lower_reg<mode>"
3405 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3406 (match_operand 1 "const_int_operand" "n")
3408 (zero_extract:GPI (match_operand:GPI 2 "register_operand" "r")
3410 (match_operand 3 "const_int_operand" "n")))]
3411 "!(UINTVAL (operands[1]) == 0
3412 || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3413 > GET_MODE_BITSIZE (<MODE>mode)))"
3414 "bfxil\\t%<w>0, %<w>2, %3, %1"
3415 [(set_attr "type" "bfm")]
3418 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3419 [(set (match_operand:GPI 0 "register_operand" "=r")
3420 (ashift:GPI (ANY_EXTEND:GPI
3421 (match_operand:ALLX 1 "register_operand" "r"))
3422 (match_operand 2 "const_int_operand" "n")))]
3423 "UINTVAL (operands[2]) < <GPI:sizen>"
3425 operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3426 ? GEN_INT (<ALLX:sizen>)
3427 : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3428 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3430 [(set_attr "type" "bfm")]
3433 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3435 (define_insn "*andim_ashift<mode>_bfiz"
3436 [(set (match_operand:GPI 0 "register_operand" "=r")
3437 (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3438 (match_operand 2 "const_int_operand" "n"))
3439 (match_operand 3 "const_int_operand" "n")))]
3440 "(INTVAL (operands[2]) < (<GPI:sizen>))
3441 && exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3442 && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3443 "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3444 [(set_attr "type" "bfm")]
3447 (define_insn "bswap<mode>2"
3448 [(set (match_operand:GPI 0 "register_operand" "=r")
3449 (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3451 "rev\\t%<w>0, %<w>1"
3452 [(set_attr "type" "rev")]
3455 (define_insn "bswaphi2"
3456 [(set (match_operand:HI 0 "register_operand" "=r")
3457 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3460 [(set_attr "type" "rev")]
3463 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
3464 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
3465 ;; each valid permutation.
3467 (define_insn "rev16<mode>2"
3468 [(set (match_operand:GPI 0 "register_operand" "=r")
3469 (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3471 (match_operand:GPI 3 "const_int_operand" "n"))
3472 (and:GPI (lshiftrt:GPI (match_dup 1)
3474 (match_operand:GPI 2 "const_int_operand" "n"))))]
3475 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3476 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3477 "rev16\\t%<w>0, %<w>1"
3478 [(set_attr "type" "rev")]
3481 (define_insn "rev16<mode>2_alt"
3482 [(set (match_operand:GPI 0 "register_operand" "=r")
3483 (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r")
3485 (match_operand:GPI 2 "const_int_operand" "n"))
3486 (and:GPI (ashift:GPI (match_dup 1)
3488 (match_operand:GPI 3 "const_int_operand" "n"))))]
3489 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3490 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3491 "rev16\\t%<w>0, %<w>1"
3492 [(set_attr "type" "rev")]
3495 ;; zero_extend version of above
3496 (define_insn "*bswapsi2_uxtw"
3497 [(set (match_operand:DI 0 "register_operand" "=r")
3498 (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3501 [(set_attr "type" "rev")]
3504 ;; -------------------------------------------------------------------
3505 ;; Floating-point intrinsics
3506 ;; -------------------------------------------------------------------
3508 ;; frint floating-point round to integral standard patterns.
3509 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round, frintn.
3511 (define_insn "<frint_pattern><mode>2"
3512 [(set (match_operand:GPF 0 "register_operand" "=w")
3513 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3516 "frint<frint_suffix>\\t%<s>0, %<s>1"
3517 [(set_attr "type" "f_rint<s>")]
3520 ;; frcvt floating-point round to integer and convert standard patterns.
3521 ;; Expands to lbtrunc, lceil, lfloor, lround.
3522 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3523 [(set (match_operand:GPI 0 "register_operand" "=r")
3524 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3527 "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3528 [(set_attr "type" "f_cvtf2i")]
3533 (define_insn "fma<mode>4"
3534 [(set (match_operand:GPF 0 "register_operand" "=w")
3535 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3536 (match_operand:GPF 2 "register_operand" "w")
3537 (match_operand:GPF 3 "register_operand" "w")))]
3539 "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3540 [(set_attr "type" "fmac<s>")]
3543 (define_insn "fnma<mode>4"
3544 [(set (match_operand:GPF 0 "register_operand" "=w")
3545 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3546 (match_operand:GPF 2 "register_operand" "w")
3547 (match_operand:GPF 3 "register_operand" "w")))]
3549 "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3550 [(set_attr "type" "fmac<s>")]
3553 (define_insn "fms<mode>4"
3554 [(set (match_operand:GPF 0 "register_operand" "=w")
3555 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3556 (match_operand:GPF 2 "register_operand" "w")
3557 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3559 "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3560 [(set_attr "type" "fmac<s>")]
3563 (define_insn "fnms<mode>4"
3564 [(set (match_operand:GPF 0 "register_operand" "=w")
3565 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3566 (match_operand:GPF 2 "register_operand" "w")
3567 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3569 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3570 [(set_attr "type" "fmac<s>")]
3573 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3574 (define_insn "*fnmadd<mode>4"
3575 [(set (match_operand:GPF 0 "register_operand" "=w")
3576 (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3577 (match_operand:GPF 2 "register_operand" "w")
3578 (match_operand:GPF 3 "register_operand" "w"))))]
3579 "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3580 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3581 [(set_attr "type" "fmac<s>")]
3584 ;; -------------------------------------------------------------------
3585 ;; Floating-point conversions
3586 ;; -------------------------------------------------------------------
3588 (define_insn "extendsfdf2"
3589 [(set (match_operand:DF 0 "register_operand" "=w")
3590 (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3593 [(set_attr "type" "f_cvt")]
3596 (define_insn "truncdfsf2"
3597 [(set (match_operand:SF 0 "register_operand" "=w")
3598 (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3601 [(set_attr "type" "f_cvt")]
3604 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3605 [(set (match_operand:GPI 0 "register_operand" "=r")
3606 (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3608 "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3609 [(set_attr "type" "f_cvtf2i")]
3612 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3613 [(set (match_operand:GPI 0 "register_operand" "=r")
3614 (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3616 "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3617 [(set_attr "type" "f_cvtf2i")]
3620 (define_insn "<optab><fcvt_target><GPF:mode>2"
3621 [(set (match_operand:GPF 0 "register_operand" "=w,w")
3622 (FLOATUORS:GPF (match_operand:<FCVT_TARGET> 1 "register_operand" "w,r")))]
3625 <su_optab>cvtf\t%<GPF:s>0, %<s>1
3626 <su_optab>cvtf\t%<GPF:s>0, %<w1>1"
3627 [(set_attr "simd" "yes,no")
3628 (set_attr "fp" "no,yes")
3629 (set_attr "type" "neon_int_to_fp_<Vetype>,f_cvti2f")]
3632 (define_insn "<optab><fcvt_iesize><GPF:mode>2"
3633 [(set (match_operand:GPF 0 "register_operand" "=w")
3634 (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand" "r")))]
3636 "<su_optab>cvtf\t%<GPF:s>0, %<w2>1"
3637 [(set_attr "type" "f_cvti2f")]
3640 ;; -------------------------------------------------------------------
3641 ;; Floating-point arithmetic
3642 ;; -------------------------------------------------------------------
3644 (define_insn "add<mode>3"
3645 [(set (match_operand:GPF 0 "register_operand" "=w")
3647 (match_operand:GPF 1 "register_operand" "w")
3648 (match_operand:GPF 2 "register_operand" "w")))]
3650 "fadd\\t%<s>0, %<s>1, %<s>2"
3651 [(set_attr "type" "fadd<s>")]
3654 (define_insn "sub<mode>3"
3655 [(set (match_operand:GPF 0 "register_operand" "=w")
3657 (match_operand:GPF 1 "register_operand" "w")
3658 (match_operand:GPF 2 "register_operand" "w")))]
3660 "fsub\\t%<s>0, %<s>1, %<s>2"
3661 [(set_attr "type" "fadd<s>")]
3664 (define_insn "mul<mode>3"
3665 [(set (match_operand:GPF 0 "register_operand" "=w")
3667 (match_operand:GPF 1 "register_operand" "w")
3668 (match_operand:GPF 2 "register_operand" "w")))]
3670 "fmul\\t%<s>0, %<s>1, %<s>2"
3671 [(set_attr "type" "fmul<s>")]
3674 (define_insn "*fnmul<mode>3"
3675 [(set (match_operand:GPF 0 "register_operand" "=w")
3677 (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3678 (match_operand:GPF 2 "register_operand" "w")))]
3680 "fnmul\\t%<s>0, %<s>1, %<s>2"
3681 [(set_attr "type" "fmul<s>")]
3684 (define_insn "div<mode>3"
3685 [(set (match_operand:GPF 0 "register_operand" "=w")
3687 (match_operand:GPF 1 "register_operand" "w")
3688 (match_operand:GPF 2 "register_operand" "w")))]
3690 "fdiv\\t%<s>0, %<s>1, %<s>2"
3691 [(set_attr "type" "fdiv<s>")]
3694 (define_insn "neg<mode>2"
3695 [(set (match_operand:GPF 0 "register_operand" "=w")
3696 (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
3698 "fneg\\t%<s>0, %<s>1"
3699 [(set_attr "type" "ffarith<s>")]
3702 (define_insn "sqrt<mode>2"
3703 [(set (match_operand:GPF 0 "register_operand" "=w")
3704 (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
3706 "fsqrt\\t%<s>0, %<s>1"
3707 [(set_attr "type" "fsqrt<s>")]
3710 (define_insn "abs<mode>2"
3711 [(set (match_operand:GPF 0 "register_operand" "=w")
3712 (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
3714 "fabs\\t%<s>0, %<s>1"
3715 [(set_attr "type" "ffarith<s>")]
3718 ;; Given that smax/smin do not specify the result when either input is NaN,
3719 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
3722 (define_insn "smax<mode>3"
3723 [(set (match_operand:GPF 0 "register_operand" "=w")
3724 (smax:GPF (match_operand:GPF 1 "register_operand" "w")
3725 (match_operand:GPF 2 "register_operand" "w")))]
3727 "fmaxnm\\t%<s>0, %<s>1, %<s>2"
3728 [(set_attr "type" "f_minmax<s>")]
3731 (define_insn "smin<mode>3"
3732 [(set (match_operand:GPF 0 "register_operand" "=w")
3733 (smin:GPF (match_operand:GPF 1 "register_operand" "w")
3734 (match_operand:GPF 2 "register_operand" "w")))]
3736 "fminnm\\t%<s>0, %<s>1, %<s>2"
3737 [(set_attr "type" "f_minmax<s>")]
3740 ;; -------------------------------------------------------------------
3742 ;; -------------------------------------------------------------------
3744 (define_expand "aarch64_reload_mov<mode>"
3745 [(set (match_operand:TX 0 "register_operand" "=w")
3746 (match_operand:TX 1 "register_operand" "w"))
3747 (clobber (match_operand:DI 2 "register_operand" "=&r"))
3751 rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
3752 rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
3753 gen_aarch64_movtilow_tilow (op0, op1);
3754 gen_aarch64_movdi_tihigh (operands[2], op1);
3755 gen_aarch64_movtihigh_di (op0, operands[2]);
3760 ;; The following secondary reload helpers patterns are invoked
3761 ;; after or during reload as we don't want these patterns to start
3762 ;; kicking in during the combiner.
3764 (define_insn "aarch64_movdi_<mode>low"
3765 [(set (match_operand:DI 0 "register_operand" "=r")
3766 (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
3767 "reload_completed || reload_in_progress"
3769 [(set_attr "type" "f_mrc")
3770 (set_attr "length" "4")
3773 (define_insn "aarch64_movdi_<mode>high"
3774 [(set (match_operand:DI 0 "register_operand" "=r")
3776 (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
3778 "reload_completed || reload_in_progress"
3779 "fmov\\t%x0, %1.d[1]"
3780 [(set_attr "type" "f_mrc")
3781 (set_attr "length" "4")
3784 (define_insn "aarch64_mov<mode>high_di"
3785 [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
3786 (const_int 64) (const_int 64))
3787 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
3788 "reload_completed || reload_in_progress"
3789 "fmov\\t%0.d[1], %x1"
3790 [(set_attr "type" "f_mcr")
3791 (set_attr "length" "4")
3794 (define_insn "aarch64_mov<mode>low_di"
3795 [(set (match_operand:TX 0 "register_operand" "=w")
3796 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
3797 "reload_completed || reload_in_progress"
3799 [(set_attr "type" "f_mcr")
3800 (set_attr "length" "4")
3803 (define_insn "aarch64_movtilow_tilow"
3804 [(set (match_operand:TI 0 "register_operand" "=w")
3806 (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
3807 "reload_completed || reload_in_progress"
3809 [(set_attr "type" "fmov")
3810 (set_attr "length" "4")
3813 ;; There is a deliberate reason why the parameters of high and lo_sum's
3814 ;; don't have modes for ADRP and ADD instructions. This is to allow high
3815 ;; and lo_sum's to be used with the labels defining the jump tables in
3818 (define_expand "add_losym"
3819 [(set (match_operand 0 "register_operand" "=r")
3820 (lo_sum (match_operand 1 "register_operand" "r")
3821 (match_operand 2 "aarch64_valid_symref" "S")))]
3824 enum machine_mode mode = GET_MODE (operands[0]);
3826 emit_insn ((mode == DImode
3828 : gen_add_losym_si) (operands[0],
3834 (define_insn "add_losym_<mode>"
3835 [(set (match_operand:P 0 "register_operand" "=r")
3836 (lo_sum:P (match_operand:P 1 "register_operand" "r")
3837 (match_operand 2 "aarch64_valid_symref" "S")))]
3839 "add\\t%<w>0, %<w>1, :lo12:%a2"
3840 [(set_attr "type" "alu_reg")]
3843 (define_insn "ldr_got_small_<mode>"
3844 [(set (match_operand:PTR 0 "register_operand" "=r")
3845 (unspec:PTR [(mem:PTR (lo_sum:PTR
3846 (match_operand:PTR 1 "register_operand" "r")
3847 (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
3848 UNSPEC_GOTSMALLPIC))]
3850 "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
3851 [(set_attr "type" "load1")]
3854 (define_insn "ldr_got_small_sidi"
3855 [(set (match_operand:DI 0 "register_operand" "=r")
3857 (unspec:SI [(mem:SI (lo_sum:DI
3858 (match_operand:DI 1 "register_operand" "r")
3859 (match_operand:DI 2 "aarch64_valid_symref" "S")))]
3860 UNSPEC_GOTSMALLPIC)))]
3862 "ldr\\t%w0, [%1, #:got_lo12:%a2]"
3863 [(set_attr "type" "load1")]
3866 (define_insn "ldr_got_tiny"
3867 [(set (match_operand:DI 0 "register_operand" "=r")
3868 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
3869 UNSPEC_GOTTINYPIC))]
3872 [(set_attr "type" "load1")]
3875 (define_insn "aarch64_load_tp_hard"
3876 [(set (match_operand:DI 0 "register_operand" "=r")
3877 (unspec:DI [(const_int 0)] UNSPEC_TLS))]
3879 "mrs\\t%0, tpidr_el0"
3880 [(set_attr "type" "mrs")]
3883 ;; The TLS ABI specifically requires that the compiler does not schedule
3884 ;; instructions in the TLS stubs, in order to enable linker relaxation.
3885 ;; Therefore we treat the stubs as an atomic sequence.
3886 (define_expand "tlsgd_small"
3887 [(parallel [(set (match_operand 0 "register_operand" "")
3888 (call (mem:DI (match_dup 2)) (const_int 1)))
3889 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
3890 (clobber (reg:DI LR_REGNUM))])]
3893 operands[2] = aarch64_tls_get_addr ();
3896 (define_insn "*tlsgd_small"
3897 [(set (match_operand 0 "register_operand" "")
3898 (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
3899 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
3900 (clobber (reg:DI LR_REGNUM))
3903 "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
3904 [(set_attr "type" "call")
3905 (set_attr "length" "16")])
3907 (define_insn "tlsie_small_<mode>"
3908 [(set (match_operand:PTR 0 "register_operand" "=r")
3909 (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
3910 UNSPEC_GOTSMALLTLS))]
3912 "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
3913 [(set_attr "type" "load1")
3914 (set_attr "length" "8")]
3917 (define_insn "tlsie_small_sidi"
3918 [(set (match_operand:DI 0 "register_operand" "=r")
3920 (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")]
3921 UNSPEC_GOTSMALLTLS)))]
3923 "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
3924 [(set_attr "type" "load1")
3925 (set_attr "length" "8")]
3928 (define_expand "tlsle_small"
3929 [(set (match_operand 0 "register_operand" "=r")
3930 (unspec [(match_operand 1 "register_operand" "r")
3931 (match_operand 2 "aarch64_tls_le_symref" "S")]
3932 UNSPEC_GOTSMALLTLS))]
3935 enum machine_mode mode = GET_MODE (operands[0]);
3936 emit_insn ((mode == DImode
3937 ? gen_tlsle_small_di
3938 : gen_tlsle_small_si) (operands[0],
3944 (define_insn "tlsle_small_<mode>"
3945 [(set (match_operand:P 0 "register_operand" "=r")
3946 (unspec:P [(match_operand:P 1 "register_operand" "r")
3947 (match_operand 2 "aarch64_tls_le_symref" "S")]
3948 UNSPEC_GOTSMALLTLS))]
3950 "add\\t%<w>0, %<w>1, #%G2\;add\\t%<w>0, %<w>0, #%L2"
3951 [(set_attr "type" "alu_reg")
3952 (set_attr "length" "8")]
3955 (define_insn "tlsdesc_small_<mode>"
3956 [(set (reg:PTR R0_REGNUM)
3957 (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
3959 (clobber (reg:DI LR_REGNUM))
3960 (clobber (reg:CC CC_REGNUM))
3961 (clobber (match_scratch:DI 1 "=r"))]
3963 "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
3964 [(set_attr "type" "call")
3965 (set_attr "length" "16")])
3967 (define_insn "stack_tie"
3968 [(set (mem:BLK (scratch))
3969 (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
3970 (match_operand:DI 1 "register_operand" "rk")]
3974 [(set_attr "length" "0")]
3977 ;; Named pattern for expanding thread pointer reference.
3978 (define_expand "get_thread_pointerdi"
3979 [(match_operand:DI 0 "register_operand" "=r")]
3982 rtx tmp = aarch64_load_tp (operands[0]);
3983 if (tmp != operands[0])
3984 emit_move_insn (operands[0], tmp);
3988 ;; Named patterns for stack smashing protection.
3989 (define_expand "stack_protect_set"
3990 [(match_operand 0 "memory_operand")
3991 (match_operand 1 "memory_operand")]
3994 enum machine_mode mode = GET_MODE (operands[0]);
3996 emit_insn ((mode == DImode
3997 ? gen_stack_protect_set_di
3998 : gen_stack_protect_set_si) (operands[0], operands[1]));
4002 (define_insn "stack_protect_set_<mode>"
4003 [(set (match_operand:PTR 0 "memory_operand" "=m")
4004 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
4006 (set (match_scratch:PTR 2 "=&r") (const_int 0))]
4008 "ldr\\t%<w>2, %1\;str\\t%<w>2, %0\;mov\t%<w>2,0"
4009 [(set_attr "length" "12")
4010 (set_attr "type" "multiple")])
4012 (define_expand "stack_protect_test"
4013 [(match_operand 0 "memory_operand")
4014 (match_operand 1 "memory_operand")
4019 enum machine_mode mode = GET_MODE (operands[0]);
4021 result = gen_reg_rtx(mode);
4023 emit_insn ((mode == DImode
4024 ? gen_stack_protect_test_di
4025 : gen_stack_protect_test_si) (result,
4030 emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4031 result, const0_rtx, operands[2]));
4033 emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4034 result, const0_rtx, operands[2]));
4038 (define_insn "stack_protect_test_<mode>"
4039 [(set (match_operand:PTR 0 "register_operand" "=r")
4040 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
4041 (match_operand:PTR 2 "memory_operand" "m")]
4043 (clobber (match_scratch:PTR 3 "=&r"))]
4045 "ldr\t%<w>3, %x1\;ldr\t%<w>0, %x2\;eor\t%<w>0, %<w>3, %<w>0"
4046 [(set_attr "length" "12")
4047 (set_attr "type" "multiple")])
4049 ;; Write Floating-point Control Register.
4050 (define_insn "set_fpcr"
4051 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
4054 [(set_attr "type" "mrs")])
4056 ;; Read Floating-point Control Register.
4057 (define_insn "get_fpcr"
4058 [(set (match_operand:SI 0 "register_operand" "=r")
4059 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
4062 [(set_attr "type" "mrs")])
4064 ;; Write Floating-point Status Register.
4065 (define_insn "set_fpsr"
4066 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
4069 [(set_attr "type" "mrs")])
4071 ;; Read Floating-point Status Register.
4072 (define_insn "get_fpsr"
4073 [(set (match_operand:SI 0 "register_operand" "=r")
4074 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
4077 [(set_attr "type" "mrs")])
4080 ;; Define the subtract-one-and-jump insns so loop.c
4081 ;; knows what to generate.
4082 (define_expand "doloop_end"
4083 [(use (match_operand 0 "" "")) ; loop pseudo
4084 (use (match_operand 1 "" ""))] ; label
4085 "optimize > 0 && flag_modulo_sched"
4094 /* Currently SMS relies on the do-loop pattern to recognize loops
4095 where (1) the control part consists of all insns defining and/or
4096 using a certain 'count' register and (2) the loop count can be
4097 adjusted by modifying this register prior to the loop.
4098 ??? The possible introduction of a new block to initialize the
4099 new IV can potentially affect branch optimizations. */
4101 if (GET_MODE (operands[0]) != DImode)
4105 insn = emit_insn (gen_adddi3_compare0 (s0, s0, GEN_INT (-1)));
4107 cmp = XVECEXP (PATTERN (insn), 0, 0);
4108 cc_reg = SET_DEST (cmp);
4109 bcomp = gen_rtx_NE (VOIDmode, cc_reg, const0_rtx);
4110 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
4111 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4112 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
4118 (include "aarch64-simd.md")
4120 ;; Atomic Operations
4121 (include "atomics.md")