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 ;; Synchronization Builtins
108 ;; -------------------------------------------------------------------
110 ;; The following sync_* attributes are applied to sychronization
111 ;; instruction patterns to control the way in which the
112 ;; synchronization loop is expanded.
113 ;; All instruction patterns that call aarch64_output_sync_insn ()
114 ;; should define these attributes. Refer to the comment above
115 ;; aarch64.c:aarch64_output_sync_loop () for more detail on the use of
118 ;; Attribute specifies the operand number which contains the
119 ;; result of a synchronization operation. The result is the old value
120 ;; loaded from SYNC_MEMORY.
121 (define_attr "sync_result" "none,0,1,2,3,4,5" (const_string "none"))
123 ;; Attribute specifies the operand number which contains the memory
124 ;; address to which the synchronization operation is being applied.
125 (define_attr "sync_memory" "none,0,1,2,3,4,5" (const_string "none"))
127 ;; Attribute specifies the operand number which contains the required
128 ;; old value expected in the memory location. This attribute may be
129 ;; none if no required value test should be performed in the expanded
131 (define_attr "sync_required_value" "none,0,1,2,3,4,5" (const_string "none"))
133 ;; Attribute specifies the operand number of the new value to be stored
134 ;; into the memory location identitifed by the sync_memory attribute.
135 (define_attr "sync_new_value" "none,0,1,2,3,4,5" (const_string "none"))
137 ;; Attribute specifies the operand number of a temporary register
138 ;; which can be clobbered by the synchronization instruction sequence.
139 ;; The register provided byn SYNC_T1 may be the same as SYNC_RESULT is
140 ;; which case the result value will be clobbered and not available
141 ;; after the synchronization loop exits.
142 (define_attr "sync_t1" "none,0,1,2,3,4,5" (const_string "none"))
144 ;; Attribute specifies the operand number of a temporary register
145 ;; which can be clobbered by the synchronization instruction sequence.
146 ;; This register is used to collect the result of a store exclusive
148 (define_attr "sync_t2" "none,0,1,2,3,4,5" (const_string "none"))
150 ;; Attribute that specifies whether or not the emitted synchronization
151 ;; loop must contain a release barrier.
152 (define_attr "sync_release_barrier" "yes,no" (const_string "yes"))
154 ;; Attribute that specifies the operation that the synchronization
155 ;; loop should apply to the old and new values to generate the value
156 ;; written back to memory.
157 (define_attr "sync_op" "none,add,sub,ior,xor,and,nand"
158 (const_string "none"))
160 ;; -------------------------------------------------------------------
161 ;; Instruction types and attributes
162 ;; -------------------------------------------------------------------
164 ;; Main data types used by the insntructions
166 (define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
167 (const_string "unknown"))
169 (define_attr "mode2" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
170 (const_string "unknown"))
172 ; The "v8type" attribute is used to for fine grained classification of
173 ; AArch64 instructions. This table briefly explains the meaning of each type.
175 ; adc add/subtract with carry.
176 ; adcs add/subtract with carry (setting condition flags).
177 ; adr calculate address.
178 ; alu simple alu instruction (no memory or fp regs access).
179 ; alu_ext simple alu instruction (sign/zero-extended register).
180 ; alu_shift simple alu instruction, with a source operand shifted by a constant.
181 ; alus simple alu instruction (setting condition flags).
182 ; alus_ext simple alu instruction (sign/zero-extended register, setting condition flags).
183 ; alus_shift simple alu instruction, with a source operand shifted by a constant (setting condition flags).
184 ; bfm bitfield move operation.
186 ; call subroutine call.
187 ; ccmp conditional compare.
188 ; clz count leading zeros/sign bits.
189 ; csel conditional select.
190 ; dmb data memory barrier.
191 ; extend sign/zero-extend (specialised bitfield move).
192 ; extr extract register-sized bitfield encoding.
193 ; fpsimd_load load single floating point / simd scalar register from memory.
194 ; fpsimd_load2 load pair of floating point / simd scalar registers from memory.
195 ; fpsimd_store store single floating point / simd scalar register to memory.
196 ; fpsimd_store2 store pair floating point / simd scalar registers to memory.
197 ; fadd floating point add/sub.
198 ; fccmp floating point conditional compare.
199 ; fcmp floating point comparison.
200 ; fconst floating point load immediate.
201 ; fcsel floating point conditional select.
202 ; fcvt floating point convert (float to float).
203 ; fcvtf2i floating point convert (float to integer).
204 ; fcvti2f floating point convert (integer to float).
205 ; fdiv floating point division operation.
206 ; ffarith floating point abs, neg or cpy.
207 ; fmadd floating point multiply-add/sub.
208 ; fminmax floating point min/max.
209 ; fmov floating point move (float to float).
210 ; fmovf2i floating point move (float to integer).
211 ; fmovi2f floating point move (integer to float).
212 ; fmul floating point multiply.
213 ; frint floating point round to integral.
214 ; fsqrt floating point square root.
215 ; load_acq load-acquire.
216 ; load load single general register from memory
217 ; load2 load pair of general registers from memory
218 ; logic logical operation (register).
219 ; logic_imm and/or/xor operation (immediate).
220 ; logic_shift logical operation with shift.
221 ; logics logical operation (register, setting condition flags).
222 ; logics_imm and/or/xor operation (immediate, setting condition flags).
223 ; logics_shift logical operation with shift (setting condition flags).
224 ; madd integer multiply-add/sub.
225 ; maddl widening integer multiply-add/sub.
226 ; misc miscellaneous - any type that doesn't fit into the rest.
227 ; move integer move operation.
228 ; move2 double integer move operation.
229 ; movk move 16-bit immediate with keep.
230 ; movz move 16-bit immmediate with zero/one.
231 ; mrs system/special register move.
232 ; mulh 64x64 to 128-bit multiply (high part).
233 ; mull widening multiply.
234 ; mult integer multiply instruction.
235 ; prefetch memory prefetch.
238 ; sdiv integer division operation (signed).
239 ; shift variable shift operation.
240 ; shift_imm immediate shift operation (specialised bitfield move).
241 ; store_rel store-release.
242 ; store store single general register to memory.
243 ; store2 store pair of general registers to memory.
244 ; udiv integer division operation (unsigned).
246 (define_attr "v8type"
319 (const_string "alu"))
322 ; The "type" attribute is used by the AArch32 backend. Below is a mapping
323 ; from "v8type" to "type".
326 "alu,alu_shift,block,branch,call,f_2_r,f_cvt,f_flag,f_loads,
327 f_loadd,f_stored,f_stores,faddd,fadds,fcmpd,fcmps,fconstd,fconsts,
328 fcpys,fdivd,fdivs,ffarithd,ffariths,fmacd,fmacs,fmuld,fmuls,load_byte,
329 load1,load2,mult,r_2_f,store1,store2"
331 (eq_attr "v8type" "alu_shift,alus_shift,logic_shift,logics_shift") (const_string "alu_shift")
332 (eq_attr "v8type" "branch") (const_string "branch")
333 (eq_attr "v8type" "call") (const_string "call")
334 (eq_attr "v8type" "fmovf2i") (const_string "f_2_r")
335 (eq_attr "v8type" "fcvt,fcvtf2i,fcvti2f") (const_string "f_cvt")
336 (and (eq_attr "v8type" "fpsimd_load") (eq_attr "mode" "SF")) (const_string "f_loads")
337 (and (eq_attr "v8type" "fpsimd_load") (eq_attr "mode" "DF")) (const_string "f_loadd")
338 (and (eq_attr "v8type" "fpsimd_store") (eq_attr "mode" "SF")) (const_string "f_stores")
339 (and (eq_attr "v8type" "fpsimd_store") (eq_attr "mode" "DF")) (const_string "f_stored")
340 (and (eq_attr "v8type" "fadd,fminmax") (eq_attr "mode" "DF")) (const_string "faddd")
341 (and (eq_attr "v8type" "fadd,fminmax") (eq_attr "mode" "SF")) (const_string "fadds")
342 (and (eq_attr "v8type" "fcmp,fccmp") (eq_attr "mode" "DF")) (const_string "fcmpd")
343 (and (eq_attr "v8type" "fcmp,fccmp") (eq_attr "mode" "SF")) (const_string "fcmps")
344 (and (eq_attr "v8type" "fconst") (eq_attr "mode" "DF")) (const_string "fconstd")
345 (and (eq_attr "v8type" "fconst") (eq_attr "mode" "SF")) (const_string "fconsts")
346 (and (eq_attr "v8type" "fdiv,fsqrt") (eq_attr "mode" "DF")) (const_string "fdivd")
347 (and (eq_attr "v8type" "fdiv,fsqrt") (eq_attr "mode" "SF")) (const_string "fdivs")
348 (and (eq_attr "v8type" "ffarith") (eq_attr "mode" "DF")) (const_string "ffarithd")
349 (and (eq_attr "v8type" "ffarith") (eq_attr "mode" "SF")) (const_string "ffariths")
350 (and (eq_attr "v8type" "fmadd") (eq_attr "mode" "DF")) (const_string "fmacd")
351 (and (eq_attr "v8type" "fmadd") (eq_attr "mode" "SF")) (const_string "fmacs")
352 (and (eq_attr "v8type" "fmul") (eq_attr "mode" "DF")) (const_string "fmuld")
353 (and (eq_attr "v8type" "fmul") (eq_attr "mode" "SF")) (const_string "fmuls")
354 (and (eq_attr "v8type" "load1") (eq_attr "mode" "QI,HI")) (const_string "load_byte")
355 (and (eq_attr "v8type" "load1") (eq_attr "mode" "SI,DI,TI")) (const_string "load1")
356 (eq_attr "v8type" "load2") (const_string "load2")
357 (and (eq_attr "v8type" "mulh,mult,mull,madd,sdiv,udiv") (eq_attr "mode" "SI")) (const_string "mult")
358 (eq_attr "v8type" "fmovi2f") (const_string "r_2_f")
359 (eq_attr "v8type" "store1") (const_string "store1")
360 (eq_attr "v8type" "store2") (const_string "store2")
362 (const_string "alu")))
364 ;; Attribute that specifies whether or not the instruction touches fp
366 (define_attr "fp" "no,yes" (const_string "no"))
368 ;; Attribute that specifies whether or not the instruction touches simd
370 (define_attr "simd" "no,yes" (const_string "no"))
372 (define_attr "length" ""
373 (cond [(not (eq_attr "sync_memory" "none"))
374 (symbol_ref "aarch64_sync_loop_insns (insn, operands) * 4")
377 ;; Attribute that controls whether an alternative is enabled or not.
378 ;; Currently it is only used to disable alternatives which touch fp or simd
379 ;; registers when -mgeneral-regs-only is specified.
380 (define_attr "enabled" "no,yes"
382 (and (eq_attr "fp" "yes")
383 (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
384 (and (eq_attr "simd" "yes")
385 (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
387 ] (const_string "yes")))
389 ;; -------------------------------------------------------------------
390 ;; Pipeline descriptions and scheduling
391 ;; -------------------------------------------------------------------
394 (include "aarch64-tune.md")
397 (include "aarch64-generic.md")
401 ;; -------------------------------------------------------------------
402 ;; Jumps and other miscellaneous insns
403 ;; -------------------------------------------------------------------
405 (define_insn "indirect_jump"
406 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
409 [(set_attr "v8type" "branch")]
413 [(set (pc) (label_ref (match_operand 0 "" "")))]
416 [(set_attr "v8type" "branch")]
419 (define_expand "cbranch<mode>4"
420 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
421 [(match_operand:GPI 1 "register_operand" "")
422 (match_operand:GPI 2 "aarch64_plus_operand" "")])
423 (label_ref (match_operand 3 "" ""))
427 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
429 operands[2] = const0_rtx;
433 (define_expand "cbranch<mode>4"
434 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
435 [(match_operand:GPF 1 "register_operand" "")
436 (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
437 (label_ref (match_operand 3 "" ""))
441 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
443 operands[2] = const0_rtx;
447 (define_insn "*condjump"
448 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
449 [(match_operand 1 "cc_register" "") (const_int 0)])
450 (label_ref (match_operand 2 "" ""))
454 [(set_attr "v8type" "branch")]
457 (define_expand "casesi"
458 [(match_operand:SI 0 "register_operand" "") ; Index
459 (match_operand:SI 1 "const_int_operand" "") ; Lower bound
460 (match_operand:SI 2 "const_int_operand" "") ; Total range
461 (match_operand:DI 3 "" "") ; Table label
462 (match_operand:DI 4 "" "")] ; Out of range label
465 if (operands[1] != const0_rtx)
467 rtx reg = gen_reg_rtx (SImode);
469 /* Canonical RTL says that if you have:
473 then this should be emitted as:
477 The use of trunc_int_for_mode ensures that the resulting
478 constant can be represented in SImode, this is important
479 for the corner case where operand[1] is INT_MIN. */
481 operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
483 if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
484 (operands[1], SImode))
485 operands[1] = force_reg (SImode, operands[1]);
486 emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
490 if (!aarch64_plus_operand (operands[2], SImode))
491 operands[2] = force_reg (SImode, operands[2]);
492 emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
494 operands[0], operands[2], operands[4]));
496 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
497 emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
503 (define_insn "casesi_dispatch"
506 (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
507 (match_operand:SI 1 "register_operand" "r")]
509 (clobber (reg:CC CC_REGNUM))
510 (clobber (match_scratch:DI 3 "=r"))
511 (clobber (match_scratch:DI 4 "=r"))
512 (use (label_ref (match_operand 2 "" "")))])]
515 return aarch64_output_casesi (operands);
517 [(set_attr "length" "16")
518 (set_attr "v8type" "branch")]
522 [(unspec[(const_int 0)] UNSPEC_NOP)]
525 [(set_attr "v8type" "misc")]
528 (define_expand "prologue"
529 [(clobber (const_int 0))]
532 aarch64_expand_prologue ();
537 (define_expand "epilogue"
538 [(clobber (const_int 0))]
541 aarch64_expand_epilogue (false);
546 (define_expand "sibcall_epilogue"
547 [(clobber (const_int 0))]
550 aarch64_expand_epilogue (true);
555 (define_insn "*do_return"
559 [(set_attr "v8type" "branch")]
562 (define_insn "eh_return"
563 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
567 [(set_attr "v8type" "branch")]
571 [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
574 [(set (match_dup 1) (match_dup 0))]
576 operands[1] = aarch64_final_eh_return_addr ();
580 (define_insn "*cb<optab><mode>1"
581 [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
583 (label_ref (match_operand 1 "" ""))
587 [(set_attr "v8type" "branch")]
590 (define_insn "*tb<optab><mode>1"
591 [(set (pc) (if_then_else
592 (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
594 (match_operand 1 "const_int_operand" "n"))
596 (label_ref (match_operand 2 "" ""))
598 (clobber (match_scratch:DI 3 "=r"))]
601 if (get_attr_length (insn) == 8)
602 return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
603 return \"<tbz>\\t%<w>0, %1, %l2\";
605 [(set_attr "v8type" "branch")
606 (set_attr "mode" "<MODE>")
608 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
609 (lt (minus (match_dup 2) (pc)) (const_int 32764)))
614 (define_insn "*cb<optab><mode>1"
615 [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
617 (label_ref (match_operand 1 "" ""))
619 (clobber (match_scratch:DI 2 "=r"))]
622 if (get_attr_length (insn) == 8)
623 return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
624 return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
626 [(set_attr "v8type" "branch")
627 (set_attr "mode" "<MODE>")
629 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
630 (lt (minus (match_dup 1) (pc)) (const_int 32764)))
635 ;; -------------------------------------------------------------------
636 ;; Subroutine calls and sibcalls
637 ;; -------------------------------------------------------------------
639 (define_expand "call"
640 [(parallel [(call (match_operand 0 "memory_operand" "")
641 (match_operand 1 "general_operand" ""))
642 (use (match_operand 2 "" ""))
643 (clobber (reg:DI LR_REGNUM))])]
649 /* In an untyped call, we can get NULL for operand 2. */
650 if (operands[2] == NULL)
651 operands[2] = const0_rtx;
653 /* Decide if we should generate indirect calls by loading the
654 64-bit address of the callee into a register before performing
655 the branch-and-link. */
656 callee = XEXP (operands[0], 0);
657 if (GET_CODE (callee) == SYMBOL_REF
658 ? aarch64_is_long_call_p (callee)
660 XEXP (operands[0], 0) = force_reg (Pmode, callee);
664 (define_insn "*call_reg"
665 [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
666 (match_operand 1 "" ""))
667 (use (match_operand 2 "" ""))
668 (clobber (reg:DI LR_REGNUM))]
671 [(set_attr "v8type" "call")]
674 (define_insn "*call_symbol"
675 [(call (mem:DI (match_operand:DI 0 "" ""))
676 (match_operand 1 "" ""))
677 (use (match_operand 2 "" ""))
678 (clobber (reg:DI LR_REGNUM))]
679 "GET_CODE (operands[0]) == SYMBOL_REF
680 && !aarch64_is_long_call_p (operands[0])"
682 [(set_attr "v8type" "call")]
685 (define_expand "call_value"
686 [(parallel [(set (match_operand 0 "" "")
687 (call (match_operand 1 "memory_operand" "")
688 (match_operand 2 "general_operand" "")))
689 (use (match_operand 3 "" ""))
690 (clobber (reg:DI LR_REGNUM))])]
696 /* In an untyped call, we can get NULL for operand 3. */
697 if (operands[3] == NULL)
698 operands[3] = const0_rtx;
700 /* Decide if we should generate indirect calls by loading the
701 64-bit address of the callee into a register before performing
702 the branch-and-link. */
703 callee = XEXP (operands[1], 0);
704 if (GET_CODE (callee) == SYMBOL_REF
705 ? aarch64_is_long_call_p (callee)
707 XEXP (operands[1], 0) = force_reg (Pmode, callee);
711 (define_insn "*call_value_reg"
712 [(set (match_operand 0 "" "")
713 (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
714 (match_operand 2 "" "")))
715 (use (match_operand 3 "" ""))
716 (clobber (reg:DI LR_REGNUM))]
719 [(set_attr "v8type" "call")]
722 (define_insn "*call_value_symbol"
723 [(set (match_operand 0 "" "")
724 (call (mem:DI (match_operand:DI 1 "" ""))
725 (match_operand 2 "" "")))
726 (use (match_operand 3 "" ""))
727 (clobber (reg:DI LR_REGNUM))]
728 "GET_CODE (operands[1]) == SYMBOL_REF
729 && !aarch64_is_long_call_p (operands[1])"
731 [(set_attr "v8type" "call")]
734 (define_expand "sibcall"
735 [(parallel [(call (match_operand 0 "memory_operand" "")
736 (match_operand 1 "general_operand" ""))
738 (use (match_operand 2 "" ""))])]
741 if (operands[2] == NULL_RTX)
742 operands[2] = const0_rtx;
746 (define_expand "sibcall_value"
747 [(parallel [(set (match_operand 0 "" "")
748 (call (match_operand 1 "memory_operand" "")
749 (match_operand 2 "general_operand" "")))
751 (use (match_operand 3 "" ""))])]
754 if (operands[3] == NULL_RTX)
755 operands[3] = const0_rtx;
759 (define_insn "*sibcall_insn"
760 [(call (mem:DI (match_operand:DI 0 "" "X"))
761 (match_operand 1 "" ""))
763 (use (match_operand 2 "" ""))]
764 "GET_CODE (operands[0]) == SYMBOL_REF"
766 [(set_attr "v8type" "branch")]
769 (define_insn "*sibcall_value_insn"
770 [(set (match_operand 0 "" "")
771 (call (mem:DI (match_operand 1 "" "X"))
772 (match_operand 2 "" "")))
774 (use (match_operand 3 "" ""))]
775 "GET_CODE (operands[1]) == SYMBOL_REF"
777 [(set_attr "v8type" "branch")]
780 ;; Call subroutine returning any type.
782 (define_expand "untyped_call"
783 [(parallel [(call (match_operand 0 "")
786 (match_operand 2 "")])]
791 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
793 for (i = 0; i < XVECLEN (operands[2], 0); i++)
795 rtx set = XVECEXP (operands[2], 0, i);
796 emit_move_insn (SET_DEST (set), SET_SRC (set));
799 /* The optimizer does not know that the call sets the function value
800 registers we stored in the result block. We avoid problems by
801 claiming that all hard registers are used and clobbered at this
803 emit_insn (gen_blockage ());
807 ;; -------------------------------------------------------------------
809 ;; -------------------------------------------------------------------
811 (define_expand "mov<mode>"
812 [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
813 (match_operand:SHORT 1 "general_operand" ""))]
816 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
817 operands[1] = force_reg (<MODE>mode, operands[1]);
821 (define_insn "*mov<mode>_aarch64"
822 [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r,r,m, r,*w")
823 (match_operand:SHORT 1 "general_operand" " r,M,m,rZ,*w,r"))]
824 "(register_operand (operands[0], <MODE>mode)
825 || aarch64_reg_or_zero (operands[1], <MODE>mode))"
831 umov\\t%w0, %1.<v>[0]
832 dup\\t%0.<Vallxd>, %w1"
833 [(set_attr "v8type" "move,alu,load1,store1,*,*")
834 (set_attr "simd_type" "*,*,*,*,simd_movgp,simd_dupgp")
835 (set_attr "mode" "<MODE>")
836 (set_attr "simd_mode" "<MODE>")]
839 (define_expand "mov<mode>"
840 [(set (match_operand:GPI 0 "nonimmediate_operand" "")
841 (match_operand:GPI 1 "general_operand" ""))]
844 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
845 operands[1] = force_reg (<MODE>mode, operands[1]);
847 if (CONSTANT_P (operands[1]))
849 aarch64_expand_mov_immediate (operands[0], operands[1]);
855 (define_insn "*movsi_aarch64"
856 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m, *w, r,*w")
857 (match_operand:SI 1 "aarch64_mov_operand" " r,M,m,rZ,rZ,*w,*w"))]
858 "(register_operand (operands[0], SImode)
859 || aarch64_reg_or_zero (operands[1], SImode))"
868 [(set_attr "v8type" "move,alu,load1,store1,fmov,fmov,fmov")
869 (set_attr "mode" "SI")
870 (set_attr "fp" "*,*,*,*,yes,yes,yes")]
873 (define_insn "*movdi_aarch64"
874 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,m, r, r, *w, r,*w,w")
875 (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,m,rZ,Usa,Ush,rZ,*w,*w,Dd"))]
876 "(register_operand (operands[0], DImode)
877 || aarch64_reg_or_zero (operands[1], DImode))"
891 [(set_attr "v8type" "move,move,move,alu,load1,store1,adr,adr,fmov,fmov,fmov,fmov")
892 (set_attr "mode" "DI")
893 (set_attr "fp" "*,*,*,*,*,*,*,*,yes,yes,yes,yes")]
896 (define_insn "insv_imm<mode>"
897 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
899 (match_operand 1 "const_int_operand" "n"))
900 (match_operand 2 "const_int_operand" "n"))]
901 "INTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
902 && INTVAL (operands[1]) % 16 == 0
903 && INTVAL (operands[2]) <= 0xffff"
904 "movk\\t%<w>0, %2, lsl %1"
905 [(set_attr "v8type" "movk")
906 (set_attr "mode" "<MODE>")]
909 (define_expand "movti"
910 [(set (match_operand:TI 0 "nonimmediate_operand" "")
911 (match_operand:TI 1 "general_operand" ""))]
914 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
915 operands[1] = force_reg (TImode, operands[1]);
919 (define_insn "*movti_aarch64"
920 [(set (match_operand:TI 0
921 "nonimmediate_operand" "=r, *w,r ,*w,r ,Ump,Ump,*w,m")
923 "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r ,Z , m,*w"))]
924 "(register_operand (operands[0], TImode)
925 || aarch64_reg_or_zero (operands[1], TImode))"
930 orr\\t%0.16b, %1.16b, %1.16b
936 [(set_attr "v8type" "move2,fmovi2f,fmovf2i,*, \
937 load2,store2,store2,fpsimd_load,fpsimd_store")
938 (set_attr "simd_type" "*,*,*,simd_move,*,*,*,*,*")
939 (set_attr "mode" "DI,DI,DI,TI,DI,DI,DI,TI,TI")
940 (set_attr "length" "8,8,8,4,4,4,4,4,4")
941 (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")
942 (set_attr "simd" "*,*,*,yes,*,*,*,*,*")])
944 ;; Split a TImode register-register or register-immediate move into
945 ;; its component DImode pieces, taking care to handle overlapping
946 ;; source and dest registers.
948 [(set (match_operand:TI 0 "register_operand" "")
949 (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
950 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
953 aarch64_split_128bit_move (operands[0], operands[1]);
957 (define_expand "mov<mode>"
958 [(set (match_operand:GPF 0 "nonimmediate_operand" "")
959 (match_operand:GPF 1 "general_operand" ""))]
964 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
968 if (GET_CODE (operands[0]) == MEM)
969 operands[1] = force_reg (<MODE>mode, operands[1]);
973 (define_insn "*movsf_aarch64"
974 [(set (match_operand:SF 0 "nonimmediate_operand" "= w,?r,w,w,m,r,m ,r")
975 (match_operand:SF 1 "general_operand" "?rY, w,w,m,w,m,rY,r"))]
976 "TARGET_FLOAT && (register_operand (operands[0], SFmode)
977 || register_operand (operands[1], SFmode))"
987 [(set_attr "v8type" "fmovi2f,fmovf2i,fmov,fpsimd_load,fpsimd_store,fpsimd_load,fpsimd_store,fmov")
988 (set_attr "mode" "SF")]
991 (define_insn "*movdf_aarch64"
992 [(set (match_operand:DF 0 "nonimmediate_operand" "= w,?r,w,w,m,r,m ,r")
993 (match_operand:DF 1 "general_operand" "?rY, w,w,m,w,m,rY,r"))]
994 "TARGET_FLOAT && (register_operand (operands[0], DFmode)
995 || register_operand (operands[1], DFmode))"
1005 [(set_attr "v8type" "fmovi2f,fmovf2i,fmov,fpsimd_load,fpsimd_store,fpsimd_load,fpsimd_store,move")
1006 (set_attr "mode" "DF")]
1009 (define_expand "movtf"
1010 [(set (match_operand:TF 0 "nonimmediate_operand" "")
1011 (match_operand:TF 1 "general_operand" ""))]
1016 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
1020 if (GET_CODE (operands[0]) == MEM)
1021 operands[1] = force_reg (TFmode, operands[1]);
1025 (define_insn "*movtf_aarch64"
1026 [(set (match_operand:TF 0
1027 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
1029 "general_operand" " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
1030 "TARGET_FLOAT && (register_operand (operands[0], TFmode)
1031 || register_operand (operands[1], TFmode))"
1033 orr\\t%0.16b, %1.16b, %1.16b
1034 mov\\t%0, %1\;mov\\t%H0, %H1
1035 fmov\\t%d0, %Q1\;fmov\\t%0.d[1], %R1
1036 fmov\\t%Q0, %d1\;fmov\\t%R0, %1.d[1]
1043 [(set_attr "v8type" "logic,move2,fmovi2f,fmovf2i,fconst,fconst,fpsimd_load,fpsimd_store,fpsimd_load2,fpsimd_store2")
1044 (set_attr "mode" "DF,DF,DF,DF,DF,DF,TF,TF,DF,DF")
1045 (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
1046 (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
1047 (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
1051 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1052 ;; fairly lax checking on the second memory operation.
1053 (define_insn "load_pair<mode>"
1054 [(set (match_operand:GPI 0 "register_operand" "=r")
1055 (match_operand:GPI 1 "aarch64_mem_pair_operand" "Ump"))
1056 (set (match_operand:GPI 2 "register_operand" "=r")
1057 (match_operand:GPI 3 "memory_operand" "m"))]
1058 "rtx_equal_p (XEXP (operands[3], 0),
1059 plus_constant (Pmode,
1060 XEXP (operands[1], 0),
1061 GET_MODE_SIZE (<MODE>mode)))"
1062 "ldp\\t%<w>0, %<w>2, %1"
1063 [(set_attr "v8type" "load2")
1064 (set_attr "mode" "<MODE>")]
1067 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1068 ;; fairly lax checking on the second memory operation.
1069 (define_insn "store_pair<mode>"
1070 [(set (match_operand:GPI 0 "aarch64_mem_pair_operand" "=Ump")
1071 (match_operand:GPI 1 "register_operand" "r"))
1072 (set (match_operand:GPI 2 "memory_operand" "=m")
1073 (match_operand:GPI 3 "register_operand" "r"))]
1074 "rtx_equal_p (XEXP (operands[2], 0),
1075 plus_constant (Pmode,
1076 XEXP (operands[0], 0),
1077 GET_MODE_SIZE (<MODE>mode)))"
1078 "stp\\t%<w>1, %<w>3, %0"
1079 [(set_attr "v8type" "store2")
1080 (set_attr "mode" "<MODE>")]
1083 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1084 ;; fairly lax checking on the second memory operation.
1085 (define_insn "load_pair<mode>"
1086 [(set (match_operand:GPF 0 "register_operand" "=w")
1087 (match_operand:GPF 1 "aarch64_mem_pair_operand" "Ump"))
1088 (set (match_operand:GPF 2 "register_operand" "=w")
1089 (match_operand:GPF 3 "memory_operand" "m"))]
1090 "rtx_equal_p (XEXP (operands[3], 0),
1091 plus_constant (Pmode,
1092 XEXP (operands[1], 0),
1093 GET_MODE_SIZE (<MODE>mode)))"
1094 "ldp\\t%<w>0, %<w>2, %1"
1095 [(set_attr "v8type" "fpsimd_load2")
1096 (set_attr "mode" "<MODE>")]
1099 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1100 ;; fairly lax checking on the second memory operation.
1101 (define_insn "store_pair<mode>"
1102 [(set (match_operand:GPF 0 "aarch64_mem_pair_operand" "=Ump")
1103 (match_operand:GPF 1 "register_operand" "w"))
1104 (set (match_operand:GPF 2 "memory_operand" "=m")
1105 (match_operand:GPF 3 "register_operand" "w"))]
1106 "rtx_equal_p (XEXP (operands[2], 0),
1107 plus_constant (Pmode,
1108 XEXP (operands[0], 0),
1109 GET_MODE_SIZE (<MODE>mode)))"
1110 "stp\\t%<w>1, %<w>3, %0"
1111 [(set_attr "v8type" "fpsimd_load2")
1112 (set_attr "mode" "<MODE>")]
1115 ;; Load pair with writeback. This is primarily used in function epilogues
1116 ;; when restoring [fp,lr]
1117 (define_insn "loadwb_pair<GPI:mode>_<PTR:mode>"
1119 [(set (match_operand:PTR 0 "register_operand" "=k")
1120 (plus:PTR (match_operand:PTR 1 "register_operand" "0")
1121 (match_operand:PTR 4 "const_int_operand" "n")))
1122 (set (match_operand:GPI 2 "register_operand" "=r")
1123 (mem:GPI (plus:PTR (match_dup 1)
1125 (set (match_operand:GPI 3 "register_operand" "=r")
1126 (mem:GPI (plus:PTR (match_dup 1)
1127 (match_operand:PTR 5 "const_int_operand" "n"))))])]
1128 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1129 "ldp\\t%<w>2, %<w>3, [%1], %4"
1130 [(set_attr "v8type" "load2")
1131 (set_attr "mode" "<GPI:MODE>")]
1134 ;; Store pair with writeback. This is primarily used in function prologues
1135 ;; when saving [fp,lr]
1136 (define_insn "storewb_pair<GPI:mode>_<PTR:mode>"
1138 [(set (match_operand:PTR 0 "register_operand" "=&k")
1139 (plus:PTR (match_operand:PTR 1 "register_operand" "0")
1140 (match_operand:PTR 4 "const_int_operand" "n")))
1141 (set (mem:GPI (plus:PTR (match_dup 0)
1143 (match_operand:GPI 2 "register_operand" "r"))
1144 (set (mem:GPI (plus:PTR (match_dup 0)
1145 (match_operand:PTR 5 "const_int_operand" "n")))
1146 (match_operand:GPI 3 "register_operand" "r"))])]
1147 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1148 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1149 [(set_attr "v8type" "store2")
1150 (set_attr "mode" "<GPI:MODE>")]
1153 ;; -------------------------------------------------------------------
1154 ;; Sign/Zero extension
1155 ;; -------------------------------------------------------------------
1157 (define_expand "<optab>sidi2"
1158 [(set (match_operand:DI 0 "register_operand")
1159 (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1163 (define_insn "*extendsidi2_aarch64"
1164 [(set (match_operand:DI 0 "register_operand" "=r,r")
1165 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1170 [(set_attr "v8type" "extend,load1")
1171 (set_attr "mode" "DI")]
1174 (define_insn "*zero_extendsidi2_aarch64"
1175 [(set (match_operand:DI 0 "register_operand" "=r,r")
1176 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1181 [(set_attr "v8type" "extend,load1")
1182 (set_attr "mode" "DI")]
1185 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1186 [(set (match_operand:GPI 0 "register_operand")
1187 (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1191 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1192 [(set (match_operand:GPI 0 "register_operand" "=r,r")
1193 (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1196 sxt<SHORT:size>\t%<GPI:w>0, %w1
1197 ldrs<SHORT:size>\t%<GPI:w>0, %1"
1198 [(set_attr "v8type" "extend,load1")
1199 (set_attr "mode" "<GPI:MODE>")]
1202 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1203 [(set (match_operand:GPI 0 "register_operand" "=r,r")
1204 (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1207 uxt<SHORT:size>\t%<GPI:w>0, %w1
1208 ldr<SHORT:size>\t%w0, %1"
1209 [(set_attr "v8type" "extend,load1")
1210 (set_attr "mode" "<GPI:MODE>")]
1213 (define_expand "<optab>qihi2"
1214 [(set (match_operand:HI 0 "register_operand")
1215 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1219 (define_insn "*<optab>qihi2_aarch64"
1220 [(set (match_operand:HI 0 "register_operand" "=r,r")
1221 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1226 [(set_attr "v8type" "extend,load1")
1227 (set_attr "mode" "HI")]
1230 ;; -------------------------------------------------------------------
1231 ;; Simple arithmetic
1232 ;; -------------------------------------------------------------------
1234 (define_expand "add<mode>3"
1236 (match_operand:GPI 0 "register_operand" "")
1237 (plus:GPI (match_operand:GPI 1 "register_operand" "")
1238 (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1241 if (! aarch64_plus_operand (operands[2], VOIDmode))
1243 rtx subtarget = ((optimize && can_create_pseudo_p ())
1244 ? gen_reg_rtx (<MODE>mode) : operands[0]);
1245 HOST_WIDE_INT imm = INTVAL (operands[2]);
1248 imm = -(-imm & ~0xfff);
1252 emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1253 operands[1] = subtarget;
1254 operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1259 (define_insn "*addsi3_aarch64"
1261 (match_operand:SI 0 "register_operand" "=rk,rk,rk")
1263 (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1264 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J")))]
1269 sub\\t%w0, %w1, #%n2"
1270 [(set_attr "v8type" "alu")
1271 (set_attr "mode" "SI")]
1274 (define_insn "*adddi3_aarch64"
1276 (match_operand:DI 0 "register_operand" "=rk,rk,rk,!w")
1278 (match_operand:DI 1 "register_operand" "%rk,rk,rk,!w")
1279 (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,!w")))]
1284 sub\\t%x0, %x1, #%n2
1285 add\\t%d0, %d1, %d2"
1286 [(set_attr "v8type" "alu")
1287 (set_attr "mode" "DI")
1288 (set_attr "simd" "*,*,*,yes")]
1291 (define_insn "*add<mode>3_compare0"
1292 [(set (reg:CC_NZ CC_REGNUM)
1294 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r")
1295 (match_operand:GPI 2 "aarch64_plus_operand" "rI,J"))
1297 (set (match_operand:GPI 0 "register_operand" "=r,r")
1298 (plus:GPI (match_dup 1) (match_dup 2)))]
1301 adds\\t%<w>0, %<w>1, %<w>2
1302 subs\\t%<w>0, %<w>1, #%n2"
1303 [(set_attr "v8type" "alus")
1304 (set_attr "mode" "<MODE>")]
1307 (define_insn "*add<mode>3nr_compare0"
1308 [(set (reg:CC_NZ CC_REGNUM)
1310 (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r")
1311 (match_operand:GPI 1 "aarch64_plus_operand" "rI,J"))
1317 [(set_attr "v8type" "alus")
1318 (set_attr "mode" "<MODE>")]
1321 (define_insn "*add_<shift>_<mode>"
1322 [(set (match_operand:GPI 0 "register_operand" "=rk")
1323 (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1324 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1325 (match_operand:GPI 3 "register_operand" "r")))]
1327 "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1328 [(set_attr "v8type" "alu_shift")
1329 (set_attr "mode" "<MODE>")]
1332 (define_insn "*add_mul_imm_<mode>"
1333 [(set (match_operand:GPI 0 "register_operand" "=rk")
1334 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1335 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1336 (match_operand:GPI 3 "register_operand" "r")))]
1338 "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1339 [(set_attr "v8type" "alu_shift")
1340 (set_attr "mode" "<MODE>")]
1343 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1344 [(set (match_operand:GPI 0 "register_operand" "=rk")
1345 (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1346 (match_operand:GPI 2 "register_operand" "r")))]
1348 "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1349 [(set_attr "v8type" "alu_ext")
1350 (set_attr "mode" "<GPI:MODE>")]
1353 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1354 [(set (match_operand:GPI 0 "register_operand" "=rk")
1355 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1356 (match_operand:ALLX 1 "register_operand" "r"))
1357 (match_operand 2 "aarch64_imm3" "Ui3"))
1358 (match_operand:GPI 3 "register_operand" "r")))]
1360 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1361 [(set_attr "v8type" "alu_ext")
1362 (set_attr "mode" "<GPI:MODE>")]
1365 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1366 [(set (match_operand:GPI 0 "register_operand" "=rk")
1367 (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1368 (match_operand:ALLX 1 "register_operand" "r"))
1369 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1370 (match_operand:GPI 3 "register_operand" "r")))]
1372 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1373 [(set_attr "v8type" "alu_ext")
1374 (set_attr "mode" "<GPI:MODE>")]
1377 (define_insn "*add_<optab><mode>_multp2"
1378 [(set (match_operand:GPI 0 "register_operand" "=rk")
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")))]
1385 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1386 "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1387 [(set_attr "v8type" "alu_ext")
1388 (set_attr "mode" "<MODE>")]
1391 (define_insn "*add<mode>3_carryin"
1393 (match_operand:GPI 0 "register_operand" "=r")
1394 (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1396 (match_operand:GPI 1 "register_operand" "r")
1397 (match_operand:GPI 2 "register_operand" "r"))))]
1399 "adc\\t%<w>0, %<w>1, %<w>2"
1400 [(set_attr "v8type" "adc")
1401 (set_attr "mode" "<MODE>")]
1404 (define_insn "*add<mode>3_carryin_alt1"
1406 (match_operand:GPI 0 "register_operand" "=r")
1408 (match_operand:GPI 1 "register_operand" "r")
1409 (match_operand:GPI 2 "register_operand" "r"))
1410 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1412 "adc\\t%<w>0, %<w>1, %<w>2"
1413 [(set_attr "v8type" "adc")
1414 (set_attr "mode" "<MODE>")]
1417 (define_insn "*add<mode>3_carryin_alt2"
1419 (match_operand:GPI 0 "register_operand" "=r")
1421 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1422 (match_operand:GPI 1 "register_operand" "r"))
1423 (match_operand:GPI 2 "register_operand" "r")))]
1425 "adc\\t%<w>0, %<w>1, %<w>2"
1426 [(set_attr "v8type" "adc")
1427 (set_attr "mode" "<MODE>")]
1430 (define_insn "*add<mode>3_carryin_alt3"
1432 (match_operand:GPI 0 "register_operand" "=r")
1434 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1435 (match_operand:GPI 2 "register_operand" "r"))
1436 (match_operand:GPI 1 "register_operand" "r")))]
1438 "adc\\t%<w>0, %<w>1, %<w>2"
1439 [(set_attr "v8type" "adc")
1440 (set_attr "mode" "<MODE>")]
1443 (define_insn "*add_uxt<mode>_multp2"
1444 [(set (match_operand:GPI 0 "register_operand" "=rk")
1446 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1447 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1448 (match_operand 3 "const_int_operand" "n"))
1449 (match_operand:GPI 4 "register_operand" "r")))]
1450 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1452 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1453 INTVAL (operands[3])));
1454 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1455 [(set_attr "v8type" "alu_ext")
1456 (set_attr "mode" "<MODE>")]
1459 (define_insn "subsi3"
1460 [(set (match_operand:SI 0 "register_operand" "=rk")
1461 (minus:SI (match_operand:SI 1 "register_operand" "r")
1462 (match_operand:SI 2 "register_operand" "r")))]
1464 "sub\\t%w0, %w1, %w2"
1465 [(set_attr "v8type" "alu")
1466 (set_attr "mode" "SI")]
1469 (define_insn "subdi3"
1470 [(set (match_operand:DI 0 "register_operand" "=rk,!w")
1471 (minus:DI (match_operand:DI 1 "register_operand" "r,!w")
1472 (match_operand:DI 2 "register_operand" "r,!w")))]
1476 sub\\t%d0, %d1, %d2"
1477 [(set_attr "v8type" "alu")
1478 (set_attr "mode" "DI")
1479 (set_attr "simd" "*,yes")]
1483 (define_insn "*sub<mode>3_compare0"
1484 [(set (reg:CC_NZ CC_REGNUM)
1485 (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1486 (match_operand:GPI 2 "register_operand" "r"))
1488 (set (match_operand:GPI 0 "register_operand" "=r")
1489 (minus:GPI (match_dup 1) (match_dup 2)))]
1491 "subs\\t%<w>0, %<w>1, %<w>2"
1492 [(set_attr "v8type" "alus")
1493 (set_attr "mode" "<MODE>")]
1496 (define_insn "*sub_<shift>_<mode>"
1497 [(set (match_operand:GPI 0 "register_operand" "=rk")
1498 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1500 (match_operand:GPI 1 "register_operand" "r")
1501 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1503 "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1504 [(set_attr "v8type" "alu_shift")
1505 (set_attr "mode" "<MODE>")]
1508 (define_insn "*sub_mul_imm_<mode>"
1509 [(set (match_operand:GPI 0 "register_operand" "=rk")
1510 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1512 (match_operand:GPI 1 "register_operand" "r")
1513 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1515 "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1516 [(set_attr "v8type" "alu_shift")
1517 (set_attr "mode" "<MODE>")]
1520 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
1521 [(set (match_operand:GPI 0 "register_operand" "=rk")
1522 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1524 (match_operand:ALLX 2 "register_operand" "r"))))]
1526 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1527 [(set_attr "v8type" "alu_ext")
1528 (set_attr "mode" "<GPI:MODE>")]
1531 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
1532 [(set (match_operand:GPI 0 "register_operand" "=rk")
1533 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1534 (ashift:GPI (ANY_EXTEND:GPI
1535 (match_operand:ALLX 2 "register_operand" "r"))
1536 (match_operand 3 "aarch64_imm3" "Ui3"))))]
1538 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1539 [(set_attr "v8type" "alu_ext")
1540 (set_attr "mode" "<GPI:MODE>")]
1543 (define_insn "*sub_<optab><mode>_multp2"
1544 [(set (match_operand:GPI 0 "register_operand" "=rk")
1545 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1547 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1548 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1549 (match_operand 3 "const_int_operand" "n")
1551 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1552 "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1553 [(set_attr "v8type" "alu_ext")
1554 (set_attr "mode" "<MODE>")]
1557 (define_insn "*sub_uxt<mode>_multp2"
1558 [(set (match_operand:GPI 0 "register_operand" "=rk")
1559 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1561 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1562 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1563 (match_operand 3 "const_int_operand" "n"))))]
1564 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
1566 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1567 INTVAL (operands[3])));
1568 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1569 [(set_attr "v8type" "alu_ext")
1570 (set_attr "mode" "<MODE>")]
1573 (define_insn "neg<mode>2"
1574 [(set (match_operand:GPI 0 "register_operand" "=r")
1575 (neg:GPI (match_operand:GPI 1 "register_operand" "r")))]
1577 "neg\\t%<w>0, %<w>1"
1578 [(set_attr "v8type" "alu")
1579 (set_attr "mode" "<MODE>")]
1582 (define_insn "*neg<mode>2_compare0"
1583 [(set (reg:CC_NZ CC_REGNUM)
1584 (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
1586 (set (match_operand:GPI 0 "register_operand" "=r")
1587 (neg:GPI (match_dup 1)))]
1589 "negs\\t%<w>0, %<w>1"
1590 [(set_attr "v8type" "alus")
1591 (set_attr "mode" "<MODE>")]
1594 (define_insn "*neg_<shift>_<mode>2"
1595 [(set (match_operand:GPI 0 "register_operand" "=r")
1596 (neg:GPI (ASHIFT:GPI
1597 (match_operand:GPI 1 "register_operand" "r")
1598 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1600 "neg\\t%<w>0, %<w>1, <shift> %2"
1601 [(set_attr "v8type" "alu_shift")
1602 (set_attr "mode" "<MODE>")]
1605 (define_insn "*neg_mul_imm_<mode>2"
1606 [(set (match_operand:GPI 0 "register_operand" "=r")
1608 (match_operand:GPI 1 "register_operand" "r")
1609 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1611 "neg\\t%<w>0, %<w>1, lsl %p2"
1612 [(set_attr "v8type" "alu_shift")
1613 (set_attr "mode" "<MODE>")]
1616 (define_insn "mul<mode>3"
1617 [(set (match_operand:GPI 0 "register_operand" "=r")
1618 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1619 (match_operand:GPI 2 "register_operand" "r")))]
1621 "mul\\t%<w>0, %<w>1, %<w>2"
1622 [(set_attr "v8type" "mult")
1623 (set_attr "mode" "<MODE>")]
1626 (define_insn "*madd<mode>"
1627 [(set (match_operand:GPI 0 "register_operand" "=r")
1628 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1629 (match_operand:GPI 2 "register_operand" "r"))
1630 (match_operand:GPI 3 "register_operand" "r")))]
1632 "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
1633 [(set_attr "v8type" "madd")
1634 (set_attr "mode" "<MODE>")]
1637 (define_insn "*msub<mode>"
1638 [(set (match_operand:GPI 0 "register_operand" "=r")
1639 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1640 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1641 (match_operand:GPI 2 "register_operand" "r"))))]
1644 "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
1645 [(set_attr "v8type" "madd")
1646 (set_attr "mode" "<MODE>")]
1649 (define_insn "*mul<mode>_neg"
1650 [(set (match_operand:GPI 0 "register_operand" "=r")
1651 (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
1652 (match_operand:GPI 2 "register_operand" "r")))]
1655 "mneg\\t%<w>0, %<w>1, %<w>2"
1656 [(set_attr "v8type" "mult")
1657 (set_attr "mode" "<MODE>")]
1660 (define_insn "<su_optab>mulsidi3"
1661 [(set (match_operand:DI 0 "register_operand" "=r")
1662 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
1663 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
1665 "<su>mull\\t%0, %w1, %w2"
1666 [(set_attr "v8type" "mull")
1667 (set_attr "mode" "DI")]
1670 (define_insn "<su_optab>maddsidi4"
1671 [(set (match_operand:DI 0 "register_operand" "=r")
1673 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
1674 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
1675 (match_operand:DI 3 "register_operand" "r")))]
1677 "<su>maddl\\t%0, %w1, %w2, %3"
1678 [(set_attr "v8type" "maddl")
1679 (set_attr "mode" "DI")]
1682 (define_insn "<su_optab>msubsidi4"
1683 [(set (match_operand:DI 0 "register_operand" "=r")
1685 (match_operand:DI 3 "register_operand" "r")
1686 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
1688 (match_operand:SI 2 "register_operand" "r")))))]
1690 "<su>msubl\\t%0, %w1, %w2, %3"
1691 [(set_attr "v8type" "maddl")
1692 (set_attr "mode" "DI")]
1695 (define_insn "*<su_optab>mulsidi_neg"
1696 [(set (match_operand:DI 0 "register_operand" "=r")
1698 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
1699 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
1701 "<su>mnegl\\t%0, %w1, %w2"
1702 [(set_attr "v8type" "mull")
1703 (set_attr "mode" "DI")]
1706 (define_insn "<su>muldi3_highpart"
1707 [(set (match_operand:DI 0 "register_operand" "=r")
1711 (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
1712 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
1715 "<su>mulh\\t%0, %1, %2"
1716 [(set_attr "v8type" "mulh")
1717 (set_attr "mode" "DI")]
1720 (define_insn "<su_optab>div<mode>3"
1721 [(set (match_operand:GPI 0 "register_operand" "=r")
1722 (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
1723 (match_operand:GPI 2 "register_operand" "r")))]
1725 "<su>div\\t%<w>0, %<w>1, %<w>2"
1726 [(set_attr "v8type" "<su>div")
1727 (set_attr "mode" "<MODE>")]
1730 ;; -------------------------------------------------------------------
1732 ;; -------------------------------------------------------------------
1734 (define_insn "*cmp<mode>"
1735 [(set (reg:CC CC_REGNUM)
1736 (compare:CC (match_operand:GPI 0 "register_operand" "r,r")
1737 (match_operand:GPI 1 "aarch64_plus_operand" "rI,J")))]
1742 [(set_attr "v8type" "alus")
1743 (set_attr "mode" "<MODE>")]
1746 (define_insn "*cmp<mode>"
1747 [(set (reg:CCFP CC_REGNUM)
1748 (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
1749 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
1753 fcmp\\t%<s>0, %<s>1"
1754 [(set_attr "v8type" "fcmp")
1755 (set_attr "mode" "<MODE>")]
1758 (define_insn "*cmpe<mode>"
1759 [(set (reg:CCFPE CC_REGNUM)
1760 (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
1761 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
1765 fcmpe\\t%<s>0, %<s>1"
1766 [(set_attr "v8type" "fcmp")
1767 (set_attr "mode" "<MODE>")]
1770 (define_insn "*cmp_swp_<shift>_reg<mode>"
1771 [(set (reg:CC_SWP CC_REGNUM)
1772 (compare:CC_SWP (ASHIFT:GPI
1773 (match_operand:GPI 0 "register_operand" "r")
1774 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
1775 (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
1777 "cmp\\t%<w>2, %<w>0, <shift> %1"
1778 [(set_attr "v8type" "alus_shift")
1779 (set_attr "mode" "<MODE>")]
1782 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
1783 [(set (reg:CC_SWP CC_REGNUM)
1784 (compare:CC_SWP (ANY_EXTEND:GPI
1785 (match_operand:ALLX 0 "register_operand" "r"))
1786 (match_operand:GPI 1 "register_operand" "r")))]
1788 "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
1789 [(set_attr "v8type" "alus_ext")
1790 (set_attr "mode" "<GPI:MODE>")]
1794 ;; -------------------------------------------------------------------
1795 ;; Store-flag and conditional select insns
1796 ;; -------------------------------------------------------------------
1798 (define_expand "cstore<mode>4"
1799 [(set (match_operand:SI 0 "register_operand" "")
1800 (match_operator:SI 1 "aarch64_comparison_operator"
1801 [(match_operand:GPI 2 "register_operand" "")
1802 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
1805 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
1807 operands[3] = const0_rtx;
1811 (define_expand "cstore<mode>4"
1812 [(set (match_operand:SI 0 "register_operand" "")
1813 (match_operator:SI 1 "aarch64_comparison_operator"
1814 [(match_operand:GPF 2 "register_operand" "")
1815 (match_operand:GPF 3 "register_operand" "")]))]
1818 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
1820 operands[3] = const0_rtx;
1824 (define_insn "*cstore<mode>_insn"
1825 [(set (match_operand:ALLI 0 "register_operand" "=r")
1826 (match_operator:ALLI 1 "aarch64_comparison_operator"
1827 [(match_operand 2 "cc_register" "") (const_int 0)]))]
1830 [(set_attr "v8type" "csel")
1831 (set_attr "mode" "<MODE>")]
1834 (define_insn "*cstore<mode>_neg"
1835 [(set (match_operand:ALLI 0 "register_operand" "=r")
1836 (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
1837 [(match_operand 2 "cc_register" "") (const_int 0)])))]
1839 "csetm\\t%<w>0, %m1"
1840 [(set_attr "v8type" "csel")
1841 (set_attr "mode" "<MODE>")]
1844 (define_expand "cmov<mode>6"
1845 [(set (match_operand:GPI 0 "register_operand" "")
1847 (match_operator 1 "aarch64_comparison_operator"
1848 [(match_operand:GPI 2 "register_operand" "")
1849 (match_operand:GPI 3 "aarch64_plus_operand" "")])
1850 (match_operand:GPI 4 "register_operand" "")
1851 (match_operand:GPI 5 "register_operand" "")))]
1854 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
1856 operands[3] = const0_rtx;
1860 (define_expand "cmov<mode>6"
1861 [(set (match_operand:GPF 0 "register_operand" "")
1863 (match_operator 1 "aarch64_comparison_operator"
1864 [(match_operand:GPF 2 "register_operand" "")
1865 (match_operand:GPF 3 "register_operand" "")])
1866 (match_operand:GPF 4 "register_operand" "")
1867 (match_operand:GPF 5 "register_operand" "")))]
1870 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
1872 operands[3] = const0_rtx;
1876 (define_insn "*cmov<mode>_insn"
1877 [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r")
1879 (match_operator 1 "aarch64_comparison_operator"
1880 [(match_operand 2 "cc_register" "") (const_int 0)])
1881 (match_operand:ALLI 3 "aarch64_reg_zero_or_m1" "rZ,rZ,UsM,UsM")
1882 (match_operand:ALLI 4 "aarch64_reg_zero_or_m1" "rZ,UsM,rZ,UsM")))]
1884 ;; Final alternative should be unreachable, but included for completeness
1886 csel\\t%<w>0, %<w>3, %<w>4, %m1
1887 csinv\\t%<w>0, %<w>3, <w>zr, %m1
1888 csinv\\t%<w>0, %<w>4, <w>zr, %M1
1890 [(set_attr "v8type" "csel")
1891 (set_attr "mode" "<MODE>")]
1894 (define_insn "*cmov<mode>_insn"
1895 [(set (match_operand:GPF 0 "register_operand" "=w")
1897 (match_operator 1 "aarch64_comparison_operator"
1898 [(match_operand 2 "cc_register" "") (const_int 0)])
1899 (match_operand:GPF 3 "register_operand" "w")
1900 (match_operand:GPF 4 "register_operand" "w")))]
1902 "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
1903 [(set_attr "v8type" "fcsel")
1904 (set_attr "mode" "<MODE>")]
1907 (define_expand "mov<mode>cc"
1908 [(set (match_operand:ALLI 0 "register_operand" "")
1909 (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
1910 (match_operand:ALLI 2 "register_operand" "")
1911 (match_operand:ALLI 3 "register_operand" "")))]
1915 enum rtx_code code = GET_CODE (operands[1]);
1917 if (code == UNEQ || code == LTGT)
1920 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
1921 XEXP (operands[1], 1));
1922 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
1926 (define_expand "mov<GPF:mode><GPI:mode>cc"
1927 [(set (match_operand:GPI 0 "register_operand" "")
1928 (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
1929 (match_operand:GPF 2 "register_operand" "")
1930 (match_operand:GPF 3 "register_operand" "")))]
1934 enum rtx_code code = GET_CODE (operands[1]);
1936 if (code == UNEQ || code == LTGT)
1939 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
1940 XEXP (operands[1], 1));
1941 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
1945 (define_insn "*csinc2<mode>_insn"
1946 [(set (match_operand:GPI 0 "register_operand" "=r")
1947 (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator"
1948 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
1949 (match_operand:GPI 1 "register_operand" "r")))]
1951 "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
1952 [(set_attr "v8type" "csel")
1953 (set_attr "mode" "<MODE>")])
1955 (define_insn "csinc3<mode>_insn"
1956 [(set (match_operand:GPI 0 "register_operand" "=r")
1958 (match_operator:GPI 1 "aarch64_comparison_operator"
1959 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
1960 (plus:GPI (match_operand:GPI 3 "register_operand" "r")
1962 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
1964 "csinc\\t%<w>0, %<w>4, %<w>3, %M1"
1965 [(set_attr "v8type" "csel")
1966 (set_attr "mode" "<MODE>")]
1969 (define_insn "*csinv3<mode>_insn"
1970 [(set (match_operand:GPI 0 "register_operand" "=r")
1972 (match_operator:GPI 1 "aarch64_comparison_operator"
1973 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
1974 (not:GPI (match_operand:GPI 3 "register_operand" "r"))
1975 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
1977 "csinv\\t%<w>0, %<w>4, %<w>3, %M1"
1978 [(set_attr "v8type" "csel")
1979 (set_attr "mode" "<MODE>")])
1981 (define_insn "*csneg3<mode>_insn"
1982 [(set (match_operand:GPI 0 "register_operand" "=r")
1984 (match_operator:GPI 1 "aarch64_comparison_operator"
1985 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
1986 (neg:GPI (match_operand:GPI 3 "register_operand" "r"))
1987 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
1989 "csneg\\t%<w>0, %<w>4, %<w>3, %M1"
1990 [(set_attr "v8type" "csel")
1991 (set_attr "mode" "<MODE>")])
1993 ;; -------------------------------------------------------------------
1994 ;; Logical operations
1995 ;; -------------------------------------------------------------------
1997 (define_insn "<optab><mode>3"
1998 [(set (match_operand:GPI 0 "register_operand" "=r,rk")
1999 (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2000 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
2002 "<logical>\\t%<w>0, %<w>1, %<w>2"
2003 [(set_attr "v8type" "logic,logic_imm")
2004 (set_attr "mode" "<MODE>")])
2006 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2007 [(set (match_operand:GPI 0 "register_operand" "=r")
2008 (LOGICAL:GPI (SHIFT:GPI
2009 (match_operand:GPI 1 "register_operand" "r")
2010 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2011 (match_operand:GPI 3 "register_operand" "r")))]
2013 "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2014 [(set_attr "v8type" "logic_shift")
2015 (set_attr "mode" "<MODE>")])
2017 (define_insn "one_cmpl<mode>2"
2018 [(set (match_operand:GPI 0 "register_operand" "=r")
2019 (not:GPI (match_operand:GPI 1 "register_operand" "r")))]
2021 "mvn\\t%<w>0, %<w>1"
2022 [(set_attr "v8type" "logic")
2023 (set_attr "mode" "<MODE>")])
2025 (define_insn "*one_cmpl_<optab><mode>2"
2026 [(set (match_operand:GPI 0 "register_operand" "=r")
2027 (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
2028 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2030 "mvn\\t%<w>0, %<w>1, <shift> %2"
2031 [(set_attr "v8type" "logic_shift")
2032 (set_attr "mode" "<MODE>")])
2034 (define_insn "*<LOGICAL:optab>_one_cmpl<mode>3"
2035 [(set (match_operand:GPI 0 "register_operand" "=r")
2036 (LOGICAL:GPI (not:GPI
2037 (match_operand:GPI 1 "register_operand" "r"))
2038 (match_operand:GPI 2 "register_operand" "r")))]
2040 "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1"
2041 [(set_attr "v8type" "logic")
2042 (set_attr "mode" "<MODE>")])
2044 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
2045 [(set (match_operand:GPI 0 "register_operand" "=r")
2046 (LOGICAL:GPI (not:GPI
2048 (match_operand:GPI 1 "register_operand" "r")
2049 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2050 (match_operand:GPI 3 "register_operand" "r")))]
2052 "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2053 [(set_attr "v8type" "logic_shift")
2054 (set_attr "mode" "<MODE>")])
2056 (define_insn "clz<mode>2"
2057 [(set (match_operand:GPI 0 "register_operand" "=r")
2058 (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
2060 "clz\\t%<w>0, %<w>1"
2061 [(set_attr "v8type" "clz")
2062 (set_attr "mode" "<MODE>")])
2064 (define_expand "ffs<mode>2"
2065 [(match_operand:GPI 0 "register_operand")
2066 (match_operand:GPI 1 "register_operand")]
2069 rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
2070 rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
2072 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2073 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2074 emit_insn (gen_csinc3<mode>_insn (operands[0], x, ccreg, operands[0], const0_rtx));
2079 (define_insn "clrsb<mode>2"
2080 [(set (match_operand:GPI 0 "register_operand" "=r")
2081 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_CLS))]
2083 "cls\\t%<w>0, %<w>1"
2084 [(set_attr "v8type" "clz")
2085 (set_attr "mode" "<MODE>")])
2087 (define_insn "rbit<mode>2"
2088 [(set (match_operand:GPI 0 "register_operand" "=r")
2089 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
2091 "rbit\\t%<w>0, %<w>1"
2092 [(set_attr "v8type" "rbit")
2093 (set_attr "mode" "<MODE>")])
2095 (define_expand "ctz<mode>2"
2096 [(match_operand:GPI 0 "register_operand")
2097 (match_operand:GPI 1 "register_operand")]
2100 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
2101 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
2106 (define_insn "*and<mode>3nr_compare0"
2107 [(set (reg:CC CC_REGNUM)
2109 (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
2110 (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
2113 "tst\\t%<w>0, %<w>1"
2114 [(set_attr "v8type" "logics")
2115 (set_attr "mode" "<MODE>")])
2117 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
2118 [(set (reg:CC CC_REGNUM)
2121 (match_operand:GPI 0 "register_operand" "r")
2122 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2123 (match_operand:GPI 2 "register_operand" "r"))
2126 "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
2127 [(set_attr "v8type" "logics_shift")
2128 (set_attr "mode" "<MODE>")])
2130 ;; -------------------------------------------------------------------
2132 ;; -------------------------------------------------------------------
2134 (define_expand "<optab><mode>3"
2135 [(set (match_operand:GPI 0 "register_operand")
2136 (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
2137 (match_operand:QI 2 "nonmemory_operand")))]
2140 if (CONST_INT_P (operands[2]))
2142 operands[2] = GEN_INT (INTVAL (operands[2])
2143 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2145 if (operands[2] == const0_rtx)
2147 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2154 (define_expand "ashl<mode>3"
2155 [(set (match_operand:SHORT 0 "register_operand")
2156 (ashift:SHORT (match_operand:SHORT 1 "register_operand")
2157 (match_operand:QI 2 "nonmemory_operand")))]
2160 if (CONST_INT_P (operands[2]))
2162 operands[2] = GEN_INT (INTVAL (operands[2])
2163 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2165 if (operands[2] == const0_rtx)
2167 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2174 (define_expand "rotr<mode>3"
2175 [(set (match_operand:GPI 0 "register_operand")
2176 (rotatert:GPI (match_operand:GPI 1 "register_operand")
2177 (match_operand:QI 2 "nonmemory_operand")))]
2180 if (CONST_INT_P (operands[2]))
2182 operands[2] = GEN_INT (INTVAL (operands[2])
2183 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2185 if (operands[2] == const0_rtx)
2187 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2194 (define_expand "rotl<mode>3"
2195 [(set (match_operand:GPI 0 "register_operand")
2196 (rotatert:GPI (match_operand:GPI 1 "register_operand")
2197 (match_operand:QI 2 "nonmemory_operand")))]
2200 /* (SZ - cnt) % SZ == -cnt % SZ */
2201 if (CONST_INT_P (operands[2]))
2203 operands[2] = GEN_INT ((-INTVAL (operands[2]))
2204 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
2205 if (operands[2] == const0_rtx)
2207 emit_insn (gen_mov<mode> (operands[0], operands[1]));
2212 operands[2] = expand_simple_unop (QImode, NEG, operands[2],
2217 (define_insn "*<optab><mode>3_insn"
2218 [(set (match_operand:GPI 0 "register_operand" "=r")
2220 (match_operand:GPI 1 "register_operand" "r")
2221 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
2223 "<shift>\\t%<w>0, %<w>1, %<w>2"
2224 [(set_attr "v8type" "shift")
2225 (set_attr "mode" "<MODE>")]
2228 (define_insn "*ashl<mode>3_insn"
2229 [(set (match_operand:SHORT 0 "register_operand" "=r")
2230 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
2231 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
2233 "lsl\\t%<w>0, %<w>1, %<w>2"
2234 [(set_attr "v8type" "shift")
2235 (set_attr "mode" "<MODE>")]
2238 (define_insn "*<optab><mode>3_insn"
2239 [(set (match_operand:SHORT 0 "register_operand" "=r")
2240 (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
2241 (match_operand 2 "const_int_operand" "n")))]
2242 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
2244 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
2245 return "<bfshift>\t%w0, %w1, %2, %3";
2247 [(set_attr "v8type" "bfm")
2248 (set_attr "mode" "<MODE>")]
2251 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
2252 [(set (match_operand:GPI 0 "register_operand" "=r")
2254 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
2255 (match_operand 2 "const_int_operand" "n"))))]
2256 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
2258 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
2259 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
2261 [(set_attr "v8type" "bfm")
2262 (set_attr "mode" "<GPI:MODE>")]
2265 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
2266 [(set (match_operand:GPI 0 "register_operand" "=r")
2268 (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
2269 (match_operand 2 "const_int_operand" "n"))))]
2270 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
2272 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
2273 return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
2275 [(set_attr "v8type" "bfm")
2276 (set_attr "mode" "<GPI:MODE>")]
2279 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
2280 [(set (match_operand:GPI 0 "register_operand" "=r")
2282 (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
2283 (match_operand 2 "const_int_operand" "n"))))]
2284 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
2286 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
2287 return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
2289 [(set_attr "v8type" "bfm")
2290 (set_attr "mode" "<GPI:MODE>")]
2293 ;; -------------------------------------------------------------------
2295 ;; -------------------------------------------------------------------
2297 (define_expand "<optab>"
2298 [(set (match_operand:DI 0 "register_operand" "=r")
2299 (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
2300 (match_operand 2 "const_int_operand" "n")
2301 (match_operand 3 "const_int_operand" "n")))]
2306 (define_insn "*<optab><mode>"
2307 [(set (match_operand:GPI 0 "register_operand" "=r")
2308 (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
2309 (match_operand 2 "const_int_operand" "n")
2310 (match_operand 3 "const_int_operand" "n")))]
2312 "<su>bfx\\t%<w>0, %<w>1, %3, %2"
2313 [(set_attr "v8type" "bfm")
2314 (set_attr "mode" "<MODE>")]
2317 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
2318 [(set (match_operand:GPI 0 "register_operand" "=r")
2319 (ashift:GPI (ANY_EXTEND:GPI
2320 (match_operand:ALLX 1 "register_operand" "r"))
2321 (match_operand 2 "const_int_operand" "n")))]
2322 "UINTVAL (operands[2]) < <GPI:sizen>"
2324 operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
2325 ? GEN_INT (<ALLX:sizen>)
2326 : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
2327 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
2329 [(set_attr "v8type" "bfm")
2330 (set_attr "mode" "<GPI:MODE>")]
2333 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
2335 (define_insn "*andim_ashift<mode>_bfiz"
2336 [(set (match_operand:GPI 0 "register_operand" "=r")
2337 (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
2338 (match_operand 2 "const_int_operand" "n"))
2339 (match_operand 3 "const_int_operand" "n")))]
2340 "exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
2341 && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
2342 "ubfiz\\t%<w>0, %<w>1, %2, %P3"
2343 [(set_attr "v8type" "bfm")
2344 (set_attr "mode" "<MODE>")]
2347 (define_insn "bswap<mode>2"
2348 [(set (match_operand:GPI 0 "register_operand" "=r")
2349 (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
2351 "rev\\t%<w>0, %<w>1"
2352 [(set_attr "v8type" "rev")
2353 (set_attr "mode" "<MODE>")]
2356 ;; -------------------------------------------------------------------
2357 ;; Floating-point intrinsics
2358 ;; -------------------------------------------------------------------
2362 (define_insn "btrunc<mode>2"
2363 [(set (match_operand:GPF 0 "register_operand" "=w")
2364 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2367 "frintz\\t%<s>0, %<s>1"
2368 [(set_attr "v8type" "frint")
2369 (set_attr "mode" "<MODE>")]
2372 (define_insn "*lbtrunc<su_optab><GPF:mode><GPI:mode>2"
2373 [(set (match_operand:GPI 0 "register_operand" "=r")
2374 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2377 "fcvtz<su>\\t%<GPI:w>0, %<GPF:s>1"
2378 [(set_attr "v8type" "fcvtf2i")
2379 (set_attr "mode" "<GPF:MODE>")
2380 (set_attr "mode2" "<GPI:MODE>")]
2385 (define_insn "ceil<mode>2"
2386 [(set (match_operand:GPF 0 "register_operand" "=w")
2387 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2390 "frintp\\t%<s>0, %<s>1"
2391 [(set_attr "v8type" "frint")
2392 (set_attr "mode" "<MODE>")]
2395 (define_insn "lceil<su_optab><GPF:mode><GPI:mode>2"
2396 [(set (match_operand:GPI 0 "register_operand" "=r")
2397 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2400 "fcvtp<su>\\t%<GPI:w>0, %<GPF:s>1"
2401 [(set_attr "v8type" "fcvtf2i")
2402 (set_attr "mode" "<GPF:MODE>")
2403 (set_attr "mode2" "<GPI:MODE>")]
2408 (define_insn "floor<mode>2"
2409 [(set (match_operand:GPF 0 "register_operand" "=w")
2410 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2413 "frintm\\t%<s>0, %<s>1"
2414 [(set_attr "v8type" "frint")
2415 (set_attr "mode" "<MODE>")]
2418 (define_insn "lfloor<su_optab><GPF:mode><GPI:mode>2"
2419 [(set (match_operand:GPI 0 "register_operand" "=r")
2420 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2423 "fcvtm<su>\\t%<GPI:w>0, %<GPF:s>1"
2424 [(set_attr "v8type" "fcvtf2i")
2425 (set_attr "mode" "<GPF:MODE>")
2426 (set_attr "mode2" "<GPI:MODE>")]
2429 ;; nearbyint - nothrow
2431 (define_insn "nearbyint<mode>2"
2432 [(set (match_operand:GPF 0 "register_operand" "=w")
2433 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2436 "frinti\\t%<s>0, %<s>1"
2437 [(set_attr "v8type" "frint")
2438 (set_attr "mode" "<MODE>")]
2443 (define_insn "rint<mode>2"
2444 [(set (match_operand:GPF 0 "register_operand" "=w")
2445 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2448 "frintx\\t%<s>0, %<s>1"
2449 [(set_attr "v8type" "frint")
2450 (set_attr "mode" "<MODE>")]
2455 (define_insn "round<mode>2"
2456 [(set (match_operand:GPF 0 "register_operand" "=w")
2457 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2460 "frinta\\t%<s>0, %<s>1"
2461 [(set_attr "v8type" "frint")
2462 (set_attr "mode" "<MODE>")]
2465 (define_insn "lround<su_optab><GPF:mode><GPI:mode>2"
2466 [(set (match_operand:GPI 0 "register_operand" "=r")
2467 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
2470 "fcvta<su>\\t%<GPI:w>0, %<GPF:s>1"
2471 [(set_attr "v8type" "fcvtf2i")
2472 (set_attr "mode" "<GPF:MODE>")
2473 (set_attr "mode2" "<GPI:MODE>")]
2478 (define_insn "fma<mode>4"
2479 [(set (match_operand:GPF 0 "register_operand" "=w")
2480 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
2481 (match_operand:GPF 2 "register_operand" "w")
2482 (match_operand:GPF 3 "register_operand" "w")))]
2484 "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
2485 [(set_attr "v8type" "fmadd")
2486 (set_attr "mode" "<MODE>")]
2489 (define_insn "fnma<mode>4"
2490 [(set (match_operand:GPF 0 "register_operand" "=w")
2491 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
2492 (match_operand:GPF 2 "register_operand" "w")
2493 (match_operand:GPF 3 "register_operand" "w")))]
2495 "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
2496 [(set_attr "v8type" "fmadd")
2497 (set_attr "mode" "<MODE>")]
2500 (define_insn "fms<mode>4"
2501 [(set (match_operand:GPF 0 "register_operand" "=w")
2502 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
2503 (match_operand:GPF 2 "register_operand" "w")
2504 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
2506 "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
2507 [(set_attr "v8type" "fmadd")
2508 (set_attr "mode" "<MODE>")]
2511 (define_insn "fnms<mode>4"
2512 [(set (match_operand:GPF 0 "register_operand" "=w")
2513 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
2514 (match_operand:GPF 2 "register_operand" "w")
2515 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
2517 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
2518 [(set_attr "v8type" "fmadd")
2519 (set_attr "mode" "<MODE>")]
2522 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
2523 (define_insn "*fnmadd<mode>4"
2524 [(set (match_operand:GPF 0 "register_operand" "=w")
2525 (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
2526 (match_operand:GPF 2 "register_operand" "w")
2527 (match_operand:GPF 3 "register_operand" "w"))))]
2528 "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
2529 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
2530 [(set_attr "v8type" "fmadd")
2531 (set_attr "mode" "<MODE>")]
2534 ;; -------------------------------------------------------------------
2535 ;; Floating-point conversions
2536 ;; -------------------------------------------------------------------
2538 (define_insn "extendsfdf2"
2539 [(set (match_operand:DF 0 "register_operand" "=w")
2540 (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
2543 [(set_attr "v8type" "fcvt")
2544 (set_attr "mode" "DF")
2545 (set_attr "mode2" "SF")]
2548 (define_insn "truncdfsf2"
2549 [(set (match_operand:SF 0 "register_operand" "=w")
2550 (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
2553 [(set_attr "v8type" "fcvt")
2554 (set_attr "mode" "SF")
2555 (set_attr "mode2" "DF")]
2558 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
2559 [(set (match_operand:GPI 0 "register_operand" "=r")
2560 (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
2562 "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
2563 [(set_attr "v8type" "fcvtf2i")
2564 (set_attr "mode" "<GPF:MODE>")
2565 (set_attr "mode2" "<GPI:MODE>")]
2568 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
2569 [(set (match_operand:GPI 0 "register_operand" "=r")
2570 (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
2572 "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
2573 [(set_attr "v8type" "fcvtf2i")
2574 (set_attr "mode" "<GPF:MODE>")
2575 (set_attr "mode2" "<GPI:MODE>")]
2578 (define_insn "float<GPI:mode><GPF:mode>2"
2579 [(set (match_operand:GPF 0 "register_operand" "=w")
2580 (float:GPF (match_operand:GPI 1 "register_operand" "r")))]
2582 "scvtf\\t%<GPF:s>0, %<GPI:w>1"
2583 [(set_attr "v8type" "fcvti2f")
2584 (set_attr "mode" "<GPF:MODE>")
2585 (set_attr "mode2" "<GPI:MODE>")]
2588 (define_insn "floatuns<GPI:mode><GPF:mode>2"
2589 [(set (match_operand:GPF 0 "register_operand" "=w")
2590 (unsigned_float:GPF (match_operand:GPI 1 "register_operand" "r")))]
2592 "ucvtf\\t%<GPF:s>0, %<GPI:w>1"
2593 [(set_attr "v8type" "fcvt")
2594 (set_attr "mode" "<GPF:MODE>")
2595 (set_attr "mode2" "<GPI:MODE>")]
2598 ;; -------------------------------------------------------------------
2599 ;; Floating-point arithmetic
2600 ;; -------------------------------------------------------------------
2602 (define_insn "add<mode>3"
2603 [(set (match_operand:GPF 0 "register_operand" "=w")
2605 (match_operand:GPF 1 "register_operand" "w")
2606 (match_operand:GPF 2 "register_operand" "w")))]
2608 "fadd\\t%<s>0, %<s>1, %<s>2"
2609 [(set_attr "v8type" "fadd")
2610 (set_attr "mode" "<MODE>")]
2613 (define_insn "sub<mode>3"
2614 [(set (match_operand:GPF 0 "register_operand" "=w")
2616 (match_operand:GPF 1 "register_operand" "w")
2617 (match_operand:GPF 2 "register_operand" "w")))]
2619 "fsub\\t%<s>0, %<s>1, %<s>2"
2620 [(set_attr "v8type" "fadd")
2621 (set_attr "mode" "<MODE>")]
2624 (define_insn "mul<mode>3"
2625 [(set (match_operand:GPF 0 "register_operand" "=w")
2627 (match_operand:GPF 1 "register_operand" "w")
2628 (match_operand:GPF 2 "register_operand" "w")))]
2630 "fmul\\t%<s>0, %<s>1, %<s>2"
2631 [(set_attr "v8type" "fmul")
2632 (set_attr "mode" "<MODE>")]
2635 (define_insn "*fnmul<mode>3"
2636 [(set (match_operand:GPF 0 "register_operand" "=w")
2638 (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
2639 (match_operand:GPF 2 "register_operand" "w")))]
2641 "fnmul\\t%<s>0, %<s>1, %<s>2"
2642 [(set_attr "v8type" "fmul")
2643 (set_attr "mode" "<MODE>")]
2646 (define_insn "div<mode>3"
2647 [(set (match_operand:GPF 0 "register_operand" "=w")
2649 (match_operand:GPF 1 "register_operand" "w")
2650 (match_operand:GPF 2 "register_operand" "w")))]
2652 "fdiv\\t%<s>0, %<s>1, %<s>2"
2653 [(set_attr "v8type" "fdiv")
2654 (set_attr "mode" "<MODE>")]
2657 (define_insn "neg<mode>2"
2658 [(set (match_operand:GPF 0 "register_operand" "=w")
2659 (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
2661 "fneg\\t%<s>0, %<s>1"
2662 [(set_attr "v8type" "ffarith")
2663 (set_attr "mode" "<MODE>")]
2666 (define_insn "sqrt<mode>2"
2667 [(set (match_operand:GPF 0 "register_operand" "=w")
2668 (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
2670 "fsqrt\\t%<s>0, %<s>1"
2671 [(set_attr "v8type" "fsqrt")
2672 (set_attr "mode" "<MODE>")]
2675 (define_insn "abs<mode>2"
2676 [(set (match_operand:GPF 0 "register_operand" "=w")
2677 (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
2679 "fabs\\t%<s>0, %<s>1"
2680 [(set_attr "v8type" "ffarith")
2681 (set_attr "mode" "<MODE>")]
2684 ;; Given that smax/smin do not specify the result when either input is NaN,
2685 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
2688 (define_insn "smax<mode>3"
2689 [(set (match_operand:GPF 0 "register_operand" "=w")
2690 (smax:GPF (match_operand:GPF 1 "register_operand" "w")
2691 (match_operand:GPF 2 "register_operand" "w")))]
2693 "fmaxnm\\t%<s>0, %<s>1, %<s>2"
2694 [(set_attr "v8type" "fminmax")
2695 (set_attr "mode" "<MODE>")]
2698 (define_insn "smin<mode>3"
2699 [(set (match_operand:GPF 0 "register_operand" "=w")
2700 (smin:GPF (match_operand:GPF 1 "register_operand" "w")
2701 (match_operand:GPF 2 "register_operand" "w")))]
2703 "fminnm\\t%<s>0, %<s>1, %<s>2"
2704 [(set_attr "v8type" "fminmax")
2705 (set_attr "mode" "<MODE>")]
2708 ;; -------------------------------------------------------------------
2710 ;; -------------------------------------------------------------------
2712 ;; Reload SP+imm where imm cannot be handled by a single ADD instruction.
2713 ;; Must load imm into a scratch register and copy SP to the dest reg before
2714 ;; adding, since SP cannot be used as a source register in an ADD
2716 (define_expand "reload_sp_immediate"
2717 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
2718 (match_operand:DI 1 "" ""))
2719 (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
2722 rtx sp = XEXP (operands[1], 0);
2723 rtx val = XEXP (operands[1], 1);
2724 unsigned regno = REGNO (operands[2]);
2725 rtx scratch = operands[1];
2726 gcc_assert (GET_CODE (operands[1]) == PLUS);
2727 gcc_assert (sp == stack_pointer_rtx);
2728 gcc_assert (CONST_INT_P (val));
2730 /* It is possible that one of the registers we got for operands[2]
2731 might coincide with that of operands[0] (which is why we made
2732 it TImode). Pick the other one to use as our scratch. */
2733 if (regno == REGNO (operands[0]))
2735 scratch = gen_rtx_REG (DImode, regno);
2737 emit_move_insn (scratch, val);
2738 emit_move_insn (operands[0], sp);
2739 emit_insn (gen_adddi3 (operands[0], operands[0], scratch));
2744 (define_expand "aarch64_reload_mov<mode>"
2745 [(set (match_operand:TX 0 "register_operand" "=w")
2746 (match_operand:TX 1 "register_operand" "w"))
2747 (clobber (match_operand:DI 2 "register_operand" "=&r"))
2751 rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
2752 rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
2753 gen_aarch64_movtilow_tilow (op0, op1);
2754 gen_aarch64_movdi_tihigh (operands[2], op1);
2755 gen_aarch64_movtihigh_di (op0, operands[2]);
2760 ;; The following secondary reload helpers patterns are invoked
2761 ;; after or during reload as we don't want these patterns to start
2762 ;; kicking in during the combiner.
2764 (define_insn "aarch64_movdi_tilow"
2765 [(set (match_operand:DI 0 "register_operand" "=r")
2766 (truncate:DI (match_operand:TI 1 "register_operand" "w")))]
2767 "reload_completed || reload_in_progress"
2769 [(set_attr "v8type" "fmovf2i")
2770 (set_attr "mode" "DI")
2771 (set_attr "length" "4")
2774 (define_insn "aarch64_movdi_tihigh"
2775 [(set (match_operand:DI 0 "register_operand" "=r")
2777 (lshiftrt:TI (match_operand:TI 1 "register_operand" "w")
2779 "reload_completed || reload_in_progress"
2780 "fmov\\t%x0, %1.d[1]"
2781 [(set_attr "v8type" "fmovf2i")
2782 (set_attr "mode" "DI")
2783 (set_attr "length" "4")
2786 (define_insn "aarch64_movtihigh_di"
2787 [(set (zero_extract:TI (match_operand:TI 0 "register_operand" "+w")
2788 (const_int 64) (const_int 64))
2789 (zero_extend:TI (match_operand:DI 1 "register_operand" "r")))]
2790 "reload_completed || reload_in_progress"
2791 "fmov\\t%0.d[1], %x1"
2793 [(set_attr "v8type" "fmovi2f")
2794 (set_attr "mode" "DI")
2795 (set_attr "length" "4")
2798 (define_insn "aarch64_movtilow_di"
2799 [(set (match_operand:TI 0 "register_operand" "=w")
2800 (zero_extend:TI (match_operand:DI 1 "register_operand" "r")))]
2801 "reload_completed || reload_in_progress"
2804 [(set_attr "v8type" "fmovi2f")
2805 (set_attr "mode" "DI")
2806 (set_attr "length" "4")
2809 (define_insn "aarch64_movtilow_tilow"
2810 [(set (match_operand:TI 0 "register_operand" "=w")
2812 (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
2813 "reload_completed || reload_in_progress"
2816 [(set_attr "v8type" "fmovi2f")
2817 (set_attr "mode" "DI")
2818 (set_attr "length" "4")
2821 ;; There is a deliberate reason why the parameters of high and lo_sum's
2822 ;; don't have modes for ADRP and ADD instructions. This is to allow high
2823 ;; and lo_sum's to be used with the labels defining the jump tables in
2826 (define_insn "add_losym"
2827 [(set (match_operand:DI 0 "register_operand" "=r")
2828 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2829 (match_operand 2 "aarch64_valid_symref" "S")))]
2831 "add\\t%0, %1, :lo12:%a2"
2832 [(set_attr "v8type" "alu")
2833 (set_attr "mode" "DI")]
2837 (define_insn "ldr_got_small"
2838 [(set (match_operand:DI 0 "register_operand" "=r")
2839 (unspec:DI [(mem:DI (lo_sum:DI
2840 (match_operand:DI 1 "register_operand" "r")
2841 (match_operand:DI 2 "aarch64_valid_symref" "S")))]
2842 UNSPEC_GOTSMALLPIC))]
2844 "ldr\\t%0, [%1, #:got_lo12:%a2]"
2845 [(set_attr "v8type" "load1")
2846 (set_attr "mode" "DI")]
2849 (define_insn "aarch64_load_tp_hard"
2850 [(set (match_operand:DI 0 "register_operand" "=r")
2851 (unspec:DI [(const_int 0)] UNSPEC_TLS))]
2853 "mrs\\t%0, tpidr_el0"
2854 [(set_attr "v8type" "mrs")
2855 (set_attr "mode" "DI")]
2858 ;; The TLS ABI specifically requires that the compiler does not schedule
2859 ;; instructions in the TLS stubs, in order to enable linker relaxation.
2860 ;; Therefore we treat the stubs as an atomic sequence.
2861 (define_expand "tlsgd_small"
2862 [(parallel [(set (match_operand 0 "register_operand" "")
2863 (call (mem:DI (match_dup 2)) (const_int 1)))
2864 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
2865 (clobber (reg:DI LR_REGNUM))])]
2868 operands[2] = aarch64_tls_get_addr ();
2871 (define_insn "*tlsgd_small"
2872 [(set (match_operand 0 "register_operand" "")
2873 (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
2874 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
2875 (clobber (reg:DI LR_REGNUM))
2878 "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
2879 [(set_attr "v8type" "call")
2880 (set_attr "length" "16")])
2882 (define_insn "tlsie_small"
2883 [(set (match_operand:DI 0 "register_operand" "=r")
2884 (unspec:DI [(match_operand:DI 1 "aarch64_tls_ie_symref" "S")]
2885 UNSPEC_GOTSMALLTLS))]
2887 "adrp\\t%0, %A1\;ldr\\t%0, [%0, #%L1]"
2888 [(set_attr "v8type" "load1")
2889 (set_attr "mode" "DI")
2890 (set_attr "length" "8")]
2893 (define_insn "tlsle_small"
2894 [(set (match_operand:DI 0 "register_operand" "=r")
2895 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
2896 (match_operand:DI 2 "aarch64_tls_le_symref" "S")]
2897 UNSPEC_GOTSMALLTLS))]
2899 "add\\t%0, %1, #%G2\;add\\t%0, %0, #%L2"
2900 [(set_attr "v8type" "alu")
2901 (set_attr "mode" "DI")
2902 (set_attr "length" "8")]
2905 (define_insn "tlsdesc_small"
2906 [(set (reg:DI R0_REGNUM)
2907 (unspec:DI [(match_operand:DI 0 "aarch64_valid_symref" "S")]
2909 (clobber (reg:DI LR_REGNUM))
2910 (clobber (match_scratch:DI 1 "=r"))]
2912 "adrp\\tx0, %A0\;ldr\\t%1, [x0, #%L0]\;add\\tx0, x0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
2913 [(set_attr "v8type" "call")
2914 (set_attr "length" "16")])
2916 (define_insn "stack_tie"
2917 [(set (mem:BLK (scratch))
2918 (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
2919 (match_operand:DI 1 "register_operand" "rk")]
2923 [(set_attr "length" "0")]
2926 ;; Named pattern for expanding thread pointer reference.
2927 (define_expand "get_thread_pointerdi"
2928 [(match_operand:DI 0 "register_operand" "=r")]
2931 rtx tmp = aarch64_load_tp (operands[0]);
2932 if (tmp != operands[0])
2933 emit_move_insn (operands[0], tmp);
2938 (include "aarch64-simd.md")
2940 ;; Synchronization Builtins