1 ;; Machine description for AArch64 architecture.
2 ;; Copyright (C) 2009, 2010, 2011, 2012 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" [
94 (define_c_enum "unspecv" [
95 UNSPECV_EH_RETURN ; Represent EH_RETURN
99 ;; If further include files are added the defintion of MD_INCLUDES
102 (include "constraints.md")
103 (include "predicates.md")
104 (include "iterators.md")
106 ;; -------------------------------------------------------------------
107 ;; Instruction types and attributes
108 ;; -------------------------------------------------------------------
110 ;; Main data types used by the insntructions
112 (define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
113 (const_string "unknown"))
115 (define_attr "mode2" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
116 (const_string "unknown"))
118 ; The "v8type" attribute is used to for fine grained classification of
119 ; AArch64 instructions. This table briefly explains the meaning of each type.
121 ; adc add/subtract with carry.
122 ; adcs add/subtract with carry (setting condition flags).
123 ; adr calculate address.
124 ; alu simple alu instruction (no memory or fp regs access).
125 ; alu_ext simple alu instruction (sign/zero-extended register).
126 ; alu_shift simple alu instruction, with a source operand shifted by a constant.
127 ; alus simple alu instruction (setting condition flags).
128 ; alus_ext simple alu instruction (sign/zero-extended register, setting condition flags).
129 ; alus_shift simple alu instruction, with a source operand shifted by a constant (setting condition flags).
130 ; bfm bitfield move operation.
132 ; call subroutine call.
133 ; ccmp conditional compare.
134 ; clz count leading zeros/sign bits.
135 ; csel conditional select.
136 ; dmb data memory barrier.
137 ; extend sign/zero-extend (specialised bitfield move).
138 ; extr extract register-sized bitfield encoding.
139 ; fpsimd_load load single floating point / simd scalar register from memory.
140 ; fpsimd_load2 load pair of floating point / simd scalar registers from memory.
141 ; fpsimd_store store single floating point / simd scalar register to memory.
142 ; fpsimd_store2 store pair floating point / simd scalar registers to memory.
143 ; fadd floating point add/sub.
144 ; fccmp floating point conditional compare.
145 ; fcmp floating point comparison.
146 ; fconst floating point load immediate.
147 ; fcsel floating point conditional select.
148 ; fcvt floating point convert (float to float).
149 ; fcvtf2i floating point convert (float to integer).
150 ; fcvti2f floating point convert (integer to float).
151 ; fdiv floating point division operation.
152 ; ffarith floating point abs, neg or cpy.
153 ; fmadd floating point multiply-add/sub.
154 ; fminmax floating point min/max.
155 ; fmov floating point move (float to float).
156 ; fmovf2i floating point move (float to integer).
157 ; fmovi2f floating point move (integer to float).
158 ; fmul floating point multiply.
159 ; frint floating point round to integral.
160 ; fsqrt floating point square root.
161 ; load_acq load-acquire.
162 ; load load single general register from memory
163 ; load2 load pair of general registers from memory
164 ; logic logical operation (register).
165 ; logic_imm and/or/xor operation (immediate).
166 ; logic_shift logical operation with shift.
167 ; logics logical operation (register, setting condition flags).
168 ; logics_imm and/or/xor operation (immediate, setting condition flags).
169 ; logics_shift logical operation with shift (setting condition flags).
170 ; madd integer multiply-add/sub.
171 ; maddl widening integer multiply-add/sub.
172 ; misc miscellaneous - any type that doesn't fit into the rest.
173 ; move integer move operation.
174 ; move2 double integer move operation.
175 ; movk move 16-bit immediate with keep.
176 ; movz move 16-bit immmediate with zero/one.
177 ; mrs system/special register move.
178 ; mulh 64x64 to 128-bit multiply (high part).
179 ; mull widening multiply.
180 ; mult integer multiply instruction.
181 ; prefetch memory prefetch.
184 ; sdiv integer division operation (signed).
185 ; shift variable shift operation.
186 ; shift_imm immediate shift operation (specialised bitfield move).
187 ; store_rel store-release.
188 ; store store single general register to memory.
189 ; store2 store pair of general registers to memory.
190 ; udiv integer division operation (unsigned).
192 (define_attr "v8type"
265 (const_string "alu"))
268 ; The "type" attribute is used by the AArch32 backend. Below is a mapping
269 ; from "v8type" to "type".
272 "alu,alu_shift,block,branch,call,f_2_r,f_cvt,f_flag,f_loads,
273 f_loadd,f_stored,f_stores,faddd,fadds,fcmpd,fcmps,fconstd,fconsts,
274 fcpys,fdivd,fdivs,ffarithd,ffariths,fmacd,fmacs,fmuld,fmuls,load_byte,
275 load1,load2,mult,r_2_f,store1,store2"
277 (eq_attr "v8type" "alu_shift,alus_shift,logic_shift,logics_shift") (const_string "alu_shift")
278 (eq_attr "v8type" "branch") (const_string "branch")
279 (eq_attr "v8type" "call") (const_string "call")
280 (eq_attr "v8type" "fmovf2i") (const_string "f_2_r")
281 (eq_attr "v8type" "fcvt,fcvtf2i,fcvti2f") (const_string "f_cvt")
282 (and (eq_attr "v8type" "fpsimd_load") (eq_attr "mode" "SF")) (const_string "f_loads")
283 (and (eq_attr "v8type" "fpsimd_load") (eq_attr "mode" "DF")) (const_string "f_loadd")
284 (and (eq_attr "v8type" "fpsimd_store") (eq_attr "mode" "SF")) (const_string "f_stores")
285 (and (eq_attr "v8type" "fpsimd_store") (eq_attr "mode" "DF")) (const_string "f_stored")
286 (and (eq_attr "v8type" "fadd,fminmax") (eq_attr "mode" "DF")) (const_string "faddd")
287 (and (eq_attr "v8type" "fadd,fminmax") (eq_attr "mode" "SF")) (const_string "fadds")
288 (and (eq_attr "v8type" "fcmp,fccmp") (eq_attr "mode" "DF")) (const_string "fcmpd")
289 (and (eq_attr "v8type" "fcmp,fccmp") (eq_attr "mode" "SF")) (const_string "fcmps")
290 (and (eq_attr "v8type" "fconst") (eq_attr "mode" "DF")) (const_string "fconstd")
291 (and (eq_attr "v8type" "fconst") (eq_attr "mode" "SF")) (const_string "fconsts")
292 (and (eq_attr "v8type" "fdiv,fsqrt") (eq_attr "mode" "DF")) (const_string "fdivd")
293 (and (eq_attr "v8type" "fdiv,fsqrt") (eq_attr "mode" "SF")) (const_string "fdivs")
294 (and (eq_attr "v8type" "ffarith") (eq_attr "mode" "DF")) (const_string "ffarithd")
295 (and (eq_attr "v8type" "ffarith") (eq_attr "mode" "SF")) (const_string "ffariths")
296 (and (eq_attr "v8type" "fmadd") (eq_attr "mode" "DF")) (const_string "fmacd")
297 (and (eq_attr "v8type" "fmadd") (eq_attr "mode" "SF")) (const_string "fmacs")
298 (and (eq_attr "v8type" "fmul") (eq_attr "mode" "DF")) (const_string "fmuld")
299 (and (eq_attr "v8type" "fmul") (eq_attr "mode" "SF")) (const_string "fmuls")
300 (and (eq_attr "v8type" "load1") (eq_attr "mode" "QI,HI")) (const_string "load_byte")
301 (and (eq_attr "v8type" "load1") (eq_attr "mode" "SI,DI,TI")) (const_string "load1")
302 (eq_attr "v8type" "load2") (const_string "load2")
303 (and (eq_attr "v8type" "mulh,mult,mull,madd,sdiv,udiv") (eq_attr "mode" "SI")) (const_string "mult")
304 (eq_attr "v8type" "fmovi2f") (const_string "r_2_f")
305 (eq_attr "v8type" "store1") (const_string "store1")
306 (eq_attr "v8type" "store2") (const_string "store2")
308 (const_string "alu")))
310 ;; Attribute that specifies whether or not the instruction touches fp
312 (define_attr "fp" "no,yes" (const_string "no"))
314 ;; Attribute that specifies whether or not the instruction touches simd
316 (define_attr "simd" "no,yes" (const_string "no"))
318 (define_attr "length" ""
321 ;; Attribute that controls whether an alternative is enabled or not.
322 ;; Currently it is only used to disable alternatives which touch fp or simd
323 ;; registers when -mgeneral-regs-only is specified.
324 (define_attr "enabled" "no,yes"
326 (and (eq_attr "fp" "yes")
327 (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
328 (and (eq_attr "simd" "yes")
329 (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
331 ] (const_string "yes")))
333 ;; -------------------------------------------------------------------
334 ;; Pipeline descriptions and scheduling
335 ;; -------------------------------------------------------------------
338 (include "aarch64-tune.md")
341 (include "aarch64-generic.md")
345 ;; -------------------------------------------------------------------
346 ;; Jumps and other miscellaneous insns
347 ;; -------------------------------------------------------------------
349 (define_insn "indirect_jump"
350 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
353 [(set_attr "v8type" "branch")]
357 [(set (pc) (label_ref (match_operand 0 "" "")))]
360 [(set_attr "v8type" "branch")]
363 (define_expand "cbranch<mode>4"
364 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
365 [(match_operand:GPI 1 "register_operand" "")
366 (match_operand:GPI 2 "aarch64_plus_operand" "")])
367 (label_ref (match_operand 3 "" ""))
371 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
373 operands[2] = const0_rtx;
377 (define_expand "cbranch<mode>4"
378 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
379 [(match_operand:GPF 1 "register_operand" "")
380 (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
381 (label_ref (match_operand 3 "" ""))
385 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
387 operands[2] = const0_rtx;
391 (define_insn "*condjump"
392 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
393 [(match_operand 1 "cc_register" "") (const_int 0)])
394 (label_ref (match_operand 2 "" ""))
398 [(set_attr "v8type" "branch")]
401 (define_expand "casesi"
402 [(match_operand:SI 0 "register_operand" "") ; Index
403 (match_operand:SI 1 "const_int_operand" "") ; Lower bound
404 (match_operand:SI 2 "const_int_operand" "") ; Total range
405 (match_operand:DI 3 "" "") ; Table label
406 (match_operand:DI 4 "" "")] ; Out of range label
409 if (operands[1] != const0_rtx)
411 rtx reg = gen_reg_rtx (SImode);
413 /* Canonical RTL says that if you have:
417 then this should be emitted as:
421 The use of trunc_int_for_mode ensures that the resulting
422 constant can be represented in SImode, this is important
423 for the corner case where operand[1] is INT_MIN. */
425 operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
427 if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
428 (operands[1], SImode))
429 operands[1] = force_reg (SImode, operands[1]);
430 emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
434 if (!aarch64_plus_operand (operands[2], SImode))
435 operands[2] = force_reg (SImode, operands[2]);
436 emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
438 operands[0], operands[2], operands[4]));
440 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
441 emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
447 (define_insn "casesi_dispatch"
450 (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
451 (match_operand:SI 1 "register_operand" "r")]
453 (clobber (reg:CC CC_REGNUM))
454 (clobber (match_scratch:DI 3 "=r"))
455 (clobber (match_scratch:DI 4 "=r"))
456 (use (label_ref (match_operand 2 "" "")))])]
459 return aarch64_output_casesi (operands);
461 [(set_attr "length" "16")
462 (set_attr "v8type" "branch")]
466 [(unspec[(const_int 0)] UNSPEC_NOP)]
469 [(set_attr "v8type" "misc")]
472 (define_expand "prologue"
473 [(clobber (const_int 0))]
476 aarch64_expand_prologue ();
481 (define_expand "epilogue"
482 [(clobber (const_int 0))]
485 aarch64_expand_epilogue (false);
490 (define_expand "sibcall_epilogue"
491 [(clobber (const_int 0))]
494 aarch64_expand_epilogue (true);
499 (define_insn "*do_return"
503 [(set_attr "v8type" "branch")]
506 (define_insn "eh_return"
507 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
511 [(set_attr "v8type" "branch")]
515 [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
518 [(set (match_dup 1) (match_dup 0))]
520 operands[1] = aarch64_final_eh_return_addr ();
524 (define_insn "*cb<optab><mode>1"
525 [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
527 (label_ref (match_operand 1 "" ""))
531 [(set_attr "v8type" "branch")]
534 (define_insn "*tb<optab><mode>1"
535 [(set (pc) (if_then_else
536 (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
538 (match_operand 1 "const_int_operand" "n"))
540 (label_ref (match_operand 2 "" ""))
542 (clobber (match_scratch:DI 3 "=r"))]
545 if (get_attr_length (insn) == 8)
546 return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
547 return \"<tbz>\\t%<w>0, %1, %l2\";
549 [(set_attr "v8type" "branch")
550 (set_attr "mode" "<MODE>")
552 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
553 (lt (minus (match_dup 2) (pc)) (const_int 32764)))
558 (define_insn "*cb<optab><mode>1"
559 [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
561 (label_ref (match_operand 1 "" ""))
563 (clobber (match_scratch:DI 2 "=r"))]
566 if (get_attr_length (insn) == 8)
567 return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
568 return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
570 [(set_attr "v8type" "branch")
571 (set_attr "mode" "<MODE>")
573 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
574 (lt (minus (match_dup 1) (pc)) (const_int 32764)))
579 ;; -------------------------------------------------------------------
580 ;; Subroutine calls and sibcalls
581 ;; -------------------------------------------------------------------
583 (define_expand "call"
584 [(parallel [(call (match_operand 0 "memory_operand" "")
585 (match_operand 1 "general_operand" ""))
586 (use (match_operand 2 "" ""))
587 (clobber (reg:DI LR_REGNUM))])]
593 /* In an untyped call, we can get NULL for operand 2. */
594 if (operands[2] == NULL)
595 operands[2] = const0_rtx;
597 /* Decide if we should generate indirect calls by loading the
598 64-bit address of the callee into a register before performing
599 the branch-and-link. */
600 callee = XEXP (operands[0], 0);
601 if (GET_CODE (callee) == SYMBOL_REF
602 ? aarch64_is_long_call_p (callee)
604 XEXP (operands[0], 0) = force_reg (Pmode, callee);
608 (define_insn "*call_reg"
609 [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
610 (match_operand 1 "" ""))
611 (use (match_operand 2 "" ""))
612 (clobber (reg:DI LR_REGNUM))]
615 [(set_attr "v8type" "call")]
618 (define_insn "*call_symbol"
619 [(call (mem:DI (match_operand:DI 0 "" ""))
620 (match_operand 1 "" ""))
621 (use (match_operand 2 "" ""))
622 (clobber (reg:DI LR_REGNUM))]
623 "GET_CODE (operands[0]) == SYMBOL_REF
624 && !aarch64_is_long_call_p (operands[0])"
626 [(set_attr "v8type" "call")]
629 (define_expand "call_value"
630 [(parallel [(set (match_operand 0 "" "")
631 (call (match_operand 1 "memory_operand" "")
632 (match_operand 2 "general_operand" "")))
633 (use (match_operand 3 "" ""))
634 (clobber (reg:DI LR_REGNUM))])]
640 /* In an untyped call, we can get NULL for operand 3. */
641 if (operands[3] == NULL)
642 operands[3] = const0_rtx;
644 /* Decide if we should generate indirect calls by loading the
645 64-bit address of the callee into a register before performing
646 the branch-and-link. */
647 callee = XEXP (operands[1], 0);
648 if (GET_CODE (callee) == SYMBOL_REF
649 ? aarch64_is_long_call_p (callee)
651 XEXP (operands[1], 0) = force_reg (Pmode, callee);
655 (define_insn "*call_value_reg"
656 [(set (match_operand 0 "" "")
657 (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
658 (match_operand 2 "" "")))
659 (use (match_operand 3 "" ""))
660 (clobber (reg:DI LR_REGNUM))]
663 [(set_attr "v8type" "call")]
666 (define_insn "*call_value_symbol"
667 [(set (match_operand 0 "" "")
668 (call (mem:DI (match_operand:DI 1 "" ""))
669 (match_operand 2 "" "")))
670 (use (match_operand 3 "" ""))
671 (clobber (reg:DI LR_REGNUM))]
672 "GET_CODE (operands[1]) == SYMBOL_REF
673 && !aarch64_is_long_call_p (operands[1])"
675 [(set_attr "v8type" "call")]
678 (define_expand "sibcall"
679 [(parallel [(call (match_operand 0 "memory_operand" "")
680 (match_operand 1 "general_operand" ""))
682 (use (match_operand 2 "" ""))])]
685 if (operands[2] == NULL_RTX)
686 operands[2] = const0_rtx;
690 (define_expand "sibcall_value"
691 [(parallel [(set (match_operand 0 "" "")
692 (call (match_operand 1 "memory_operand" "")
693 (match_operand 2 "general_operand" "")))
695 (use (match_operand 3 "" ""))])]
698 if (operands[3] == NULL_RTX)
699 operands[3] = const0_rtx;
703 (define_insn "*sibcall_insn"
704 [(call (mem:DI (match_operand:DI 0 "" "X"))
705 (match_operand 1 "" ""))
707 (use (match_operand 2 "" ""))]
708 "GET_CODE (operands[0]) == SYMBOL_REF"
710 [(set_attr "v8type" "branch")]
713 (define_insn "*sibcall_value_insn"
714 [(set (match_operand 0 "" "")
715 (call (mem:DI (match_operand 1 "" "X"))
716 (match_operand 2 "" "")))
718 (use (match_operand 3 "" ""))]
719 "GET_CODE (operands[1]) == SYMBOL_REF"
721 [(set_attr "v8type" "branch")]
724 ;; Call subroutine returning any type.
726 (define_expand "untyped_call"
727 [(parallel [(call (match_operand 0 "")
730 (match_operand 2 "")])]
735 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
737 for (i = 0; i < XVECLEN (operands[2], 0); i++)
739 rtx set = XVECEXP (operands[2], 0, i);
740 emit_move_insn (SET_DEST (set), SET_SRC (set));
743 /* The optimizer does not know that the call sets the function value
744 registers we stored in the result block. We avoid problems by
745 claiming that all hard registers are used and clobbered at this
747 emit_insn (gen_blockage ());
751 ;; -------------------------------------------------------------------
753 ;; -------------------------------------------------------------------
755 (define_expand "mov<mode>"
756 [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
757 (match_operand:SHORT 1 "general_operand" ""))]
760 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
761 operands[1] = force_reg (<MODE>mode, operands[1]);
765 (define_insn "*mov<mode>_aarch64"
766 [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r,r,m, r,*w")
767 (match_operand:SHORT 1 "general_operand" " r,M,m,rZ,*w,r"))]
768 "(register_operand (operands[0], <MODE>mode)
769 || aarch64_reg_or_zero (operands[1], <MODE>mode))"
775 umov\\t%w0, %1.<v>[0]
776 dup\\t%0.<Vallxd>, %w1"
777 [(set_attr "v8type" "move,alu,load1,store1,*,*")
778 (set_attr "simd_type" "*,*,*,*,simd_movgp,simd_dupgp")
779 (set_attr "mode" "<MODE>")
780 (set_attr "simd_mode" "<MODE>")]
783 (define_expand "mov<mode>"
784 [(set (match_operand:GPI 0 "nonimmediate_operand" "")
785 (match_operand:GPI 1 "general_operand" ""))]
788 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
789 operands[1] = force_reg (<MODE>mode, operands[1]);
791 if (CONSTANT_P (operands[1]))
793 aarch64_expand_mov_immediate (operands[0], operands[1]);
799 (define_insn "*movsi_aarch64"
800 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m, *w, r,*w")
801 (match_operand:SI 1 "aarch64_mov_operand" " r,M,m,rZ,rZ,*w,*w"))]
802 "(register_operand (operands[0], SImode)
803 || aarch64_reg_or_zero (operands[1], SImode))"
812 [(set_attr "v8type" "move,alu,load1,store1,fmov,fmov,fmov")
813 (set_attr "mode" "SI")
814 (set_attr "fp" "*,*,*,*,yes,yes,yes")]
817 (define_insn "*movdi_aarch64"
818 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,m, r, r, *w, r,*w,w")
819 (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,m,rZ,Usa,Ush,rZ,*w,*w,Dd"))]
820 "(register_operand (operands[0], DImode)
821 || aarch64_reg_or_zero (operands[1], DImode))"
835 [(set_attr "v8type" "move,move,move,alu,load1,store1,adr,adr,fmov,fmov,fmov,fmov")
836 (set_attr "mode" "DI")
837 (set_attr "fp" "*,*,*,*,*,*,*,*,yes,yes,yes,yes")]
840 (define_insn "insv_imm<mode>"
841 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
843 (match_operand 1 "const_int_operand" "n"))
844 (match_operand 2 "const_int_operand" "n"))]
845 "INTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
846 && INTVAL (operands[1]) % 16 == 0
847 && INTVAL (operands[2]) <= 0xffff"
848 "movk\\t%<w>0, %2, lsl %1"
849 [(set_attr "v8type" "movk")
850 (set_attr "mode" "<MODE>")]
853 (define_expand "movti"
854 [(set (match_operand:TI 0 "nonimmediate_operand" "")
855 (match_operand:TI 1 "general_operand" ""))]
858 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
859 operands[1] = force_reg (TImode, operands[1]);
863 (define_insn "*movti_aarch64"
864 [(set (match_operand:TI 0
865 "nonimmediate_operand" "=r, *w,r ,*w,r ,Ump,Ump,*w,m")
867 "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r ,Z , m,*w"))]
868 "(register_operand (operands[0], TImode)
869 || aarch64_reg_or_zero (operands[1], TImode))"
874 orr\\t%0.16b, %1.16b, %1.16b
880 [(set_attr "v8type" "move2,fmovi2f,fmovf2i,*, \
881 load2,store2,store2,fpsimd_load,fpsimd_store")
882 (set_attr "simd_type" "*,*,*,simd_move,*,*,*,*,*")
883 (set_attr "mode" "DI,DI,DI,TI,DI,DI,DI,TI,TI")
884 (set_attr "length" "8,8,8,4,4,4,4,4,4")
885 (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")
886 (set_attr "simd" "*,*,*,yes,*,*,*,*,*")])
888 ;; Split a TImode register-register or register-immediate move into
889 ;; its component DImode pieces, taking care to handle overlapping
890 ;; source and dest registers.
892 [(set (match_operand:TI 0 "register_operand" "")
893 (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
894 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
897 aarch64_split_128bit_move (operands[0], operands[1]);
901 (define_expand "mov<mode>"
902 [(set (match_operand:GPF 0 "nonimmediate_operand" "")
903 (match_operand:GPF 1 "general_operand" ""))]
908 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
912 if (GET_CODE (operands[0]) == MEM)
913 operands[1] = force_reg (<MODE>mode, operands[1]);
917 (define_insn "*movsf_aarch64"
918 [(set (match_operand:SF 0 "nonimmediate_operand" "= w,?r,w,w,m,r,m ,r")
919 (match_operand:SF 1 "general_operand" "?rY, w,w,m,w,m,rY,r"))]
920 "TARGET_FLOAT && (register_operand (operands[0], SFmode)
921 || register_operand (operands[1], SFmode))"
931 [(set_attr "v8type" "fmovi2f,fmovf2i,fmov,fpsimd_load,fpsimd_store,fpsimd_load,fpsimd_store,fmov")
932 (set_attr "mode" "SF")]
935 (define_insn "*movdf_aarch64"
936 [(set (match_operand:DF 0 "nonimmediate_operand" "= w,?r,w,w,m,r,m ,r")
937 (match_operand:DF 1 "general_operand" "?rY, w,w,m,w,m,rY,r"))]
938 "TARGET_FLOAT && (register_operand (operands[0], DFmode)
939 || register_operand (operands[1], DFmode))"
949 [(set_attr "v8type" "fmovi2f,fmovf2i,fmov,fpsimd_load,fpsimd_store,fpsimd_load,fpsimd_store,move")
950 (set_attr "mode" "DF")]
953 (define_expand "movtf"
954 [(set (match_operand:TF 0 "nonimmediate_operand" "")
955 (match_operand:TF 1 "general_operand" ""))]
960 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
964 if (GET_CODE (operands[0]) == MEM)
965 operands[1] = force_reg (TFmode, operands[1]);
969 (define_insn "*movtf_aarch64"
970 [(set (match_operand:TF 0
971 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
973 "general_operand" " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
974 "TARGET_FLOAT && (register_operand (operands[0], TFmode)
975 || register_operand (operands[1], TFmode))"
977 orr\\t%0.16b, %1.16b, %1.16b
978 mov\\t%0, %1\;mov\\t%H0, %H1
979 fmov\\t%d0, %Q1\;fmov\\t%0.d[1], %R1
980 fmov\\t%Q0, %d1\;fmov\\t%R0, %1.d[1]
987 [(set_attr "v8type" "logic,move2,fmovi2f,fmovf2i,fconst,fconst,fpsimd_load,fpsimd_store,fpsimd_load2,fpsimd_store2")
988 (set_attr "mode" "DF,DF,DF,DF,DF,DF,TF,TF,DF,DF")
989 (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
990 (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
991 (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
995 ;; Operands 1 and 3 are tied together by the final condition; so we allow
996 ;; fairly lax checking on the second memory operation.
997 (define_insn "load_pair<mode>"
998 [(set (match_operand:GPI 0 "register_operand" "=r")
999 (match_operand:GPI 1 "aarch64_mem_pair_operand" "Ump"))
1000 (set (match_operand:GPI 2 "register_operand" "=r")
1001 (match_operand:GPI 3 "memory_operand" "m"))]
1002 "rtx_equal_p (XEXP (operands[3], 0),
1003 plus_constant (Pmode,
1004 XEXP (operands[1], 0),
1005 GET_MODE_SIZE (<MODE>mode)))"
1006 "ldp\\t%<w>0, %<w>2, %1"
1007 [(set_attr "v8type" "load2")
1008 (set_attr "mode" "<MODE>")]
1011 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1012 ;; fairly lax checking on the second memory operation.
1013 (define_insn "store_pair<mode>"
1014 [(set (match_operand:GPI 0 "aarch64_mem_pair_operand" "=Ump")
1015 (match_operand:GPI 1 "register_operand" "r"))
1016 (set (match_operand:GPI 2 "memory_operand" "=m")
1017 (match_operand:GPI 3 "register_operand" "r"))]
1018 "rtx_equal_p (XEXP (operands[2], 0),
1019 plus_constant (Pmode,
1020 XEXP (operands[0], 0),
1021 GET_MODE_SIZE (<MODE>mode)))"
1022 "stp\\t%<w>1, %<w>3, %0"
1023 [(set_attr "v8type" "store2")
1024 (set_attr "mode" "<MODE>")]
1027 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1028 ;; fairly lax checking on the second memory operation.
1029 (define_insn "load_pair<mode>"
1030 [(set (match_operand:GPF 0 "register_operand" "=w")
1031 (match_operand:GPF 1 "aarch64_mem_pair_operand" "Ump"))
1032 (set (match_operand:GPF 2 "register_operand" "=w")
1033 (match_operand:GPF 3 "memory_operand" "m"))]
1034 "rtx_equal_p (XEXP (operands[3], 0),
1035 plus_constant (Pmode,
1036 XEXP (operands[1], 0),
1037 GET_MODE_SIZE (<MODE>mode)))"
1038 "ldp\\t%<w>0, %<w>2, %1"
1039 [(set_attr "v8type" "fpsimd_load2")
1040 (set_attr "mode" "<MODE>")]
1043 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1044 ;; fairly lax checking on the second memory operation.
1045 (define_insn "store_pair<mode>"
1046 [(set (match_operand:GPF 0 "aarch64_mem_pair_operand" "=Ump")
1047 (match_operand:GPF 1 "register_operand" "w"))
1048 (set (match_operand:GPF 2 "memory_operand" "=m")
1049 (match_operand:GPF 3 "register_operand" "w"))]
1050 "rtx_equal_p (XEXP (operands[2], 0),
1051 plus_constant (Pmode,
1052 XEXP (operands[0], 0),
1053 GET_MODE_SIZE (<MODE>mode)))"
1054 "stp\\t%<w>1, %<w>3, %0"
1055 [(set_attr "v8type" "fpsimd_load2")
1056 (set_attr "mode" "<MODE>")]
1059 ;; Load pair with writeback. This is primarily used in function epilogues
1060 ;; when restoring [fp,lr]
1061 (define_insn "loadwb_pair<GPI:mode>_<PTR:mode>"
1063 [(set (match_operand:PTR 0 "register_operand" "=k")
1064 (plus:PTR (match_operand:PTR 1 "register_operand" "0")
1065 (match_operand:PTR 4 "const_int_operand" "n")))
1066 (set (match_operand:GPI 2 "register_operand" "=r")
1067 (mem:GPI (plus:PTR (match_dup 1)
1069 (set (match_operand:GPI 3 "register_operand" "=r")
1070 (mem:GPI (plus:PTR (match_dup 1)
1071 (match_operand:PTR 5 "const_int_operand" "n"))))])]
1072 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1073 "ldp\\t%<w>2, %<w>3, [%1], %4"
1074 [(set_attr "v8type" "load2")
1075 (set_attr "mode" "<GPI:MODE>")]
1078 ;; Store pair with writeback. This is primarily used in function prologues
1079 ;; when saving [fp,lr]
1080 (define_insn "storewb_pair<GPI:mode>_<PTR:mode>"
1082 [(set (match_operand:PTR 0 "register_operand" "=&k")
1083 (plus:PTR (match_operand:PTR 1 "register_operand" "0")
1084 (match_operand:PTR 4 "const_int_operand" "n")))
1085 (set (mem:GPI (plus:PTR (match_dup 0)
1087 (match_operand:GPI 2 "register_operand" "r"))
1088 (set (mem:GPI (plus:PTR (match_dup 0)
1089 (match_operand:PTR 5 "const_int_operand" "n")))
1090 (match_operand:GPI 3 "register_operand" "r"))])]
1091 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1092 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1093 [(set_attr "v8type" "store2")
1094 (set_attr "mode" "<GPI:MODE>")]
1097 ;; -------------------------------------------------------------------
1098 ;; Sign/Zero extension
1099 ;; -------------------------------------------------------------------
1101 (define_expand "<optab>sidi2"
1102 [(set (match_operand:DI 0 "register_operand")
1103 (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1107 (define_insn "*extendsidi2_aarch64"
1108 [(set (match_operand:DI 0 "register_operand" "=r,r")
1109 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1114 [(set_attr "v8type" "extend,load1")
1115 (set_attr "mode" "DI")]
1118 (define_insn "*zero_extendsidi2_aarch64"
1119 [(set (match_operand:DI 0 "register_operand" "=r,r")
1120 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1125 [(set_attr "v8type" "extend,load1")
1126 (set_attr "mode" "DI")]
1129 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1130 [(set (match_operand:GPI 0 "register_operand")
1131 (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1135 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1136 [(set (match_operand:GPI 0 "register_operand" "=r,r")
1137 (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1140 sxt<SHORT:size>\t%<GPI:w>0, %w1
1141 ldrs<SHORT:size>\t%<GPI:w>0, %1"
1142 [(set_attr "v8type" "extend,load1")
1143 (set_attr "mode" "<GPI:MODE>")]
1146 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1147 [(set (match_operand:GPI 0 "register_operand" "=r,r")
1148 (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1151 uxt<SHORT:size>\t%<GPI:w>0, %w1
1152 ldr<SHORT:size>\t%w0, %1"
1153 [(set_attr "v8type" "extend,load1")
1154 (set_attr "mode" "<GPI:MODE>")]
1157 (define_expand "<optab>qihi2"
1158 [(set (match_operand:HI 0 "register_operand")
1159 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1163 (define_insn "*<optab>qihi2_aarch64"
1164 [(set (match_operand:HI 0 "register_operand" "=r,r")
1165 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1170 [(set_attr "v8type" "extend,load1")
1171 (set_attr "mode" "HI")]
1174 ;; -------------------------------------------------------------------
1175 ;; Simple arithmetic
1176 ;; -------------------------------------------------------------------
1178 (define_expand "add<mode>3"
1180 (match_operand:GPI 0 "register_operand" "")
1181 (plus:GPI (match_operand:GPI 1 "register_operand" "")
1182 (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1185 if (! aarch64_plus_operand (operands[2], VOIDmode))
1187 rtx subtarget = ((optimize && can_create_pseudo_p ())
1188 ? gen_reg_rtx (<MODE>mode) : operands[0]);
1189 HOST_WIDE_INT imm = INTVAL (operands[2]);
1192 imm = -(-imm & ~0xfff);
1196 emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1197 operands[1] = subtarget;
1198 operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1203 (define_insn "*addsi3_aarch64"
1205 (match_operand:SI 0 "register_operand" "=rk,rk,rk")
1207 (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1208 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J")))]
1213 sub\\t%w0, %w1, #%n2"
1214 [(set_attr "v8type" "alu")
1215 (set_attr "mode" "SI")]
1218 (define_insn "*adddi3_aarch64"
1220 (match_operand:DI 0 "register_operand" "=rk,rk,rk,!w")
1222 (match_operand:DI 1 "register_operand" "%rk,rk,rk,!w")
1223 (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,!w")))]
1228 sub\\t%x0, %x1, #%n2
1229 add\\t%d0, %d1, %d2"
1230 [(set_attr "v8type" "alu")
1231 (set_attr "mode" "DI")
1232 (set_attr "simd" "*,*,*,yes")]
1235 (define_insn "*add<mode>3_compare0"
1236 [(set (reg:CC_NZ CC_REGNUM)
1238 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r")
1239 (match_operand:GPI 2 "aarch64_plus_operand" "rI,J"))
1241 (set (match_operand:GPI 0 "register_operand" "=r,r")
1242 (plus:GPI (match_dup 1) (match_dup 2)))]
1245 adds\\t%<w>0, %<w>1, %<w>2
1246 subs\\t%<w>0, %<w>1, #%n2"
1247 [(set_attr "v8type" "alus")
1248 (set_attr "mode" "<MODE>")]
1251 (define_insn "*add<mode>3nr_compare0"
1252 [(set (reg:CC_NZ CC_REGNUM)
1254 (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r")
1255 (match_operand:GPI 1 "aarch64_plus_operand" "rI,J"))
1261 [(set_attr "v8type" "alus")
1262 (set_attr "mode" "<MODE>")]
1265 (define_insn "*compare_neg<mode>"
1266 [(set (reg:CC CC_REGNUM)
1268 (match_operand:GPI 0 "register_operand" "r")
1269 (neg:GPI (match_operand:GPI 1 "register_operand" "r"))))]
1271 "cmn\\t%<w>0, %<w>1"
1272 [(set_attr "v8type" "alus")
1273 (set_attr "mode" "<MODE>")]
1276 (define_insn "*add_<shift>_<mode>"
1277 [(set (match_operand:GPI 0 "register_operand" "=rk")
1278 (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1279 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1280 (match_operand:GPI 3 "register_operand" "r")))]
1282 "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1283 [(set_attr "v8type" "alu_shift")
1284 (set_attr "mode" "<MODE>")]
1287 (define_insn "*add_mul_imm_<mode>"
1288 [(set (match_operand:GPI 0 "register_operand" "=rk")
1289 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1290 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1291 (match_operand:GPI 3 "register_operand" "r")))]
1293 "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1294 [(set_attr "v8type" "alu_shift")
1295 (set_attr "mode" "<MODE>")]
1298 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1299 [(set (match_operand:GPI 0 "register_operand" "=rk")
1300 (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1301 (match_operand:GPI 2 "register_operand" "r")))]
1303 "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1304 [(set_attr "v8type" "alu_ext")
1305 (set_attr "mode" "<GPI:MODE>")]
1308 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1309 [(set (match_operand:GPI 0 "register_operand" "=rk")
1310 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1311 (match_operand:ALLX 1 "register_operand" "r"))
1312 (match_operand 2 "aarch64_imm3" "Ui3"))
1313 (match_operand:GPI 3 "register_operand" "r")))]
1315 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1316 [(set_attr "v8type" "alu_ext")
1317 (set_attr "mode" "<GPI:MODE>")]
1320 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1321 [(set (match_operand:GPI 0 "register_operand" "=rk")
1322 (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1323 (match_operand:ALLX 1 "register_operand" "r"))
1324 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1325 (match_operand:GPI 3 "register_operand" "r")))]
1327 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1328 [(set_attr "v8type" "alu_ext")
1329 (set_attr "mode" "<GPI:MODE>")]
1332 (define_insn "*add_<optab><mode>_multp2"
1333 [(set (match_operand:GPI 0 "register_operand" "=rk")
1334 (plus:GPI (ANY_EXTRACT:GPI
1335 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1336 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1337 (match_operand 3 "const_int_operand" "n")
1339 (match_operand:GPI 4 "register_operand" "r")))]
1340 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1341 "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1342 [(set_attr "v8type" "alu_ext")
1343 (set_attr "mode" "<MODE>")]
1346 (define_insn "*add<mode>3_carryin"
1348 (match_operand:GPI 0 "register_operand" "=r")
1349 (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1351 (match_operand:GPI 1 "register_operand" "r")
1352 (match_operand:GPI 2 "register_operand" "r"))))]
1354 "adc\\t%<w>0, %<w>1, %<w>2"
1355 [(set_attr "v8type" "adc")
1356 (set_attr "mode" "<MODE>")]
1359 (define_insn "*add<mode>3_carryin_alt1"
1361 (match_operand:GPI 0 "register_operand" "=r")
1363 (match_operand:GPI 1 "register_operand" "r")
1364 (match_operand:GPI 2 "register_operand" "r"))
1365 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1367 "adc\\t%<w>0, %<w>1, %<w>2"
1368 [(set_attr "v8type" "adc")
1369 (set_attr "mode" "<MODE>")]
1372 (define_insn "*add<mode>3_carryin_alt2"
1374 (match_operand:GPI 0 "register_operand" "=r")
1376 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1377 (match_operand:GPI 1 "register_operand" "r"))
1378 (match_operand:GPI 2 "register_operand" "r")))]
1380 "adc\\t%<w>0, %<w>1, %<w>2"
1381 [(set_attr "v8type" "adc")
1382 (set_attr "mode" "<MODE>")]
1385 (define_insn "*add<mode>3_carryin_alt3"
1387 (match_operand:GPI 0 "register_operand" "=r")
1389 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1390 (match_operand:GPI 2 "register_operand" "r"))
1391 (match_operand:GPI 1 "register_operand" "r")))]
1393 "adc\\t%<w>0, %<w>1, %<w>2"
1394 [(set_attr "v8type" "adc")
1395 (set_attr "mode" "<MODE>")]
1398 (define_insn "*add_uxt<mode>_multp2"
1399 [(set (match_operand:GPI 0 "register_operand" "=rk")
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"))
1404 (match_operand:GPI 4 "register_operand" "r")))]
1405 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1407 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1408 INTVAL (operands[3])));
1409 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1410 [(set_attr "v8type" "alu_ext")
1411 (set_attr "mode" "<MODE>")]
1414 (define_insn "subsi3"
1415 [(set (match_operand:SI 0 "register_operand" "=rk")
1416 (minus:SI (match_operand:SI 1 "register_operand" "r")
1417 (match_operand:SI 2 "register_operand" "r")))]
1419 "sub\\t%w0, %w1, %w2"
1420 [(set_attr "v8type" "alu")
1421 (set_attr "mode" "SI")]
1424 (define_insn "subdi3"
1425 [(set (match_operand:DI 0 "register_operand" "=rk,!w")
1426 (minus:DI (match_operand:DI 1 "register_operand" "r,!w")
1427 (match_operand:DI 2 "register_operand" "r,!w")))]
1431 sub\\t%d0, %d1, %d2"
1432 [(set_attr "v8type" "alu")
1433 (set_attr "mode" "DI")
1434 (set_attr "simd" "*,yes")]
1438 (define_insn "*sub<mode>3_compare0"
1439 [(set (reg:CC_NZ CC_REGNUM)
1440 (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1441 (match_operand:GPI 2 "register_operand" "r"))
1443 (set (match_operand:GPI 0 "register_operand" "=r")
1444 (minus:GPI (match_dup 1) (match_dup 2)))]
1446 "subs\\t%<w>0, %<w>1, %<w>2"
1447 [(set_attr "v8type" "alus")
1448 (set_attr "mode" "<MODE>")]
1451 (define_insn "*sub_<shift>_<mode>"
1452 [(set (match_operand:GPI 0 "register_operand" "=rk")
1453 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1455 (match_operand:GPI 1 "register_operand" "r")
1456 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1458 "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1459 [(set_attr "v8type" "alu_shift")
1460 (set_attr "mode" "<MODE>")]
1463 (define_insn "*sub_mul_imm_<mode>"
1464 [(set (match_operand:GPI 0 "register_operand" "=rk")
1465 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1467 (match_operand:GPI 1 "register_operand" "r")
1468 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1470 "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1471 [(set_attr "v8type" "alu_shift")
1472 (set_attr "mode" "<MODE>")]
1475 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
1476 [(set (match_operand:GPI 0 "register_operand" "=rk")
1477 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1479 (match_operand:ALLX 2 "register_operand" "r"))))]
1481 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1482 [(set_attr "v8type" "alu_ext")
1483 (set_attr "mode" "<GPI:MODE>")]
1486 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
1487 [(set (match_operand:GPI 0 "register_operand" "=rk")
1488 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1489 (ashift:GPI (ANY_EXTEND:GPI
1490 (match_operand:ALLX 2 "register_operand" "r"))
1491 (match_operand 3 "aarch64_imm3" "Ui3"))))]
1493 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1494 [(set_attr "v8type" "alu_ext")
1495 (set_attr "mode" "<GPI:MODE>")]
1498 (define_insn "*sub_<optab><mode>_multp2"
1499 [(set (match_operand:GPI 0 "register_operand" "=rk")
1500 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1502 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1503 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1504 (match_operand 3 "const_int_operand" "n")
1506 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1507 "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1508 [(set_attr "v8type" "alu_ext")
1509 (set_attr "mode" "<MODE>")]
1512 (define_insn "*sub_uxt<mode>_multp2"
1513 [(set (match_operand:GPI 0 "register_operand" "=rk")
1514 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1516 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1517 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1518 (match_operand 3 "const_int_operand" "n"))))]
1519 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1521 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1522 INTVAL (operands[3])));
1523 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1524 [(set_attr "v8type" "alu_ext")
1525 (set_attr "mode" "<MODE>")]
1528 (define_insn "neg<mode>2"
1529 [(set (match_operand:GPI 0 "register_operand" "=r")
1530 (neg:GPI (match_operand:GPI 1 "register_operand" "r")))]
1532 "neg\\t%<w>0, %<w>1"
1533 [(set_attr "v8type" "alu")
1534 (set_attr "mode" "<MODE>")]
1537 (define_insn "*neg<mode>2_compare0"
1538 [(set (reg:CC_NZ CC_REGNUM)
1539 (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
1541 (set (match_operand:GPI 0 "register_operand" "=r")
1542 (neg:GPI (match_dup 1)))]
1544 "negs\\t%<w>0, %<w>1"
1545 [(set_attr "v8type" "alus")
1546 (set_attr "mode" "<MODE>")]
1549 (define_insn "*neg_<shift>_<mode>2"
1550 [(set (match_operand:GPI 0 "register_operand" "=r")
1551 (neg:GPI (ASHIFT:GPI
1552 (match_operand:GPI 1 "register_operand" "r")
1553 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1555 "neg\\t%<w>0, %<w>1, <shift> %2"
1556 [(set_attr "v8type" "alu_shift")
1557 (set_attr "mode" "<MODE>")]
1560 (define_insn "*neg_mul_imm_<mode>2"
1561 [(set (match_operand:GPI 0 "register_operand" "=r")
1563 (match_operand:GPI 1 "register_operand" "r")
1564 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1566 "neg\\t%<w>0, %<w>1, lsl %p2"
1567 [(set_attr "v8type" "alu_shift")
1568 (set_attr "mode" "<MODE>")]
1571 (define_insn "mul<mode>3"
1572 [(set (match_operand:GPI 0 "register_operand" "=r")
1573 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1574 (match_operand:GPI 2 "register_operand" "r")))]
1576 "mul\\t%<w>0, %<w>1, %<w>2"
1577 [(set_attr "v8type" "mult")
1578 (set_attr "mode" "<MODE>")]
1581 (define_insn "*madd<mode>"
1582 [(set (match_operand:GPI 0 "register_operand" "=r")
1583 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1584 (match_operand:GPI 2 "register_operand" "r"))
1585 (match_operand:GPI 3 "register_operand" "r")))]
1587 "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
1588 [(set_attr "v8type" "madd")
1589 (set_attr "mode" "<MODE>")]
1592 (define_insn "*msub<mode>"
1593 [(set (match_operand:GPI 0 "register_operand" "=r")
1594 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1595 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1596 (match_operand:GPI 2 "register_operand" "r"))))]
1599 "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
1600 [(set_attr "v8type" "madd")
1601 (set_attr "mode" "<MODE>")]
1604 (define_insn "*mul<mode>_neg"
1605 [(set (match_operand:GPI 0 "register_operand" "=r")
1606 (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
1607 (match_operand:GPI 2 "register_operand" "r")))]
1610 "mneg\\t%<w>0, %<w>1, %<w>2"
1611 [(set_attr "v8type" "mult")
1612 (set_attr "mode" "<MODE>")]
1615 (define_insn "<su_optab>mulsidi3"
1616 [(set (match_operand:DI 0 "register_operand" "=r")
1617 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
1618 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
1620 "<su>mull\\t%0, %w1, %w2"
1621 [(set_attr "v8type" "mull")
1622 (set_attr "mode" "DI")]
1625 (define_insn "<su_optab>maddsidi4"
1626 [(set (match_operand:DI 0 "register_operand" "=r")
1628 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
1629 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
1630 (match_operand:DI 3 "register_operand" "r")))]
1632 "<su>maddl\\t%0, %w1, %w2, %3"
1633 [(set_attr "v8type" "maddl")
1634 (set_attr "mode" "DI")]
1637 (define_insn "<su_optab>msubsidi4"
1638 [(set (match_operand:DI 0 "register_operand" "=r")
1640 (match_operand:DI 3 "register_operand" "r")
1641 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
1643 (match_operand:SI 2 "register_operand" "r")))))]
1645 "<su>msubl\\t%0, %w1, %w2, %3"
1646 [(set_attr "v8type" "maddl")
1647 (set_attr "mode" "DI")]
1650 (define_insn "*<su_optab>mulsidi_neg"
1651 [(set (match_operand:DI 0 "register_operand" "=r")
1653 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
1654 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
1656 "<su>mnegl\\t%0, %w1, %w2"
1657 [(set_attr "v8type" "mull")
1658 (set_attr "mode" "DI")]
1661 (define_insn "<su>muldi3_highpart"
1662 [(set (match_operand:DI 0 "register_operand" "=r")
1666 (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
1667 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
1670 "<su>mulh\\t%0, %1, %2"
1671 [(set_attr "v8type" "mulh")
1672 (set_attr "mode" "DI")]
1675 (define_insn "<su_optab>div<mode>3"
1676 [(set (match_operand:GPI 0 "register_operand" "=r")
1677 (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
1678 (match_operand:GPI 2 "register_operand" "r")))]
1680 "<su>div\\t%<w>0, %<w>1, %<w>2"
1681 [(set_attr "v8type" "<su>div")
1682 (set_attr "mode" "<MODE>")]
1685 ;; -------------------------------------------------------------------
1687 ;; -------------------------------------------------------------------
1689 (define_insn "*cmp<mode>"
1690 [(set (reg:CC CC_REGNUM)
1691 (compare:CC (match_operand:GPI 0 "register_operand" "r,r")
1692 (match_operand:GPI 1 "aarch64_plus_operand" "rI,J")))]
1697 [(set_attr "v8type" "alus")
1698 (set_attr "mode" "<MODE>")]
1701 (define_insn "*cmp<mode>"
1702 [(set (reg:CCFP CC_REGNUM)
1703 (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
1704 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
1708 fcmp\\t%<s>0, %<s>1"
1709 [(set_attr "v8type" "fcmp")
1710 (set_attr "mode" "<MODE>")]
1713 (define_insn "*cmpe<mode>"
1714 [(set (reg:CCFPE CC_REGNUM)
1715 (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
1716 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
1720 fcmpe\\t%<s>0, %<s>1"
1721 [(set_attr "v8type" "fcmp")
1722 (set_attr "mode" "<MODE>")]
1725 (define_insn "*cmp_swp_<shift>_reg<mode>"
1726 [(set (reg:CC_SWP CC_REGNUM)
1727 (compare:CC_SWP (ASHIFT:GPI
1728 (match_operand:GPI 0 "register_operand" "r")
1729 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
1730 (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
1732 "cmp\\t%<w>2, %<w>0, <shift> %1"
1733 [(set_attr "v8type" "alus_shift")
1734 (set_attr "mode" "<MODE>")]
1737 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
1738 [(set (reg:CC_SWP CC_REGNUM)
1739 (compare:CC_SWP (ANY_EXTEND:GPI
1740 (match_operand:ALLX 0 "register_operand" "r"))
1741 (match_operand:GPI 1 "register_operand" "r")))]
1743 "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
1744 [(set_attr "v8type" "alus_ext")
1745 (set_attr "mode" "<GPI:MODE>")]
1749 ;; -------------------------------------------------------------------
1750 ;; Store-flag and conditional select insns
1751 ;; -------------------------------------------------------------------
1753 (define_expand "cstore<mode>4"
1754 [(set (match_operand:SI 0 "register_operand" "")
1755 (match_operator:SI 1 "aarch64_comparison_operator"
1756 [(match_operand:GPI 2 "register_operand" "")
1757 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
1760 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
1762 operands[3] = const0_rtx;
1766 (define_expand "cstore<mode>4"
1767 [(set (match_operand:SI 0 "register_operand" "")
1768 (match_operator:SI 1 "aarch64_comparison_operator"
1769 [(match_operand:GPF 2 "register_operand" "")
1770 (match_operand:GPF 3 "register_operand" "")]))]
1773 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
1775 operands[3] = const0_rtx;
1779 (define_insn "*cstore<mode>_insn"
1780 [(set (match_operand:ALLI 0 "register_operand" "=r")
1781 (match_operator:ALLI 1 "aarch64_comparison_operator"
1782 [(match_operand 2 "cc_register" "") (const_int 0)]))]
1785 [(set_attr "v8type" "csel")
1786 (set_attr "mode" "<MODE>")]
1789 (define_insn "*cstore<mode>_neg"
1790 [(set (match_operand:ALLI 0 "register_operand" "=r")
1791 (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
1792 [(match_operand 2 "cc_register" "") (const_int 0)])))]
1794 "csetm\\t%<w>0, %m1"
1795 [(set_attr "v8type" "csel")
1796 (set_attr "mode" "<MODE>")]
1799 (define_expand "cmov<mode>6"
1800 [(set (match_operand:GPI 0 "register_operand" "")
1802 (match_operator 1 "aarch64_comparison_operator"
1803 [(match_operand:GPI 2 "register_operand" "")
1804 (match_operand:GPI 3 "aarch64_plus_operand" "")])
1805 (match_operand:GPI 4 "register_operand" "")
1806 (match_operand:GPI 5 "register_operand" "")))]
1809 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
1811 operands[3] = const0_rtx;
1815 (define_expand "cmov<mode>6"
1816 [(set (match_operand:GPF 0 "register_operand" "")
1818 (match_operator 1 "aarch64_comparison_operator"
1819 [(match_operand:GPF 2 "register_operand" "")
1820 (match_operand:GPF 3 "register_operand" "")])
1821 (match_operand:GPF 4 "register_operand" "")
1822 (match_operand:GPF 5 "register_operand" "")))]
1825 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
1827 operands[3] = const0_rtx;
1831 (define_insn "*cmov<mode>_insn"
1832 [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
1834 (match_operator 1 "aarch64_comparison_operator"
1835 [(match_operand 2 "cc_register" "") (const_int 0)])
1836 (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
1837 (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
1838 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
1839 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
1840 ;; Final two alternatives should be unreachable, but included for completeness
1842 csel\\t%<w>0, %<w>3, %<w>4, %m1
1843 csinv\\t%<w>0, %<w>3, <w>zr, %m1
1844 csinv\\t%<w>0, %<w>4, <w>zr, %M1
1845 csinc\\t%<w>0, %<w>3, <w>zr, %m1
1846 csinc\\t%<w>0, %<w>4, <w>zr, %M1
1849 [(set_attr "v8type" "csel")
1850 (set_attr "mode" "<MODE>")]
1853 (define_insn "*cmov<mode>_insn"
1854 [(set (match_operand:GPF 0 "register_operand" "=w")
1856 (match_operator 1 "aarch64_comparison_operator"
1857 [(match_operand 2 "cc_register" "") (const_int 0)])
1858 (match_operand:GPF 3 "register_operand" "w")
1859 (match_operand:GPF 4 "register_operand" "w")))]
1861 "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
1862 [(set_attr "v8type" "fcsel")
1863 (set_attr "mode" "<MODE>")]
1866 (define_expand "mov<mode>cc"
1867 [(set (match_operand:ALLI 0 "register_operand" "")
1868 (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
1869 (match_operand:ALLI 2 "register_operand" "")
1870 (match_operand:ALLI 3 "register_operand" "")))]
1874 enum rtx_code code = GET_CODE (operands[1]);
1876 if (code == UNEQ || code == LTGT)
1879 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
1880 XEXP (operands[1], 1));
1881 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
1885 (define_expand "mov<GPF:mode><GPI:mode>cc"
1886 [(set (match_operand:GPI 0 "register_operand" "")
1887 (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
1888 (match_operand:GPF 2 "register_operand" "")
1889 (match_operand:GPF 3 "register_operand" "")))]
1893 enum rtx_code code = GET_CODE (operands[1]);
1895 if (code == UNEQ || code == LTGT)
1898 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
1899 XEXP (operands[1], 1));
1900 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
1904 (define_insn "*csinc2<mode>_insn"
1905 [(set (match_operand:GPI 0 "register_operand" "=r")
1906 (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator"
1907 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
1908 (match_operand:GPI 1 "register_operand" "r")))]
1910 "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
1911 [(set_attr "v8type" "csel")
1912 (set_attr "mode" "<MODE>")])
1914 (define_insn "csinc3<mode>_insn"
1915 [(set (match_operand:GPI 0 "register_operand" "=r")
1917 (match_operator:GPI 1 "aarch64_comparison_operator"
1918 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
1919 (plus:GPI (match_operand:GPI 3 "register_operand" "r")
1921 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
1923 "csinc\\t%<w>0, %<w>4, %<w>3, %M1"
1924 [(set_attr "v8type" "csel")
1925 (set_attr "mode" "<MODE>")]
1928 (define_insn "*csinv3<mode>_insn"
1929 [(set (match_operand:GPI 0 "register_operand" "=r")
1931 (match_operator:GPI 1 "aarch64_comparison_operator"
1932 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
1933 (not:GPI (match_operand:GPI 3 "register_operand" "r"))
1934 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
1936 "csinv\\t%<w>0, %<w>4, %<w>3, %M1"
1937 [(set_attr "v8type" "csel")
1938 (set_attr "mode" "<MODE>")])
1940 (define_insn "*csneg3<mode>_insn"
1941 [(set (match_operand:GPI 0 "register_operand" "=r")
1943 (match_operator:GPI 1 "aarch64_comparison_operator"
1944 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
1945 (neg:GPI (match_operand:GPI 3 "register_operand" "r"))
1946 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
1948 "csneg\\t%<w>0, %<w>4, %<w>3, %M1"
1949 [(set_attr "v8type" "csel")
1950 (set_attr "mode" "<MODE>")])
1952 ;; -------------------------------------------------------------------
1953 ;; Logical operations
1954 ;; -------------------------------------------------------------------
1956 (define_insn "<optab><mode>3"
1957 [(set (match_operand:GPI 0 "register_operand" "=r,rk")
1958 (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r")
1959 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
1961 "<logical>\\t%<w>0, %<w>1, %<w>2"
1962 [(set_attr "v8type" "logic,logic_imm")
1963 (set_attr "mode" "<MODE>")])
1965 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
1966 [(set (match_operand:GPI 0 "register_operand" "=r")
1967 (LOGICAL:GPI (SHIFT:GPI
1968 (match_operand:GPI 1 "register_operand" "r")
1969 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1970 (match_operand:GPI 3 "register_operand" "r")))]
1972 "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
1973 [(set_attr "v8type" "logic_shift")
1974 (set_attr "mode" "<MODE>")])
1976 (define_insn "one_cmpl<mode>2"
1977 [(set (match_operand:GPI 0 "register_operand" "=r")
1978 (not:GPI (match_operand:GPI 1 "register_operand" "r")))]
1980 "mvn\\t%<w>0, %<w>1"
1981 [(set_attr "v8type" "logic")
1982 (set_attr "mode" "<MODE>")])
1984 (define_insn "*one_cmpl_<optab><mode>2"
1985 [(set (match_operand:GPI 0 "register_operand" "=r")
1986 (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1987 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1989 "mvn\\t%<w>0, %<w>1, <shift> %2"
1990 [(set_attr "v8type" "logic_shift")
1991 (set_attr "mode" "<MODE>")])
1993 (define_insn "*<LOGICAL:optab>_one_cmpl<mode>3"
1994 [(set (match_operand:GPI 0 "register_operand" "=r")
1995 (LOGICAL:GPI (not:GPI
1996 (match_operand:GPI 1 "register_operand" "r"))
1997 (match_operand:GPI 2 "register_operand" "r")))]
1999 "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1"
2000 [(set_attr "v8type" "logic")
2001 (set_attr "mode" "<MODE>")])
2003 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
2004 [(set (match_operand:GPI 0 "register_operand" "=r")
2005 (LOGICAL:GPI (not:GPI
2007 (match_operand:GPI 1 "register_operand" "r")
2008 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2009 (match_operand:GPI 3 "register_operand" "r")))]
2011 "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2012 [(set_attr "v8type" "logic_shift")
2013 (set_attr "mode" "<MODE>")])
2015 (define_insn "clz<mode>2"
2016 [(set (match_operand:GPI 0 "register_operand" "=r")
2017 (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
2019 "clz\\t%<w>0, %<w>1"
2020 [(set_attr "v8type" "clz")
2021 (set_attr "mode" "<MODE>")])
2023 (define_expand "ffs<mode>2"
2024 [(match_operand:GPI 0 "register_operand")
2025 (match_operand:GPI 1 "register_operand")]
2028 rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
2029 rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
2031 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2032 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2033 emit_insn (gen_csinc3<mode>_insn (operands[0], x, ccreg, operands[0], const0_rtx));
2038 (define_insn "clrsb<mode>2"
2039 [(set (match_operand:GPI 0 "register_operand" "=r")
2040 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_CLS))]
2042 "cls\\t%<w>0, %<w>1"
2043 [(set_attr "v8type" "clz")
2044 (set_attr "mode" "<MODE>")])
2046 (define_insn "rbit<mode>2"
2047 [(set (match_operand:GPI 0 "register_operand" "=r")
2048 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
2050 "rbit\\t%<w>0, %<w>1"
2051 [(set_attr "v8type" "rbit")
2052 (set_attr "mode" "<MODE>")])
2054 (define_expand "ctz<mode>2"
2055 [(match_operand:GPI 0 "register_operand")
2056 (match_operand:GPI 1 "register_operand")]
2059 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2060 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2065 (define_insn "*and<mode>3nr_compare0"
2066 [(set (reg:CC CC_REGNUM)
2068 (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
2069 (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
2072 "tst\\t%<w>0, %<w>1"
2073 [(set_attr "v8type" "logics")
2074 (set_attr "mode" "<MODE>")])
2076 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
2077 [(set (reg:CC CC_REGNUM)
2080 (match_operand:GPI 0 "register_operand" "r")
2081 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2082 (match_operand:GPI 2 "register_operand" "r"))
2085 "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
2086 [(set_attr "v8type" "logics_shift")
2087 (set_attr "mode" "<MODE>")])
2089 ;; -------------------------------------------------------------------
2091 ;; -------------------------------------------------------------------
2093 (define_expand "<optab><mode>3"
2094 [(set (match_operand:GPI 0 "register_operand")
2095 (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
2096 (match_operand:QI 2 "nonmemory_operand")))]
2099 if (CONST_INT_P (operands[2]))
2101 operands[2] = GEN_INT (INTVAL (operands[2])
2102 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2104 if (operands[2] == const0_rtx)
2106 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2113 (define_expand "ashl<mode>3"
2114 [(set (match_operand:SHORT 0 "register_operand")
2115 (ashift:SHORT (match_operand:SHORT 1 "register_operand")
2116 (match_operand:QI 2 "nonmemory_operand")))]
2119 if (CONST_INT_P (operands[2]))
2121 operands[2] = GEN_INT (INTVAL (operands[2])
2122 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2124 if (operands[2] == const0_rtx)
2126 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2133 (define_expand "rotr<mode>3"
2134 [(set (match_operand:GPI 0 "register_operand")
2135 (rotatert:GPI (match_operand:GPI 1 "register_operand")
2136 (match_operand:QI 2 "nonmemory_operand")))]
2139 if (CONST_INT_P (operands[2]))
2141 operands[2] = GEN_INT (INTVAL (operands[2])
2142 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2144 if (operands[2] == const0_rtx)
2146 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2153 (define_expand "rotl<mode>3"
2154 [(set (match_operand:GPI 0 "register_operand")
2155 (rotatert:GPI (match_operand:GPI 1 "register_operand")
2156 (match_operand:QI 2 "nonmemory_operand")))]
2159 /* (SZ - cnt) % SZ == -cnt % SZ */
2160 if (CONST_INT_P (operands[2]))
2162 operands[2] = GEN_INT ((-INTVAL (operands[2]))
2163 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2164 if (operands[2] == const0_rtx)
2166 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2171 operands[2] = expand_simple_unop (QImode, NEG, operands[2],
2176 (define_insn "*<optab><mode>3_insn"
2177 [(set (match_operand:GPI 0 "register_operand" "=r")
2179 (match_operand:GPI 1 "register_operand" "r")
2180 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
2182 "<shift>\\t%<w>0, %<w>1, %<w>2"
2183 [(set_attr "v8type" "shift")
2184 (set_attr "mode" "<MODE>")]
2187 (define_insn "*ashl<mode>3_insn"
2188 [(set (match_operand:SHORT 0 "register_operand" "=r")
2189 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
2190 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
2192 "lsl\\t%<w>0, %<w>1, %<w>2"
2193 [(set_attr "v8type" "shift")
2194 (set_attr "mode" "<MODE>")]
2197 (define_insn "*<optab><mode>3_insn"
2198 [(set (match_operand:SHORT 0 "register_operand" "=r")
2199 (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
2200 (match_operand 2 "const_int_operand" "n")))]
2201 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
2203 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
2204 return "<bfshift>\t%w0, %w1, %2, %3";
2206 [(set_attr "v8type" "bfm")
2207 (set_attr "mode" "<MODE>")]
2210 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
2211 [(set (match_operand:GPI 0 "register_operand" "=r")
2213 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
2214 (match_operand 2 "const_int_operand" "n"))))]
2215 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
2217 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
2218 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
2220 [(set_attr "v8type" "bfm")
2221 (set_attr "mode" "<GPI:MODE>")]
2224 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
2225 [(set (match_operand:GPI 0 "register_operand" "=r")
2227 (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
2228 (match_operand 2 "const_int_operand" "n"))))]
2229 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
2231 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
2232 return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
2234 [(set_attr "v8type" "bfm")
2235 (set_attr "mode" "<GPI:MODE>")]
2238 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
2239 [(set (match_operand:GPI 0 "register_operand" "=r")
2241 (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
2242 (match_operand 2 "const_int_operand" "n"))))]
2243 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
2245 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
2246 return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
2248 [(set_attr "v8type" "bfm")
2249 (set_attr "mode" "<GPI:MODE>")]
2252 ;; -------------------------------------------------------------------
2254 ;; -------------------------------------------------------------------
2256 (define_expand "<optab>"
2257 [(set (match_operand:DI 0 "register_operand" "=r")
2258 (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
2259 (match_operand 2 "const_int_operand" "n")
2260 (match_operand 3 "const_int_operand" "n")))]
2265 (define_insn "*<optab><mode>"
2266 [(set (match_operand:GPI 0 "register_operand" "=r")
2267 (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
2268 (match_operand 2 "const_int_operand" "n")
2269 (match_operand 3 "const_int_operand" "n")))]
2271 "<su>bfx\\t%<w>0, %<w>1, %3, %2"
2272 [(set_attr "v8type" "bfm")
2273 (set_attr "mode" "<MODE>")]
2276 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
2277 [(set (match_operand:GPI 0 "register_operand" "=r")
2278 (ashift:GPI (ANY_EXTEND:GPI
2279 (match_operand:ALLX 1 "register_operand" "r"))
2280 (match_operand 2 "const_int_operand" "n")))]
2281 "UINTVAL (operands[2]) < <GPI:sizen>"
2283 operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
2284 ? GEN_INT (<ALLX:sizen>)
2285 : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
2286 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
2288 [(set_attr "v8type" "bfm")
2289 (set_attr "mode" "<GPI:MODE>")]
2292 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
2294 (define_insn "*andim_ashift<mode>_bfiz"
2295 [(set (match_operand:GPI 0 "register_operand" "=r")
2296 (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
2297 (match_operand 2 "const_int_operand" "n"))
2298 (match_operand 3 "const_int_operand" "n")))]
2299 "exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
2300 && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
2301 "ubfiz\\t%<w>0, %<w>1, %2, %P3"
2302 [(set_attr "v8type" "bfm")
2303 (set_attr "mode" "<MODE>")]
2306 (define_insn "bswap<mode>2"
2307 [(set (match_operand:GPI 0 "register_operand" "=r")
2308 (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
2310 "rev\\t%<w>0, %<w>1"
2311 [(set_attr "v8type" "rev")
2312 (set_attr "mode" "<MODE>")]
2315 (define_insn "bswaphi2"
2316 [(set (match_operand:HI 0 "register_operand" "=r")
2317 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
2320 [(set_attr "v8type" "rev")
2321 (set_attr "mode" "HI")]
2324 ;; -------------------------------------------------------------------
2325 ;; Floating-point intrinsics
2326 ;; -------------------------------------------------------------------
2330 (define_insn "btrunc<mode>2"
2331 [(set (match_operand:GPF 0 "register_operand" "=w")
2332 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2335 "frintz\\t%<s>0, %<s>1"
2336 [(set_attr "v8type" "frint")
2337 (set_attr "mode" "<MODE>")]
2340 (define_insn "*lbtrunc<su_optab><GPF:mode><GPI:mode>2"
2341 [(set (match_operand:GPI 0 "register_operand" "=r")
2342 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2345 "fcvtz<su>\\t%<GPI:w>0, %<GPF:s>1"
2346 [(set_attr "v8type" "fcvtf2i")
2347 (set_attr "mode" "<GPF:MODE>")
2348 (set_attr "mode2" "<GPI:MODE>")]
2353 (define_insn "ceil<mode>2"
2354 [(set (match_operand:GPF 0 "register_operand" "=w")
2355 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2358 "frintp\\t%<s>0, %<s>1"
2359 [(set_attr "v8type" "frint")
2360 (set_attr "mode" "<MODE>")]
2363 (define_insn "lceil<su_optab><GPF:mode><GPI:mode>2"
2364 [(set (match_operand:GPI 0 "register_operand" "=r")
2365 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2368 "fcvtp<su>\\t%<GPI:w>0, %<GPF:s>1"
2369 [(set_attr "v8type" "fcvtf2i")
2370 (set_attr "mode" "<GPF:MODE>")
2371 (set_attr "mode2" "<GPI:MODE>")]
2376 (define_insn "floor<mode>2"
2377 [(set (match_operand:GPF 0 "register_operand" "=w")
2378 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2381 "frintm\\t%<s>0, %<s>1"
2382 [(set_attr "v8type" "frint")
2383 (set_attr "mode" "<MODE>")]
2386 (define_insn "lfloor<su_optab><GPF:mode><GPI:mode>2"
2387 [(set (match_operand:GPI 0 "register_operand" "=r")
2388 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2391 "fcvtm<su>\\t%<GPI:w>0, %<GPF:s>1"
2392 [(set_attr "v8type" "fcvtf2i")
2393 (set_attr "mode" "<GPF:MODE>")
2394 (set_attr "mode2" "<GPI:MODE>")]
2397 ;; nearbyint - nothrow
2399 (define_insn "nearbyint<mode>2"
2400 [(set (match_operand:GPF 0 "register_operand" "=w")
2401 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2404 "frinti\\t%<s>0, %<s>1"
2405 [(set_attr "v8type" "frint")
2406 (set_attr "mode" "<MODE>")]
2411 (define_insn "rint<mode>2"
2412 [(set (match_operand:GPF 0 "register_operand" "=w")
2413 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2416 "frintx\\t%<s>0, %<s>1"
2417 [(set_attr "v8type" "frint")
2418 (set_attr "mode" "<MODE>")]
2423 (define_insn "round<mode>2"
2424 [(set (match_operand:GPF 0 "register_operand" "=w")
2425 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2428 "frinta\\t%<s>0, %<s>1"
2429 [(set_attr "v8type" "frint")
2430 (set_attr "mode" "<MODE>")]
2433 (define_insn "lround<su_optab><GPF:mode><GPI:mode>2"
2434 [(set (match_operand:GPI 0 "register_operand" "=r")
2435 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2438 "fcvta<su>\\t%<GPI:w>0, %<GPF:s>1"
2439 [(set_attr "v8type" "fcvtf2i")
2440 (set_attr "mode" "<GPF:MODE>")
2441 (set_attr "mode2" "<GPI:MODE>")]
2446 (define_insn "fma<mode>4"
2447 [(set (match_operand:GPF 0 "register_operand" "=w")
2448 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
2449 (match_operand:GPF 2 "register_operand" "w")
2450 (match_operand:GPF 3 "register_operand" "w")))]
2452 "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
2453 [(set_attr "v8type" "fmadd")
2454 (set_attr "mode" "<MODE>")]
2457 (define_insn "fnma<mode>4"
2458 [(set (match_operand:GPF 0 "register_operand" "=w")
2459 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
2460 (match_operand:GPF 2 "register_operand" "w")
2461 (match_operand:GPF 3 "register_operand" "w")))]
2463 "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
2464 [(set_attr "v8type" "fmadd")
2465 (set_attr "mode" "<MODE>")]
2468 (define_insn "fms<mode>4"
2469 [(set (match_operand:GPF 0 "register_operand" "=w")
2470 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
2471 (match_operand:GPF 2 "register_operand" "w")
2472 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
2474 "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
2475 [(set_attr "v8type" "fmadd")
2476 (set_attr "mode" "<MODE>")]
2479 (define_insn "fnms<mode>4"
2480 [(set (match_operand:GPF 0 "register_operand" "=w")
2481 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
2482 (match_operand:GPF 2 "register_operand" "w")
2483 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
2485 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
2486 [(set_attr "v8type" "fmadd")
2487 (set_attr "mode" "<MODE>")]
2490 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
2491 (define_insn "*fnmadd<mode>4"
2492 [(set (match_operand:GPF 0 "register_operand" "=w")
2493 (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
2494 (match_operand:GPF 2 "register_operand" "w")
2495 (match_operand:GPF 3 "register_operand" "w"))))]
2496 "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
2497 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
2498 [(set_attr "v8type" "fmadd")
2499 (set_attr "mode" "<MODE>")]
2502 ;; -------------------------------------------------------------------
2503 ;; Floating-point conversions
2504 ;; -------------------------------------------------------------------
2506 (define_insn "extendsfdf2"
2507 [(set (match_operand:DF 0 "register_operand" "=w")
2508 (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
2511 [(set_attr "v8type" "fcvt")
2512 (set_attr "mode" "DF")
2513 (set_attr "mode2" "SF")]
2516 (define_insn "truncdfsf2"
2517 [(set (match_operand:SF 0 "register_operand" "=w")
2518 (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
2521 [(set_attr "v8type" "fcvt")
2522 (set_attr "mode" "SF")
2523 (set_attr "mode2" "DF")]
2526 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
2527 [(set (match_operand:GPI 0 "register_operand" "=r")
2528 (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
2530 "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
2531 [(set_attr "v8type" "fcvtf2i")
2532 (set_attr "mode" "<GPF:MODE>")
2533 (set_attr "mode2" "<GPI:MODE>")]
2536 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
2537 [(set (match_operand:GPI 0 "register_operand" "=r")
2538 (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
2540 "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
2541 [(set_attr "v8type" "fcvtf2i")
2542 (set_attr "mode" "<GPF:MODE>")
2543 (set_attr "mode2" "<GPI:MODE>")]
2546 (define_insn "float<GPI:mode><GPF:mode>2"
2547 [(set (match_operand:GPF 0 "register_operand" "=w")
2548 (float:GPF (match_operand:GPI 1 "register_operand" "r")))]
2550 "scvtf\\t%<GPF:s>0, %<GPI:w>1"
2551 [(set_attr "v8type" "fcvti2f")
2552 (set_attr "mode" "<GPF:MODE>")
2553 (set_attr "mode2" "<GPI:MODE>")]
2556 (define_insn "floatuns<GPI:mode><GPF:mode>2"
2557 [(set (match_operand:GPF 0 "register_operand" "=w")
2558 (unsigned_float:GPF (match_operand:GPI 1 "register_operand" "r")))]
2560 "ucvtf\\t%<GPF:s>0, %<GPI:w>1"
2561 [(set_attr "v8type" "fcvt")
2562 (set_attr "mode" "<GPF:MODE>")
2563 (set_attr "mode2" "<GPI:MODE>")]
2566 ;; -------------------------------------------------------------------
2567 ;; Floating-point arithmetic
2568 ;; -------------------------------------------------------------------
2570 (define_insn "add<mode>3"
2571 [(set (match_operand:GPF 0 "register_operand" "=w")
2573 (match_operand:GPF 1 "register_operand" "w")
2574 (match_operand:GPF 2 "register_operand" "w")))]
2576 "fadd\\t%<s>0, %<s>1, %<s>2"
2577 [(set_attr "v8type" "fadd")
2578 (set_attr "mode" "<MODE>")]
2581 (define_insn "sub<mode>3"
2582 [(set (match_operand:GPF 0 "register_operand" "=w")
2584 (match_operand:GPF 1 "register_operand" "w")
2585 (match_operand:GPF 2 "register_operand" "w")))]
2587 "fsub\\t%<s>0, %<s>1, %<s>2"
2588 [(set_attr "v8type" "fadd")
2589 (set_attr "mode" "<MODE>")]
2592 (define_insn "mul<mode>3"
2593 [(set (match_operand:GPF 0 "register_operand" "=w")
2595 (match_operand:GPF 1 "register_operand" "w")
2596 (match_operand:GPF 2 "register_operand" "w")))]
2598 "fmul\\t%<s>0, %<s>1, %<s>2"
2599 [(set_attr "v8type" "fmul")
2600 (set_attr "mode" "<MODE>")]
2603 (define_insn "*fnmul<mode>3"
2604 [(set (match_operand:GPF 0 "register_operand" "=w")
2606 (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
2607 (match_operand:GPF 2 "register_operand" "w")))]
2609 "fnmul\\t%<s>0, %<s>1, %<s>2"
2610 [(set_attr "v8type" "fmul")
2611 (set_attr "mode" "<MODE>")]
2614 (define_insn "div<mode>3"
2615 [(set (match_operand:GPF 0 "register_operand" "=w")
2617 (match_operand:GPF 1 "register_operand" "w")
2618 (match_operand:GPF 2 "register_operand" "w")))]
2620 "fdiv\\t%<s>0, %<s>1, %<s>2"
2621 [(set_attr "v8type" "fdiv")
2622 (set_attr "mode" "<MODE>")]
2625 (define_insn "neg<mode>2"
2626 [(set (match_operand:GPF 0 "register_operand" "=w")
2627 (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
2629 "fneg\\t%<s>0, %<s>1"
2630 [(set_attr "v8type" "ffarith")
2631 (set_attr "mode" "<MODE>")]
2634 (define_insn "sqrt<mode>2"
2635 [(set (match_operand:GPF 0 "register_operand" "=w")
2636 (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
2638 "fsqrt\\t%<s>0, %<s>1"
2639 [(set_attr "v8type" "fsqrt")
2640 (set_attr "mode" "<MODE>")]
2643 (define_insn "abs<mode>2"
2644 [(set (match_operand:GPF 0 "register_operand" "=w")
2645 (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
2647 "fabs\\t%<s>0, %<s>1"
2648 [(set_attr "v8type" "ffarith")
2649 (set_attr "mode" "<MODE>")]
2652 ;; Given that smax/smin do not specify the result when either input is NaN,
2653 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
2656 (define_insn "smax<mode>3"
2657 [(set (match_operand:GPF 0 "register_operand" "=w")
2658 (smax:GPF (match_operand:GPF 1 "register_operand" "w")
2659 (match_operand:GPF 2 "register_operand" "w")))]
2661 "fmaxnm\\t%<s>0, %<s>1, %<s>2"
2662 [(set_attr "v8type" "fminmax")
2663 (set_attr "mode" "<MODE>")]
2666 (define_insn "smin<mode>3"
2667 [(set (match_operand:GPF 0 "register_operand" "=w")
2668 (smin:GPF (match_operand:GPF 1 "register_operand" "w")
2669 (match_operand:GPF 2 "register_operand" "w")))]
2671 "fminnm\\t%<s>0, %<s>1, %<s>2"
2672 [(set_attr "v8type" "fminmax")
2673 (set_attr "mode" "<MODE>")]
2676 ;; -------------------------------------------------------------------
2678 ;; -------------------------------------------------------------------
2680 ;; Reload SP+imm where imm cannot be handled by a single ADD instruction.
2681 ;; Must load imm into a scratch register and copy SP to the dest reg before
2682 ;; adding, since SP cannot be used as a source register in an ADD
2684 (define_expand "reload_sp_immediate"
2685 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
2686 (match_operand:DI 1 "" ""))
2687 (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
2690 rtx sp = XEXP (operands[1], 0);
2691 rtx val = XEXP (operands[1], 1);
2692 unsigned regno = REGNO (operands[2]);
2693 rtx scratch = operands[1];
2694 gcc_assert (GET_CODE (operands[1]) == PLUS);
2695 gcc_assert (sp == stack_pointer_rtx);
2696 gcc_assert (CONST_INT_P (val));
2698 /* It is possible that one of the registers we got for operands[2]
2699 might coincide with that of operands[0] (which is why we made
2700 it TImode). Pick the other one to use as our scratch. */
2701 if (regno == REGNO (operands[0]))
2703 scratch = gen_rtx_REG (DImode, regno);
2705 emit_move_insn (scratch, val);
2706 emit_move_insn (operands[0], sp);
2707 emit_insn (gen_adddi3 (operands[0], operands[0], scratch));
2712 (define_expand "aarch64_reload_mov<mode>"
2713 [(set (match_operand:TX 0 "register_operand" "=w")
2714 (match_operand:TX 1 "register_operand" "w"))
2715 (clobber (match_operand:DI 2 "register_operand" "=&r"))
2719 rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
2720 rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
2721 gen_aarch64_movtilow_tilow (op0, op1);
2722 gen_aarch64_movdi_tihigh (operands[2], op1);
2723 gen_aarch64_movtihigh_di (op0, operands[2]);
2728 ;; The following secondary reload helpers patterns are invoked
2729 ;; after or during reload as we don't want these patterns to start
2730 ;; kicking in during the combiner.
2732 (define_insn "aarch64_movdi_tilow"
2733 [(set (match_operand:DI 0 "register_operand" "=r")
2734 (truncate:DI (match_operand:TI 1 "register_operand" "w")))]
2735 "reload_completed || reload_in_progress"
2737 [(set_attr "v8type" "fmovf2i")
2738 (set_attr "mode" "DI")
2739 (set_attr "length" "4")
2742 (define_insn "aarch64_movdi_tihigh"
2743 [(set (match_operand:DI 0 "register_operand" "=r")
2745 (lshiftrt:TI (match_operand:TI 1 "register_operand" "w")
2747 "reload_completed || reload_in_progress"
2748 "fmov\\t%x0, %1.d[1]"
2749 [(set_attr "v8type" "fmovf2i")
2750 (set_attr "mode" "DI")
2751 (set_attr "length" "4")
2754 (define_insn "aarch64_movtihigh_di"
2755 [(set (zero_extract:TI (match_operand:TI 0 "register_operand" "+w")
2756 (const_int 64) (const_int 64))
2757 (zero_extend:TI (match_operand:DI 1 "register_operand" "r")))]
2758 "reload_completed || reload_in_progress"
2759 "fmov\\t%0.d[1], %x1"
2761 [(set_attr "v8type" "fmovi2f")
2762 (set_attr "mode" "DI")
2763 (set_attr "length" "4")
2766 (define_insn "aarch64_movtilow_di"
2767 [(set (match_operand:TI 0 "register_operand" "=w")
2768 (zero_extend:TI (match_operand:DI 1 "register_operand" "r")))]
2769 "reload_completed || reload_in_progress"
2772 [(set_attr "v8type" "fmovi2f")
2773 (set_attr "mode" "DI")
2774 (set_attr "length" "4")
2777 (define_insn "aarch64_movtilow_tilow"
2778 [(set (match_operand:TI 0 "register_operand" "=w")
2780 (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
2781 "reload_completed || reload_in_progress"
2784 [(set_attr "v8type" "fmovi2f")
2785 (set_attr "mode" "DI")
2786 (set_attr "length" "4")
2789 ;; There is a deliberate reason why the parameters of high and lo_sum's
2790 ;; don't have modes for ADRP and ADD instructions. This is to allow high
2791 ;; and lo_sum's to be used with the labels defining the jump tables in
2794 (define_insn "add_losym"
2795 [(set (match_operand:DI 0 "register_operand" "=r")
2796 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2797 (match_operand 2 "aarch64_valid_symref" "S")))]
2799 "add\\t%0, %1, :lo12:%a2"
2800 [(set_attr "v8type" "alu")
2801 (set_attr "mode" "DI")]
2805 (define_insn "ldr_got_small"
2806 [(set (match_operand:DI 0 "register_operand" "=r")
2807 (unspec:DI [(mem:DI (lo_sum:DI
2808 (match_operand:DI 1 "register_operand" "r")
2809 (match_operand:DI 2 "aarch64_valid_symref" "S")))]
2810 UNSPEC_GOTSMALLPIC))]
2812 "ldr\\t%0, [%1, #:got_lo12:%a2]"
2813 [(set_attr "v8type" "load1")
2814 (set_attr "mode" "DI")]
2817 (define_insn "aarch64_load_tp_hard"
2818 [(set (match_operand:DI 0 "register_operand" "=r")
2819 (unspec:DI [(const_int 0)] UNSPEC_TLS))]
2821 "mrs\\t%0, tpidr_el0"
2822 [(set_attr "v8type" "mrs")
2823 (set_attr "mode" "DI")]
2826 ;; The TLS ABI specifically requires that the compiler does not schedule
2827 ;; instructions in the TLS stubs, in order to enable linker relaxation.
2828 ;; Therefore we treat the stubs as an atomic sequence.
2829 (define_expand "tlsgd_small"
2830 [(parallel [(set (match_operand 0 "register_operand" "")
2831 (call (mem:DI (match_dup 2)) (const_int 1)))
2832 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
2833 (clobber (reg:DI LR_REGNUM))])]
2836 operands[2] = aarch64_tls_get_addr ();
2839 (define_insn "*tlsgd_small"
2840 [(set (match_operand 0 "register_operand" "")
2841 (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
2842 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
2843 (clobber (reg:DI LR_REGNUM))
2846 "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
2847 [(set_attr "v8type" "call")
2848 (set_attr "length" "16")])
2850 (define_insn "tlsie_small"
2851 [(set (match_operand:DI 0 "register_operand" "=r")
2852 (unspec:DI [(match_operand:DI 1 "aarch64_tls_ie_symref" "S")]
2853 UNSPEC_GOTSMALLTLS))]
2855 "adrp\\t%0, %A1\;ldr\\t%0, [%0, #%L1]"
2856 [(set_attr "v8type" "load1")
2857 (set_attr "mode" "DI")
2858 (set_attr "length" "8")]
2861 (define_insn "tlsle_small"
2862 [(set (match_operand:DI 0 "register_operand" "=r")
2863 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
2864 (match_operand:DI 2 "aarch64_tls_le_symref" "S")]
2865 UNSPEC_GOTSMALLTLS))]
2867 "add\\t%0, %1, #%G2\;add\\t%0, %0, #%L2"
2868 [(set_attr "v8type" "alu")
2869 (set_attr "mode" "DI")
2870 (set_attr "length" "8")]
2873 (define_insn "tlsdesc_small"
2874 [(set (reg:DI R0_REGNUM)
2875 (unspec:DI [(match_operand:DI 0 "aarch64_valid_symref" "S")]
2877 (clobber (reg:DI LR_REGNUM))
2878 (clobber (match_scratch:DI 1 "=r"))]
2880 "adrp\\tx0, %A0\;ldr\\t%1, [x0, #%L0]\;add\\tx0, x0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
2881 [(set_attr "v8type" "call")
2882 (set_attr "length" "16")])
2884 (define_insn "stack_tie"
2885 [(set (mem:BLK (scratch))
2886 (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
2887 (match_operand:DI 1 "register_operand" "rk")]
2891 [(set_attr "length" "0")]
2894 ;; Named pattern for expanding thread pointer reference.
2895 (define_expand "get_thread_pointerdi"
2896 [(match_operand:DI 0 "register_operand" "=r")]
2899 rtx tmp = aarch64_load_tp (operands[0]);
2900 if (tmp != operands[0])
2901 emit_move_insn (operands[0], tmp);
2906 (include "aarch64-simd.md")
2908 ;; Atomic Operations
2909 (include "atomics.md")