(define_insn "ior<mode>3<vczle><vczbe>"
[(set (match_operand:VDQ_I 0 "register_operand")
(ior:VDQ_I (match_operand:VDQ_I 1 "register_operand")
- (match_operand:VDQ_I 2 "aarch64_orr_imm_sve_advsimd")))]
+ (match_operand:VDQ_I 2 "aarch64_reg_or_orr_imm")))]
"TARGET_SIMD"
- {@ [ cons: =0 , 1 , 2; attrs: arch ]
- [ w , w , w ; simd ] orr\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>
- [ w , 0 , vsl; sve ] orr\t%Z0.<Vetype>, %Z0.<Vetype>, #%2
- [ w , 0 , Do ; simd ] \
- << aarch64_output_simd_orr_imm (operands[2], <bitsize>);
+ {@ [ cons: =0 , 1 , 2 ]
+ [ w , w , w ] orr\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>
+ [ w , 0 , Do ] << aarch64_output_simd_orr_imm (operands[2], <bitsize>);
}
[(set_attr "type" "neon_logic<q>")]
)
/* Information about a legitimate vector immediate operand. */
struct simd_immediate_info
{
- enum insn_type { MOV, MVN, INDEX, PTRUE };
+ enum insn_type { MOV, MVN, INDEX, PTRUE, SVE_MOV };
enum modifier_type { LSL, MSL };
simd_immediate_info () {}
{
/* DUP with no shift. */
if (info)
- *info = simd_immediate_info (mode, val);
+ *info = simd_immediate_info (mode, val,
+ simd_immediate_info::SVE_MOV);
return true;
}
if ((val & 0xff) == 0 && IN_RANGE (val, -0x8000, 0x7f00))
{
/* DUP with LSL #8. */
if (info)
- *info = simd_immediate_info (mode, val);
+ *info = simd_immediate_info (mode, val,
+ simd_immediate_info::SVE_MOV);
return true;
}
}
{
/* DUPM. */
if (info)
- *info = simd_immediate_info (mode, val);
+ *info = simd_immediate_info (mode, val, simd_immediate_info::SVE_MOV);
return true;
}
return false;
if (vec_flags & VEC_SVE_DATA)
return aarch64_sve_valid_immediate (ival, imode, info, which);
- else
- return aarch64_advsimd_valid_immediate (val64, imode, info, which);
+
+ if (aarch64_advsimd_valid_immediate (val64, imode, info, which))
+ return true;
+
+ if (TARGET_SVE)
+ return aarch64_sve_valid_immediate (ival, imode, info, which);
+ return false;
}
/* Return true if OP is a valid SIMD move immediate for SVE or AdvSIMD. */
return templ;
}
+ if (info.insn == simd_immediate_info::SVE_MOV)
+ {
+ gcc_assert (TARGET_SVE);
+ snprintf (templ, sizeof (templ), "mov\t%%Z0.%c, #" HOST_WIDE_INT_PRINT_DEC,
+ element_char, INTVAL (info.u.mov.value));
+ return templ;
+ }
+
mnemonic = info.insn == simd_immediate_info::MVN ? "mvni" : "movi";
shift_op = (info.u.mov.modifier == simd_immediate_info::MSL
? "msl" : "lsl");
else
{
/* AARCH64_CHECK_ORR or AARCH64_CHECK_AND. */
- mnemonic = info.insn == simd_immediate_info::MVN ? "bic" : "orr";
- if (info.u.mov.shift)
+ mnemonic = "orr";
+ if (which == AARCH64_CHECK_AND)
+ mnemonic = info.insn == simd_immediate_info::MVN ? "bic" : "and";
+
+ if (info.insn == simd_immediate_info::SVE_MOV)
+ {
+ gcc_assert (TARGET_SVE);
+ snprintf (templ, sizeof (templ), "%s\t%%Z0.%c, %%Z0.%c, "
+ HOST_WIDE_INT_PRINT_DEC, mnemonic, element_char,
+ element_char, INTVAL (info.u.mov.value));
+ }
+ else if (info.u.mov.shift)
snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, #"
HOST_WIDE_INT_PRINT_DEC ", %s #%d", mnemonic, lane_count,
element_char, UINTVAL (info.u.mov.value), "lsl",
/*
** t1:
-** orr z[0-9]+.s, z[0-9]+.s, #-2147483648
+** orr v0.2s, #?128, lsl #?24
** ret
*/
float32x2_t t1 (float32x2_t a)
/*
** t2:
-** orr z[0-9]+.s, z[0-9]+.s, #-2147483648
+** orr v0.4s, #?128, lsl #?24
** ret
*/
float32x4_t t2 (float32x4_t a)
/*
** t3:
-** orr z[0-9]+.d, z[0-9]+.d, #-9223372036854775808
+** orr z[0-9]+.d, z[0-9]+.d, #?-9223372036854775808
** ret
*/
float64x2_t t3 (float64x2_t a)
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+#include <arm_neon.h>
+
+typedef short v8hi __attribute__((vector_size(16)));
+typedef int v4si __attribute__((vector_size(16)));
+typedef long v2di __attribute__((vector_size(16)));
+
+/*
+** t1:
+** mov z0.s, #?4092
+** ret
+*/
+v4si t1 ()
+{
+ return (v4si) { 0xffc, 0xffc, 0xffc, 0xffc };
+}
+
+/*
+** t2:
+** mov z0.h, #?510
+** ret
+*/
+v8hi t2 ()
+{
+ return (v8hi) { 510, 510, 510, 510, 510, 510, 510, 510 };
+}
+
+/*
+** t3:
+** mov z0.d, #?1
+** ret
+*/
+v2di t3 ()
+{
+ return (v2di) { 1, 1 };
+}