;; Machine description for AArch64 AdvSIMD architecture.
-;; Copyright (C) 2011-2018 Free Software Foundation, Inc.
+;; Copyright (C) 2011-2020 Free Software Foundation, Inc.
;; Contributed by ARM Ltd.
;;
;; This file is part of GCC.
;; <http://www.gnu.org/licenses/>.
(define_expand "mov<mode>"
- [(set (match_operand:VALL_F16 0 "nonimmediate_operand" "")
- (match_operand:VALL_F16 1 "general_operand" ""))]
+ [(set (match_operand:VALL_F16 0 "nonimmediate_operand")
+ (match_operand:VALL_F16 1 "general_operand"))]
"TARGET_SIMD"
"
/* Force the operand into a register if it is not an
)
(define_expand "movmisalign<mode>"
- [(set (match_operand:VALL 0 "nonimmediate_operand" "")
- (match_operand:VALL 1 "general_operand" ""))]
+ [(set (match_operand:VALL 0 "nonimmediate_operand")
+ (match_operand:VALL 1 "general_operand"))]
"TARGET_SIMD"
{
/* This pattern is not permitted to fail during expansion: if both arguments
DONE;
})
-(define_expand "aarch64_split_simd_mov<mode>"
+(define_expand "@aarch64_split_simd_mov<mode>"
[(set (match_operand:VQ 0)
(match_operand:VQ 1))]
"TARGET_SIMD"
}
)
+;; The fcadd and fcmla patterns are made UNSPEC for the explicitly due to the
+;; fact that their usage need to guarantee that the source vectors are
+;; contiguous. It would be wrong to describe the operation without being able
+;; to describe the permute that is also required, but even if that is done
+;; the permute would have been created as a LOAD_LANES which means the values
+;; in the registers are in the wrong order.
+(define_insn "aarch64_fcadd<rot><mode>"
+ [(set (match_operand:VHSDF 0 "register_operand" "=w")
+ (unspec:VHSDF [(match_operand:VHSDF 1 "register_operand" "w")
+ (match_operand:VHSDF 2 "register_operand" "w")]
+ FCADD))]
+ "TARGET_COMPLEX"
+ "fcadd\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>, #<rot>"
+ [(set_attr "type" "neon_fcadd")]
+)
+
+(define_insn "aarch64_fcmla<rot><mode>"
+ [(set (match_operand:VHSDF 0 "register_operand" "=w")
+ (plus:VHSDF (match_operand:VHSDF 1 "register_operand" "0")
+ (unspec:VHSDF [(match_operand:VHSDF 2 "register_operand" "w")
+ (match_operand:VHSDF 3 "register_operand" "w")]
+ FCMLA)))]
+ "TARGET_COMPLEX"
+ "fcmla\t%0.<Vtype>, %2.<Vtype>, %3.<Vtype>, #<rot>"
+ [(set_attr "type" "neon_fcmla")]
+)
+
+
+(define_insn "aarch64_fcmla_lane<rot><mode>"
+ [(set (match_operand:VHSDF 0 "register_operand" "=w")
+ (plus:VHSDF (match_operand:VHSDF 1 "register_operand" "0")
+ (unspec:VHSDF [(match_operand:VHSDF 2 "register_operand" "w")
+ (match_operand:VHSDF 3 "register_operand" "w")
+ (match_operand:SI 4 "const_int_operand" "n")]
+ FCMLA)))]
+ "TARGET_COMPLEX"
+{
+ operands[4] = aarch64_endian_lane_rtx (<VHALF>mode, INTVAL (operands[4]));
+ return "fcmla\t%0.<Vtype>, %2.<Vtype>, %3.<FCMLA_maybe_lane>, #<rot>";
+}
+ [(set_attr "type" "neon_fcmla")]
+)
+
+(define_insn "aarch64_fcmla_laneq<rot>v4hf"
+ [(set (match_operand:V4HF 0 "register_operand" "=w")
+ (plus:V4HF (match_operand:V4HF 1 "register_operand" "0")
+ (unspec:V4HF [(match_operand:V4HF 2 "register_operand" "w")
+ (match_operand:V8HF 3 "register_operand" "w")
+ (match_operand:SI 4 "const_int_operand" "n")]
+ FCMLA)))]
+ "TARGET_COMPLEX"
+{
+ operands[4] = aarch64_endian_lane_rtx (V4HFmode, INTVAL (operands[4]));
+ return "fcmla\t%0.4h, %2.4h, %3.h[%4], #<rot>";
+}
+ [(set_attr "type" "neon_fcmla")]
+)
+
+(define_insn "aarch64_fcmlaq_lane<rot><mode>"
+ [(set (match_operand:VQ_HSF 0 "register_operand" "=w")
+ (plus:VQ_HSF (match_operand:VQ_HSF 1 "register_operand" "0")
+ (unspec:VQ_HSF [(match_operand:VQ_HSF 2 "register_operand" "w")
+ (match_operand:<VHALF> 3 "register_operand" "w")
+ (match_operand:SI 4 "const_int_operand" "n")]
+ FCMLA)))]
+ "TARGET_COMPLEX"
+{
+ int nunits = GET_MODE_NUNITS (<VHALF>mode).to_constant ();
+ operands[4]
+ = gen_int_mode (ENDIAN_LANE_N (nunits / 2, INTVAL (operands[4])), SImode);
+ return "fcmla\t%0.<Vtype>, %2.<Vtype>, %3.<FCMLA_maybe_lane>, #<rot>";
+}
+ [(set_attr "type" "neon_fcmla")]
+)
+
;; These instructions map to the __builtins for the Dot Product operations.
(define_insn "aarch64_<sur>dot<vsi2qi>"
[(set (match_operand:VS 0 "register_operand" "=w")
DOTPROD)))]
"TARGET_DOTPROD"
"<sur>dot\\t%0.<Vtype>, %2.<Vdottype>, %3.<Vdottype>"
- [(set_attr "type" "neon_dot")]
+ [(set_attr "type" "neon_dot<q>")]
)
;; These expands map to the Dot Product optab the vectorizer checks for.
operands[4] = aarch64_endian_lane_rtx (V8QImode, INTVAL (operands[4]));
return "<sur>dot\\t%0.<Vtype>, %2.<Vdottype>, %3.4b[%4]";
}
- [(set_attr "type" "neon_dot")]
+ [(set_attr "type" "neon_dot<q>")]
)
(define_insn "aarch64_<sur>dot_laneq<vsi2qi>"
operands[4] = aarch64_endian_lane_rtx (V16QImode, INTVAL (operands[4]));
return "<sur>dot\\t%0.<Vtype>, %2.<Vdottype>, %3.4b[%4]";
}
- [(set_attr "type" "neon_dot")]
+ [(set_attr "type" "neon_dot<q>")]
)
(define_expand "copysign<mode>3"
[(set_attr "type" "neon<fp>_mul_<stype>_scalar<q>")]
)
-(define_insn "aarch64_rsqrte<mode>"
+(define_insn "@aarch64_rsqrte<mode>"
[(set (match_operand:VHSDF_HSDF 0 "register_operand" "=w")
(unspec:VHSDF_HSDF [(match_operand:VHSDF_HSDF 1 "register_operand" "w")]
UNSPEC_RSQRTE))]
"frsqrte\\t%<v>0<Vmtype>, %<v>1<Vmtype>"
[(set_attr "type" "neon_fp_rsqrte_<stype><q>")])
-(define_insn "aarch64_rsqrts<mode>"
+(define_insn "@aarch64_rsqrts<mode>"
[(set (match_operand:VHSDF_HSDF 0 "register_operand" "=w")
(unspec:VHSDF_HSDF [(match_operand:VHSDF_HSDF 1 "register_operand" "w")
(match_operand:VHSDF_HSDF 2 "register_operand" "w")]
[(set_attr "type" "neon_fp_rsqrts_<stype><q>")])
(define_expand "rsqrt<mode>2"
- [(set (match_operand:VALLF 0 "register_operand" "=w")
- (unspec:VALLF [(match_operand:VALLF 1 "register_operand" "w")]
+ [(set (match_operand:VALLF 0 "register_operand")
+ (unspec:VALLF [(match_operand:VALLF 1 "register_operand")]
UNSPEC_RSQRT))]
"TARGET_SIMD"
{
[(set_attr "type" "neon_abs<q>")]
)
-(define_insn "abd<mode>_3"
+;; It's tempting to represent SABD as ABS (MINUS op1 op2).
+;; This isn't accurate as ABS treats always its input as a signed value.
+;; So (ABS:QI (minus:QI 64 -128)) == (ABS:QI (192 or -64 signed)) == 64.
+;; Whereas SABD would return 192 (-64 signed) on the above example.
+;; Use MINUS ([us]max (op1, op2), [us]min (op1, op2)) instead.
+(define_insn "aarch64_<su>abd<mode>_3"
[(set (match_operand:VDQ_BHSI 0 "register_operand" "=w")
- (abs:VDQ_BHSI (minus:VDQ_BHSI
- (match_operand:VDQ_BHSI 1 "register_operand" "w")
- (match_operand:VDQ_BHSI 2 "register_operand" "w"))))]
- "TARGET_SIMD"
- "sabd\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
+ (minus:VDQ_BHSI
+ (USMAX:VDQ_BHSI
+ (match_operand:VDQ_BHSI 1 "register_operand" "w")
+ (match_operand:VDQ_BHSI 2 "register_operand" "w"))
+ (<max_opp>:VDQ_BHSI
+ (match_dup 1)
+ (match_dup 2))))]
+ "TARGET_SIMD"
+ "<su>abd\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
[(set_attr "type" "neon_abd<q>")]
)
;; UABAL tmp.8h, op1.16b, op2.16b
;; UADALP op3.4s, tmp.8h
;; MOV op0, op3 // should be eliminated in later passes.
-;; The signed version just uses the signed variants of the above instructions.
+;;
+;; For TARGET_DOTPROD we do:
+;; MOV tmp1.16b, #1 // Can be CSE'd and hoisted out of loops.
+;; UABD tmp2.16b, op1.16b, op2.16b
+;; UDOT op3.4s, tmp2.16b, tmp1.16b
+;; MOV op0, op3 // RA will tie the operands of UDOT appropriately.
+;;
+;; The signed version just uses the signed variants of the above instructions
+;; but for TARGET_DOTPROD still emits a UDOT as the absolute difference is
+;; unsigned.
(define_expand "<sur>sadv16qi"
[(use (match_operand:V4SI 0 "register_operand"))
(use (match_operand:V4SI 3 "register_operand"))]
"TARGET_SIMD"
{
+ if (TARGET_DOTPROD)
+ {
+ rtx ones = force_reg (V16QImode, CONST1_RTX (V16QImode));
+ rtx abd = gen_reg_rtx (V16QImode);
+ emit_insn (gen_aarch64_<sur>abdv16qi_3 (abd, operands[1], operands[2]));
+ emit_insn (gen_aarch64_udotv16qi (operands[0], operands[3],
+ abd, ones));
+ DONE;
+ }
rtx reduc = gen_reg_rtx (V8HImode);
emit_insn (gen_aarch64_<sur>abdl2v16qi_3 (reduc, operands[1],
operands[2]));
[(set_attr "type" "neon_ins<q>")]
)
+(define_expand "signbit<mode>2"
+ [(use (match_operand:<V_INT_EQUIV> 0 "register_operand"))
+ (use (match_operand:VDQSF 1 "register_operand"))]
+ "TARGET_SIMD"
+{
+ int shift_amount = GET_MODE_UNIT_BITSIZE (<V_INT_EQUIV>mode) - 1;
+ rtx shift_vector = aarch64_simd_gen_const_vector_dup (<V_INT_EQUIV>mode,
+ shift_amount);
+ operands[1] = lowpart_subreg (<V_INT_EQUIV>mode, operands[1], <MODE>mode);
+
+ emit_insn (gen_aarch64_simd_lshr<v_int_equiv> (operands[0], operands[1],
+ shift_vector));
+ DONE;
+})
+
(define_insn "aarch64_simd_lshr<mode>"
[(set (match_operand:VDQ_I 0 "register_operand" "=w")
(lshiftrt:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w")
[(set_attr "type" "neon_shift_imm<q>")]
)
+(define_insn "*aarch64_simd_sra<mode>"
+ [(set (match_operand:VDQ_I 0 "register_operand" "=w")
+ (plus:VDQ_I
+ (SHIFTRT:VDQ_I
+ (match_operand:VDQ_I 1 "register_operand" "w")
+ (match_operand:VDQ_I 2 "aarch64_simd_rshift_imm" "Dr"))
+ (match_operand:VDQ_I 3 "register_operand" "0")))]
+ "TARGET_SIMD"
+ "<sra_op>sra\t%0.<Vtype>, %1.<Vtype>, %2"
+ [(set_attr "type" "neon_shift_acc<q>")]
+)
+
(define_insn "aarch64_simd_imm_shl<mode>"
[(set (match_operand:VDQ_I 0 "register_operand" "=w")
(ashift:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w")
)
(define_expand "ashl<mode>3"
- [(match_operand:VDQ_I 0 "register_operand" "")
- (match_operand:VDQ_I 1 "register_operand" "")
- (match_operand:SI 2 "general_operand" "")]
+ [(match_operand:VDQ_I 0 "register_operand")
+ (match_operand:VDQ_I 1 "register_operand")
+ (match_operand:SI 2 "general_operand")]
"TARGET_SIMD"
{
int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
)
(define_expand "lshr<mode>3"
- [(match_operand:VDQ_I 0 "register_operand" "")
- (match_operand:VDQ_I 1 "register_operand" "")
- (match_operand:SI 2 "general_operand" "")]
+ [(match_operand:VDQ_I 0 "register_operand")
+ (match_operand:VDQ_I 1 "register_operand")
+ (match_operand:SI 2 "general_operand")]
"TARGET_SIMD"
{
int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
)
(define_expand "ashr<mode>3"
- [(match_operand:VDQ_I 0 "register_operand" "")
- (match_operand:VDQ_I 1 "register_operand" "")
- (match_operand:SI 2 "general_operand" "")]
+ [(match_operand:VDQ_I 0 "register_operand")
+ (match_operand:VDQ_I 1 "register_operand")
+ (match_operand:SI 2 "general_operand")]
"TARGET_SIMD"
{
int bit_width = GET_MODE_UNIT_SIZE (<MODE>mode) * BITS_PER_UNIT;
)
(define_expand "vashl<mode>3"
- [(match_operand:VDQ_I 0 "register_operand" "")
- (match_operand:VDQ_I 1 "register_operand" "")
- (match_operand:VDQ_I 2 "register_operand" "")]
+ [(match_operand:VDQ_I 0 "register_operand")
+ (match_operand:VDQ_I 1 "register_operand")
+ (match_operand:VDQ_I 2 "register_operand")]
"TARGET_SIMD"
{
emit_insn (gen_aarch64_simd_reg_sshl<mode> (operands[0], operands[1],
;; Negating individual lanes most certainly offsets the
;; gain from vectorization.
(define_expand "vashr<mode>3"
- [(match_operand:VDQ_BHSI 0 "register_operand" "")
- (match_operand:VDQ_BHSI 1 "register_operand" "")
- (match_operand:VDQ_BHSI 2 "register_operand" "")]
+ [(match_operand:VDQ_BHSI 0 "register_operand")
+ (match_operand:VDQ_BHSI 1 "register_operand")
+ (match_operand:VDQ_BHSI 2 "register_operand")]
"TARGET_SIMD"
{
rtx neg = gen_reg_rtx (<MODE>mode);
;; DI vector shift
(define_expand "aarch64_ashr_simddi"
- [(match_operand:DI 0 "register_operand" "=w")
- (match_operand:DI 1 "register_operand" "w")
- (match_operand:SI 2 "aarch64_shift_imm64_di" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
+ (match_operand:SI 2 "aarch64_shift_imm64_di")]
"TARGET_SIMD"
{
/* An arithmetic shift right by 64 fills the result with copies of the sign
)
(define_expand "vlshr<mode>3"
- [(match_operand:VDQ_BHSI 0 "register_operand" "")
- (match_operand:VDQ_BHSI 1 "register_operand" "")
- (match_operand:VDQ_BHSI 2 "register_operand" "")]
+ [(match_operand:VDQ_BHSI 0 "register_operand")
+ (match_operand:VDQ_BHSI 1 "register_operand")
+ (match_operand:VDQ_BHSI 2 "register_operand")]
"TARGET_SIMD"
{
rtx neg = gen_reg_rtx (<MODE>mode);
})
(define_expand "aarch64_lshr_simddi"
- [(match_operand:DI 0 "register_operand" "=w")
- (match_operand:DI 1 "register_operand" "w")
- (match_operand:SI 2 "aarch64_shift_imm64_di" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
+ (match_operand:SI 2 "aarch64_shift_imm64_di")]
"TARGET_SIMD"
{
if (INTVAL (operands[2]) == 64)
)
(define_expand "vec_set<mode>"
- [(match_operand:VALL_F16 0 "register_operand" "+w")
- (match_operand:<VEL> 1 "register_operand" "w")
- (match_operand:SI 2 "immediate_operand" "")]
+ [(match_operand:VALL_F16 0 "register_operand")
+ (match_operand:<VEL> 1 "register_operand")
+ (match_operand:SI 2 "immediate_operand")]
"TARGET_SIMD"
{
HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << INTVAL (operands[2]);
)
(define_expand "<su><maxmin>v2di3"
- [(set (match_operand:V2DI 0 "register_operand" "")
- (MAXMIN:V2DI (match_operand:V2DI 1 "register_operand" "")
- (match_operand:V2DI 2 "register_operand" "")))]
+ [(set (match_operand:V2DI 0 "register_operand")
+ (MAXMIN:V2DI (match_operand:V2DI 1 "register_operand")
+ (match_operand:V2DI 2 "register_operand")))]
"TARGET_SIMD"
{
enum rtx_code cmp_operator;
fmov\\t%d0, %1
dup\\t%d0, %1"
[(set_attr "type" "neon_dup<q>,f_mcr,neon_dup<q>")
- (set_attr "simd" "yes,*,yes")
- (set_attr "fp" "*,yes,*")
- (set_attr "length" "4")]
+ (set_attr "length" "4")
+ (set_attr "arch" "simd,fp,simd")]
)
(define_insn "move_lo_quad_internal_<mode>"
fmov\\t%d0, %1
dup\\t%d0, %1"
[(set_attr "type" "neon_dup<q>,f_mcr,neon_dup<q>")
- (set_attr "simd" "yes,*,yes")
- (set_attr "fp" "*,yes,*")
- (set_attr "length" "4")]
+ (set_attr "length" "4")
+ (set_attr "arch" "simd,fp,simd")]
)
(define_insn "move_lo_quad_internal_be_<mode>"
fmov\\t%d0, %1
dup\\t%d0, %1"
[(set_attr "type" "neon_dup<q>,f_mcr,neon_dup<q>")
- (set_attr "simd" "yes,*,yes")
- (set_attr "fp" "*,yes,*")
- (set_attr "length" "4")]
+ (set_attr "length" "4")
+ (set_attr "arch" "simd,fp,simd")]
)
(define_insn "move_lo_quad_internal_be_<mode>"
fmov\\t%d0, %1
dup\\t%d0, %1"
[(set_attr "type" "neon_dup<q>,f_mcr,neon_dup<q>")
- (set_attr "simd" "yes,*,yes")
- (set_attr "fp" "*,yes,*")
- (set_attr "length" "4")]
+ (set_attr "length" "4")
+ (set_attr "arch" "simd,fp,simd")]
)
(define_expand "move_lo_quad_<mode>"
)
(define_expand "move_hi_quad_<mode>"
- [(match_operand:VQ 0 "register_operand" "")
- (match_operand:<VHALF> 1 "register_operand" "")]
+ [(match_operand:VQ 0 "register_operand")
+ (match_operand:<VHALF> 1 "register_operand")]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, false);
)
(define_expand "vec_pack_trunc_<mode>"
- [(match_operand:<VNARROWD> 0 "register_operand" "")
- (match_operand:VDN 1 "register_operand" "")
- (match_operand:VDN 2 "register_operand" "")]
+ [(match_operand:<VNARROWD> 0 "register_operand")
+ (match_operand:VDN 1 "register_operand")
+ (match_operand:VDN 2 "register_operand")]
"TARGET_SIMD"
{
rtx tempreg = gen_reg_rtx (<VDBL>mode);
)
(define_expand "vec_unpack<su>_hi_<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "")
+ [(match_operand:<VWIDE> 0 "register_operand")
(ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand"))]
"TARGET_SIMD"
{
)
(define_expand "vec_unpack<su>_lo_<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "")
- (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand" ""))]
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand"))]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, false);
)
(define_expand "vec_widen_<su>mult_lo_<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "")
- (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand" ""))
- (ANY_EXTEND:<VWIDE> (match_operand:VQW 2 "register_operand" ""))]
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand"))
+ (ANY_EXTEND:<VWIDE> (match_operand:VQW 2 "register_operand"))]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, false);
)
(define_expand "vec_widen_<su>mult_hi_<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "")
- (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand" ""))
- (ANY_EXTEND:<VWIDE> (match_operand:VQW 2 "register_operand" ""))]
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (ANY_EXTEND:<VWIDE> (match_operand:VQW 1 "register_operand"))
+ (ANY_EXTEND:<VWIDE> (match_operand:VQW 2 "register_operand"))]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
)
(define_expand "div<mode>3"
- [(set (match_operand:VHSDF 0 "register_operand" "=w")
- (div:VHSDF (match_operand:VHSDF 1 "register_operand" "w")
- (match_operand:VHSDF 2 "register_operand" "w")))]
+ [(set (match_operand:VHSDF 0 "register_operand")
+ (div:VHSDF (match_operand:VHSDF 1 "register_operand")
+ (match_operand:VHSDF 2 "register_operand")))]
"TARGET_SIMD"
{
if (aarch64_emit_approx_div (operands[0], operands[1], operands[2]))
;; other big-endian patterns their behavior is as required.
(define_expand "vec_unpacks_lo_<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "")
- (match_operand:VQ_HSF 1 "register_operand" "")]
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (match_operand:VQ_HSF 1 "register_operand")]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, false);
)
(define_expand "vec_unpacks_hi_<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "")
- (match_operand:VQ_HSF 1 "register_operand" "")]
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (match_operand:VQ_HSF 1 "register_operand")]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
)
(define_expand "aarch64_float_truncate_hi_<Vdbl>"
- [(match_operand:<VDBL> 0 "register_operand" "=w")
- (match_operand:VDF 1 "register_operand" "0")
- (match_operand:<VWIDE> 2 "register_operand" "w")]
+ [(match_operand:<VDBL> 0 "register_operand")
+ (match_operand:VDF 1 "register_operand")
+ (match_operand:<VWIDE> 2 "register_operand")]
"TARGET_SIMD"
{
rtx (*gen) (rtx, rtx, rtx) = BYTES_BIG_ENDIAN
;; 'across lanes' add.
(define_expand "reduc_plus_scal_<mode>"
- [(match_operand:<VEL> 0 "register_operand" "=w")
- (unspec:VDQ_I [(match_operand:VDQ_I 1 "register_operand" "w")]
+ [(match_operand:<VEL> 0 "register_operand")
+ (unspec:VDQ_I [(match_operand:VDQ_I 1 "register_operand")]
UNSPEC_ADDV)]
"TARGET_SIMD"
{
(define_insn "*aarch64_get_lane_extend<GPI:mode><VDQQH:mode>"
[(set (match_operand:GPI 0 "register_operand" "=r")
(sign_extend:GPI
- (vec_select:<VEL>
+ (vec_select:<VDQQH:VEL>
(match_operand:VDQQH 1 "register_operand" "w")
(parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
"TARGET_SIMD"
{
- operands[2] = aarch64_endian_lane_rtx (<MODE>mode, INTVAL (operands[2]));
+ operands[2] = aarch64_endian_lane_rtx (<VDQQH:MODE>mode,
+ INTVAL (operands[2]));
return "smov\\t%<GPI:w>0, %1.<VDQQH:Vetype>[%2]";
}
- [(set_attr "type" "neon_to_gp<q>")]\r
-)\r
-\r
-(define_insn "*aarch64_get_lane_zero_extend<GPI:mode><VDQQH:mode>"\r
- [(set (match_operand:GPI 0 "register_operand" "=r")\r
- (zero_extend:GPI\r
- (vec_select:<VEL>\r
- (match_operand:VDQQH 1 "register_operand" "w")\r
- (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]\r
- "TARGET_SIMD"\r
- {\r
- operands[2] = aarch64_endian_lane_rtx (<VDQQH:MODE>mode,\r
- INTVAL (operands[2]));\r
- return "umov\\t%w0, %1.<Vetype>[%2]";\r
- }\r
- [(set_attr "type" "neon_to_gp<q>")]\r
+ [(set_attr "type" "neon_to_gp<VDQQH:q>")]
+)
+
+(define_insn "*aarch64_get_lane_zero_extend<GPI:mode><VDQQH:mode>"
+ [(set (match_operand:GPI 0 "register_operand" "=r")
+ (zero_extend:GPI
+ (vec_select:<VDQQH:VEL>
+ (match_operand:VDQQH 1 "register_operand" "w")
+ (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
+ "TARGET_SIMD"
+ {
+ operands[2] = aarch64_endian_lane_rtx (<VDQQH:MODE>mode,
+ INTVAL (operands[2]));
+ return "umov\\t%w0, %1.<VDQQH:Vetype>[%2]";
+ }
+ [(set_attr "type" "neon_to_gp<VDQQH:q>")]
)
;; Lane extraction of a value, neither sign nor zero extension
;; In this insn, operand 1 should be low, and operand 2 the high part of the
;; dest vector.
-(define_insn "*aarch64_combinez<mode>"
+(define_insn "@aarch64_combinez<mode>"
[(set (match_operand:<VDBL> 0 "register_operand" "=w,w,w")
(vec_concat:<VDBL>
(match_operand:VDC 1 "general_operand" "w,?r,m")
fmov\t%d0, %1
ldr\\t%d0, %1"
[(set_attr "type" "neon_move<q>, neon_from_gp, neon_load1_1reg")
- (set_attr "simd" "yes,*,yes")
- (set_attr "fp" "*,yes,*")]
+ (set_attr "arch" "simd,fp,simd")]
)
-(define_insn "*aarch64_combinez_be<mode>"
+(define_insn "@aarch64_combinez_be<mode>"
[(set (match_operand:<VDBL> 0 "register_operand" "=w,w,w")
(vec_concat:<VDBL>
(match_operand:VDC 2 "aarch64_simd_or_scalar_imm_zero")
fmov\t%d0, %1
ldr\\t%d0, %1"
[(set_attr "type" "neon_move<q>, neon_from_gp, neon_load1_1reg")
- (set_attr "simd" "yes,*,yes")
- (set_attr "fp" "*,yes,*")]
+ (set_attr "arch" "simd,fp,simd")]
)
(define_expand "aarch64_combine<mode>"
}
)
-(define_expand "aarch64_simd_combine<mode>"
+(define_expand "@aarch64_simd_combine<mode>"
[(match_operand:<VDBL> 0 "register_operand")
(match_operand:VDC 1 "register_operand")
(match_operand:VDC 2 "register_operand")]
(define_expand "aarch64_saddl2<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:VQW 1 "register_operand" "w")
- (match_operand:VQW 2 "register_operand" "w")]
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (match_operand:VQW 1 "register_operand")
+ (match_operand:VQW 2 "register_operand")]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
})
(define_expand "aarch64_uaddl2<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:VQW 1 "register_operand" "w")
- (match_operand:VQW 2 "register_operand" "w")]
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (match_operand:VQW 1 "register_operand")
+ (match_operand:VQW 2 "register_operand")]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
})
(define_expand "aarch64_ssubl2<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:VQW 1 "register_operand" "w")
- (match_operand:VQW 2 "register_operand" "w")]
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (match_operand:VQW 1 "register_operand")
+ (match_operand:VQW 2 "register_operand")]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
})
(define_expand "aarch64_usubl2<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:VQW 1 "register_operand" "w")
- (match_operand:VQW 2 "register_operand" "w")]
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (match_operand:VQW 1 "register_operand")
+ (match_operand:VQW 2 "register_operand")]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
;; <su><addsub>w<q>.
(define_expand "widen_ssum<mode>3"
- [(set (match_operand:<VDBLW> 0 "register_operand" "")
+ [(set (match_operand:<VDBLW> 0 "register_operand")
(plus:<VDBLW> (sign_extend:<VDBLW>
- (match_operand:VQW 1 "register_operand" ""))
- (match_operand:<VDBLW> 2 "register_operand" "")))]
+ (match_operand:VQW 1 "register_operand"))
+ (match_operand:<VDBLW> 2 "register_operand")))]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, false);
)
(define_expand "widen_ssum<mode>3"
- [(set (match_operand:<VWIDE> 0 "register_operand" "")
+ [(set (match_operand:<VWIDE> 0 "register_operand")
(plus:<VWIDE> (sign_extend:<VWIDE>
- (match_operand:VD_BHSI 1 "register_operand" ""))
- (match_operand:<VWIDE> 2 "register_operand" "")))]
+ (match_operand:VD_BHSI 1 "register_operand"))
+ (match_operand:<VWIDE> 2 "register_operand")))]
"TARGET_SIMD"
{
emit_insn (gen_aarch64_saddw<mode> (operands[0], operands[2], operands[1]));
})
(define_expand "widen_usum<mode>3"
- [(set (match_operand:<VDBLW> 0 "register_operand" "")
+ [(set (match_operand:<VDBLW> 0 "register_operand")
(plus:<VDBLW> (zero_extend:<VDBLW>
- (match_operand:VQW 1 "register_operand" ""))
- (match_operand:<VDBLW> 2 "register_operand" "")))]
+ (match_operand:VQW 1 "register_operand"))
+ (match_operand:<VDBLW> 2 "register_operand")))]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, false);
)
(define_expand "widen_usum<mode>3"
- [(set (match_operand:<VWIDE> 0 "register_operand" "")
+ [(set (match_operand:<VWIDE> 0 "register_operand")
(plus:<VWIDE> (zero_extend:<VWIDE>
- (match_operand:VD_BHSI 1 "register_operand" ""))
- (match_operand:<VWIDE> 2 "register_operand" "")))]
+ (match_operand:VD_BHSI 1 "register_operand"))
+ (match_operand:<VWIDE> 2 "register_operand")))]
"TARGET_SIMD"
{
emit_insn (gen_aarch64_uaddw<mode> (operands[0], operands[2], operands[1]));
)
(define_expand "aarch64_saddw2<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "w")
- (match_operand:VQW 2 "register_operand" "w")]
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (match_operand:<VWIDE> 1 "register_operand")
+ (match_operand:VQW 2 "register_operand")]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
})
(define_expand "aarch64_uaddw2<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "w")
- (match_operand:VQW 2 "register_operand" "w")]
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (match_operand:<VWIDE> 1 "register_operand")
+ (match_operand:VQW 2 "register_operand")]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
(define_expand "aarch64_ssubw2<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "w")
- (match_operand:VQW 2 "register_operand" "w")]
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (match_operand:<VWIDE> 1 "register_operand")
+ (match_operand:VQW 2 "register_operand")]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
})
(define_expand "aarch64_usubw2<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "w")
- (match_operand:VQW 2 "register_operand" "w")]
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (match_operand:<VWIDE> 1 "register_operand")
+ (match_operand:VQW 2 "register_operand")]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
)
(define_expand "aarch64_sqdmlal2<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "w")
- (match_operand:VQ_HSI 2 "register_operand" "w")
- (match_operand:VQ_HSI 3 "register_operand" "w")]
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (match_operand:<VWIDE> 1 "register_operand")
+ (match_operand:VQ_HSI 2 "register_operand")
+ (match_operand:VQ_HSI 3 "register_operand")]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
})
(define_expand "aarch64_sqdmlsl2<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "w")
- (match_operand:VQ_HSI 2 "register_operand" "w")
- (match_operand:VQ_HSI 3 "register_operand" "w")]
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (match_operand:<VWIDE> 1 "register_operand")
+ (match_operand:VQ_HSI 2 "register_operand")
+ (match_operand:VQ_HSI 3 "register_operand")]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
)
(define_expand "aarch64_sqdmlal2_lane<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "w")
- (match_operand:VQ_HSI 2 "register_operand" "w")
- (match_operand:<VCOND> 3 "register_operand" "<vwx>")
- (match_operand:SI 4 "immediate_operand" "i")]
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (match_operand:<VWIDE> 1 "register_operand")
+ (match_operand:VQ_HSI 2 "register_operand")
+ (match_operand:<VCOND> 3 "register_operand")
+ (match_operand:SI 4 "immediate_operand")]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
})
(define_expand "aarch64_sqdmlal2_laneq<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "w")
- (match_operand:VQ_HSI 2 "register_operand" "w")
- (match_operand:<VCONQ> 3 "register_operand" "<vwx>")
- (match_operand:SI 4 "immediate_operand" "i")]
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (match_operand:<VWIDE> 1 "register_operand")
+ (match_operand:VQ_HSI 2 "register_operand")
+ (match_operand:<VCONQ> 3 "register_operand")
+ (match_operand:SI 4 "immediate_operand")]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
})
(define_expand "aarch64_sqdmlsl2_lane<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "w")
- (match_operand:VQ_HSI 2 "register_operand" "w")
- (match_operand:<VCOND> 3 "register_operand" "<vwx>")
- (match_operand:SI 4 "immediate_operand" "i")]
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (match_operand:<VWIDE> 1 "register_operand")
+ (match_operand:VQ_HSI 2 "register_operand")
+ (match_operand:<VCOND> 3 "register_operand")
+ (match_operand:SI 4 "immediate_operand")]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
})
(define_expand "aarch64_sqdmlsl2_laneq<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "w")
- (match_operand:VQ_HSI 2 "register_operand" "w")
- (match_operand:<VCONQ> 3 "register_operand" "<vwx>")
- (match_operand:SI 4 "immediate_operand" "i")]
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (match_operand:<VWIDE> 1 "register_operand")
+ (match_operand:VQ_HSI 2 "register_operand")
+ (match_operand:<VCONQ> 3 "register_operand")
+ (match_operand:SI 4 "immediate_operand")]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
)
(define_expand "aarch64_sqdmlal2_n<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "w")
- (match_operand:VQ_HSI 2 "register_operand" "w")
- (match_operand:<VEL> 3 "register_operand" "w")]
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (match_operand:<VWIDE> 1 "register_operand")
+ (match_operand:VQ_HSI 2 "register_operand")
+ (match_operand:<VEL> 3 "register_operand")]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
})
(define_expand "aarch64_sqdmlsl2_n<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:<VWIDE> 1 "register_operand" "w")
- (match_operand:VQ_HSI 2 "register_operand" "w")
- (match_operand:<VEL> 3 "register_operand" "w")]
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (match_operand:<VWIDE> 1 "register_operand")
+ (match_operand:VQ_HSI 2 "register_operand")
+ (match_operand:<VEL> 3 "register_operand")]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
)
(define_expand "aarch64_sqdmull2<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:VQ_HSI 1 "register_operand" "w")
- (match_operand:VQ_HSI 2 "register_operand" "w")]
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (match_operand:VQ_HSI 1 "register_operand")
+ (match_operand:VQ_HSI 2 "register_operand")]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
)
(define_expand "aarch64_sqdmull2_lane<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:VQ_HSI 1 "register_operand" "w")
- (match_operand:<VCOND> 2 "register_operand" "<vwx>")
- (match_operand:SI 3 "immediate_operand" "i")]
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (match_operand:VQ_HSI 1 "register_operand")
+ (match_operand:<VCOND> 2 "register_operand")
+ (match_operand:SI 3 "immediate_operand")]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
})
(define_expand "aarch64_sqdmull2_laneq<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:VQ_HSI 1 "register_operand" "w")
- (match_operand:<VCONQ> 2 "register_operand" "<vwx>")
- (match_operand:SI 3 "immediate_operand" "i")]
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (match_operand:VQ_HSI 1 "register_operand")
+ (match_operand:<VCONQ> 2 "register_operand")
+ (match_operand:SI 3 "immediate_operand")]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
)
(define_expand "aarch64_sqdmull2_n<mode>"
- [(match_operand:<VWIDE> 0 "register_operand" "=w")
- (match_operand:VQ_HSI 1 "register_operand" "w")
- (match_operand:<VEL> 2 "register_operand" "w")]
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (match_operand:VQ_HSI 1 "register_operand")
+ (match_operand:<VEL> 2 "register_operand")]
"TARGET_SIMD"
{
rtx p = aarch64_simd_vect_par_cnst_half (<MODE>mode, <nunits>, true);
;; sqrt
(define_expand "sqrt<mode>2"
- [(set (match_operand:VHSDF 0 "register_operand" "=w")
- (sqrt:VHSDF (match_operand:VHSDF 1 "register_operand" "w")))]
+ [(set (match_operand:VHSDF 0 "register_operand")
+ (sqrt:VHSDF (match_operand:VHSDF 1 "register_operand")))]
"TARGET_SIMD"
{
if (aarch64_emit_approx_sqrt (operands[0], operands[1], false))
)
(define_expand "vec_load_lanesoi<mode>"
- [(set (match_operand:OI 0 "register_operand" "=w")
- (unspec:OI [(match_operand:OI 1 "aarch64_simd_struct_operand" "Utv")
+ [(set (match_operand:OI 0 "register_operand")
+ (unspec:OI [(match_operand:OI 1 "aarch64_simd_struct_operand")
(unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
UNSPEC_LD2))]
"TARGET_SIMD"
)
(define_expand "vec_store_lanesoi<mode>"
- [(set (match_operand:OI 0 "aarch64_simd_struct_operand" "=Utv")
- (unspec:OI [(match_operand:OI 1 "register_operand" "w")
+ [(set (match_operand:OI 0 "aarch64_simd_struct_operand")
+ (unspec:OI [(match_operand:OI 1 "register_operand")
(unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
UNSPEC_ST2))]
"TARGET_SIMD"
)
(define_expand "vec_load_lanesci<mode>"
- [(set (match_operand:CI 0 "register_operand" "=w")
- (unspec:CI [(match_operand:CI 1 "aarch64_simd_struct_operand" "Utv")
+ [(set (match_operand:CI 0 "register_operand")
+ (unspec:CI [(match_operand:CI 1 "aarch64_simd_struct_operand")
(unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
UNSPEC_LD3))]
"TARGET_SIMD"
)
(define_expand "vec_store_lanesci<mode>"
- [(set (match_operand:CI 0 "aarch64_simd_struct_operand" "=Utv")
- (unspec:CI [(match_operand:CI 1 "register_operand" "w")
+ [(set (match_operand:CI 0 "aarch64_simd_struct_operand")
+ (unspec:CI [(match_operand:CI 1 "register_operand")
(unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
UNSPEC_ST3))]
"TARGET_SIMD"
)
(define_expand "vec_load_lanesxi<mode>"
- [(set (match_operand:XI 0 "register_operand" "=w")
- (unspec:XI [(match_operand:XI 1 "aarch64_simd_struct_operand" "Utv")
+ [(set (match_operand:XI 0 "register_operand")
+ (unspec:XI [(match_operand:XI 1 "aarch64_simd_struct_operand")
(unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
UNSPEC_LD4))]
"TARGET_SIMD"
)
(define_expand "vec_store_lanesxi<mode>"
- [(set (match_operand:XI 0 "aarch64_simd_struct_operand" "=Utv")
- (unspec:XI [(match_operand:XI 1 "register_operand" "w")
+ [(set (match_operand:XI 0 "aarch64_simd_struct_operand")
+ (unspec:XI [(match_operand:XI 1 "register_operand")
(unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
UNSPEC_ST4))]
"TARGET_SIMD"
;; Reload patterns for AdvSIMD register list operands.
(define_expand "mov<mode>"
- [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "")
- (match_operand:VSTRUCT 1 "general_operand" ""))]
+ [(set (match_operand:VSTRUCT 0 "nonimmediate_operand")
+ (match_operand:VSTRUCT 1 "general_operand"))]
"TARGET_SIMD"
{
if (can_create_pseudo_p ())
(define_expand "aarch64_ld1x3<VALLDIF:mode>"
- [(match_operand:CI 0 "register_operand" "=w")
- (match_operand:DI 1 "register_operand" "r")
+ [(match_operand:CI 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
(unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
"TARGET_SIMD"
{
[(set_attr "type" "neon_load1_3reg<q>")]
)
+(define_expand "aarch64_ld1x4<VALLDIF:mode>"
+ [(match_operand:XI 0 "register_operand" "=w")
+ (match_operand:DI 1 "register_operand" "r")
+ (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
+ "TARGET_SIMD"
+{
+ rtx mem = gen_rtx_MEM (XImode, operands[1]);
+ emit_insn (gen_aarch64_ld1_x4_<VALLDIF:mode> (operands[0], mem));
+ DONE;
+})
+
+(define_insn "aarch64_ld1_x4_<mode>"
+ [(set (match_operand:XI 0 "register_operand" "=w")
+ (unspec:XI
+ [(match_operand:XI 1 "aarch64_simd_struct_operand" "Utv")
+ (unspec:VALLDIF [(const_int 4)] UNSPEC_VSTRUCTDUMMY)]
+ UNSPEC_LD1))]
+ "TARGET_SIMD"
+ "ld1\\t{%S0.<Vtype> - %V0.<Vtype>}, %1"
+ [(set_attr "type" "neon_load1_4reg<q>")]
+)
+
(define_expand "aarch64_st1x2<VALLDIF:mode>"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:OI 1 "register_operand" "")
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:OI 1 "register_operand")
(unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
"TARGET_SIMD"
{
)
(define_expand "aarch64_st1x3<VALLDIF:mode>"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:CI 1 "register_operand" "")
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:CI 1 "register_operand")
(unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
"TARGET_SIMD"
{
[(set_attr "type" "neon_store1_3reg<q>")]
)
+(define_expand "aarch64_st1x4<VALLDIF:mode>"
+ [(match_operand:DI 0 "register_operand" "")
+ (match_operand:XI 1 "register_operand" "")
+ (unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
+ "TARGET_SIMD"
+{
+ rtx mem = gen_rtx_MEM (XImode, operands[0]);
+ emit_insn (gen_aarch64_st1_x4_<VALLDIF:mode> (mem, operands[1]));
+ DONE;
+})
+
+(define_insn "aarch64_st1_x4_<mode>"
+ [(set (match_operand:XI 0 "aarch64_simd_struct_operand" "=Utv")
+ (unspec:XI
+ [(match_operand:XI 1 "register_operand" "w")
+ (unspec:VALLDIF [(const_int 4)] UNSPEC_VSTRUCTDUMMY)]
+ UNSPEC_ST1))]
+ "TARGET_SIMD"
+ "st1\\t{%S1.<Vtype> - %V1.<Vtype>}, %0"
+ [(set_attr "type" "neon_store1_4reg<q>")]
+)
+
(define_insn "*aarch64_mov<mode>"
[(set (match_operand:VSTRUCT 0 "aarch64_simd_nonimmediate_operand" "=w,Utv,w")
(match_operand:VSTRUCT 1 "aarch64_simd_general_operand" " w,w,Utv"))]
})
(define_expand "aarch64_ld<VSTRUCT:nregs>r<VALLDIF:mode>"
- [(match_operand:VSTRUCT 0 "register_operand" "=w")
- (match_operand:DI 1 "register_operand" "w")
+ [(match_operand:VSTRUCT 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
(unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
"TARGET_SIMD"
{
)
(define_expand "aarch64_ld<VSTRUCT:nregs><VDC:mode>"
- [(match_operand:VSTRUCT 0 "register_operand" "=w")
- (match_operand:DI 1 "register_operand" "r")
+ [(match_operand:VSTRUCT 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
(unspec:VDC [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
"TARGET_SIMD"
{
})
(define_expand "aarch64_ld<VSTRUCT:nregs><VQ:mode>"
- [(match_operand:VSTRUCT 0 "register_operand" "=w")
- (match_operand:DI 1 "register_operand" "r")
+ [(match_operand:VSTRUCT 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
(unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
"TARGET_SIMD"
{
})
(define_expand "aarch64_ld1x2<VQ:mode>"
- [(match_operand:OI 0 "register_operand" "=w")
- (match_operand:DI 1 "register_operand" "r")
+ [(match_operand:OI 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
(unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
"TARGET_SIMD"
{
})
(define_expand "aarch64_ld1x2<VDC:mode>"
- [(match_operand:OI 0 "register_operand" "=w")
- (match_operand:DI 1 "register_operand" "r")
+ [(match_operand:OI 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
(unspec:VDC [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
"TARGET_SIMD"
{
(define_expand "aarch64_ld<VSTRUCT:nregs>_lane<VALLDIF:mode>"
- [(match_operand:VSTRUCT 0 "register_operand" "=w")
- (match_operand:DI 1 "register_operand" "w")
- (match_operand:VSTRUCT 2 "register_operand" "0")
- (match_operand:SI 3 "immediate_operand" "i")
+ [(match_operand:VSTRUCT 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
+ (match_operand:VSTRUCT 2 "register_operand")
+ (match_operand:SI 3 "immediate_operand")
(unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
"TARGET_SIMD"
{
;; D-register list.
(define_expand "aarch64_get_dreg<VSTRUCT:mode><VDC:mode>"
- [(match_operand:VDC 0 "register_operand" "=w")
- (match_operand:VSTRUCT 1 "register_operand" "w")
- (match_operand:SI 2 "immediate_operand" "i")]
+ [(match_operand:VDC 0 "register_operand")
+ (match_operand:VSTRUCT 1 "register_operand")
+ (match_operand:SI 2 "immediate_operand")]
"TARGET_SIMD"
{
int part = INTVAL (operands[2]);
;; Q-register list.
(define_expand "aarch64_get_qreg<VSTRUCT:mode><VQ:mode>"
- [(match_operand:VQ 0 "register_operand" "=w")
- (match_operand:VSTRUCT 1 "register_operand" "w")
- (match_operand:SI 2 "immediate_operand" "i")]
+ [(match_operand:VQ 0 "register_operand")
+ (match_operand:VSTRUCT 1 "register_operand")
+ (match_operand:SI 2 "immediate_operand")]
"TARGET_SIMD"
{
int part = INTVAL (operands[2]);
;; This instruction's pattern is generated directly by
;; aarch64_expand_vec_perm_const, so any changes to the pattern would
;; need corresponding changes there.
-(define_insn "aarch64_<PERMUTE:perm_insn><PERMUTE:perm_hilo><mode>"
+(define_insn "aarch64_<PERMUTE:perm_insn><mode>"
[(set (match_operand:VALL_F16 0 "register_operand" "=w")
(unspec:VALL_F16 [(match_operand:VALL_F16 1 "register_operand" "w")
(match_operand:VALL_F16 2 "register_operand" "w")]
PERMUTE))]
"TARGET_SIMD"
- "<PERMUTE:perm_insn><PERMUTE:perm_hilo>\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
+ "<PERMUTE:perm_insn>\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
[(set_attr "type" "neon_permute<q>")]
)
)
(define_expand "aarch64_st<VSTRUCT:nregs><VDC:mode>"
- [(match_operand:DI 0 "register_operand" "r")
- (match_operand:VSTRUCT 1 "register_operand" "w")
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:VSTRUCT 1 "register_operand")
(unspec:VDC [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
"TARGET_SIMD"
{
})
(define_expand "aarch64_st<VSTRUCT:nregs><VQ:mode>"
- [(match_operand:DI 0 "register_operand" "r")
- (match_operand:VSTRUCT 1 "register_operand" "w")
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:VSTRUCT 1 "register_operand")
(unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
"TARGET_SIMD"
{
})
(define_expand "aarch64_st<VSTRUCT:nregs>_lane<VALLDIF:mode>"
- [(match_operand:DI 0 "register_operand" "r")
- (match_operand:VSTRUCT 1 "register_operand" "w")
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:VSTRUCT 1 "register_operand")
(unspec:VALLDIF [(const_int 0)] UNSPEC_VSTRUCTDUMMY)
(match_operand:SI 2 "immediate_operand")]
"TARGET_SIMD"
;; extend them in arm_neon.h and insert the resulting Q-regs.
(define_expand "aarch64_set_qreg<VSTRUCT:mode><VQ:mode>"
- [(match_operand:VSTRUCT 0 "register_operand" "+w")
- (match_operand:VSTRUCT 1 "register_operand" "0")
- (match_operand:VQ 2 "register_operand" "w")
- (match_operand:SI 3 "immediate_operand" "i")]
+ [(match_operand:VSTRUCT 0 "register_operand")
+ (match_operand:VSTRUCT 1 "register_operand")
+ (match_operand:VQ 2 "register_operand")
+ (match_operand:SI 3 "immediate_operand")]
"TARGET_SIMD"
{
int part = INTVAL (operands[3]);
;; Standard pattern name vec_init<mode><Vel>.
(define_expand "vec_init<mode><Vel>"
- [(match_operand:VALL_F16 0 "register_operand" "")
+ [(match_operand:VALL_F16 0 "register_operand")
+ (match_operand 1 "" "")]
+ "TARGET_SIMD"
+{
+ aarch64_expand_vector_init (operands[0], operands[1]);
+ DONE;
+})
+
+(define_expand "vec_init<mode><Vhalf>"
+ [(match_operand:VQ_NO2E 0 "register_operand")
(match_operand 1 "" "")]
"TARGET_SIMD"
{
)
-(define_insn "aarch64_frecpe<mode>"
- [(set (match_operand:VHSDF 0 "register_operand" "=w")
- (unspec:VHSDF [(match_operand:VHSDF 1 "register_operand" "w")]
+(define_insn "@aarch64_frecpe<mode>"
+ [(set (match_operand:VHSDF_HSDF 0 "register_operand" "=w")
+ (unspec:VHSDF_HSDF
+ [(match_operand:VHSDF_HSDF 1 "register_operand" "w")]
UNSPEC_FRECPE))]
"TARGET_SIMD"
- "frecpe\\t%0.<Vtype>, %1.<Vtype>"
+ "frecpe\t%<v>0<Vmtype>, %<v>1<Vmtype>"
[(set_attr "type" "neon_fp_recpe_<stype><q>")]
)
-(define_insn "aarch64_frecp<FRECP:frecp_suffix><mode>"
+(define_insn "aarch64_frecpx<mode>"
[(set (match_operand:GPF_F16 0 "register_operand" "=w")
(unspec:GPF_F16 [(match_operand:GPF_F16 1 "register_operand" "w")]
- FRECP))]
+ UNSPEC_FRECPX))]
"TARGET_SIMD"
- "frecp<FRECP:frecp_suffix>\\t%<s>0, %<s>1"
- [(set_attr "type" "neon_fp_recp<FRECP:frecp_suffix>_<GPF_F16:stype>")]
+ "frecpx\t%<s>0, %<s>1"
+ [(set_attr "type" "neon_fp_recpx_<GPF_F16:stype>")]
)
-(define_insn "aarch64_frecps<mode>"
+(define_insn "@aarch64_frecps<mode>"
[(set (match_operand:VHSDF_HSDF 0 "register_operand" "=w")
(unspec:VHSDF_HSDF
[(match_operand:VHSDF_HSDF 1 "register_operand" "w")
;; Standard pattern name vec_extract<mode><Vel>.
(define_expand "vec_extract<mode><Vel>"
- [(match_operand:<VEL> 0 "aarch64_simd_nonimmediate_operand" "")
- (match_operand:VALL_F16 1 "register_operand" "")
- (match_operand:SI 2 "immediate_operand" "")]
+ [(match_operand:<VEL> 0 "aarch64_simd_nonimmediate_operand")
+ (match_operand:VALL_F16 1 "register_operand")
+ (match_operand:SI 2 "immediate_operand")]
"TARGET_SIMD"
{
emit_insn
(define_insn "aarch64_crypto_aes<aes_op>v16qi"
[(set (match_operand:V16QI 0 "register_operand" "=w")
- (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "%0")
- (match_operand:V16QI 2 "register_operand" "w")]
+ (unspec:V16QI
+ [(xor:V16QI
+ (match_operand:V16QI 1 "register_operand" "%0")
+ (match_operand:V16QI 2 "register_operand" "w"))]
CRYPTO_AES))]
"TARGET_SIMD && TARGET_AES"
"aes<aes_op>\\t%0.16b, %2.16b"
[(set_attr "type" "crypto_aese")]
)
-(define_insn "*aarch64_crypto_aes<aes_op>v16qi_xor_combine"
- [(set (match_operand:V16QI 0 "register_operand" "=w")
- (unspec:V16QI [(xor:V16QI
- (match_operand:V16QI 1 "register_operand" "%0")
- (match_operand:V16QI 2 "register_operand" "w"))
- (match_operand:V16QI 3 "aarch64_simd_imm_zero" "")]
- CRYPTO_AES))]
- "TARGET_SIMD && TARGET_AES"
- "aes<aes_op>\\t%0.16b, %2.16b"
- [(set_attr "type" "crypto_aese")]
-)
-
-(define_insn "*aarch64_crypto_aes<aes_op>v16qi_xor_combine"
- [(set (match_operand:V16QI 0 "register_operand" "=w")
- (unspec:V16QI [(match_operand:V16QI 3 "aarch64_simd_imm_zero" "")
- (xor:V16QI (match_operand:V16QI 1 "register_operand" "%0")
- (match_operand:V16QI 2 "register_operand" "w"))]
- CRYPTO_AES))]
- "TARGET_SIMD && TARGET_AES"
- "aes<aes_op>\\t%0.16b, %2.16b"
- [(set_attr "type" "crypto_aese")]
-)
-
-;; When AES/AESMC fusion is enabled we want the register allocation to
-;; look like:
-;; AESE Vn, _
-;; AESMC Vn, Vn
-;; So prefer to tie operand 1 to operand 0 when fusing.
-
(define_insn "aarch64_crypto_aes<aesmc_op>v16qi"
- [(set (match_operand:V16QI 0 "register_operand" "=w,w")
- (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "0,w")]
+ [(set (match_operand:V16QI 0 "register_operand" "=w")
+ (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "w")]
CRYPTO_AESMC))]
"TARGET_SIMD && TARGET_AES"
"aes<aesmc_op>\\t%0.16b, %1.16b"
- [(set_attr "type" "crypto_aesmc")
- (set_attr_alternative "enabled"
- [(if_then_else (match_test
- "aarch64_fusion_enabled_p (AARCH64_FUSE_AES_AESMC)")
- (const_string "yes" )
- (const_string "no"))
- (const_string "yes")])]
+ [(set_attr "type" "crypto_aesmc")]
)
;; When AESE/AESMC fusion is enabled we really want to keep the two together
;; Mash the two together during combine.
(define_insn "*aarch64_crypto_aese_fused"
- [(set (match_operand:V16QI 0 "register_operand" "=&w")
+ [(set (match_operand:V16QI 0 "register_operand" "=w")
(unspec:V16QI
[(unspec:V16QI
- [(match_operand:V16QI 1 "register_operand" "0")
- (match_operand:V16QI 2 "register_operand" "w")] UNSPEC_AESE)
- ] UNSPEC_AESMC))]
+ [(xor:V16QI
+ (match_operand:V16QI 1 "register_operand" "%0")
+ (match_operand:V16QI 2 "register_operand" "w"))]
+ UNSPEC_AESE)]
+ UNSPEC_AESMC))]
"TARGET_SIMD && TARGET_AES
&& aarch64_fusion_enabled_p (AARCH64_FUSE_AES_AESMC)"
"aese\\t%0.16b, %2.16b\;aesmc\\t%0.16b, %0.16b"
;; Mash the two together during combine.
(define_insn "*aarch64_crypto_aesd_fused"
- [(set (match_operand:V16QI 0 "register_operand" "=&w")
+ [(set (match_operand:V16QI 0 "register_operand" "=w")
(unspec:V16QI
[(unspec:V16QI
- [(match_operand:V16QI 1 "register_operand" "0")
- (match_operand:V16QI 2 "register_operand" "w")] UNSPEC_AESD)
- ] UNSPEC_AESIMC))]
+ [(xor:V16QI
+ (match_operand:V16QI 1 "register_operand" "%0")
+ (match_operand:V16QI 2 "register_operand" "w"))]
+ UNSPEC_AESD)]
+ UNSPEC_AESIMC))]
"TARGET_SIMD && TARGET_AES
&& aarch64_fusion_enabled_p (AARCH64_FUSE_AES_AESMC)"
"aesd\\t%0.16b, %2.16b\;aesimc\\t%0.16b, %0.16b"
;; fp16fml
(define_expand "aarch64_fml<f16mac1>l<f16quad>_low<mode>"
- [(set (match_operand:VDQSF 0 "register_operand" "=w")
+ [(set (match_operand:VDQSF 0 "register_operand")
(unspec:VDQSF
- [(match_operand:VDQSF 1 "register_operand" "0")
- (match_operand:<VFMLA_W> 2 "register_operand" "w")
- (match_operand:<VFMLA_W> 3 "register_operand" "w")]
+ [(match_operand:VDQSF 1 "register_operand")
+ (match_operand:<VFMLA_W> 2 "register_operand")
+ (match_operand:<VFMLA_W> 3 "register_operand")]
VFMLA16_LOW))]
"TARGET_F16FML"
{
})
(define_expand "aarch64_fml<f16mac1>l<f16quad>_high<mode>"
- [(set (match_operand:VDQSF 0 "register_operand" "=w")
+ [(set (match_operand:VDQSF 0 "register_operand")
(unspec:VDQSF
- [(match_operand:VDQSF 1 "register_operand" "0")
- (match_operand:<VFMLA_W> 2 "register_operand" "w")
- (match_operand:<VFMLA_W> 3 "register_operand" "w")]
+ [(match_operand:VDQSF 1 "register_operand")
+ (match_operand:<VFMLA_W> 2 "register_operand")
+ (match_operand:<VFMLA_W> 3 "register_operand")]
VFMLA16_HIGH))]
"TARGET_F16FML"
{
)
(define_expand "aarch64_fml<f16mac1>l_lane_lowv2sf"
- [(set (match_operand:V2SF 0 "register_operand" "")
- (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "")
- (match_operand:V4HF 2 "register_operand" "")
- (match_operand:V4HF 3 "register_operand" "")
- (match_operand:SI 4 "aarch64_imm2" "")]
+ [(set (match_operand:V2SF 0 "register_operand")
+ (unspec:V2SF [(match_operand:V2SF 1 "register_operand")
+ (match_operand:V4HF 2 "register_operand")
+ (match_operand:V4HF 3 "register_operand")
+ (match_operand:SI 4 "aarch64_imm2")]
VFMLA16_LOW))]
"TARGET_F16FML"
{
)
(define_expand "aarch64_fml<f16mac1>l_lane_highv2sf"
- [(set (match_operand:V2SF 0 "register_operand" "")
- (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "")
- (match_operand:V4HF 2 "register_operand" "")
- (match_operand:V4HF 3 "register_operand" "")
- (match_operand:SI 4 "aarch64_imm2" "")]
+ [(set (match_operand:V2SF 0 "register_operand")
+ (unspec:V2SF [(match_operand:V2SF 1 "register_operand")
+ (match_operand:V4HF 2 "register_operand")
+ (match_operand:V4HF 3 "register_operand")
+ (match_operand:SI 4 "aarch64_imm2")]
VFMLA16_HIGH))]
"TARGET_F16FML"
{
)
(define_expand "aarch64_fml<f16mac1>lq_laneq_lowv4sf"
- [(set (match_operand:V4SF 0 "register_operand" "")
- (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "")
- (match_operand:V8HF 2 "register_operand" "")
- (match_operand:V8HF 3 "register_operand" "")
- (match_operand:SI 4 "aarch64_lane_imm3" "")]
+ [(set (match_operand:V4SF 0 "register_operand")
+ (unspec:V4SF [(match_operand:V4SF 1 "register_operand")
+ (match_operand:V8HF 2 "register_operand")
+ (match_operand:V8HF 3 "register_operand")
+ (match_operand:SI 4 "aarch64_lane_imm3")]
VFMLA16_LOW))]
"TARGET_F16FML"
{
})
(define_expand "aarch64_fml<f16mac1>lq_laneq_highv4sf"
- [(set (match_operand:V4SF 0 "register_operand" "")
- (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "")
- (match_operand:V8HF 2 "register_operand" "")
- (match_operand:V8HF 3 "register_operand" "")
- (match_operand:SI 4 "aarch64_lane_imm3" "")]
+ [(set (match_operand:V4SF 0 "register_operand")
+ (unspec:V4SF [(match_operand:V4SF 1 "register_operand")
+ (match_operand:V8HF 2 "register_operand")
+ (match_operand:V8HF 3 "register_operand")
+ (match_operand:SI 4 "aarch64_lane_imm3")]
VFMLA16_HIGH))]
"TARGET_F16FML"
{
)
(define_expand "aarch64_fml<f16mac1>l_laneq_lowv2sf"
- [(set (match_operand:V2SF 0 "register_operand" "")
- (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "")
- (match_operand:V4HF 2 "register_operand" "")
- (match_operand:V8HF 3 "register_operand" "")
- (match_operand:SI 4 "aarch64_lane_imm3" "")]
+ [(set (match_operand:V2SF 0 "register_operand")
+ (unspec:V2SF [(match_operand:V2SF 1 "register_operand")
+ (match_operand:V4HF 2 "register_operand")
+ (match_operand:V8HF 3 "register_operand")
+ (match_operand:SI 4 "aarch64_lane_imm3")]
VFMLA16_LOW))]
"TARGET_F16FML"
{
})
(define_expand "aarch64_fml<f16mac1>l_laneq_highv2sf"
- [(set (match_operand:V2SF 0 "register_operand" "")
- (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "")
- (match_operand:V4HF 2 "register_operand" "")
- (match_operand:V8HF 3 "register_operand" "")
- (match_operand:SI 4 "aarch64_lane_imm3" "")]
+ [(set (match_operand:V2SF 0 "register_operand")
+ (unspec:V2SF [(match_operand:V2SF 1 "register_operand")
+ (match_operand:V4HF 2 "register_operand")
+ (match_operand:V8HF 3 "register_operand")
+ (match_operand:SI 4 "aarch64_lane_imm3")]
VFMLA16_HIGH))]
"TARGET_F16FML"
{
)
(define_expand "aarch64_fml<f16mac1>lq_lane_lowv4sf"
- [(set (match_operand:V4SF 0 "register_operand" "")
- (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "")
- (match_operand:V8HF 2 "register_operand" "")
- (match_operand:V4HF 3 "register_operand" "")
- (match_operand:SI 4 "aarch64_imm2" "")]
+ [(set (match_operand:V4SF 0 "register_operand")
+ (unspec:V4SF [(match_operand:V4SF 1 "register_operand")
+ (match_operand:V8HF 2 "register_operand")
+ (match_operand:V4HF 3 "register_operand")
+ (match_operand:SI 4 "aarch64_imm2")]
VFMLA16_LOW))]
"TARGET_F16FML"
{
})
(define_expand "aarch64_fml<f16mac1>lq_lane_highv4sf"
- [(set (match_operand:V4SF 0 "register_operand" "")
- (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "")
- (match_operand:V8HF 2 "register_operand" "")
- (match_operand:V4HF 3 "register_operand" "")
- (match_operand:SI 4 "aarch64_imm2" "")]
+ [(set (match_operand:V4SF 0 "register_operand")
+ (unspec:V4SF [(match_operand:V4SF 1 "register_operand")
+ (match_operand:V8HF 2 "register_operand")
+ (match_operand:V4HF 3 "register_operand")
+ (match_operand:SI 4 "aarch64_imm2")]
VFMLA16_HIGH))]
"TARGET_F16FML"
{
"pmull2\\t%0.1q, %1.2d, %2.2d"
[(set_attr "type" "crypto_pmull")]
)
+
+;; Sign- or zero-extend a 64-bit integer vector to a 128-bit vector.
+(define_insn "<optab><Vnarrowq><mode>2"
+ [(set (match_operand:VQN 0 "register_operand" "=w")
+ (ANY_EXTEND:VQN (match_operand:<VNARROWQ> 1 "register_operand" "w")))]
+ "TARGET_SIMD"
+ "<su>xtl\t%0.<Vtype>, %1.<Vntype>"
+ [(set_attr "type" "neon_shift_imm_long")]
+)
+
+;; Truncate a 128-bit integer vector to a 64-bit vector.
+(define_insn "trunc<mode><Vnarrowq>2"
+ [(set (match_operand:<VNARROWQ> 0 "register_operand" "=w")
+ (truncate:<VNARROWQ> (match_operand:VQN 1 "register_operand" "w")))]
+ "TARGET_SIMD"
+ "xtn\t%0.<Vntype>, %1.<Vtype>"
+ [(set_attr "type" "neon_shift_imm_narrow_q")]
+)