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" [
126 (define_c_enum "unspecv" [
127 UNSPECV_EH_RETURN ; Represent EH_RETURN
128 UNSPECV_GET_FPCR ; Represent fetch of FPCR content.
129 UNSPECV_SET_FPCR ; Represent assign of FPCR content.
130 UNSPECV_GET_FPSR ; Represent fetch of FPSR content.
131 UNSPECV_SET_FPSR ; Represent assign of FPSR content.
135 ;; If further include files are added the defintion of MD_INCLUDES
138 (include "constraints.md")
139 (include "predicates.md")
140 (include "iterators.md")
142 ;; -------------------------------------------------------------------
143 ;; Instruction types and attributes
144 ;; -------------------------------------------------------------------
146 ; The "type" attribute is is included here from AArch32 backend to be able
147 ; to share pipeline descriptions.
148 (include "../arm/types.md")
150 ;; It is important to set the fp or simd attributes to yes when a pattern
151 ;; alternative uses the FP or SIMD register files, usually signified by use of
152 ;; the 'w' constraint. This will ensure that the alternative will be
153 ;; disabled when compiling with -mgeneral-regs-only or with the +nofp/+nosimd
154 ;; architecture extensions. If all the alternatives in a pattern use the
155 ;; FP or SIMD registers then the pattern predicate should include TARGET_FLOAT
158 ;; Attribute that specifies whether or not the instruction touches fp
159 ;; registers. When this is set to yes for an alternative, that alternative
160 ;; will be disabled when !TARGET_FLOAT.
161 (define_attr "fp" "no,yes" (const_string "no"))
163 ;; Attribute that specifies whether or not the instruction touches simd
164 ;; registers. When this is set to yes for an alternative, that alternative
165 ;; will be disabled when !TARGET_SIMD.
166 (define_attr "simd" "no,yes" (const_string "no"))
168 (define_attr "length" ""
171 ;; Attribute that controls whether an alternative is enabled or not.
172 ;; Currently it is only used to disable alternatives which touch fp or simd
173 ;; registers when -mgeneral-regs-only is specified.
174 (define_attr "enabled" "no,yes"
176 (and (eq_attr "fp" "yes")
177 (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
178 (and (eq_attr "simd" "yes")
179 (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
181 ] (const_string "yes")))
183 ;; -------------------------------------------------------------------
184 ;; Pipeline descriptions and scheduling
185 ;; -------------------------------------------------------------------
188 (include "aarch64-tune.md")
190 ;; True if the generic scheduling description should be used.
192 (define_attr "generic_sched" "yes,no"
194 (eq_attr "tune" "cortexa53,cortexa15")
196 (const_string "yes"))))
199 (include "../arm/cortex-a53.md")
200 (include "../arm/cortex-a15.md")
202 ;; -------------------------------------------------------------------
203 ;; Jumps and other miscellaneous insns
204 ;; -------------------------------------------------------------------
206 (define_insn "indirect_jump"
207 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
210 [(set_attr "type" "branch")]
214 [(set (pc) (label_ref (match_operand 0 "" "")))]
217 [(set_attr "type" "branch")]
220 (define_expand "cbranch<mode>4"
221 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
222 [(match_operand:GPI 1 "register_operand" "")
223 (match_operand:GPI 2 "aarch64_plus_operand" "")])
224 (label_ref (match_operand 3 "" ""))
228 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
230 operands[2] = const0_rtx;
234 (define_expand "cbranch<mode>4"
235 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
236 [(match_operand:GPF 1 "register_operand" "")
237 (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
238 (label_ref (match_operand 3 "" ""))
242 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
244 operands[2] = const0_rtx;
248 (define_insn "*condjump"
249 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
250 [(match_operand 1 "cc_register" "") (const_int 0)])
251 (label_ref (match_operand 2 "" ""))
255 [(set_attr "type" "branch")]
258 (define_expand "casesi"
259 [(match_operand:SI 0 "register_operand" "") ; Index
260 (match_operand:SI 1 "const_int_operand" "") ; Lower bound
261 (match_operand:SI 2 "const_int_operand" "") ; Total range
262 (match_operand:DI 3 "" "") ; Table label
263 (match_operand:DI 4 "" "")] ; Out of range label
266 if (operands[1] != const0_rtx)
268 rtx reg = gen_reg_rtx (SImode);
270 /* Canonical RTL says that if you have:
274 then this should be emitted as:
278 The use of trunc_int_for_mode ensures that the resulting
279 constant can be represented in SImode, this is important
280 for the corner case where operand[1] is INT_MIN. */
282 operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
284 if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
285 (operands[1], SImode))
286 operands[1] = force_reg (SImode, operands[1]);
287 emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
291 if (!aarch64_plus_operand (operands[2], SImode))
292 operands[2] = force_reg (SImode, operands[2]);
293 emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
295 operands[0], operands[2], operands[4]));
297 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
298 emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
304 (define_insn "casesi_dispatch"
307 (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
308 (match_operand:SI 1 "register_operand" "r")]
310 (clobber (reg:CC CC_REGNUM))
311 (clobber (match_scratch:DI 3 "=r"))
312 (clobber (match_scratch:DI 4 "=r"))
313 (use (label_ref (match_operand 2 "" "")))])]
316 return aarch64_output_casesi (operands);
318 [(set_attr "length" "16")
319 (set_attr "type" "branch")]
323 [(unspec[(const_int 0)] UNSPEC_NOP)]
326 [(set_attr "type" "no_insn")]
330 [(trap_if (const_int 1) (const_int 8))]
333 [(set_attr "type" "trap")])
335 (define_expand "prologue"
336 [(clobber (const_int 0))]
339 aarch64_expand_prologue ();
344 (define_expand "epilogue"
345 [(clobber (const_int 0))]
348 aarch64_expand_epilogue (false);
353 (define_expand "sibcall_epilogue"
354 [(clobber (const_int 0))]
357 aarch64_expand_epilogue (true);
362 (define_insn "*do_return"
366 [(set_attr "type" "branch")]
369 (define_expand "return"
371 "aarch64_use_return_insn_p ()"
375 (define_insn "simple_return"
379 [(set_attr "type" "branch")]
382 (define_insn "eh_return"
383 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
387 [(set_attr "type" "branch")]
392 [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
395 [(set (match_dup 1) (match_dup 0))]
397 operands[1] = aarch64_final_eh_return_addr ();
401 (define_insn "*cb<optab><mode>1"
402 [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
404 (label_ref (match_operand 1 "" ""))
408 [(set_attr "type" "branch")]
412 (define_insn "*tb<optab><mode>1"
413 [(set (pc) (if_then_else
414 (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
416 (match_operand 1 "const_int_operand" "n"))
418 (label_ref (match_operand 2 "" ""))
420 (clobber (match_scratch:DI 3 "=r"))]
423 if (get_attr_length (insn) == 8)
424 return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
425 return \"<tbz>\\t%<w>0, %1, %l2\";
427 [(set_attr "type" "branch")
429 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
430 (lt (minus (match_dup 2) (pc)) (const_int 32764)))
435 (define_insn "*cb<optab><mode>1"
436 [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
438 (label_ref (match_operand 1 "" ""))
440 (clobber (match_scratch:DI 2 "=r"))]
443 if (get_attr_length (insn) == 8)
444 return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
445 return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
447 [(set_attr "type" "branch")
449 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
450 (lt (minus (match_dup 1) (pc)) (const_int 32764)))
455 ;; -------------------------------------------------------------------
456 ;; Subroutine calls and sibcalls
457 ;; -------------------------------------------------------------------
459 (define_expand "call_internal"
460 [(parallel [(call (match_operand 0 "memory_operand" "")
461 (match_operand 1 "general_operand" ""))
462 (use (match_operand 2 "" ""))
463 (clobber (reg:DI LR_REGNUM))])])
465 (define_expand "call"
466 [(parallel [(call (match_operand 0 "memory_operand" "")
467 (match_operand 1 "general_operand" ""))
468 (use (match_operand 2 "" ""))
469 (clobber (reg:DI LR_REGNUM))])]
475 /* In an untyped call, we can get NULL for operand 2. */
476 if (operands[2] == NULL)
477 operands[2] = const0_rtx;
479 /* Decide if we should generate indirect calls by loading the
480 64-bit address of the callee into a register before performing
481 the branch-and-link. */
482 callee = XEXP (operands[0], 0);
483 if (GET_CODE (callee) == SYMBOL_REF
484 ? aarch64_is_long_call_p (callee)
486 XEXP (operands[0], 0) = force_reg (Pmode, callee);
488 pat = gen_call_internal (operands[0], operands[1], operands[2]);
489 aarch64_emit_call_insn (pat);
494 (define_insn "*call_reg"
495 [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
496 (match_operand 1 "" ""))
497 (use (match_operand 2 "" ""))
498 (clobber (reg:DI LR_REGNUM))]
501 [(set_attr "type" "call")]
504 (define_insn "*call_symbol"
505 [(call (mem:DI (match_operand:DI 0 "" ""))
506 (match_operand 1 "" ""))
507 (use (match_operand 2 "" ""))
508 (clobber (reg:DI LR_REGNUM))]
509 "GET_CODE (operands[0]) == SYMBOL_REF
510 && !aarch64_is_long_call_p (operands[0])"
512 [(set_attr "type" "call")]
515 (define_expand "call_value_internal"
516 [(parallel [(set (match_operand 0 "" "")
517 (call (match_operand 1 "memory_operand" "")
518 (match_operand 2 "general_operand" "")))
519 (use (match_operand 3 "" ""))
520 (clobber (reg:DI LR_REGNUM))])])
522 (define_expand "call_value"
523 [(parallel [(set (match_operand 0 "" "")
524 (call (match_operand 1 "memory_operand" "")
525 (match_operand 2 "general_operand" "")))
526 (use (match_operand 3 "" ""))
527 (clobber (reg:DI LR_REGNUM))])]
533 /* In an untyped call, we can get NULL for operand 3. */
534 if (operands[3] == NULL)
535 operands[3] = const0_rtx;
537 /* Decide if we should generate indirect calls by loading the
538 64-bit address of the callee into a register before performing
539 the branch-and-link. */
540 callee = XEXP (operands[1], 0);
541 if (GET_CODE (callee) == SYMBOL_REF
542 ? aarch64_is_long_call_p (callee)
544 XEXP (operands[1], 0) = force_reg (Pmode, callee);
546 pat = gen_call_value_internal (operands[0], operands[1], operands[2],
548 aarch64_emit_call_insn (pat);
553 (define_insn "*call_value_reg"
554 [(set (match_operand 0 "" "")
555 (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
556 (match_operand 2 "" "")))
557 (use (match_operand 3 "" ""))
558 (clobber (reg:DI LR_REGNUM))]
561 [(set_attr "type" "call")]
565 (define_insn "*call_value_symbol"
566 [(set (match_operand 0 "" "")
567 (call (mem:DI (match_operand:DI 1 "" ""))
568 (match_operand 2 "" "")))
569 (use (match_operand 3 "" ""))
570 (clobber (reg:DI LR_REGNUM))]
571 "GET_CODE (operands[1]) == SYMBOL_REF
572 && !aarch64_is_long_call_p (operands[1])"
574 [(set_attr "type" "call")]
577 (define_expand "sibcall_internal"
578 [(parallel [(call (match_operand 0 "memory_operand" "")
579 (match_operand 1 "general_operand" ""))
581 (use (match_operand 2 "" ""))])])
583 (define_expand "sibcall"
584 [(parallel [(call (match_operand 0 "memory_operand" "")
585 (match_operand 1 "general_operand" ""))
587 (use (match_operand 2 "" ""))])]
592 if (!REG_P (XEXP (operands[0], 0))
593 && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
594 XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
596 if (operands[2] == NULL_RTX)
597 operands[2] = const0_rtx;
599 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
600 aarch64_emit_call_insn (pat);
605 (define_expand "sibcall_value_internal"
606 [(parallel [(set (match_operand 0 "" "")
607 (call (match_operand 1 "memory_operand" "")
608 (match_operand 2 "general_operand" "")))
610 (use (match_operand 3 "" ""))])])
612 (define_expand "sibcall_value"
613 [(parallel [(set (match_operand 0 "" "")
614 (call (match_operand 1 "memory_operand" "")
615 (match_operand 2 "general_operand" "")))
617 (use (match_operand 3 "" ""))])]
622 if (!REG_P (XEXP (operands[1], 0))
623 && (GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF))
624 XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
626 if (operands[3] == NULL_RTX)
627 operands[3] = const0_rtx;
629 pat = gen_sibcall_value_internal (operands[0], operands[1], operands[2],
631 aarch64_emit_call_insn (pat);
636 (define_insn "*sibcall_insn"
637 [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucs, Usf"))
638 (match_operand 1 "" ""))
640 (use (match_operand 2 "" ""))]
641 "SIBLING_CALL_P (insn)"
645 [(set_attr "type" "branch, branch")]
648 (define_insn "*sibcall_value_insn"
649 [(set (match_operand 0 "" "")
651 (match_operand:DI 1 "aarch64_call_insn_operand" "Ucs, Usf"))
652 (match_operand 2 "" "")))
654 (use (match_operand 3 "" ""))]
655 "SIBLING_CALL_P (insn)"
659 [(set_attr "type" "branch, branch")]
662 ;; Call subroutine returning any type.
664 (define_expand "untyped_call"
665 [(parallel [(call (match_operand 0 "")
668 (match_operand 2 "")])]
673 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
675 for (i = 0; i < XVECLEN (operands[2], 0); i++)
677 rtx set = XVECEXP (operands[2], 0, i);
678 emit_move_insn (SET_DEST (set), SET_SRC (set));
681 /* The optimizer does not know that the call sets the function value
682 registers we stored in the result block. We avoid problems by
683 claiming that all hard registers are used and clobbered at this
685 emit_insn (gen_blockage ());
689 ;; -------------------------------------------------------------------
691 ;; -------------------------------------------------------------------
693 (define_expand "mov<mode>"
694 [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
695 (match_operand:SHORT 1 "general_operand" ""))]
698 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
699 operands[1] = force_reg (<MODE>mode, operands[1]);
703 (define_insn "*mov<mode>_aarch64"
704 [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r, *w,r,*w, m, m, r,*w,*w")
705 (match_operand:SHORT 1 "general_operand" " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
706 "(register_operand (operands[0], <MODE>mode)
707 || aarch64_reg_or_zero (operands[1], <MODE>mode))"
709 switch (which_alternative)
712 return "mov\t%w0, %w1";
714 return "mov\t%w0, %1";
716 return aarch64_output_scalar_simd_mov_immediate (operands[1],
719 return "ldr<size>\t%w0, %1";
721 return "ldr\t%<size>0, %1";
723 return "str<size>\t%w1, %0";
725 return "str\t%<size>1, %0";
727 return "umov\t%w0, %1.<v>[0]";
729 return "dup\t%0.<Vallxd>, %w1";
731 return "dup\t%<Vetype>0, %1.<v>[0]";
736 [(set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
737 neon_from_gp<q>,neon_from_gp<q>, neon_dup")
738 (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")]
741 (define_expand "mov<mode>"
742 [(set (match_operand:GPI 0 "nonimmediate_operand" "")
743 (match_operand:GPI 1 "general_operand" ""))]
746 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
747 operands[1] = force_reg (<MODE>mode, operands[1]);
749 if (CONSTANT_P (operands[1]))
751 aarch64_expand_mov_immediate (operands[0], operands[1]);
757 (define_insn "*movsi_aarch64"
758 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m, m,r,r ,*w, r,*w")
759 (match_operand:SI 1 "aarch64_mov_operand" " r,r,k,M,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
760 "(register_operand (operands[0], SImode)
761 || aarch64_reg_or_zero (operands[1], SImode))"
776 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
777 adr,adr,f_mcr,f_mrc,fmov")
778 (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
781 (define_insn "*movdi_aarch64"
782 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m, m,r,r, *w, r,*w,w")
783 (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))]
784 "(register_operand (operands[0], DImode)
785 || aarch64_reg_or_zero (operands[1], DImode))"
801 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
802 adr,adr,f_mcr,f_mrc,fmov,fmov")
803 (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
804 (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
807 (define_insn "insv_imm<mode>"
808 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
810 (match_operand:GPI 1 "const_int_operand" "n"))
811 (match_operand:GPI 2 "const_int_operand" "n"))]
812 "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
813 && UINTVAL (operands[1]) % 16 == 0"
814 "movk\\t%<w>0, %X2, lsl %1"
815 [(set_attr "type" "mov_imm")]
818 (define_expand "movti"
819 [(set (match_operand:TI 0 "nonimmediate_operand" "")
820 (match_operand:TI 1 "general_operand" ""))]
823 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
824 operands[1] = force_reg (TImode, operands[1]);
828 (define_insn "*movti_aarch64"
829 [(set (match_operand:TI 0
830 "nonimmediate_operand" "=r, *w,r ,*w,r ,Ump,Ump,*w,m")
832 "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r ,Z , m,*w"))]
833 "(register_operand (operands[0], TImode)
834 || aarch64_reg_or_zero (operands[1], TImode))"
839 orr\\t%0.16b, %1.16b, %1.16b
845 [(set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \
846 load2,store2,store2,f_loadd,f_stored")
847 (set_attr "length" "8,8,8,4,4,4,4,4,4")
848 (set_attr "simd" "*,*,*,yes,*,*,*,*,*")
849 (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
852 ;; Split a TImode register-register or register-immediate move into
853 ;; its component DImode pieces, taking care to handle overlapping
854 ;; source and dest registers.
856 [(set (match_operand:TI 0 "register_operand" "")
857 (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
858 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
861 aarch64_split_128bit_move (operands[0], operands[1]);
865 (define_expand "mov<mode>"
866 [(set (match_operand:GPF 0 "nonimmediate_operand" "")
867 (match_operand:GPF 1 "general_operand" ""))]
872 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
876 if (GET_CODE (operands[0]) == MEM)
877 operands[1] = force_reg (<MODE>mode, operands[1]);
881 (define_insn "*movsf_aarch64"
882 [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
883 (match_operand:SF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
884 "TARGET_FLOAT && (register_operand (operands[0], SFmode)
885 || register_operand (operands[1], SFmode))"
896 [(set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
897 f_loads,f_stores,f_loads,f_stores,mov_reg")]
900 (define_insn "*movdf_aarch64"
901 [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
902 (match_operand:DF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
903 "TARGET_FLOAT && (register_operand (operands[0], DFmode)
904 || register_operand (operands[1], DFmode))"
915 [(set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
916 f_loadd,f_stored,f_loadd,f_stored,mov_reg")]
919 (define_expand "movtf"
920 [(set (match_operand:TF 0 "nonimmediate_operand" "")
921 (match_operand:TF 1 "general_operand" ""))]
926 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
930 if (GET_CODE (operands[0]) == MEM)
931 operands[1] = force_reg (TFmode, operands[1]);
935 (define_insn "*movtf_aarch64"
936 [(set (match_operand:TF 0
937 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
939 "general_operand" " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
940 "TARGET_FLOAT && (register_operand (operands[0], TFmode)
941 || register_operand (operands[1], TFmode))"
943 orr\\t%0.16b, %1.16b, %1.16b
953 [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,fconstd,fconstd,\
954 f_loadd,f_stored,neon_load1_2reg,neon_store1_2reg")
955 (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
956 (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
957 (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
961 [(set (match_operand:TF 0 "register_operand" "")
962 (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
963 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
966 aarch64_split_128bit_move (operands[0], operands[1]);
973 ;; 2 is size of move in bytes
976 (define_expand "movmemdi"
977 [(match_operand:BLK 0 "memory_operand")
978 (match_operand:BLK 1 "memory_operand")
979 (match_operand:DI 2 "immediate_operand")
980 (match_operand:DI 3 "immediate_operand")]
983 if (aarch64_expand_movmem (operands))
989 ;; Operands 1 and 3 are tied together by the final condition; so we allow
990 ;; fairly lax checking on the second memory operation.
991 (define_insn "load_pair<mode>"
992 [(set (match_operand:GPI 0 "register_operand" "=r")
993 (match_operand:GPI 1 "aarch64_mem_pair_operand" "Ump"))
994 (set (match_operand:GPI 2 "register_operand" "=r")
995 (match_operand:GPI 3 "memory_operand" "m"))]
996 "rtx_equal_p (XEXP (operands[3], 0),
997 plus_constant (Pmode,
998 XEXP (operands[1], 0),
999 GET_MODE_SIZE (<MODE>mode)))"
1000 "ldp\\t%<w>0, %<w>2, %1"
1001 [(set_attr "type" "load2")]
1004 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1005 ;; fairly lax checking on the second memory operation.
1006 (define_insn "store_pair<mode>"
1007 [(set (match_operand:GPI 0 "aarch64_mem_pair_operand" "=Ump")
1008 (match_operand:GPI 1 "register_operand" "r"))
1009 (set (match_operand:GPI 2 "memory_operand" "=m")
1010 (match_operand:GPI 3 "register_operand" "r"))]
1011 "rtx_equal_p (XEXP (operands[2], 0),
1012 plus_constant (Pmode,
1013 XEXP (operands[0], 0),
1014 GET_MODE_SIZE (<MODE>mode)))"
1015 "stp\\t%<w>1, %<w>3, %0"
1016 [(set_attr "type" "store2")]
1019 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1020 ;; fairly lax checking on the second memory operation.
1021 (define_insn "load_pair<mode>"
1022 [(set (match_operand:GPF 0 "register_operand" "=w")
1023 (match_operand:GPF 1 "aarch64_mem_pair_operand" "Ump"))
1024 (set (match_operand:GPF 2 "register_operand" "=w")
1025 (match_operand:GPF 3 "memory_operand" "m"))]
1026 "rtx_equal_p (XEXP (operands[3], 0),
1027 plus_constant (Pmode,
1028 XEXP (operands[1], 0),
1029 GET_MODE_SIZE (<MODE>mode)))"
1030 "ldp\\t%<w>0, %<w>2, %1"
1031 [(set_attr "type" "neon_load1_2reg<q>")]
1034 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1035 ;; fairly lax checking on the second memory operation.
1036 (define_insn "store_pair<mode>"
1037 [(set (match_operand:GPF 0 "aarch64_mem_pair_operand" "=Ump")
1038 (match_operand:GPF 1 "register_operand" "w"))
1039 (set (match_operand:GPF 2 "memory_operand" "=m")
1040 (match_operand:GPF 3 "register_operand" "w"))]
1041 "rtx_equal_p (XEXP (operands[2], 0),
1042 plus_constant (Pmode,
1043 XEXP (operands[0], 0),
1044 GET_MODE_SIZE (<MODE>mode)))"
1045 "stp\\t%<w>1, %<w>3, %0"
1046 [(set_attr "type" "neon_store1_2reg<q>")]
1049 ;; Load pair with post-index writeback. This is primarily used in function
1051 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
1053 [(set (match_operand:P 0 "register_operand" "=k")
1054 (plus:P (match_operand:P 1 "register_operand" "0")
1055 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1056 (set (match_operand:GPI 2 "register_operand" "=r")
1057 (mem:GPI (match_dup 1)))
1058 (set (match_operand:GPI 3 "register_operand" "=r")
1059 (mem:GPI (plus:P (match_dup 1)
1060 (match_operand:P 5 "const_int_operand" "n"))))])]
1061 "INTVAL (operands[5]) == GET_MODE_SIZE (<GPI:MODE>mode)"
1062 "ldp\\t%<w>2, %<w>3, [%1], %4"
1063 [(set_attr "type" "load2")]
1066 (define_insn "loadwb_pair<GPF:mode>_<P:mode>"
1068 [(set (match_operand:P 0 "register_operand" "=k")
1069 (plus:P (match_operand:P 1 "register_operand" "0")
1070 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1071 (set (match_operand:GPF 2 "register_operand" "=w")
1072 (mem:GPF (match_dup 1)))
1073 (set (match_operand:GPF 3 "register_operand" "=w")
1074 (mem:GPF (plus:P (match_dup 1)
1075 (match_operand:P 5 "const_int_operand" "n"))))])]
1076 "INTVAL (operands[5]) == GET_MODE_SIZE (<GPF:MODE>mode)"
1077 "ldp\\t%<w>2, %<w>3, [%1], %4"
1078 [(set_attr "type" "neon_load1_2reg")]
1081 ;; Store pair with pre-index writeback. This is primarily used in function
1083 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
1085 [(set (match_operand:P 0 "register_operand" "=&k")
1086 (plus:P (match_operand:P 1 "register_operand" "0")
1087 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1088 (set (mem:GPI (plus:P (match_dup 0)
1090 (match_operand:GPI 2 "register_operand" "r"))
1091 (set (mem:GPI (plus:P (match_dup 0)
1092 (match_operand:P 5 "const_int_operand" "n")))
1093 (match_operand:GPI 3 "register_operand" "r"))])]
1094 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1095 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1096 [(set_attr "type" "store2")]
1099 (define_insn "storewb_pair<GPF:mode>_<P:mode>"
1101 [(set (match_operand:P 0 "register_operand" "=&k")
1102 (plus:P (match_operand:P 1 "register_operand" "0")
1103 (match_operand:P 4 "aarch64_mem_pair_offset" "n")))
1104 (set (mem:GPF (plus:P (match_dup 0)
1106 (match_operand:GPF 2 "register_operand" "w"))
1107 (set (mem:GPF (plus:P (match_dup 0)
1108 (match_operand:P 5 "const_int_operand" "n")))
1109 (match_operand:GPF 3 "register_operand" "w"))])]
1110 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPF:MODE>mode)"
1111 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1112 [(set_attr "type" "neon_store1_2reg<q>")]
1115 ;; -------------------------------------------------------------------
1116 ;; Sign/Zero extension
1117 ;; -------------------------------------------------------------------
1119 (define_expand "<optab>sidi2"
1120 [(set (match_operand:DI 0 "register_operand")
1121 (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1125 (define_insn "*extendsidi2_aarch64"
1126 [(set (match_operand:DI 0 "register_operand" "=r,r")
1127 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1132 [(set_attr "type" "extend,load1")]
1135 (define_insn "*zero_extendsidi2_aarch64"
1136 [(set (match_operand:DI 0 "register_operand" "=r,r")
1137 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1142 [(set_attr "type" "extend,load1")]
1145 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1146 [(set (match_operand:GPI 0 "register_operand")
1147 (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1151 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1152 [(set (match_operand:GPI 0 "register_operand" "=r,r")
1153 (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1156 sxt<SHORT:size>\t%<GPI:w>0, %w1
1157 ldrs<SHORT:size>\t%<GPI:w>0, %1"
1158 [(set_attr "type" "extend,load1")]
1161 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1162 [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1163 (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1166 uxt<SHORT:size>\t%<GPI:w>0, %w1
1167 ldr<SHORT:size>\t%w0, %1
1168 ldr\t%<SHORT:size>0, %1"
1169 [(set_attr "type" "extend,load1,load1")]
1172 (define_expand "<optab>qihi2"
1173 [(set (match_operand:HI 0 "register_operand")
1174 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1178 (define_insn "*<optab>qihi2_aarch64"
1179 [(set (match_operand:HI 0 "register_operand" "=r,r")
1180 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1185 [(set_attr "type" "extend,load1")]
1188 ;; -------------------------------------------------------------------
1189 ;; Simple arithmetic
1190 ;; -------------------------------------------------------------------
1192 (define_expand "add<mode>3"
1194 (match_operand:GPI 0 "register_operand" "")
1195 (plus:GPI (match_operand:GPI 1 "register_operand" "")
1196 (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1199 if (! aarch64_plus_operand (operands[2], VOIDmode))
1201 rtx subtarget = ((optimize && can_create_pseudo_p ())
1202 ? gen_reg_rtx (<MODE>mode) : operands[0]);
1203 HOST_WIDE_INT imm = INTVAL (operands[2]);
1206 imm = -(-imm & ~0xfff);
1210 emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1211 operands[1] = subtarget;
1212 operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1217 (define_insn "*addsi3_aarch64"
1219 (match_operand:SI 0 "register_operand" "=rk,rk,w,rk")
1221 (match_operand:SI 1 "register_operand" "%rk,rk,w,rk")
1222 (match_operand:SI 2 "aarch64_plus_operand" "I,r,w,J")))]
1227 add\\t%0.2s, %1.2s, %2.2s
1228 sub\\t%w0, %w1, #%n2"
1229 [(set_attr "type" "alu_imm,alu_sreg,neon_add,alu_imm")
1230 (set_attr "simd" "*,*,yes,*")]
1233 ;; zero_extend version of above
1234 (define_insn "*addsi3_aarch64_uxtw"
1236 (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1238 (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1239 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1244 sub\\t%w0, %w1, #%n2"
1245 [(set_attr "type" "alu_imm,alu_sreg,alu_imm")]
1248 (define_insn "*adddi3_aarch64"
1250 (match_operand:DI 0 "register_operand" "=rk,rk,rk,!w")
1252 (match_operand:DI 1 "register_operand" "%rk,rk,rk,!w")
1253 (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,!w")))]
1258 sub\\t%x0, %x1, #%n2
1259 add\\t%d0, %d1, %d2"
1260 [(set_attr "type" "alu_imm,alu_sreg,alu_imm,neon_add")
1261 (set_attr "simd" "*,*,*,yes")]
1264 (define_expand "addti3"
1265 [(set (match_operand:TI 0 "register_operand" "")
1266 (plus:TI (match_operand:TI 1 "register_operand" "")
1267 (match_operand:TI 2 "register_operand" "")))]
1270 rtx low = gen_reg_rtx (DImode);
1271 emit_insn (gen_adddi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1272 gen_lowpart (DImode, operands[2])));
1274 rtx high = gen_reg_rtx (DImode);
1275 emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]),
1276 gen_highpart (DImode, operands[2])));
1278 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1279 emit_move_insn (gen_highpart (DImode, operands[0]), high);
1283 (define_insn "add<mode>3_compare0"
1284 [(set (reg:CC_NZ CC_REGNUM)
1286 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1287 (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1289 (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1290 (plus:GPI (match_dup 1) (match_dup 2)))]
1293 adds\\t%<w>0, %<w>1, %<w>2
1294 adds\\t%<w>0, %<w>1, %<w>2
1295 subs\\t%<w>0, %<w>1, #%n2"
1296 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1299 ;; zero_extend version of above
1300 (define_insn "*addsi3_compare0_uxtw"
1301 [(set (reg:CC_NZ CC_REGNUM)
1303 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1304 (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1306 (set (match_operand:DI 0 "register_operand" "=r,r,r")
1307 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1310 adds\\t%w0, %w1, %w2
1311 adds\\t%w0, %w1, %w2
1312 subs\\t%w0, %w1, #%n2"
1313 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1316 (define_insn "*adds_mul_imm_<mode>"
1317 [(set (reg:CC_NZ CC_REGNUM)
1320 (match_operand:GPI 1 "register_operand" "r")
1321 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1322 (match_operand:GPI 3 "register_operand" "r"))
1324 (set (match_operand:GPI 0 "register_operand" "=r")
1325 (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1328 "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1329 [(set_attr "type" "alus_shift_imm")]
1332 (define_insn "*subs_mul_imm_<mode>"
1333 [(set (reg:CC_NZ CC_REGNUM)
1335 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1337 (match_operand:GPI 2 "register_operand" "r")
1338 (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1340 (set (match_operand:GPI 0 "register_operand" "=r")
1341 (minus:GPI (match_dup 1)
1342 (mult:GPI (match_dup 2) (match_dup 3))))]
1344 "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1345 [(set_attr "type" "alus_shift_imm")]
1348 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1349 [(set (reg:CC_NZ CC_REGNUM)
1352 (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1353 (match_operand:GPI 2 "register_operand" "r"))
1355 (set (match_operand:GPI 0 "register_operand" "=r")
1356 (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1358 "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1359 [(set_attr "type" "alus_ext")]
1362 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1363 [(set (reg:CC_NZ CC_REGNUM)
1365 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1367 (match_operand:ALLX 2 "register_operand" "r")))
1369 (set (match_operand:GPI 0 "register_operand" "=r")
1370 (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1372 "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1373 [(set_attr "type" "alus_ext")]
1376 (define_insn "*adds_<optab><mode>_multp2"
1377 [(set (reg:CC_NZ CC_REGNUM)
1379 (plus:GPI (ANY_EXTRACT:GPI
1380 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1381 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1382 (match_operand 3 "const_int_operand" "n")
1384 (match_operand:GPI 4 "register_operand" "r"))
1386 (set (match_operand:GPI 0 "register_operand" "=r")
1387 (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1391 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1392 "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1393 [(set_attr "type" "alus_ext")]
1396 (define_insn "*subs_<optab><mode>_multp2"
1397 [(set (reg:CC_NZ CC_REGNUM)
1399 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1401 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1402 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1403 (match_operand 3 "const_int_operand" "n")
1406 (set (match_operand:GPI 0 "register_operand" "=r")
1407 (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1408 (mult:GPI (match_dup 1) (match_dup 2))
1411 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1412 "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1413 [(set_attr "type" "alus_ext")]
1416 (define_insn "*add<mode>3nr_compare0"
1417 [(set (reg:CC_NZ CC_REGNUM)
1419 (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1420 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1427 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
1430 (define_insn "*compare_neg<mode>"
1431 [(set (reg:CC_Z CC_REGNUM)
1433 (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
1434 (match_operand:GPI 1 "register_operand" "r")))]
1436 "cmn\\t%<w>1, %<w>0"
1437 [(set_attr "type" "alus_sreg")]
1440 (define_insn "*add_<shift>_<mode>"
1441 [(set (match_operand:GPI 0 "register_operand" "=r")
1442 (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1443 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1444 (match_operand:GPI 3 "register_operand" "r")))]
1446 "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1447 [(set_attr "type" "alu_shift_imm")]
1450 ;; zero_extend version of above
1451 (define_insn "*add_<shift>_si_uxtw"
1452 [(set (match_operand:DI 0 "register_operand" "=r")
1454 (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1455 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1456 (match_operand:SI 3 "register_operand" "r"))))]
1458 "add\\t%w0, %w3, %w1, <shift> %2"
1459 [(set_attr "type" "alu_shift_imm")]
1462 (define_insn "*add_mul_imm_<mode>"
1463 [(set (match_operand:GPI 0 "register_operand" "=r")
1464 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1465 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1466 (match_operand:GPI 3 "register_operand" "r")))]
1468 "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1469 [(set_attr "type" "alu_shift_imm")]
1472 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1473 [(set (match_operand:GPI 0 "register_operand" "=rk")
1474 (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1475 (match_operand:GPI 2 "register_operand" "r")))]
1477 "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1478 [(set_attr "type" "alu_ext")]
1481 ;; zero_extend version of above
1482 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1483 [(set (match_operand:DI 0 "register_operand" "=rk")
1485 (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1486 (match_operand:GPI 2 "register_operand" "r"))))]
1488 "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1489 [(set_attr "type" "alu_ext")]
1492 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1493 [(set (match_operand:GPI 0 "register_operand" "=rk")
1494 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1495 (match_operand:ALLX 1 "register_operand" "r"))
1496 (match_operand 2 "aarch64_imm3" "Ui3"))
1497 (match_operand:GPI 3 "register_operand" "r")))]
1499 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1500 [(set_attr "type" "alu_ext")]
1503 ;; zero_extend version of above
1504 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1505 [(set (match_operand:DI 0 "register_operand" "=rk")
1507 (plus:SI (ashift:SI (ANY_EXTEND:SI
1508 (match_operand:SHORT 1 "register_operand" "r"))
1509 (match_operand 2 "aarch64_imm3" "Ui3"))
1510 (match_operand:SI 3 "register_operand" "r"))))]
1512 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1513 [(set_attr "type" "alu_ext")]
1516 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1517 [(set (match_operand:GPI 0 "register_operand" "=rk")
1518 (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1519 (match_operand:ALLX 1 "register_operand" "r"))
1520 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1521 (match_operand:GPI 3 "register_operand" "r")))]
1523 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1524 [(set_attr "type" "alu_ext")]
1527 ;; zero_extend version of above
1528 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1529 [(set (match_operand:DI 0 "register_operand" "=rk")
1530 (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1531 (match_operand:SHORT 1 "register_operand" "r"))
1532 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1533 (match_operand:SI 3 "register_operand" "r"))))]
1535 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1536 [(set_attr "type" "alu_ext")]
1539 (define_insn "*add_<optab><mode>_multp2"
1540 [(set (match_operand:GPI 0 "register_operand" "=rk")
1541 (plus:GPI (ANY_EXTRACT:GPI
1542 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1543 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1544 (match_operand 3 "const_int_operand" "n")
1546 (match_operand:GPI 4 "register_operand" "r")))]
1547 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1548 "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1549 [(set_attr "type" "alu_ext")]
1552 ;; zero_extend version of above
1553 (define_insn "*add_<optab>si_multp2_uxtw"
1554 [(set (match_operand:DI 0 "register_operand" "=rk")
1556 (plus:SI (ANY_EXTRACT:SI
1557 (mult:SI (match_operand:SI 1 "register_operand" "r")
1558 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1559 (match_operand 3 "const_int_operand" "n")
1561 (match_operand:SI 4 "register_operand" "r"))))]
1562 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1563 "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1564 [(set_attr "type" "alu_ext")]
1567 (define_insn "add<mode>3_carryin"
1569 (match_operand:GPI 0 "register_operand" "=r")
1570 (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1572 (match_operand:GPI 1 "register_operand" "r")
1573 (match_operand:GPI 2 "register_operand" "r"))))]
1575 "adc\\t%<w>0, %<w>1, %<w>2"
1576 [(set_attr "type" "adc_reg")]
1579 ;; zero_extend version of above
1580 (define_insn "*addsi3_carryin_uxtw"
1582 (match_operand:DI 0 "register_operand" "=r")
1584 (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1586 (match_operand:SI 1 "register_operand" "r")
1587 (match_operand:SI 2 "register_operand" "r")))))]
1589 "adc\\t%w0, %w1, %w2"
1590 [(set_attr "type" "adc_reg")]
1593 (define_insn "*add<mode>3_carryin_alt1"
1595 (match_operand:GPI 0 "register_operand" "=r")
1597 (match_operand:GPI 1 "register_operand" "r")
1598 (match_operand:GPI 2 "register_operand" "r"))
1599 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1601 "adc\\t%<w>0, %<w>1, %<w>2"
1602 [(set_attr "type" "adc_reg")]
1605 ;; zero_extend version of above
1606 (define_insn "*addsi3_carryin_alt1_uxtw"
1608 (match_operand:DI 0 "register_operand" "=r")
1611 (match_operand:SI 1 "register_operand" "r")
1612 (match_operand:SI 2 "register_operand" "r"))
1613 (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1615 "adc\\t%w0, %w1, %w2"
1616 [(set_attr "type" "adc_reg")]
1619 (define_insn "*add<mode>3_carryin_alt2"
1621 (match_operand:GPI 0 "register_operand" "=r")
1623 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1624 (match_operand:GPI 1 "register_operand" "r"))
1625 (match_operand:GPI 2 "register_operand" "r")))]
1627 "adc\\t%<w>0, %<w>1, %<w>2"
1628 [(set_attr "type" "adc_reg")]
1631 ;; zero_extend version of above
1632 (define_insn "*addsi3_carryin_alt2_uxtw"
1634 (match_operand:DI 0 "register_operand" "=r")
1637 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1638 (match_operand:SI 1 "register_operand" "r"))
1639 (match_operand:SI 2 "register_operand" "r"))))]
1641 "adc\\t%w0, %w1, %w2"
1642 [(set_attr "type" "adc_reg")]
1645 (define_insn "*add<mode>3_carryin_alt3"
1647 (match_operand:GPI 0 "register_operand" "=r")
1649 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1650 (match_operand:GPI 2 "register_operand" "r"))
1651 (match_operand:GPI 1 "register_operand" "r")))]
1653 "adc\\t%<w>0, %<w>1, %<w>2"
1654 [(set_attr "type" "adc_reg")]
1657 ;; zero_extend version of above
1658 (define_insn "*addsi3_carryin_alt3_uxtw"
1660 (match_operand:DI 0 "register_operand" "=r")
1663 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1664 (match_operand:SI 2 "register_operand" "r"))
1665 (match_operand:SI 1 "register_operand" "r"))))]
1667 "adc\\t%w0, %w1, %w2"
1668 [(set_attr "type" "adc_reg")]
1671 (define_insn "*add_uxt<mode>_multp2"
1672 [(set (match_operand:GPI 0 "register_operand" "=rk")
1674 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1675 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1676 (match_operand 3 "const_int_operand" "n"))
1677 (match_operand:GPI 4 "register_operand" "r")))]
1678 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1680 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1681 INTVAL (operands[3])));
1682 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1683 [(set_attr "type" "alu_ext")]
1686 ;; zero_extend version of above
1687 (define_insn "*add_uxtsi_multp2_uxtw"
1688 [(set (match_operand:DI 0 "register_operand" "=rk")
1691 (mult:SI (match_operand:SI 1 "register_operand" "r")
1692 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1693 (match_operand 3 "const_int_operand" "n"))
1694 (match_operand:SI 4 "register_operand" "r"))))]
1695 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1697 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1698 INTVAL (operands[3])));
1699 return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1700 [(set_attr "type" "alu_ext")]
1703 (define_insn "subsi3"
1704 [(set (match_operand:SI 0 "register_operand" "=rk")
1705 (minus:SI (match_operand:SI 1 "register_operand" "r")
1706 (match_operand:SI 2 "register_operand" "r")))]
1708 "sub\\t%w0, %w1, %w2"
1709 [(set_attr "type" "alu_sreg")]
1712 ;; zero_extend version of above
1713 (define_insn "*subsi3_uxtw"
1714 [(set (match_operand:DI 0 "register_operand" "=rk")
1716 (minus:SI (match_operand:SI 1 "register_operand" "r")
1717 (match_operand:SI 2 "register_operand" "r"))))]
1719 "sub\\t%w0, %w1, %w2"
1720 [(set_attr "type" "alu_sreg")]
1723 (define_insn "subdi3"
1724 [(set (match_operand:DI 0 "register_operand" "=rk,!w")
1725 (minus:DI (match_operand:DI 1 "register_operand" "r,!w")
1726 (match_operand:DI 2 "register_operand" "r,!w")))]
1730 sub\\t%d0, %d1, %d2"
1731 [(set_attr "type" "alu_sreg, neon_sub")
1732 (set_attr "simd" "*,yes")]
1735 (define_expand "subti3"
1736 [(set (match_operand:TI 0 "register_operand" "")
1737 (minus:TI (match_operand:TI 1 "register_operand" "")
1738 (match_operand:TI 2 "register_operand" "")))]
1741 rtx low = gen_reg_rtx (DImode);
1742 emit_insn (gen_subdi3_compare0 (low, gen_lowpart (DImode, operands[1]),
1743 gen_lowpart (DImode, operands[2])));
1745 rtx high = gen_reg_rtx (DImode);
1746 emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]),
1747 gen_highpart (DImode, operands[2])));
1749 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
1750 emit_move_insn (gen_highpart (DImode, operands[0]), high);
1754 (define_insn "sub<mode>3_compare0"
1755 [(set (reg:CC_NZ CC_REGNUM)
1756 (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1757 (match_operand:GPI 2 "register_operand" "r"))
1759 (set (match_operand:GPI 0 "register_operand" "=r")
1760 (minus:GPI (match_dup 1) (match_dup 2)))]
1762 "subs\\t%<w>0, %<w>1, %<w>2"
1763 [(set_attr "type" "alus_sreg")]
1766 ;; zero_extend version of above
1767 (define_insn "*subsi3_compare0_uxtw"
1768 [(set (reg:CC_NZ CC_REGNUM)
1769 (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1770 (match_operand:SI 2 "register_operand" "r"))
1772 (set (match_operand:DI 0 "register_operand" "=r")
1773 (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1775 "subs\\t%w0, %w1, %w2"
1776 [(set_attr "type" "alus_sreg")]
1779 (define_insn "*sub_<shift>_<mode>"
1780 [(set (match_operand:GPI 0 "register_operand" "=r")
1781 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1783 (match_operand:GPI 1 "register_operand" "r")
1784 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1786 "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1787 [(set_attr "type" "alu_shift_imm")]
1790 ;; zero_extend version of above
1791 (define_insn "*sub_<shift>_si_uxtw"
1792 [(set (match_operand:DI 0 "register_operand" "=r")
1794 (minus:SI (match_operand:SI 3 "register_operand" "r")
1796 (match_operand:SI 1 "register_operand" "r")
1797 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1799 "sub\\t%w0, %w3, %w1, <shift> %2"
1800 [(set_attr "type" "alu_shift_imm")]
1803 (define_insn "*sub_mul_imm_<mode>"
1804 [(set (match_operand:GPI 0 "register_operand" "=r")
1805 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1807 (match_operand:GPI 1 "register_operand" "r")
1808 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1810 "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1811 [(set_attr "type" "alu_shift_imm")]
1814 ;; zero_extend version of above
1815 (define_insn "*sub_mul_imm_si_uxtw"
1816 [(set (match_operand:DI 0 "register_operand" "=r")
1818 (minus:SI (match_operand:SI 3 "register_operand" "r")
1820 (match_operand:SI 1 "register_operand" "r")
1821 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
1823 "sub\\t%w0, %w3, %w1, lsl %p2"
1824 [(set_attr "type" "alu_shift_imm")]
1827 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
1828 [(set (match_operand:GPI 0 "register_operand" "=rk")
1829 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1831 (match_operand:ALLX 2 "register_operand" "r"))))]
1833 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1834 [(set_attr "type" "alu_ext")]
1837 ;; zero_extend version of above
1838 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
1839 [(set (match_operand:DI 0 "register_operand" "=rk")
1841 (minus:SI (match_operand:SI 1 "register_operand" "r")
1843 (match_operand:SHORT 2 "register_operand" "r")))))]
1845 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
1846 [(set_attr "type" "alu_ext")]
1849 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
1850 [(set (match_operand:GPI 0 "register_operand" "=rk")
1851 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1852 (ashift:GPI (ANY_EXTEND:GPI
1853 (match_operand:ALLX 2 "register_operand" "r"))
1854 (match_operand 3 "aarch64_imm3" "Ui3"))))]
1856 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1857 [(set_attr "type" "alu_ext")]
1860 ;; zero_extend version of above
1861 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
1862 [(set (match_operand:DI 0 "register_operand" "=rk")
1864 (minus:SI (match_operand:SI 1 "register_operand" "r")
1865 (ashift:SI (ANY_EXTEND:SI
1866 (match_operand:SHORT 2 "register_operand" "r"))
1867 (match_operand 3 "aarch64_imm3" "Ui3")))))]
1869 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
1870 [(set_attr "type" "alu_ext")]
1873 (define_insn "*sub_<optab><mode>_multp2"
1874 [(set (match_operand:GPI 0 "register_operand" "=rk")
1875 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1877 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1878 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1879 (match_operand 3 "const_int_operand" "n")
1881 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1882 "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1883 [(set_attr "type" "alu_ext")]
1886 ;; zero_extend version of above
1887 (define_insn "*sub_<optab>si_multp2_uxtw"
1888 [(set (match_operand:DI 0 "register_operand" "=rk")
1890 (minus:SI (match_operand:SI 4 "register_operand" "r")
1892 (mult:SI (match_operand:SI 1 "register_operand" "r")
1893 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1894 (match_operand 3 "const_int_operand" "n")
1896 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1897 "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1898 [(set_attr "type" "alu_ext")]
1901 (define_insn "sub<mode>3_carryin"
1903 (match_operand:GPI 0 "register_operand" "=r")
1904 (minus:GPI (minus:GPI
1905 (match_operand:GPI 1 "register_operand" "r")
1906 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
1907 (match_operand:GPI 2 "register_operand" "r")))]
1909 "sbc\\t%<w>0, %<w>1, %<w>2"
1910 [(set_attr "type" "adc_reg")]
1913 ;; zero_extend version of the above
1914 (define_insn "*subsi3_carryin_uxtw"
1916 (match_operand:DI 0 "register_operand" "=r")
1919 (match_operand:SI 1 "register_operand" "r")
1920 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
1921 (match_operand:SI 2 "register_operand" "r"))))]
1923 "sbc\\t%w0, %w1, %w2"
1924 [(set_attr "type" "adc_reg")]
1927 (define_insn "*sub_uxt<mode>_multp2"
1928 [(set (match_operand:GPI 0 "register_operand" "=rk")
1929 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1931 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1932 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1933 (match_operand 3 "const_int_operand" "n"))))]
1934 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1936 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1937 INTVAL (operands[3])));
1938 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1939 [(set_attr "type" "alu_ext")]
1942 ;; zero_extend version of above
1943 (define_insn "*sub_uxtsi_multp2_uxtw"
1944 [(set (match_operand:DI 0 "register_operand" "=rk")
1946 (minus:SI (match_operand:SI 4 "register_operand" "r")
1948 (mult:SI (match_operand:SI 1 "register_operand" "r")
1949 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1950 (match_operand 3 "const_int_operand" "n")))))]
1951 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1953 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1954 INTVAL (operands[3])));
1955 return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
1956 [(set_attr "type" "alu_ext")]
1959 (define_insn_and_split "absdi2"
1960 [(set (match_operand:DI 0 "register_operand" "=r,w")
1961 (abs:DI (match_operand:DI 1 "register_operand" "r,w")))
1962 (clobber (match_scratch:DI 2 "=&r,X"))]
1968 && GP_REGNUM_P (REGNO (operands[0]))
1969 && GP_REGNUM_P (REGNO (operands[1]))"
1972 emit_insn (gen_rtx_SET (VOIDmode, operands[2],
1973 gen_rtx_XOR (DImode,
1974 gen_rtx_ASHIFTRT (DImode,
1978 emit_insn (gen_rtx_SET (VOIDmode,
1980 gen_rtx_MINUS (DImode,
1982 gen_rtx_ASHIFTRT (DImode,
1987 [(set_attr "type" "alu_sreg")
1988 (set_attr "simd" "no,yes")]
1991 (define_insn "neg<mode>2"
1992 [(set (match_operand:GPI 0 "register_operand" "=r,w")
1993 (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
1997 neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
1998 [(set_attr "type" "alu_sreg, neon_neg<q>")
1999 (set_attr "simd" "*,yes")]
2002 ;; zero_extend version of above
2003 (define_insn "*negsi2_uxtw"
2004 [(set (match_operand:DI 0 "register_operand" "=r")
2005 (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
2008 [(set_attr "type" "alu_sreg")]
2011 (define_insn "*ngc<mode>"
2012 [(set (match_operand:GPI 0 "register_operand" "=r")
2013 (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2014 (match_operand:GPI 1 "register_operand" "r")))]
2016 "ngc\\t%<w>0, %<w>1"
2017 [(set_attr "type" "adc_reg")]
2020 (define_insn "*ngcsi_uxtw"
2021 [(set (match_operand:DI 0 "register_operand" "=r")
2023 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2024 (match_operand:SI 1 "register_operand" "r"))))]
2027 [(set_attr "type" "adc_reg")]
2030 (define_insn "*neg<mode>2_compare0"
2031 [(set (reg:CC_NZ CC_REGNUM)
2032 (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2034 (set (match_operand:GPI 0 "register_operand" "=r")
2035 (neg:GPI (match_dup 1)))]
2037 "negs\\t%<w>0, %<w>1"
2038 [(set_attr "type" "alus_sreg")]
2041 ;; zero_extend version of above
2042 (define_insn "*negsi2_compare0_uxtw"
2043 [(set (reg:CC_NZ CC_REGNUM)
2044 (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
2046 (set (match_operand:DI 0 "register_operand" "=r")
2047 (zero_extend:DI (neg:SI (match_dup 1))))]
2050 [(set_attr "type" "alus_sreg")]
2053 (define_insn "*neg_<shift><mode>3_compare0"
2054 [(set (reg:CC_NZ CC_REGNUM)
2056 (neg:GPI (ASHIFT:GPI
2057 (match_operand:GPI 1 "register_operand" "r")
2058 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2060 (set (match_operand:GPI 0 "register_operand" "=r")
2061 (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2063 "negs\\t%<w>0, %<w>1, <shift> %2"
2064 [(set_attr "type" "alus_shift_imm")]
2067 (define_insn "*neg_<shift>_<mode>2"
2068 [(set (match_operand:GPI 0 "register_operand" "=r")
2069 (neg:GPI (ASHIFT:GPI
2070 (match_operand:GPI 1 "register_operand" "r")
2071 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2073 "neg\\t%<w>0, %<w>1, <shift> %2"
2074 [(set_attr "type" "alu_shift_imm")]
2077 ;; zero_extend version of above
2078 (define_insn "*neg_<shift>_si2_uxtw"
2079 [(set (match_operand:DI 0 "register_operand" "=r")
2082 (match_operand:SI 1 "register_operand" "r")
2083 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2085 "neg\\t%w0, %w1, <shift> %2"
2086 [(set_attr "type" "alu_shift_imm")]
2089 (define_insn "*neg_mul_imm_<mode>2"
2090 [(set (match_operand:GPI 0 "register_operand" "=r")
2092 (match_operand:GPI 1 "register_operand" "r")
2093 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2095 "neg\\t%<w>0, %<w>1, lsl %p2"
2096 [(set_attr "type" "alu_shift_imm")]
2099 ;; zero_extend version of above
2100 (define_insn "*neg_mul_imm_si2_uxtw"
2101 [(set (match_operand:DI 0 "register_operand" "=r")
2104 (match_operand:SI 1 "register_operand" "r")
2105 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2107 "neg\\t%w0, %w1, lsl %p2"
2108 [(set_attr "type" "alu_shift_imm")]
2111 (define_insn "mul<mode>3"
2112 [(set (match_operand:GPI 0 "register_operand" "=r")
2113 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2114 (match_operand:GPI 2 "register_operand" "r")))]
2116 "mul\\t%<w>0, %<w>1, %<w>2"
2117 [(set_attr "type" "mul")]
2120 ;; zero_extend version of above
2121 (define_insn "*mulsi3_uxtw"
2122 [(set (match_operand:DI 0 "register_operand" "=r")
2124 (mult:SI (match_operand:SI 1 "register_operand" "r")
2125 (match_operand:SI 2 "register_operand" "r"))))]
2127 "mul\\t%w0, %w1, %w2"
2128 [(set_attr "type" "mul")]
2131 (define_insn "madd<mode>"
2132 [(set (match_operand:GPI 0 "register_operand" "=r")
2133 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2134 (match_operand:GPI 2 "register_operand" "r"))
2135 (match_operand:GPI 3 "register_operand" "r")))]
2137 "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2138 [(set_attr "type" "mla")]
2141 ;; zero_extend version of above
2142 (define_insn "*maddsi_uxtw"
2143 [(set (match_operand:DI 0 "register_operand" "=r")
2145 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2146 (match_operand:SI 2 "register_operand" "r"))
2147 (match_operand:SI 3 "register_operand" "r"))))]
2149 "madd\\t%w0, %w1, %w2, %w3"
2150 [(set_attr "type" "mla")]
2153 (define_insn "*msub<mode>"
2154 [(set (match_operand:GPI 0 "register_operand" "=r")
2155 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2156 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2157 (match_operand:GPI 2 "register_operand" "r"))))]
2160 "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2161 [(set_attr "type" "mla")]
2164 ;; zero_extend version of above
2165 (define_insn "*msubsi_uxtw"
2166 [(set (match_operand:DI 0 "register_operand" "=r")
2168 (minus:SI (match_operand:SI 3 "register_operand" "r")
2169 (mult:SI (match_operand:SI 1 "register_operand" "r")
2170 (match_operand:SI 2 "register_operand" "r")))))]
2173 "msub\\t%w0, %w1, %w2, %w3"
2174 [(set_attr "type" "mla")]
2177 (define_insn "*mul<mode>_neg"
2178 [(set (match_operand:GPI 0 "register_operand" "=r")
2179 (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2180 (match_operand:GPI 2 "register_operand" "r")))]
2183 "mneg\\t%<w>0, %<w>1, %<w>2"
2184 [(set_attr "type" "mul")]
2187 ;; zero_extend version of above
2188 (define_insn "*mulsi_neg_uxtw"
2189 [(set (match_operand:DI 0 "register_operand" "=r")
2191 (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2192 (match_operand:SI 2 "register_operand" "r"))))]
2195 "mneg\\t%w0, %w1, %w2"
2196 [(set_attr "type" "mul")]
2199 (define_insn "<su_optab>mulsidi3"
2200 [(set (match_operand:DI 0 "register_operand" "=r")
2201 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2202 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2204 "<su>mull\\t%0, %w1, %w2"
2205 [(set_attr "type" "<su>mull")]
2208 (define_insn "<su_optab>maddsidi4"
2209 [(set (match_operand:DI 0 "register_operand" "=r")
2211 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2212 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2213 (match_operand:DI 3 "register_operand" "r")))]
2215 "<su>maddl\\t%0, %w1, %w2, %3"
2216 [(set_attr "type" "<su>mlal")]
2219 (define_insn "<su_optab>msubsidi4"
2220 [(set (match_operand:DI 0 "register_operand" "=r")
2222 (match_operand:DI 3 "register_operand" "r")
2223 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2225 (match_operand:SI 2 "register_operand" "r")))))]
2227 "<su>msubl\\t%0, %w1, %w2, %3"
2228 [(set_attr "type" "<su>mlal")]
2231 (define_insn "*<su_optab>mulsidi_neg"
2232 [(set (match_operand:DI 0 "register_operand" "=r")
2234 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2235 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2237 "<su>mnegl\\t%0, %w1, %w2"
2238 [(set_attr "type" "<su>mull")]
2241 (define_expand "<su_optab>mulditi3"
2242 [(set (match_operand:TI 0 "register_operand")
2243 (mult:TI (ANY_EXTEND:TI (match_operand:DI 1 "register_operand"))
2244 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand"))))]
2247 rtx low = gen_reg_rtx (DImode);
2248 emit_insn (gen_muldi3 (low, operands[1], operands[2]));
2250 rtx high = gen_reg_rtx (DImode);
2251 emit_insn (gen_<su>muldi3_highpart (high, operands[1], operands[2]));
2253 emit_move_insn (gen_lowpart (DImode, operands[0]), low);
2254 emit_move_insn (gen_highpart (DImode, operands[0]), high);
2258 ;; The default expansion of multi3 using umuldi3_highpart will perform
2259 ;; the additions in an order that fails to combine into two madd insns.
2260 (define_expand "multi3"
2261 [(set (match_operand:TI 0 "register_operand")
2262 (mult:TI (match_operand:TI 1 "register_operand")
2263 (match_operand:TI 2 "register_operand")))]
2266 rtx l0 = gen_reg_rtx (DImode);
2267 rtx l1 = gen_lowpart (DImode, operands[1]);
2268 rtx l2 = gen_lowpart (DImode, operands[2]);
2269 rtx h0 = gen_reg_rtx (DImode);
2270 rtx h1 = gen_highpart (DImode, operands[1]);
2271 rtx h2 = gen_highpart (DImode, operands[2]);
2273 emit_insn (gen_muldi3 (l0, l1, l2));
2274 emit_insn (gen_umuldi3_highpart (h0, l1, l2));
2275 emit_insn (gen_madddi (h0, h1, l2, h0));
2276 emit_insn (gen_madddi (h0, l1, h2, h0));
2278 emit_move_insn (gen_lowpart (DImode, operands[0]), l0);
2279 emit_move_insn (gen_highpart (DImode, operands[0]), h0);
2283 (define_insn "<su>muldi3_highpart"
2284 [(set (match_operand:DI 0 "register_operand" "=r")
2288 (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2289 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2292 "<su>mulh\\t%0, %1, %2"
2293 [(set_attr "type" "<su>mull")]
2296 (define_insn "<su_optab>div<mode>3"
2297 [(set (match_operand:GPI 0 "register_operand" "=r")
2298 (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2299 (match_operand:GPI 2 "register_operand" "r")))]
2301 "<su>div\\t%<w>0, %<w>1, %<w>2"
2302 [(set_attr "type" "<su>div")]
2305 ;; zero_extend version of above
2306 (define_insn "*<su_optab>divsi3_uxtw"
2307 [(set (match_operand:DI 0 "register_operand" "=r")
2309 (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2310 (match_operand:SI 2 "register_operand" "r"))))]
2312 "<su>div\\t%w0, %w1, %w2"
2313 [(set_attr "type" "<su>div")]
2316 ;; -------------------------------------------------------------------
2318 ;; -------------------------------------------------------------------
2320 (define_insn "*cmp<mode>"
2321 [(set (reg:CC CC_REGNUM)
2322 (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2323 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2329 [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
2332 (define_insn "*cmp<mode>"
2333 [(set (reg:CCFP CC_REGNUM)
2334 (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2335 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2339 fcmp\\t%<s>0, %<s>1"
2340 [(set_attr "type" "fcmp<s>")]
2343 (define_insn "*cmpe<mode>"
2344 [(set (reg:CCFPE CC_REGNUM)
2345 (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2346 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2350 fcmpe\\t%<s>0, %<s>1"
2351 [(set_attr "type" "fcmp<s>")]
2354 (define_insn "*cmp_swp_<shift>_reg<mode>"
2355 [(set (reg:CC_SWP CC_REGNUM)
2356 (compare:CC_SWP (ASHIFT:GPI
2357 (match_operand:GPI 0 "register_operand" "r")
2358 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2359 (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2361 "cmp\\t%<w>2, %<w>0, <shift> %1"
2362 [(set_attr "type" "alus_shift_imm")]
2365 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2366 [(set (reg:CC_SWP CC_REGNUM)
2367 (compare:CC_SWP (ANY_EXTEND:GPI
2368 (match_operand:ALLX 0 "register_operand" "r"))
2369 (match_operand:GPI 1 "register_operand" "r")))]
2371 "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2372 [(set_attr "type" "alus_ext")]
2375 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2376 [(set (reg:CC_SWP CC_REGNUM)
2377 (compare:CC_SWP (ashift:GPI
2379 (match_operand:ALLX 0 "register_operand" "r"))
2380 (match_operand 1 "aarch64_imm3" "Ui3"))
2381 (match_operand:GPI 2 "register_operand" "r")))]
2383 "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2384 [(set_attr "type" "alus_ext")]
2387 ;; -------------------------------------------------------------------
2388 ;; Store-flag and conditional select insns
2389 ;; -------------------------------------------------------------------
2391 (define_expand "cstore<mode>4"
2392 [(set (match_operand:SI 0 "register_operand" "")
2393 (match_operator:SI 1 "aarch64_comparison_operator"
2394 [(match_operand:GPI 2 "register_operand" "")
2395 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2398 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2400 operands[3] = const0_rtx;
2404 (define_expand "cstore<mode>4"
2405 [(set (match_operand:SI 0 "register_operand" "")
2406 (match_operator:SI 1 "aarch64_comparison_operator"
2407 [(match_operand:GPF 2 "register_operand" "")
2408 (match_operand:GPF 3 "register_operand" "")]))]
2411 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2413 operands[3] = const0_rtx;
2417 (define_insn "*cstore<mode>_insn"
2418 [(set (match_operand:ALLI 0 "register_operand" "=r")
2419 (match_operator:ALLI 1 "aarch64_comparison_operator"
2420 [(match_operand 2 "cc_register" "") (const_int 0)]))]
2423 [(set_attr "type" "csel")]
2426 ;; zero_extend version of the above
2427 (define_insn "*cstoresi_insn_uxtw"
2428 [(set (match_operand:DI 0 "register_operand" "=r")
2430 (match_operator:SI 1 "aarch64_comparison_operator"
2431 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2434 [(set_attr "type" "csel")]
2437 (define_insn "cstore<mode>_neg"
2438 [(set (match_operand:ALLI 0 "register_operand" "=r")
2439 (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2440 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2442 "csetm\\t%<w>0, %m1"
2443 [(set_attr "type" "csel")]
2446 ;; zero_extend version of the above
2447 (define_insn "*cstoresi_neg_uxtw"
2448 [(set (match_operand:DI 0 "register_operand" "=r")
2450 (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2451 [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2454 [(set_attr "type" "csel")]
2457 (define_expand "cmov<mode>6"
2458 [(set (match_operand:GPI 0 "register_operand" "")
2460 (match_operator 1 "aarch64_comparison_operator"
2461 [(match_operand:GPI 2 "register_operand" "")
2462 (match_operand:GPI 3 "aarch64_plus_operand" "")])
2463 (match_operand:GPI 4 "register_operand" "")
2464 (match_operand:GPI 5 "register_operand" "")))]
2467 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2469 operands[3] = const0_rtx;
2473 (define_expand "cmov<mode>6"
2474 [(set (match_operand:GPF 0 "register_operand" "")
2476 (match_operator 1 "aarch64_comparison_operator"
2477 [(match_operand:GPF 2 "register_operand" "")
2478 (match_operand:GPF 3 "register_operand" "")])
2479 (match_operand:GPF 4 "register_operand" "")
2480 (match_operand:GPF 5 "register_operand" "")))]
2483 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2485 operands[3] = const0_rtx;
2489 (define_insn "*cmov<mode>_insn"
2490 [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2492 (match_operator 1 "aarch64_comparison_operator"
2493 [(match_operand 2 "cc_register" "") (const_int 0)])
2494 (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2495 (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2496 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2497 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2498 ;; Final two alternatives should be unreachable, but included for completeness
2500 csel\\t%<w>0, %<w>3, %<w>4, %m1
2501 csinv\\t%<w>0, %<w>3, <w>zr, %m1
2502 csinv\\t%<w>0, %<w>4, <w>zr, %M1
2503 csinc\\t%<w>0, %<w>3, <w>zr, %m1
2504 csinc\\t%<w>0, %<w>4, <w>zr, %M1
2507 [(set_attr "type" "csel")]
2510 ;; zero_extend version of above
2511 (define_insn "*cmovsi_insn_uxtw"
2512 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2515 (match_operator 1 "aarch64_comparison_operator"
2516 [(match_operand 2 "cc_register" "") (const_int 0)])
2517 (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2518 (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2519 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2520 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2521 ;; Final two alternatives should be unreachable, but included for completeness
2523 csel\\t%w0, %w3, %w4, %m1
2524 csinv\\t%w0, %w3, wzr, %m1
2525 csinv\\t%w0, %w4, wzr, %M1
2526 csinc\\t%w0, %w3, wzr, %m1
2527 csinc\\t%w0, %w4, wzr, %M1
2530 [(set_attr "type" "csel")]
2533 (define_insn "*cmov<mode>_insn"
2534 [(set (match_operand:GPF 0 "register_operand" "=w")
2536 (match_operator 1 "aarch64_comparison_operator"
2537 [(match_operand 2 "cc_register" "") (const_int 0)])
2538 (match_operand:GPF 3 "register_operand" "w")
2539 (match_operand:GPF 4 "register_operand" "w")))]
2541 "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2542 [(set_attr "type" "fcsel")]
2545 (define_expand "mov<mode>cc"
2546 [(set (match_operand:ALLI 0 "register_operand" "")
2547 (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2548 (match_operand:ALLI 2 "register_operand" "")
2549 (match_operand:ALLI 3 "register_operand" "")))]
2553 enum rtx_code code = GET_CODE (operands[1]);
2555 if (code == UNEQ || code == LTGT)
2558 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2559 XEXP (operands[1], 1));
2560 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2564 (define_expand "mov<GPF:mode><GPI:mode>cc"
2565 [(set (match_operand:GPI 0 "register_operand" "")
2566 (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2567 (match_operand:GPF 2 "register_operand" "")
2568 (match_operand:GPF 3 "register_operand" "")))]
2572 enum rtx_code code = GET_CODE (operands[1]);
2574 if (code == UNEQ || code == LTGT)
2577 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2578 XEXP (operands[1], 1));
2579 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2583 (define_expand "mov<mode>cc"
2584 [(set (match_operand:GPF 0 "register_operand" "")
2585 (if_then_else:GPF (match_operand 1 "aarch64_comparison_operator" "")
2586 (match_operand:GPF 2 "register_operand" "")
2587 (match_operand:GPF 3 "register_operand" "")))]
2591 enum rtx_code code = GET_CODE (operands[1]);
2593 if (code == UNEQ || code == LTGT)
2596 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2597 XEXP (operands[1], 1));
2598 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2603 ;; CRC32 instructions.
2604 (define_insn "aarch64_<crc_variant>"
2605 [(set (match_operand:SI 0 "register_operand" "=r")
2606 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2607 (match_operand:<crc_mode> 2 "register_operand" "r")]
2611 if (GET_MODE_BITSIZE (GET_MODE (operands[2])) >= 64)
2612 return "<crc_variant>\\t%w0, %w1, %x2";
2614 return "<crc_variant>\\t%w0, %w1, %w2";
2616 [(set_attr "type" "crc")]
2619 (define_insn "*csinc2<mode>_insn"
2620 [(set (match_operand:GPI 0 "register_operand" "=r")
2621 (plus:GPI (match_operand 2 "aarch64_comparison_operation" "")
2622 (match_operand:GPI 1 "register_operand" "r")))]
2624 "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2625 [(set_attr "type" "csel")]
2628 (define_insn "csinc3<mode>_insn"
2629 [(set (match_operand:GPI 0 "register_operand" "=r")
2631 (match_operand 1 "aarch64_comparison_operation" "")
2632 (plus:GPI (match_operand:GPI 2 "register_operand" "r")
2634 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2636 "csinc\\t%<w>0, %<w>3, %<w>2, %M1"
2637 [(set_attr "type" "csel")]
2640 (define_insn "*csinv3<mode>_insn"
2641 [(set (match_operand:GPI 0 "register_operand" "=r")
2643 (match_operand 1 "aarch64_comparison_operation" "")
2644 (not:GPI (match_operand:GPI 2 "register_operand" "r"))
2645 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2647 "csinv\\t%<w>0, %<w>3, %<w>2, %M1"
2648 [(set_attr "type" "csel")]
2651 (define_insn "*csneg3<mode>_insn"
2652 [(set (match_operand:GPI 0 "register_operand" "=r")
2654 (match_operand 1 "aarch64_comparison_operation" "")
2655 (neg:GPI (match_operand:GPI 2 "register_operand" "r"))
2656 (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
2658 "csneg\\t%<w>0, %<w>3, %<w>2, %M1"
2659 [(set_attr "type" "csel")]
2662 ;; -------------------------------------------------------------------
2663 ;; Logical operations
2664 ;; -------------------------------------------------------------------
2666 (define_insn "<optab><mode>3"
2667 [(set (match_operand:GPI 0 "register_operand" "=r,rk")
2668 (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2669 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
2671 "<logical>\\t%<w>0, %<w>1, %<w>2"
2672 [(set_attr "type" "logic_reg,logic_imm")]
2675 ;; zero_extend version of above
2676 (define_insn "*<optab>si3_uxtw"
2677 [(set (match_operand:DI 0 "register_operand" "=r,rk")
2679 (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2680 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2682 "<logical>\\t%w0, %w1, %w2"
2683 [(set_attr "type" "logic_reg,logic_imm")]
2686 (define_insn "*and<mode>3_compare0"
2687 [(set (reg:CC_NZ CC_REGNUM)
2689 (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2690 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2692 (set (match_operand:GPI 0 "register_operand" "=r,r")
2693 (and:GPI (match_dup 1) (match_dup 2)))]
2695 "ands\\t%<w>0, %<w>1, %<w>2"
2696 [(set_attr "type" "logics_reg,logics_imm")]
2699 ;; zero_extend version of above
2700 (define_insn "*andsi3_compare0_uxtw"
2701 [(set (reg:CC_NZ CC_REGNUM)
2703 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2704 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2706 (set (match_operand:DI 0 "register_operand" "=r,r")
2707 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2709 "ands\\t%w0, %w1, %w2"
2710 [(set_attr "type" "logics_reg,logics_imm")]
2713 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2714 [(set (reg:CC_NZ CC_REGNUM)
2717 (match_operand:GPI 1 "register_operand" "r")
2718 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2719 (match_operand:GPI 3 "register_operand" "r"))
2721 (set (match_operand:GPI 0 "register_operand" "=r")
2722 (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2724 "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2725 [(set_attr "type" "logics_shift_imm")]
2728 ;; zero_extend version of above
2729 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2730 [(set (reg:CC_NZ CC_REGNUM)
2733 (match_operand:SI 1 "register_operand" "r")
2734 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2735 (match_operand:SI 3 "register_operand" "r"))
2737 (set (match_operand:DI 0 "register_operand" "=r")
2738 (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2741 "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2742 [(set_attr "type" "logics_shift_imm")]
2745 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2746 [(set (match_operand:GPI 0 "register_operand" "=r")
2747 (LOGICAL:GPI (SHIFT:GPI
2748 (match_operand:GPI 1 "register_operand" "r")
2749 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2750 (match_operand:GPI 3 "register_operand" "r")))]
2752 "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2753 [(set_attr "type" "logic_shift_imm")]
2756 (define_insn "*<optab>_rol<mode>3"
2757 [(set (match_operand:GPI 0 "register_operand" "=r")
2758 (LOGICAL:GPI (rotate:GPI
2759 (match_operand:GPI 1 "register_operand" "r")
2760 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2761 (match_operand:GPI 3 "register_operand" "r")))]
2763 "<logical>\\t%<w>0, %<w>3, %<w>1, ror (<sizen> - %2)"
2764 [(set_attr "type" "logic_shift_imm")]
2767 ;; zero_extend versions of above
2768 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
2769 [(set (match_operand:DI 0 "register_operand" "=r")
2771 (LOGICAL:SI (SHIFT:SI
2772 (match_operand:SI 1 "register_operand" "r")
2773 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2774 (match_operand:SI 3 "register_operand" "r"))))]
2776 "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2777 [(set_attr "type" "logic_shift_imm")]
2780 (define_insn "*<optab>_rolsi3_uxtw"
2781 [(set (match_operand:DI 0 "register_operand" "=r")
2783 (LOGICAL:SI (rotate:SI
2784 (match_operand:SI 1 "register_operand" "r")
2785 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2786 (match_operand:SI 3 "register_operand" "r"))))]
2788 "<logical>\\t%w0, %w3, %w1, ror (32 - %2)"
2789 [(set_attr "type" "logic_shift_imm")]
2792 (define_insn "one_cmpl<mode>2"
2793 [(set (match_operand:GPI 0 "register_operand" "=r")
2794 (not:GPI (match_operand:GPI 1 "register_operand" "r")))]
2796 "mvn\\t%<w>0, %<w>1"
2797 [(set_attr "type" "logic_reg")]
2800 (define_insn "*one_cmpl_<optab><mode>2"
2801 [(set (match_operand:GPI 0 "register_operand" "=r")
2802 (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
2803 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2805 "mvn\\t%<w>0, %<w>1, <shift> %2"
2806 [(set_attr "type" "logic_shift_imm")]
2809 (define_insn "*<LOGICAL:optab>_one_cmpl<mode>3"
2810 [(set (match_operand:GPI 0 "register_operand" "=r")
2811 (LOGICAL:GPI (not:GPI
2812 (match_operand:GPI 1 "register_operand" "r"))
2813 (match_operand:GPI 2 "register_operand" "r")))]
2815 "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1"
2816 [(set_attr "type" "logic_reg")]
2819 (define_insn "*and_one_cmpl<mode>3_compare0"
2820 [(set (reg:CC_NZ CC_REGNUM)
2823 (match_operand:GPI 1 "register_operand" "r"))
2824 (match_operand:GPI 2 "register_operand" "r"))
2826 (set (match_operand:GPI 0 "register_operand" "=r")
2827 (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
2829 "bics\\t%<w>0, %<w>2, %<w>1"
2830 [(set_attr "type" "logics_reg")]
2833 ;; zero_extend version of above
2834 (define_insn "*and_one_cmplsi3_compare0_uxtw"
2835 [(set (reg:CC_NZ CC_REGNUM)
2838 (match_operand:SI 1 "register_operand" "r"))
2839 (match_operand:SI 2 "register_operand" "r"))
2841 (set (match_operand:DI 0 "register_operand" "=r")
2842 (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
2844 "bics\\t%w0, %w2, %w1"
2845 [(set_attr "type" "logics_reg")]
2848 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
2849 [(set (match_operand:GPI 0 "register_operand" "=r")
2850 (LOGICAL:GPI (not:GPI
2852 (match_operand:GPI 1 "register_operand" "r")
2853 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2854 (match_operand:GPI 3 "register_operand" "r")))]
2856 "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2857 [(set_attr "type" "logics_shift_imm")]
2860 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
2861 [(set (reg:CC_NZ CC_REGNUM)
2865 (match_operand:GPI 1 "register_operand" "r")
2866 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2867 (match_operand:GPI 3 "register_operand" "r"))
2869 (set (match_operand:GPI 0 "register_operand" "=r")
2872 (match_dup 1) (match_dup 2))) (match_dup 3)))]
2874 "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2875 [(set_attr "type" "logics_shift_imm")]
2878 ;; zero_extend version of above
2879 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
2880 [(set (reg:CC_NZ CC_REGNUM)
2884 (match_operand:SI 1 "register_operand" "r")
2885 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
2886 (match_operand:SI 3 "register_operand" "r"))
2888 (set (match_operand:DI 0 "register_operand" "=r")
2889 (zero_extend:DI (and:SI
2891 (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
2893 "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2894 [(set_attr "type" "logics_shift_imm")]
2897 (define_insn "clz<mode>2"
2898 [(set (match_operand:GPI 0 "register_operand" "=r")
2899 (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
2901 "clz\\t%<w>0, %<w>1"
2902 [(set_attr "type" "clz")]
2905 (define_expand "ffs<mode>2"
2906 [(match_operand:GPI 0 "register_operand")
2907 (match_operand:GPI 1 "register_operand")]
2910 rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
2911 rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
2913 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2914 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2915 emit_insn (gen_csinc3<mode>_insn (operands[0], x, operands[0], const0_rtx));
2920 (define_insn "clrsb<mode>2"
2921 [(set (match_operand:GPI 0 "register_operand" "=r")
2922 (clrsb:GPI (match_operand:GPI 1 "register_operand" "r")))]
2924 "cls\\t%<w>0, %<w>1"
2925 [(set_attr "type" "clz")]
2928 (define_insn "rbit<mode>2"
2929 [(set (match_operand:GPI 0 "register_operand" "=r")
2930 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
2932 "rbit\\t%<w>0, %<w>1"
2933 [(set_attr "type" "rbit")]
2936 (define_expand "ctz<mode>2"
2937 [(match_operand:GPI 0 "register_operand")
2938 (match_operand:GPI 1 "register_operand")]
2941 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2942 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2947 (define_insn "*and<mode>3nr_compare0"
2948 [(set (reg:CC_NZ CC_REGNUM)
2950 (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
2951 (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
2954 "tst\\t%<w>0, %<w>1"
2955 [(set_attr "type" "logics_reg")]
2958 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
2959 [(set (reg:CC_NZ CC_REGNUM)
2962 (match_operand:GPI 0 "register_operand" "r")
2963 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2964 (match_operand:GPI 2 "register_operand" "r"))
2967 "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
2968 [(set_attr "type" "logics_shift_imm")]
2971 ;; -------------------------------------------------------------------
2973 ;; -------------------------------------------------------------------
2975 (define_expand "<optab><mode>3"
2976 [(set (match_operand:GPI 0 "register_operand")
2977 (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
2978 (match_operand:QI 2 "nonmemory_operand")))]
2981 if (CONST_INT_P (operands[2]))
2983 operands[2] = GEN_INT (INTVAL (operands[2])
2984 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2986 if (operands[2] == const0_rtx)
2988 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2995 (define_expand "ashl<mode>3"
2996 [(set (match_operand:SHORT 0 "register_operand")
2997 (ashift:SHORT (match_operand:SHORT 1 "register_operand")
2998 (match_operand:QI 2 "nonmemory_operand")))]
3001 if (CONST_INT_P (operands[2]))
3003 operands[2] = GEN_INT (INTVAL (operands[2])
3004 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3006 if (operands[2] == const0_rtx)
3008 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3015 (define_expand "rotr<mode>3"
3016 [(set (match_operand:GPI 0 "register_operand")
3017 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3018 (match_operand:QI 2 "nonmemory_operand")))]
3021 if (CONST_INT_P (operands[2]))
3023 operands[2] = GEN_INT (INTVAL (operands[2])
3024 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3026 if (operands[2] == const0_rtx)
3028 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3035 (define_expand "rotl<mode>3"
3036 [(set (match_operand:GPI 0 "register_operand")
3037 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3038 (match_operand:QI 2 "nonmemory_operand")))]
3041 /* (SZ - cnt) % SZ == -cnt % SZ */
3042 if (CONST_INT_P (operands[2]))
3044 operands[2] = GEN_INT ((-INTVAL (operands[2]))
3045 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3046 if (operands[2] == const0_rtx)
3048 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3053 operands[2] = expand_simple_unop (QImode, NEG, operands[2],
3058 ;; Logical left shift using SISD or Integer instruction
3059 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
3060 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3062 (match_operand:GPI 1 "register_operand" "w,w,r")
3063 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3066 shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3067 ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
3068 lsl\t%<w>0, %<w>1, %<w>2"
3069 [(set_attr "simd" "yes,yes,no")
3070 (set_attr "type" "neon_shift_imm<q>, neon_shift_reg<q>,shift_reg")]
3073 ;; Logical right shift using SISD or Integer instruction
3074 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3075 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3077 (match_operand:GPI 1 "register_operand" "w,w,r")
3078 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3081 ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3083 lsr\t%<w>0, %<w>1, %<w>2"
3084 [(set_attr "simd" "yes,yes,no")
3085 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,shift_reg")]
3089 [(set (match_operand:DI 0 "aarch64_simd_register")
3091 (match_operand:DI 1 "aarch64_simd_register")
3092 (match_operand:QI 2 "aarch64_simd_register")))]
3093 "TARGET_SIMD && reload_completed"
3095 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3097 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_USHL))]
3102 [(set (match_operand:SI 0 "aarch64_simd_register")
3104 (match_operand:SI 1 "aarch64_simd_register")
3105 (match_operand:QI 2 "aarch64_simd_register")))]
3106 "TARGET_SIMD && reload_completed"
3108 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3110 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_USHL_2S))]
3114 ;; Arithmetic right shift using SISD or Integer instruction
3115 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3116 [(set (match_operand:GPI 0 "register_operand" "=w,&w,&w,r")
3118 (match_operand:GPI 1 "register_operand" "w,w,w,r")
3119 (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,0,rUs<cmode>")))]
3122 sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3125 asr\t%<w>0, %<w>1, %<w>2"
3126 [(set_attr "simd" "yes,yes,yes,no")
3127 (set_attr "type" "neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>,shift_reg")]
3131 [(set (match_operand:DI 0 "aarch64_simd_register")
3133 (match_operand:DI 1 "aarch64_simd_register")
3134 (match_operand:QI 2 "aarch64_simd_register")))]
3135 "TARGET_SIMD && reload_completed"
3137 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3139 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_SISD_SSHL))]
3141 operands[3] = gen_lowpart (QImode, operands[0]);
3146 [(set (match_operand:SI 0 "aarch64_simd_register")
3148 (match_operand:SI 1 "aarch64_simd_register")
3149 (match_operand:QI 2 "aarch64_simd_register")))]
3150 "TARGET_SIMD && reload_completed"
3152 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3154 (unspec:SI [(match_dup 1) (match_dup 3)] UNSPEC_SSHL_2S))]
3156 operands[3] = gen_lowpart (QImode, operands[0]);
3160 (define_insn "*aarch64_sisd_ushl"
3161 [(set (match_operand:DI 0 "register_operand" "=w")
3162 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3163 (match_operand:QI 2 "register_operand" "w")]
3166 "ushl\t%d0, %d1, %d2"
3167 [(set_attr "simd" "yes")
3168 (set_attr "type" "neon_shift_reg")]
3171 (define_insn "*aarch64_ushl_2s"
3172 [(set (match_operand:SI 0 "register_operand" "=w")
3173 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3174 (match_operand:QI 2 "register_operand" "w")]
3177 "ushl\t%0.2s, %1.2s, %2.2s"
3178 [(set_attr "simd" "yes")
3179 (set_attr "type" "neon_shift_reg")]
3182 (define_insn "*aarch64_sisd_sshl"
3183 [(set (match_operand:DI 0 "register_operand" "=w")
3184 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3185 (match_operand:QI 2 "register_operand" "w")]
3188 "sshl\t%d0, %d1, %d2"
3189 [(set_attr "simd" "yes")
3190 (set_attr "type" "neon_shift_reg")]
3193 (define_insn "*aarch64_sshl_2s"
3194 [(set (match_operand:SI 0 "register_operand" "=w")
3195 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3196 (match_operand:QI 2 "register_operand" "w")]
3199 "sshl\t%0.2s, %1.2s, %2.2s"
3200 [(set_attr "simd" "yes")
3201 (set_attr "type" "neon_shift_reg")]
3204 (define_insn "*aarch64_sisd_neg_qi"
3205 [(set (match_operand:QI 0 "register_operand" "=w")
3206 (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3210 [(set_attr "simd" "yes")
3211 (set_attr "type" "neon_neg")]
3215 (define_insn "*ror<mode>3_insn"
3216 [(set (match_operand:GPI 0 "register_operand" "=r")
3218 (match_operand:GPI 1 "register_operand" "r")
3219 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3221 "ror\\t%<w>0, %<w>1, %<w>2"
3222 [(set_attr "type" "shift_reg")]
3225 ;; zero_extend version of above
3226 (define_insn "*<optab>si3_insn_uxtw"
3227 [(set (match_operand:DI 0 "register_operand" "=r")
3228 (zero_extend:DI (SHIFT:SI
3229 (match_operand:SI 1 "register_operand" "r")
3230 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3232 "<shift>\\t%w0, %w1, %w2"
3233 [(set_attr "type" "shift_reg")]
3236 (define_insn "*ashl<mode>3_insn"
3237 [(set (match_operand:SHORT 0 "register_operand" "=r")
3238 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3239 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
3241 "lsl\\t%<w>0, %<w>1, %<w>2"
3242 [(set_attr "type" "shift_reg")]
3245 (define_insn "*<optab><mode>3_insn"
3246 [(set (match_operand:SHORT 0 "register_operand" "=r")
3247 (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3248 (match_operand 2 "const_int_operand" "n")))]
3249 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3251 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3252 return "<bfshift>\t%w0, %w1, %2, %3";
3254 [(set_attr "type" "bfm")]
3257 (define_insn "*extr<mode>5_insn"
3258 [(set (match_operand:GPI 0 "register_operand" "=r")
3259 (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3260 (match_operand 3 "const_int_operand" "n"))
3261 (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3262 (match_operand 4 "const_int_operand" "n"))))]
3263 "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3264 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3265 "extr\\t%<w>0, %<w>1, %<w>2, %4"
3266 [(set_attr "type" "shift_imm")]
3269 ;; zero_extend version of the above
3270 (define_insn "*extrsi5_insn_uxtw"
3271 [(set (match_operand:DI 0 "register_operand" "=r")
3273 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3274 (match_operand 3 "const_int_operand" "n"))
3275 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3276 (match_operand 4 "const_int_operand" "n")))))]
3277 "UINTVAL (operands[3]) < 32 &&
3278 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3279 "extr\\t%w0, %w1, %w2, %4"
3280 [(set_attr "type" "shift_imm")]
3283 (define_insn "*ror<mode>3_insn"
3284 [(set (match_operand:GPI 0 "register_operand" "=r")
3285 (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3286 (match_operand 2 "const_int_operand" "n")))]
3287 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3289 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3290 return "ror\\t%<w>0, %<w>1, %3";
3292 [(set_attr "type" "shift_imm")]
3295 ;; zero_extend version of the above
3296 (define_insn "*rorsi3_insn_uxtw"
3297 [(set (match_operand:DI 0 "register_operand" "=r")
3299 (rotate:SI (match_operand:SI 1 "register_operand" "r")
3300 (match_operand 2 "const_int_operand" "n"))))]
3301 "UINTVAL (operands[2]) < 32"
3303 operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3304 return "ror\\t%w0, %w1, %3";
3306 [(set_attr "type" "shift_imm")]
3309 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3310 [(set (match_operand:GPI 0 "register_operand" "=r")
3312 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3313 (match_operand 2 "const_int_operand" "n"))))]
3314 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3316 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3317 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3319 [(set_attr "type" "bfm")]
3322 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3323 [(set (match_operand:GPI 0 "register_operand" "=r")
3325 (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3326 (match_operand 2 "const_int_operand" "n"))))]
3327 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3329 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3330 return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3332 [(set_attr "type" "bfm")]
3335 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3336 [(set (match_operand:GPI 0 "register_operand" "=r")
3338 (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3339 (match_operand 2 "const_int_operand" "n"))))]
3340 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3342 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3343 return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3345 [(set_attr "type" "bfm")]
3348 ;; -------------------------------------------------------------------
3350 ;; -------------------------------------------------------------------
3352 (define_expand "<optab>"
3353 [(set (match_operand:DI 0 "register_operand" "=r")
3354 (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3355 (match_operand 2 "const_int_operand" "n")
3356 (match_operand 3 "const_int_operand" "n")))]
3361 (define_insn "*<optab><mode>"
3362 [(set (match_operand:GPI 0 "register_operand" "=r")
3363 (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3364 (match_operand 2 "const_int_operand" "n")
3365 (match_operand 3 "const_int_operand" "n")))]
3367 "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3368 [(set_attr "type" "bfm")]
3371 ;; Bitfield Insert (insv)
3372 (define_expand "insv<mode>"
3373 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3374 (match_operand 1 "const_int_operand")
3375 (match_operand 2 "const_int_operand"))
3376 (match_operand:GPI 3 "general_operand"))]
3379 unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3380 unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3381 rtx value = operands[3];
3383 if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3386 if (CONST_INT_P (value))
3388 unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3390 /* Prefer AND/OR for inserting all zeros or all ones. */
3391 if ((UINTVAL (value) & mask) == 0
3392 || (UINTVAL (value) & mask) == mask)
3395 /* 16-bit aligned 16-bit wide insert is handled by insv_imm. */
3396 if (width == 16 && (pos % 16) == 0)
3399 operands[3] = force_reg (<MODE>mode, value);
3402 (define_insn "*insv_reg<mode>"
3403 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3404 (match_operand 1 "const_int_operand" "n")
3405 (match_operand 2 "const_int_operand" "n"))
3406 (match_operand:GPI 3 "register_operand" "r"))]
3407 "!(UINTVAL (operands[1]) == 0
3408 || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3409 > GET_MODE_BITSIZE (<MODE>mode)))"
3410 "bfi\\t%<w>0, %<w>3, %2, %1"
3411 [(set_attr "type" "bfm")]
3414 (define_insn "*extr_insv_lower_reg<mode>"
3415 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3416 (match_operand 1 "const_int_operand" "n")
3418 (zero_extract:GPI (match_operand:GPI 2 "register_operand" "r")
3420 (match_operand 3 "const_int_operand" "n")))]
3421 "!(UINTVAL (operands[1]) == 0
3422 || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3423 > GET_MODE_BITSIZE (<MODE>mode)))"
3424 "bfxil\\t%<w>0, %<w>2, %3, %1"
3425 [(set_attr "type" "bfm")]
3428 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3429 [(set (match_operand:GPI 0 "register_operand" "=r")
3430 (ashift:GPI (ANY_EXTEND:GPI
3431 (match_operand:ALLX 1 "register_operand" "r"))
3432 (match_operand 2 "const_int_operand" "n")))]
3433 "UINTVAL (operands[2]) < <GPI:sizen>"
3435 operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3436 ? GEN_INT (<ALLX:sizen>)
3437 : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3438 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3440 [(set_attr "type" "bfm")]
3443 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3445 (define_insn "*andim_ashift<mode>_bfiz"
3446 [(set (match_operand:GPI 0 "register_operand" "=r")
3447 (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3448 (match_operand 2 "const_int_operand" "n"))
3449 (match_operand 3 "const_int_operand" "n")))]
3450 "(INTVAL (operands[2]) < (<GPI:sizen>))
3451 && exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3452 && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3453 "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3454 [(set_attr "type" "bfm")]
3457 (define_insn "bswap<mode>2"
3458 [(set (match_operand:GPI 0 "register_operand" "=r")
3459 (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3461 "rev\\t%<w>0, %<w>1"
3462 [(set_attr "type" "rev")]
3465 (define_insn "bswaphi2"
3466 [(set (match_operand:HI 0 "register_operand" "=r")
3467 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3470 [(set_attr "type" "rev")]
3473 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
3474 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
3475 ;; each valid permutation.
3477 (define_insn "rev16<mode>2"
3478 [(set (match_operand:GPI 0 "register_operand" "=r")
3479 (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3481 (match_operand:GPI 3 "const_int_operand" "n"))
3482 (and:GPI (lshiftrt:GPI (match_dup 1)
3484 (match_operand:GPI 2 "const_int_operand" "n"))))]
3485 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3486 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3487 "rev16\\t%<w>0, %<w>1"
3488 [(set_attr "type" "rev")]
3491 (define_insn "rev16<mode>2_alt"
3492 [(set (match_operand:GPI 0 "register_operand" "=r")
3493 (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r")
3495 (match_operand:GPI 2 "const_int_operand" "n"))
3496 (and:GPI (ashift:GPI (match_dup 1)
3498 (match_operand:GPI 3 "const_int_operand" "n"))))]
3499 "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode)
3500 && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)"
3501 "rev16\\t%<w>0, %<w>1"
3502 [(set_attr "type" "rev")]
3505 ;; zero_extend version of above
3506 (define_insn "*bswapsi2_uxtw"
3507 [(set (match_operand:DI 0 "register_operand" "=r")
3508 (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3511 [(set_attr "type" "rev")]
3514 ;; -------------------------------------------------------------------
3515 ;; Floating-point intrinsics
3516 ;; -------------------------------------------------------------------
3518 ;; frint floating-point round to integral standard patterns.
3519 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round, frintn.
3521 (define_insn "<frint_pattern><mode>2"
3522 [(set (match_operand:GPF 0 "register_operand" "=w")
3523 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3526 "frint<frint_suffix>\\t%<s>0, %<s>1"
3527 [(set_attr "type" "f_rint<s>")]
3530 ;; frcvt floating-point round to integer and convert standard patterns.
3531 ;; Expands to lbtrunc, lceil, lfloor, lround.
3532 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3533 [(set (match_operand:GPI 0 "register_operand" "=r")
3534 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3537 "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3538 [(set_attr "type" "f_cvtf2i")]
3543 (define_insn "fma<mode>4"
3544 [(set (match_operand:GPF 0 "register_operand" "=w")
3545 (fma: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 "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3550 [(set_attr "type" "fmac<s>")]
3553 (define_insn "fnma<mode>4"
3554 [(set (match_operand:GPF 0 "register_operand" "=w")
3555 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3556 (match_operand:GPF 2 "register_operand" "w")
3557 (match_operand:GPF 3 "register_operand" "w")))]
3559 "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3560 [(set_attr "type" "fmac<s>")]
3563 (define_insn "fms<mode>4"
3564 [(set (match_operand:GPF 0 "register_operand" "=w")
3565 (fma: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 "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3570 [(set_attr "type" "fmac<s>")]
3573 (define_insn "fnms<mode>4"
3574 [(set (match_operand:GPF 0 "register_operand" "=w")
3575 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3576 (match_operand:GPF 2 "register_operand" "w")
3577 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3579 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3580 [(set_attr "type" "fmac<s>")]
3583 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3584 (define_insn "*fnmadd<mode>4"
3585 [(set (match_operand:GPF 0 "register_operand" "=w")
3586 (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3587 (match_operand:GPF 2 "register_operand" "w")
3588 (match_operand:GPF 3 "register_operand" "w"))))]
3589 "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3590 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3591 [(set_attr "type" "fmac<s>")]
3594 ;; -------------------------------------------------------------------
3595 ;; Floating-point conversions
3596 ;; -------------------------------------------------------------------
3598 (define_insn "extendsfdf2"
3599 [(set (match_operand:DF 0 "register_operand" "=w")
3600 (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3603 [(set_attr "type" "f_cvt")]
3606 (define_insn "truncdfsf2"
3607 [(set (match_operand:SF 0 "register_operand" "=w")
3608 (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3611 [(set_attr "type" "f_cvt")]
3614 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3615 [(set (match_operand:GPI 0 "register_operand" "=r")
3616 (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3618 "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3619 [(set_attr "type" "f_cvtf2i")]
3622 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3623 [(set (match_operand:GPI 0 "register_operand" "=r")
3624 (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3626 "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3627 [(set_attr "type" "f_cvtf2i")]
3630 (define_insn "<optab><fcvt_target><GPF:mode>2"
3631 [(set (match_operand:GPF 0 "register_operand" "=w,w")
3632 (FLOATUORS:GPF (match_operand:<FCVT_TARGET> 1 "register_operand" "w,r")))]
3635 <su_optab>cvtf\t%<GPF:s>0, %<s>1
3636 <su_optab>cvtf\t%<GPF:s>0, %<w1>1"
3637 [(set_attr "simd" "yes,no")
3638 (set_attr "fp" "no,yes")
3639 (set_attr "type" "neon_int_to_fp_<Vetype>,f_cvti2f")]
3642 (define_insn "<optab><fcvt_iesize><GPF:mode>2"
3643 [(set (match_operand:GPF 0 "register_operand" "=w")
3644 (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand" "r")))]
3646 "<su_optab>cvtf\t%<GPF:s>0, %<w2>1"
3647 [(set_attr "type" "f_cvti2f")]
3650 ;; -------------------------------------------------------------------
3651 ;; Floating-point arithmetic
3652 ;; -------------------------------------------------------------------
3654 (define_insn "add<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 "fadd\\t%<s>0, %<s>1, %<s>2"
3661 [(set_attr "type" "fadd<s>")]
3664 (define_insn "sub<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 "fsub\\t%<s>0, %<s>1, %<s>2"
3671 [(set_attr "type" "fadd<s>")]
3674 (define_insn "mul<mode>3"
3675 [(set (match_operand:GPF 0 "register_operand" "=w")
3677 (match_operand:GPF 1 "register_operand" "w")
3678 (match_operand:GPF 2 "register_operand" "w")))]
3680 "fmul\\t%<s>0, %<s>1, %<s>2"
3681 [(set_attr "type" "fmul<s>")]
3684 (define_insn "*fnmul<mode>3"
3685 [(set (match_operand:GPF 0 "register_operand" "=w")
3687 (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3688 (match_operand:GPF 2 "register_operand" "w")))]
3690 "fnmul\\t%<s>0, %<s>1, %<s>2"
3691 [(set_attr "type" "fmul<s>")]
3694 (define_insn "div<mode>3"
3695 [(set (match_operand:GPF 0 "register_operand" "=w")
3697 (match_operand:GPF 1 "register_operand" "w")
3698 (match_operand:GPF 2 "register_operand" "w")))]
3700 "fdiv\\t%<s>0, %<s>1, %<s>2"
3701 [(set_attr "type" "fdiv<s>")]
3704 (define_insn "neg<mode>2"
3705 [(set (match_operand:GPF 0 "register_operand" "=w")
3706 (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
3708 "fneg\\t%<s>0, %<s>1"
3709 [(set_attr "type" "ffarith<s>")]
3712 (define_insn "sqrt<mode>2"
3713 [(set (match_operand:GPF 0 "register_operand" "=w")
3714 (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
3716 "fsqrt\\t%<s>0, %<s>1"
3717 [(set_attr "type" "fsqrt<s>")]
3720 (define_insn "abs<mode>2"
3721 [(set (match_operand:GPF 0 "register_operand" "=w")
3722 (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
3724 "fabs\\t%<s>0, %<s>1"
3725 [(set_attr "type" "ffarith<s>")]
3728 ;; Given that smax/smin do not specify the result when either input is NaN,
3729 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
3732 (define_insn "smax<mode>3"
3733 [(set (match_operand:GPF 0 "register_operand" "=w")
3734 (smax:GPF (match_operand:GPF 1 "register_operand" "w")
3735 (match_operand:GPF 2 "register_operand" "w")))]
3737 "fmaxnm\\t%<s>0, %<s>1, %<s>2"
3738 [(set_attr "type" "f_minmax<s>")]
3741 (define_insn "smin<mode>3"
3742 [(set (match_operand:GPF 0 "register_operand" "=w")
3743 (smin:GPF (match_operand:GPF 1 "register_operand" "w")
3744 (match_operand:GPF 2 "register_operand" "w")))]
3746 "fminnm\\t%<s>0, %<s>1, %<s>2"
3747 [(set_attr "type" "f_minmax<s>")]
3750 ;; -------------------------------------------------------------------
3752 ;; -------------------------------------------------------------------
3754 (define_expand "aarch64_reload_mov<mode>"
3755 [(set (match_operand:TX 0 "register_operand" "=w")
3756 (match_operand:TX 1 "register_operand" "w"))
3757 (clobber (match_operand:DI 2 "register_operand" "=&r"))
3761 rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
3762 rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
3763 gen_aarch64_movtilow_tilow (op0, op1);
3764 gen_aarch64_movdi_tihigh (operands[2], op1);
3765 gen_aarch64_movtihigh_di (op0, operands[2]);
3770 ;; The following secondary reload helpers patterns are invoked
3771 ;; after or during reload as we don't want these patterns to start
3772 ;; kicking in during the combiner.
3774 (define_insn "aarch64_movdi_<mode>low"
3775 [(set (match_operand:DI 0 "register_operand" "=r")
3776 (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
3777 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
3779 [(set_attr "type" "f_mrc")
3780 (set_attr "length" "4")
3783 (define_insn "aarch64_movdi_<mode>high"
3784 [(set (match_operand:DI 0 "register_operand" "=r")
3786 (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
3788 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
3789 "fmov\\t%x0, %1.d[1]"
3790 [(set_attr "type" "f_mrc")
3791 (set_attr "length" "4")
3794 (define_insn "aarch64_mov<mode>high_di"
3795 [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
3796 (const_int 64) (const_int 64))
3797 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
3798 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
3799 "fmov\\t%0.d[1], %x1"
3800 [(set_attr "type" "f_mcr")
3801 (set_attr "length" "4")
3804 (define_insn "aarch64_mov<mode>low_di"
3805 [(set (match_operand:TX 0 "register_operand" "=w")
3806 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
3807 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
3809 [(set_attr "type" "f_mcr")
3810 (set_attr "length" "4")
3813 (define_insn "aarch64_movtilow_tilow"
3814 [(set (match_operand:TI 0 "register_operand" "=w")
3816 (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
3817 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
3819 [(set_attr "type" "fmov")
3820 (set_attr "length" "4")
3823 ;; There is a deliberate reason why the parameters of high and lo_sum's
3824 ;; don't have modes for ADRP and ADD instructions. This is to allow high
3825 ;; and lo_sum's to be used with the labels defining the jump tables in
3828 (define_expand "add_losym"
3829 [(set (match_operand 0 "register_operand" "=r")
3830 (lo_sum (match_operand 1 "register_operand" "r")
3831 (match_operand 2 "aarch64_valid_symref" "S")))]
3834 machine_mode mode = GET_MODE (operands[0]);
3836 emit_insn ((mode == DImode
3838 : gen_add_losym_si) (operands[0],
3844 (define_insn "add_losym_<mode>"
3845 [(set (match_operand:P 0 "register_operand" "=r")
3846 (lo_sum:P (match_operand:P 1 "register_operand" "r")
3847 (match_operand 2 "aarch64_valid_symref" "S")))]
3849 "add\\t%<w>0, %<w>1, :lo12:%a2"
3850 [(set_attr "type" "alu_imm")]
3853 (define_insn "ldr_got_small_<mode>"
3854 [(set (match_operand:PTR 0 "register_operand" "=r")
3855 (unspec:PTR [(mem:PTR (lo_sum:PTR
3856 (match_operand:PTR 1 "register_operand" "r")
3857 (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
3858 UNSPEC_GOTSMALLPIC))]
3860 "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
3861 [(set_attr "type" "load1")]
3864 (define_insn "ldr_got_small_sidi"
3865 [(set (match_operand:DI 0 "register_operand" "=r")
3867 (unspec:SI [(mem:SI (lo_sum:DI
3868 (match_operand:DI 1 "register_operand" "r")
3869 (match_operand:DI 2 "aarch64_valid_symref" "S")))]
3870 UNSPEC_GOTSMALLPIC)))]
3872 "ldr\\t%w0, [%1, #:got_lo12:%a2]"
3873 [(set_attr "type" "load1")]
3876 (define_insn "ldr_got_tiny"
3877 [(set (match_operand:DI 0 "register_operand" "=r")
3878 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
3879 UNSPEC_GOTTINYPIC))]
3882 [(set_attr "type" "load1")]
3885 (define_insn "aarch64_load_tp_hard"
3886 [(set (match_operand:DI 0 "register_operand" "=r")
3887 (unspec:DI [(const_int 0)] UNSPEC_TLS))]
3889 "mrs\\t%0, tpidr_el0"
3890 [(set_attr "type" "mrs")]
3893 ;; The TLS ABI specifically requires that the compiler does not schedule
3894 ;; instructions in the TLS stubs, in order to enable linker relaxation.
3895 ;; Therefore we treat the stubs as an atomic sequence.
3896 (define_expand "tlsgd_small"
3897 [(parallel [(set (match_operand 0 "register_operand" "")
3898 (call (mem:DI (match_dup 2)) (const_int 1)))
3899 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
3900 (clobber (reg:DI LR_REGNUM))])]
3903 operands[2] = aarch64_tls_get_addr ();
3906 (define_insn "*tlsgd_small"
3907 [(set (match_operand 0 "register_operand" "")
3908 (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
3909 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
3910 (clobber (reg:DI LR_REGNUM))
3913 "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
3914 [(set_attr "type" "call")
3915 (set_attr "length" "16")])
3917 (define_insn "tlsie_small_<mode>"
3918 [(set (match_operand:PTR 0 "register_operand" "=r")
3919 (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
3920 UNSPEC_GOTSMALLTLS))]
3922 "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
3923 [(set_attr "type" "load1")
3924 (set_attr "length" "8")]
3927 (define_insn "tlsie_small_sidi"
3928 [(set (match_operand:DI 0 "register_operand" "=r")
3930 (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")]
3931 UNSPEC_GOTSMALLTLS)))]
3933 "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
3934 [(set_attr "type" "load1")
3935 (set_attr "length" "8")]
3938 (define_expand "tlsle_small"
3939 [(set (match_operand 0 "register_operand" "=r")
3940 (unspec [(match_operand 1 "register_operand" "r")
3941 (match_operand 2 "aarch64_tls_le_symref" "S")]
3942 UNSPEC_GOTSMALLTLS))]
3945 machine_mode mode = GET_MODE (operands[0]);
3946 emit_insn ((mode == DImode
3947 ? gen_tlsle_small_di
3948 : gen_tlsle_small_si) (operands[0],
3954 (define_insn "tlsle_small_<mode>"
3955 [(set (match_operand:P 0 "register_operand" "=r")
3956 (unspec:P [(match_operand:P 1 "register_operand" "r")
3957 (match_operand 2 "aarch64_tls_le_symref" "S")]
3958 UNSPEC_GOTSMALLTLS))]
3960 "add\\t%<w>0, %<w>1, #%G2\;add\\t%<w>0, %<w>0, #%L2"
3961 [(set_attr "type" "alu_sreg")
3962 (set_attr "length" "8")]
3965 (define_insn "tlsdesc_small_<mode>"
3966 [(set (reg:PTR R0_REGNUM)
3967 (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
3969 (clobber (reg:DI LR_REGNUM))
3970 (clobber (reg:CC CC_REGNUM))
3971 (clobber (match_scratch:DI 1 "=r"))]
3973 "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
3974 [(set_attr "type" "call")
3975 (set_attr "length" "16")])
3977 (define_insn "stack_tie"
3978 [(set (mem:BLK (scratch))
3979 (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
3980 (match_operand:DI 1 "register_operand" "rk")]
3984 [(set_attr "length" "0")]
3987 ;; Named pattern for expanding thread pointer reference.
3988 (define_expand "get_thread_pointerdi"
3989 [(match_operand:DI 0 "register_operand" "=r")]
3992 rtx tmp = aarch64_load_tp (operands[0]);
3993 if (tmp != operands[0])
3994 emit_move_insn (operands[0], tmp);
3998 ;; Named patterns for stack smashing protection.
3999 (define_expand "stack_protect_set"
4000 [(match_operand 0 "memory_operand")
4001 (match_operand 1 "memory_operand")]
4004 machine_mode mode = GET_MODE (operands[0]);
4006 emit_insn ((mode == DImode
4007 ? gen_stack_protect_set_di
4008 : gen_stack_protect_set_si) (operands[0], operands[1]));
4012 (define_insn "stack_protect_set_<mode>"
4013 [(set (match_operand:PTR 0 "memory_operand" "=m")
4014 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
4016 (set (match_scratch:PTR 2 "=&r") (const_int 0))]
4018 "ldr\\t%<w>2, %1\;str\\t%<w>2, %0\;mov\t%<w>2,0"
4019 [(set_attr "length" "12")
4020 (set_attr "type" "multiple")])
4022 (define_expand "stack_protect_test"
4023 [(match_operand 0 "memory_operand")
4024 (match_operand 1 "memory_operand")
4029 machine_mode mode = GET_MODE (operands[0]);
4031 result = gen_reg_rtx(mode);
4033 emit_insn ((mode == DImode
4034 ? gen_stack_protect_test_di
4035 : gen_stack_protect_test_si) (result,
4040 emit_jump_insn (gen_cbranchdi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4041 result, const0_rtx, operands[2]));
4043 emit_jump_insn (gen_cbranchsi4 (gen_rtx_EQ (VOIDmode, result, const0_rtx),
4044 result, const0_rtx, operands[2]));
4048 (define_insn "stack_protect_test_<mode>"
4049 [(set (match_operand:PTR 0 "register_operand" "=r")
4050 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")
4051 (match_operand:PTR 2 "memory_operand" "m")]
4053 (clobber (match_scratch:PTR 3 "=&r"))]
4055 "ldr\t%<w>3, %x1\;ldr\t%<w>0, %x2\;eor\t%<w>0, %<w>3, %<w>0"
4056 [(set_attr "length" "12")
4057 (set_attr "type" "multiple")])
4059 ;; Write Floating-point Control Register.
4060 (define_insn "set_fpcr"
4061 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
4064 [(set_attr "type" "mrs")])
4066 ;; Read Floating-point Control Register.
4067 (define_insn "get_fpcr"
4068 [(set (match_operand:SI 0 "register_operand" "=r")
4069 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
4072 [(set_attr "type" "mrs")])
4074 ;; Write Floating-point Status Register.
4075 (define_insn "set_fpsr"
4076 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
4079 [(set_attr "type" "mrs")])
4081 ;; Read Floating-point Status Register.
4082 (define_insn "get_fpsr"
4083 [(set (match_operand:SI 0 "register_operand" "=r")
4084 (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
4087 [(set_attr "type" "mrs")])
4091 (include "aarch64-simd.md")
4093 ;; Atomic Operations
4094 (include "atomics.md")