diff --git a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp index ed5a7d927d101d..561ffb818b04b0 100644 --- a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp @@ -2082,6 +2082,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) GetEmitter()->emitIns_R_R(ins, emitSize, targetReg, op2Reg, opt); break; } + case NI_Sve_Compute8BitAddresses: case NI_Sve_Compute16BitAddresses: case NI_Sve_Compute32BitAddresses: @@ -2095,6 +2096,22 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) INS_SCALABLE_OPTS_LSL_N); break; } + + case NI_Sve_InsertIntoShiftedVector: + { + assert(isRMW); + assert(emitter::isFloatReg(op2Reg) == varTypeIsFloating(intrin.baseType)); + if (targetReg != op1Reg) + { + assert(targetReg != op2Reg); + GetEmitter()->emitIns_Mov(INS_mov, emitTypeSize(node), targetReg, op1Reg, + /* canSkip */ true); + } + + GetEmitter()->emitIns_R_R(ins, emitSize, targetReg, op2Reg, opt); + break; + } + default: unreached(); } diff --git a/src/coreclr/jit/hwintrinsiclistarm64sve.h b/src/coreclr/jit/hwintrinsiclistarm64sve.h index 03c77c21e15fbe..31b406bf2656d4 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64sve.h +++ b/src/coreclr/jit/hwintrinsiclistarm64sve.h @@ -88,6 +88,7 @@ HARDWARE_INTRINSIC(Sve, GatherVectorUInt32WithByteOffsetsZeroExtend, HARDWARE_INTRINSIC(Sve, GatherVectorUInt32ZeroExtend, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1w, INS_sve_ld1w, INS_sve_ld1w, INS_sve_ld1w, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, GatherVectorWithByteOffsets, -1, 3, true, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1w, INS_sve_ld1w, INS_sve_ld1d, INS_sve_ld1d, INS_sve_ld1w, INS_sve_ld1d}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, GetActiveElementCount, -1, 2, true, {INS_sve_cntp, INS_sve_cntp, INS_sve_cntp, INS_sve_cntp, INS_sve_cntp, INS_sve_cntp, INS_sve_cntp, INS_sve_cntp, INS_sve_cntp, INS_sve_cntp}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_ExplicitMaskedOperation) +HARDWARE_INTRINSIC(Sve, InsertIntoShiftedVector, -1, 2, true, {INS_sve_insr, INS_sve_insr, INS_sve_insr, INS_sve_insr, INS_sve_insr, INS_sve_insr, INS_sve_insr, INS_sve_insr, INS_sve_insr, INS_sve_insr}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve, LeadingSignCount, -1, -1, false, {INS_sve_cls, INS_invalid, INS_sve_cls, INS_invalid, INS_sve_cls, INS_invalid, INS_sve_cls, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, LeadingZeroCount, -1, -1, false, {INS_sve_clz, INS_sve_clz, INS_sve_clz, INS_sve_clz, INS_sve_clz, INS_sve_clz, INS_sve_clz, INS_sve_clz, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, LoadVector, -1, 2, true, {INS_sve_ld1b, INS_sve_ld1b, INS_sve_ld1h, INS_sve_ld1h, INS_sve_ld1w, INS_sve_ld1w, INS_sve_ld1d, INS_sve_ld1d, INS_sve_ld1w, INS_sve_ld1d}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) @@ -159,6 +160,7 @@ HARDWARE_INTRINSIC(Sve, MultiplyBySelectedScalar, HARDWARE_INTRINSIC(Sve, MultiplyExtended, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fmulx, INS_sve_fmulx}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, MultiplySubtract, -1, -1, false, {INS_sve_mls, INS_sve_mls, INS_sve_mls, INS_sve_mls, INS_sve_mls, INS_sve_mls, INS_sve_mls, INS_sve_mls, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation|HW_Flag_FmaIntrinsic|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Sve, Negate, -1, -1, false, {INS_sve_neg, INS_invalid, INS_sve_neg, INS_invalid, INS_sve_neg, INS_invalid, INS_sve_neg, INS_invalid, INS_sve_fneg, INS_sve_fneg}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, Not, -1, -1, false, {INS_sve_not, INS_sve_not, INS_sve_not, INS_sve_not, INS_sve_not, INS_sve_not, INS_sve_not, INS_sve_not, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation) HARDWARE_INTRINSIC(Sve, Or, -1, -1, false, {INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, OrAcross, -1, -1, false, {INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, PopCount, -1, -1, false, {INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs index 32f94f7c1d7d31..fb07d8a6a8fe61 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs @@ -2365,6 +2365,79 @@ internal Arm64() { } public static unsafe ulong GetActiveElementCount(Vector mask, Vector from) { throw new PlatformNotSupportedException(); } + /// Insert scalar into shifted vector + + /// + /// svuint8_t svinsr[_n_u8](svuint8_t op1, uint8_t op2) + /// INSR Ztied1.B, Wop2 + /// INSR Ztied1.B, Bop2 + /// + public static unsafe Vector InsertIntoShiftedVector(Vector left, byte right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat64_t svinsr[_n_f64](svfloat64_t op1, float64_t op2) + /// INSR Ztied1.D, Xop2 + /// INSR Ztied1.D, Dop2 + /// + public static unsafe Vector InsertIntoShiftedVector(Vector left, double right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svinsr[_n_s16](svint16_t op1, int16_t op2) + /// INSR Ztied1.H, Wop2 + /// INSR Ztied1.H, Hop2 + /// + public static unsafe Vector InsertIntoShiftedVector(Vector left, short right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svinsr[_n_s32](svint32_t op1, int32_t op2) + /// INSR Ztied1.S, Wop2 + /// INSR Ztied1.S, Sop2 + /// + public static unsafe Vector InsertIntoShiftedVector(Vector left, int right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svinsr[_n_s64](svint64_t op1, int64_t op2) + /// INSR Ztied1.D, Xop2 + /// INSR Ztied1.D, Dop2 + /// + public static unsafe Vector InsertIntoShiftedVector(Vector left, long right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svinsr[_n_s8](svint8_t op1, int8_t op2) + /// INSR Ztied1.B, Wop2 + /// INSR Ztied1.B, Bop2 + /// + public static unsafe Vector InsertIntoShiftedVector(Vector left, sbyte right) { throw new PlatformNotSupportedException(); } + + /// + /// svfloat32_t svinsr[_n_f32](svfloat32_t op1, float32_t op2) + /// INSR Ztied1.S, Wop2 + /// INSR Ztied1.S, Sop2 + /// + public static unsafe Vector InsertIntoShiftedVector(Vector left, float right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svinsr[_n_u16](svuint16_t op1, uint16_t op2) + /// INSR Ztied1.H, Wop2 + /// INSR Ztied1.H, Hop2 + /// + public static unsafe Vector InsertIntoShiftedVector(Vector left, ushort right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svinsr[_n_u32](svuint32_t op1, uint32_t op2) + /// INSR Ztied1.S, Wop2 + /// INSR Ztied1.S, Sop2 + /// + public static unsafe Vector InsertIntoShiftedVector(Vector left, uint right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svinsr[_n_u64](svuint64_t op1, uint64_t op2) + /// INSR Ztied1.D, Xop2 + /// INSR Ztied1.D, Dop2 + /// + public static unsafe Vector InsertIntoShiftedVector(Vector left, ulong right) { throw new PlatformNotSupportedException(); } + + /// Count leading sign bits /// @@ -4034,6 +4107,96 @@ internal Arm64() { } /// public static unsafe Vector Negate(Vector value) { throw new PlatformNotSupportedException(); } + /// Bitwise invert + + /// + /// svuint8_t svnot[_u8]_m(svuint8_t inactive, svbool_t pg, svuint8_t op) + /// NOT Ztied.B, Pg/M, Zop.B + /// svuint8_t svnot[_u8]_x(svbool_t pg, svuint8_t op) + /// NOT Ztied.B, Pg/M, Ztied.B + /// svuint8_t svnot[_u8]_z(svbool_t pg, svuint8_t op) + /// svbool_t svnot[_b]_z(svbool_t pg, svbool_t op) + /// EOR Presult.B, Pg/Z, Pop.B, Pg.B + /// + public static unsafe Vector Not(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svnot[_s16]_m(svint16_t inactive, svbool_t pg, svint16_t op) + /// NOT Ztied.H, Pg/M, Zop.H + /// svint16_t svnot[_s16]_x(svbool_t pg, svint16_t op) + /// NOT Ztied.H, Pg/M, Ztied.H + /// svint16_t svnot[_s16]_z(svbool_t pg, svint16_t op) + /// svbool_t svnot[_b]_z(svbool_t pg, svbool_t op) + /// EOR Presult.B, Pg/Z, Pop.B, Pg.B + /// + public static unsafe Vector Not(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svnot[_s32]_m(svint32_t inactive, svbool_t pg, svint32_t op) + /// NOT Ztied.S, Pg/M, Zop.S + /// svint32_t svnot[_s32]_x(svbool_t pg, svint32_t op) + /// NOT Ztied.S, Pg/M, Ztied.S + /// svint32_t svnot[_s32]_z(svbool_t pg, svint32_t op) + /// svbool_t svnot[_b]_z(svbool_t pg, svbool_t op) + /// EOR Presult.B, Pg/Z, Pop.B, Pg.B + /// + public static unsafe Vector Not(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svnot[_s64]_m(svint64_t inactive, svbool_t pg, svint64_t op) + /// NOT Ztied.D, Pg/M, Zop.D + /// svint64_t svnot[_s64]_x(svbool_t pg, svint64_t op) + /// NOT Ztied.D, Pg/M, Ztied.D + /// svint64_t svnot[_s64]_z(svbool_t pg, svint64_t op) + /// svbool_t svnot[_b]_z(svbool_t pg, svbool_t op) + /// EOR Presult.B, Pg/Z, Pop.B, Pg.B + /// + public static unsafe Vector Not(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svnot[_s8]_m(svint8_t inactive, svbool_t pg, svint8_t op) + /// NOT Ztied.B, Pg/M, Zop.B + /// svint8_t svnot[_s8]_x(svbool_t pg, svint8_t op) + /// NOT Ztied.B, Pg/M, Ztied.B + /// svint8_t svnot[_s8]_z(svbool_t pg, svint8_t op) + /// svbool_t svnot[_b]_z(svbool_t pg, svbool_t op) + /// EOR Presult.B, Pg/Z, Pop.B, Pg.B + /// + public static unsafe Vector Not(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svnot[_u16]_m(svuint16_t inactive, svbool_t pg, svuint16_t op) + /// NOT Ztied.H, Pg/M, Zop.H + /// svuint16_t svnot[_u16]_x(svbool_t pg, svuint16_t op) + /// NOT Ztied.H, Pg/M, Ztied.H + /// svuint16_t svnot[_u16]_z(svbool_t pg, svuint16_t op) + /// svbool_t svnot[_b]_z(svbool_t pg, svbool_t op) + /// EOR Presult.B, Pg/Z, Pop.B, Pg.B + /// + public static unsafe Vector Not(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svnot[_u32]_m(svuint32_t inactive, svbool_t pg, svuint32_t op) + /// NOT Ztied.S, Pg/M, Zop.S + /// svuint32_t svnot[_u32]_x(svbool_t pg, svuint32_t op) + /// NOT Ztied.S, Pg/M, Ztied.S + /// svuint32_t svnot[_u32]_z(svbool_t pg, svuint32_t op) + /// svbool_t svnot[_b]_z(svbool_t pg, svbool_t op) + /// EOR Presult.B, Pg/Z, Pop.B, Pg.B + /// + public static unsafe Vector Not(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svnot[_u64]_m(svuint64_t inactive, svbool_t pg, svuint64_t op) + /// NOT Ztied.D, Pg/M, Zop.D + /// svuint64_t svnot[_u64]_x(svbool_t pg, svuint64_t op) + /// NOT Ztied.D, Pg/M, Ztied.D + /// svuint64_t svnot[_u64]_z(svbool_t pg, svuint64_t op) + /// svbool_t svnot[_b]_z(svbool_t pg, svbool_t op) + /// EOR Presult.B, Pg/Z, Pop.B, Pg.B + /// + public static unsafe Vector Not(Vector value) { throw new PlatformNotSupportedException(); } + /// Or : Bitwise inclusive OR /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs index 6a541cd7b1c2c4..ac3b7dd98b88bd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs @@ -2421,6 +2421,79 @@ internal Arm64() { } public static unsafe ulong GetActiveElementCount(Vector mask, Vector from) => GetActiveElementCount(mask, from); + /// Insert scalar into shifted vector + + /// + /// svuint8_t svinsr[_n_u8](svuint8_t op1, uint8_t op2) + /// INSR Ztied1.B, Wop2 + /// INSR Ztied1.B, Bop2 + /// + public static unsafe Vector InsertIntoShiftedVector(Vector left, byte right) => InsertIntoShiftedVector(left, right); + + /// + /// svfloat64_t svinsr[_n_f64](svfloat64_t op1, float64_t op2) + /// INSR Ztied1.D, Xop2 + /// INSR Ztied1.D, Dop2 + /// + public static unsafe Vector InsertIntoShiftedVector(Vector left, double right) => InsertIntoShiftedVector(left, right); + + /// + /// svint16_t svinsr[_n_s16](svint16_t op1, int16_t op2) + /// INSR Ztied1.H, Wop2 + /// INSR Ztied1.H, Hop2 + /// + public static unsafe Vector InsertIntoShiftedVector(Vector left, short right) => InsertIntoShiftedVector(left, right); + + /// + /// svint32_t svinsr[_n_s32](svint32_t op1, int32_t op2) + /// INSR Ztied1.S, Wop2 + /// INSR Ztied1.S, Sop2 + /// + public static unsafe Vector InsertIntoShiftedVector(Vector left, int right) => InsertIntoShiftedVector(left, right); + + /// + /// svint64_t svinsr[_n_s64](svint64_t op1, int64_t op2) + /// INSR Ztied1.D, Xop2 + /// INSR Ztied1.D, Dop2 + /// + public static unsafe Vector InsertIntoShiftedVector(Vector left, long right) => InsertIntoShiftedVector(left, right); + + /// + /// svint8_t svinsr[_n_s8](svint8_t op1, int8_t op2) + /// INSR Ztied1.B, Wop2 + /// INSR Ztied1.B, Bop2 + /// + public static unsafe Vector InsertIntoShiftedVector(Vector left, sbyte right) => InsertIntoShiftedVector(left, right); + + /// + /// svfloat32_t svinsr[_n_f32](svfloat32_t op1, float32_t op2) + /// INSR Ztied1.S, Wop2 + /// INSR Ztied1.S, Sop2 + /// + public static unsafe Vector InsertIntoShiftedVector(Vector left, float right) => InsertIntoShiftedVector(left, right); + + /// + /// svuint16_t svinsr[_n_u16](svuint16_t op1, uint16_t op2) + /// INSR Ztied1.H, Wop2 + /// INSR Ztied1.H, Hop2 + /// + public static unsafe Vector InsertIntoShiftedVector(Vector left, ushort right) => InsertIntoShiftedVector(left, right); + + /// + /// svuint32_t svinsr[_n_u32](svuint32_t op1, uint32_t op2) + /// INSR Ztied1.S, Wop2 + /// INSR Ztied1.S, Sop2 + /// + public static unsafe Vector InsertIntoShiftedVector(Vector left, uint right) => InsertIntoShiftedVector(left, right); + + /// + /// svuint64_t svinsr[_n_u64](svuint64_t op1, uint64_t op2) + /// INSR Ztied1.D, Xop2 + /// INSR Ztied1.D, Dop2 + /// + public static unsafe Vector InsertIntoShiftedVector(Vector left, ulong right) => InsertIntoShiftedVector(left, right); + + /// LeadingSignCount : Count leading sign bits /// @@ -4088,6 +4161,96 @@ internal Arm64() { } /// public static unsafe Vector Negate(Vector value) => Negate(value); + /// Bitwise invert + + /// + /// svuint8_t svnot[_u8]_m(svuint8_t inactive, svbool_t pg, svuint8_t op) + /// NOT Ztied.B, Pg/M, Zop.B + /// svuint8_t svnot[_u8]_x(svbool_t pg, svuint8_t op) + /// NOT Ztied.B, Pg/M, Ztied.B + /// svuint8_t svnot[_u8]_z(svbool_t pg, svuint8_t op) + /// svbool_t svnot[_b]_z(svbool_t pg, svbool_t op) + /// EOR Presult.B, Pg/Z, Pop.B, Pg.B + /// + public static unsafe Vector Not(Vector value) => Not(value); + + /// + /// svint16_t svnot[_s16]_m(svint16_t inactive, svbool_t pg, svint16_t op) + /// NOT Ztied.H, Pg/M, Zop.H + /// svint16_t svnot[_s16]_x(svbool_t pg, svint16_t op) + /// NOT Ztied.H, Pg/M, Ztied.H + /// svint16_t svnot[_s16]_z(svbool_t pg, svint16_t op) + /// svbool_t svnot[_b]_z(svbool_t pg, svbool_t op) + /// EOR Presult.B, Pg/Z, Pop.B, Pg.B + /// + public static unsafe Vector Not(Vector value) => Not(value); + + /// + /// svint32_t svnot[_s32]_m(svint32_t inactive, svbool_t pg, svint32_t op) + /// NOT Ztied.S, Pg/M, Zop.S + /// svint32_t svnot[_s32]_x(svbool_t pg, svint32_t op) + /// NOT Ztied.S, Pg/M, Ztied.S + /// svint32_t svnot[_s32]_z(svbool_t pg, svint32_t op) + /// svbool_t svnot[_b]_z(svbool_t pg, svbool_t op) + /// EOR Presult.B, Pg/Z, Pop.B, Pg.B + /// + public static unsafe Vector Not(Vector value) => Not(value); + + /// + /// svint64_t svnot[_s64]_m(svint64_t inactive, svbool_t pg, svint64_t op) + /// NOT Ztied.D, Pg/M, Zop.D + /// svint64_t svnot[_s64]_x(svbool_t pg, svint64_t op) + /// NOT Ztied.D, Pg/M, Ztied.D + /// svint64_t svnot[_s64]_z(svbool_t pg, svint64_t op) + /// svbool_t svnot[_b]_z(svbool_t pg, svbool_t op) + /// EOR Presult.B, Pg/Z, Pop.B, Pg.B + /// + public static unsafe Vector Not(Vector value) => Not(value); + + /// + /// svint8_t svnot[_s8]_m(svint8_t inactive, svbool_t pg, svint8_t op) + /// NOT Ztied.B, Pg/M, Zop.B + /// svint8_t svnot[_s8]_x(svbool_t pg, svint8_t op) + /// NOT Ztied.B, Pg/M, Ztied.B + /// svint8_t svnot[_s8]_z(svbool_t pg, svint8_t op) + /// svbool_t svnot[_b]_z(svbool_t pg, svbool_t op) + /// EOR Presult.B, Pg/Z, Pop.B, Pg.B + /// + public static unsafe Vector Not(Vector value) => Not(value); + + /// + /// svuint16_t svnot[_u16]_m(svuint16_t inactive, svbool_t pg, svuint16_t op) + /// NOT Ztied.H, Pg/M, Zop.H + /// svuint16_t svnot[_u16]_x(svbool_t pg, svuint16_t op) + /// NOT Ztied.H, Pg/M, Ztied.H + /// svuint16_t svnot[_u16]_z(svbool_t pg, svuint16_t op) + /// svbool_t svnot[_b]_z(svbool_t pg, svbool_t op) + /// EOR Presult.B, Pg/Z, Pop.B, Pg.B + /// + public static unsafe Vector Not(Vector value) => Not(value); + + /// + /// svuint32_t svnot[_u32]_m(svuint32_t inactive, svbool_t pg, svuint32_t op) + /// NOT Ztied.S, Pg/M, Zop.S + /// svuint32_t svnot[_u32]_x(svbool_t pg, svuint32_t op) + /// NOT Ztied.S, Pg/M, Ztied.S + /// svuint32_t svnot[_u32]_z(svbool_t pg, svuint32_t op) + /// svbool_t svnot[_b]_z(svbool_t pg, svbool_t op) + /// EOR Presult.B, Pg/Z, Pop.B, Pg.B + /// + public static unsafe Vector Not(Vector value) => Not(value); + + /// + /// svuint64_t svnot[_u64]_m(svuint64_t inactive, svbool_t pg, svuint64_t op) + /// NOT Ztied.D, Pg/M, Zop.D + /// svuint64_t svnot[_u64]_x(svbool_t pg, svuint64_t op) + /// NOT Ztied.D, Pg/M, Ztied.D + /// svuint64_t svnot[_u64]_z(svbool_t pg, svuint64_t op) + /// svbool_t svnot[_b]_z(svbool_t pg, svbool_t op) + /// EOR Presult.B, Pg/Z, Pop.B, Pg.B + /// + public static unsafe Vector Not(Vector value) => Not(value); + /// Or : Bitwise inclusive OR /// diff --git a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index 2629c669e4608a..d297de265fc748 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -4555,6 +4555,17 @@ internal Arm64() { } public static System.Numerics.Vector LeadingZeroCount(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector LeadingZeroCount(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector InsertIntoShiftedVector(System.Numerics.Vector left, byte right) { throw null; } + public static System.Numerics.Vector InsertIntoShiftedVector(System.Numerics.Vector left, double right) { throw null; } + public static System.Numerics.Vector InsertIntoShiftedVector(System.Numerics.Vector left, short right) { throw null; } + public static System.Numerics.Vector InsertIntoShiftedVector(System.Numerics.Vector left, int right) { throw null; } + public static System.Numerics.Vector InsertIntoShiftedVector(System.Numerics.Vector left, long right) { throw null; } + public static System.Numerics.Vector InsertIntoShiftedVector(System.Numerics.Vector left, sbyte right) { throw null; } + public static System.Numerics.Vector InsertIntoShiftedVector(System.Numerics.Vector left, float right) { throw null; } + public static System.Numerics.Vector InsertIntoShiftedVector(System.Numerics.Vector left, ushort right) { throw null; } + public static System.Numerics.Vector InsertIntoShiftedVector(System.Numerics.Vector left, uint right) { throw null; } + public static System.Numerics.Vector InsertIntoShiftedVector(System.Numerics.Vector left, ulong right) { throw null; } + public static unsafe System.Numerics.Vector LoadVector(System.Numerics.Vector mask, sbyte* address) { throw null; } public static unsafe System.Numerics.Vector LoadVector(System.Numerics.Vector mask, short* address) { throw null; } public static unsafe System.Numerics.Vector LoadVector(System.Numerics.Vector mask, int* address) { throw null; } @@ -4772,6 +4783,15 @@ internal Arm64() { } public static System.Numerics.Vector Negate(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector Negate(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector Not(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector Not(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector Not(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector Not(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector Not(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector Not(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector Not(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector Not(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector Or(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector Or(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector Or(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs index 17aee7df961b9c..a5665955554876 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -190,6 +190,7 @@ ("_SveImm2UnaryOpTestTemplate.template", "SveVecImm2UnOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), ("_SveMinimalUnaryOpTestTemplate.template", "SveVecReduceUnOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = VecReduceOpTest_ValidationLogic }), ("_SveMasklessUnaryOpTestTemplate.template", "SveMasklessSimpleVecOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), + ("_SveVecAndScalarOpTest.template", "SveVecAndScalarOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_VectorValidationLogic }), ("_SveMasklessBinaryOpTestTemplate.template", "SveMasklessVecBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), ("_SveStoreTemplate.template", "SveStoreTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), ("_SveStoreTemplate.template", "SveStoreNonTemporalTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), @@ -3561,6 +3562,26 @@ ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Negate_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Negate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "-TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Negate(firstOp[i]) != result[i]", ["GetIterResult"] = "(int)Helpers.Negate(leftOp[i])"}), ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Negate_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Negate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "-TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "(long)Helpers.Negate(firstOp[i]) != (long)result[i]", ["GetIterResult"] = "(long)Helpers.Negate(leftOp[i])"}), + ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), + ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), + ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), + ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), + ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), + ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), + ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), + ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), + ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), + ("SveVecAndScalarOpTest.template", new Dictionary {["TestName"] = "Sve_InsertIntoShiftedVector_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "InsertIntoShiftedVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.ShiftAndInsert(firstOp, secondOp))",}), + + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Not_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Not", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Not(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Not_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Not", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Not(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Not_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Not", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Not(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Not_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Not", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Not(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Not_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Not", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Not(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Not_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Not", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Not(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Not_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Not", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Not(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_Not_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Not", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Not(firstOp[i]) != result[i]", ["GetIterResult"] = "Helpers.Not(leftOp[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(sbyte)TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "(short)TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Or_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Or", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.Or(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Or(left[i], right[i])"}), diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index f18c40c8de2abb..17238a8c168705 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -3353,6 +3353,18 @@ private static sbyte SignedShift(sbyte op1, sbyte op2, bool rounding = false, bo return result; } + public static T[] ShiftAndInsert(T[] op1, T op2) + { + T nextValue = op2; + + for (int i = 0; i < op1.Length; i++) + { + (op1[i], nextValue) = (nextValue, op1[i]); + } + + return op1; + } + public static sbyte ShiftLeftLogical(sbyte op1, byte op2) => UnsignedShift(op1, (sbyte)op2); public static byte ShiftLeftLogical(byte op1, byte op2) => UnsignedShift(op1, (sbyte)op2); diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveVecAndScalarOpTest.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveVecAndScalarOpTest.template new file mode 100644 index 00000000000000..c2f9c3b75a8ef6 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveVecAndScalarOpTest.template @@ -0,0 +1,317 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics.Arm\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Linq; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; +using Xunit; + +namespace JIT.HardwareIntrinsics.Arm +{ + public static partial class Program + { + [Fact] + public static void {TestName}() + { + var test = new {TemplateName}UnaryOpTest__{TestName}(); + + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if ({LoadIsa}.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + // Validates passing an instance member of a class works + test.RunClassFldScenario(); + + // Validates passing the field of a local struct works + test.RunStructLclFldScenario(); + + // Validates passing an instance member of a struct works + test.RunStructFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class {TemplateName}UnaryOpTest__{TestName} + { + private struct DataTable + { + private byte[] inArray1; + private byte[] outArray; + + private GCHandle inHandle1; + private GCHandle outHandle; + + private ulong alignment; + + public DataTable({Op1BaseType}[] inArray1, {RetBaseType}[] outArray, int alignment) + { + int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>(); + int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>(); + if ((alignment != 64 && alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray) + { + throw new ArgumentException($"Invalid value of alignment: {alignment}, sizeOfinArray1: {sizeOfinArray1}, sizeOfoutArray: {sizeOfoutArray}"); + } + + this.inArray1 = new byte[alignment * 2]; + this.outArray = new byte[alignment * 2]; + + this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned); + this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned); + + this.alignment = (ulong)alignment; + + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray1Ptr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1); + } + + public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); + public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment); + + public void Dispose() + { + inHandle1.Free(); + outHandle.Free(); + } + + private static unsafe void* Align(byte* buffer, ulong expectedAlignment) + { + return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1)); + } + } + + private struct TestStruct + { + public {Op1VectorType}<{Op1BaseType}> _fld1; + public {Op1BaseType} _fld2; + + public static TestStruct Create() + { + var testStruct = new TestStruct(); + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + testStruct._fld2 = {NextValueOp1}; + + return testStruct; + } + + public void RunStructFldScenario({TemplateName}UnaryOpTest__{TestName} testClass) + { + var result = {Isa}.{Method}(_fld1, _fld2); + + Unsafe.Write(testClass._dataTable.outArrayPtr, result); + testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr); + } + } + + private static readonly int LargestVectorSize = {LargestVectorSize}; + + private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); + private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); + + private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; + + private {Op1VectorType}<{Op1BaseType}> _mask; + private {Op1VectorType}<{Op1BaseType}> _fld1; + private {Op1BaseType} _fld2; + + private DataTable _dataTable; + + public {TemplateName}UnaryOpTest__{TestName}() + { + Succeeded = true; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + + _fld2 = {NextValueOp1}; + + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + _dataTable = new DataTable(_data1, new {RetBaseType}[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => {Isa}.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead)); + + var op2 = {NextValueOp1}; + var result = {Isa}.{Method}( + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), + op2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, op2, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); + + {Op1VectorType}<{Op1BaseType}> loadMask = Sve.CreateTrueMask{Op1BaseType}(SveMaskPattern.All); + + var op2 = {NextValueOp1}; + var result = {Isa}.{Method}( + {LoadIsa}.Load{Op1VectorType}(loadMask, ({Op1BaseType}*)(_dataTable.inArray1Ptr)), + op2 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArray1Ptr, op2, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); + + var op2 = {NextValueOp1}; + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op1BaseType}) }) + .Invoke(null, new object[] { + Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), + op2 + }); + + Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result)); + ValidateResult(_dataTable.inArray1Ptr, op2, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); + + var op1 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr); + var op2 = {NextValueOp1}; + var result = {Isa}.{Method}(op1, op2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(op1, op2, _dataTable.outArrayPtr); + } + + public void RunClassFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); + + var result = {Isa}.{Method}(_fld1, _fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr); + } + + public void RunStructLclFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); + + var test = TestStruct.Create(); + var result = {Isa}.{Method}(test._fld1, test._fld2); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr); + } + + public void RunStructFldScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario)); + + var test = TestStruct.Create(); + test.RunStructFldScenario(this); + } + + public void RunUnsupportedScenario() + { + TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); + + bool succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + succeeded = true; + } + + if (!succeeded) + { + Succeeded = false; + } + } + + private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, {Op1BaseType} op2, void* result, [CallerMemberName] string method = "") + { + {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + ValidateResult(inArray1, op2, outArray, method); + } + + private void ValidateResult(void* op1, {Op1BaseType} op2, void* result, [CallerMemberName] string method = "") + { + {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + ValidateResult(inArray1, op2, outArray, method); + } + + private void ValidateResult({Op1BaseType}[] firstOp, {Op1BaseType} secondOp, {RetBaseType}[] result, [CallerMemberName] string method = "") + { + bool succeeded = true; + + {TemplateValidationLogic} + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" secondOp: {secondOp}"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + } +}