From 55c904024601c133f8ad081bc704c3c1fc5c7c9b Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Mon, 29 Apr 2024 20:05:01 -0700 Subject: [PATCH] Arm64/Sve: Add SignExtend* and ZeroExtend* math APIs (#101702) * Add [Sign|Zero]Extend[8|16|32] APIs: * Add API to instruction mapping * eliminate extra movprfx for AllBitsSetMask * Add test cases --- src/coreclr/jit/hwintrinsiccodegenarm64.cpp | 3 +- src/coreclr/jit/hwintrinsiclistarm64sve.h | 7 +- .../Arm/Sve.PlatformNotSupported.cs | 158 +++++++++++++++++ .../src/System/Runtime/Intrinsics/Arm/Sve.cs | 160 ++++++++++++++++++ .../ref/System.Runtime.Intrinsics.cs | 17 ++ .../GenerateHWIntrinsicTests_Arm.cs | 28 ++- .../HardwareIntrinsics/Arm/Shared/Helpers.cs | 23 +++ 7 files changed, 386 insertions(+), 10 deletions(-) diff --git a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp index f58ca6c6e858d..1f7f2865631c1 100644 --- a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp @@ -448,14 +448,13 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) if (intrin.op3->isContained()) { assert(intrin.op3->IsVectorZero()); - if (intrin.op1->isContained()) + if (intrin.op1->isContained() || intrin.op1->IsMaskAllBitsSet()) { // We already skip importing ConditionalSelect if op1 == trueAll, however // if we still see it here, it is because we wrapped the predicated instruction // inside ConditionalSelect. // As such, no need to move the `falseReg` to `targetReg` // because the predicated instruction will eventually set it. - assert(intrin.op1->IsMaskAllBitsSet()); } else { diff --git a/src/coreclr/jit/hwintrinsiclistarm64sve.h b/src/coreclr/jit/hwintrinsiclistarm64sve.h index cbd5ea6eb4983..b4d0c1319a227 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64sve.h +++ b/src/coreclr/jit/hwintrinsiclistarm64sve.h @@ -69,10 +69,15 @@ HARDWARE_INTRINSIC(Sve, LoadVectorUInt16ZeroExtendToUInt64, HARDWARE_INTRINSIC(Sve, LoadVectorUInt32ZeroExtendToInt64, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1w, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, LoadVectorUInt32ZeroExtendToUInt64, -1, 2, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1w, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, Multiply, -1, 2, true, {INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_fmul, INS_sve_fmul}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve, SignExtend16, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sxth, INS_invalid, INS_sve_sxth, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, SignExtend32, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sxtw, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, SignExtend8, -1, -1, false, {INS_invalid, INS_invalid, INS_sve_sxtb, INS_invalid, INS_sve_sxtb, INS_invalid, INS_sve_sxtb, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, Subtract, -1, 2, true, {INS_sve_sub, INS_sve_sub, INS_sve_sub, INS_sve_sub, INS_sve_sub, INS_sve_sub, INS_sve_sub, INS_sve_sub, INS_sve_fsub, INS_sve_fsub}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics) - HARDWARE_INTRINSIC(Sve, UnzipEven, -1, 2, true, {INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1, INS_sve_uzp1}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Sve, UnzipOdd, -1, 2, true, {INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Sve, ZeroExtend16, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_uxth, INS_invalid, INS_sve_uxth, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, ZeroExtend32, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_uxtw, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, ZeroExtend8, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_sve_uxtb, INS_invalid, INS_sve_uxtb, INS_invalid, INS_sve_uxtb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, ZipHigh, -1, 2, true, {INS_sve_zip2, INS_sve_zip2, INS_sve_zip2, INS_sve_zip2, INS_sve_zip2, INS_sve_zip2, INS_sve_zip2, INS_sve_zip2, INS_sve_zip2, INS_sve_zip2}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Sve, ZipLow, -1, 2, true, {INS_sve_zip1, INS_sve_zip1, INS_sve_zip1, INS_sve_zip1, INS_sve_zip1, INS_sve_zip1, INS_sve_zip1, INS_sve_zip1, INS_sve_zip1, INS_sve_zip1}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen) 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 84583b4687456..afbaa6e8969c5 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 @@ -1010,6 +1010,86 @@ internal Arm64() { } /// public static unsafe Vector Multiply(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + /// SignExtend16 : Sign-extend the low 16 bits + + /// + /// svint32_t svexth[_s32]_m(svint32_t inactive, svbool_t pg, svint32_t op) + /// SXTH Ztied.S, Pg/M, Zop.S + /// MOVPRFX Zresult, Zinactive; SXTH Zresult.S, Pg/M, Zop.S + /// svint32_t svexth[_s32]_x(svbool_t pg, svint32_t op) + /// SXTH Ztied.S, Pg/M, Ztied.S + /// MOVPRFX Zresult, Zop; SXTH Zresult.S, Pg/M, Zop.S + /// svint32_t svexth[_s32]_z(svbool_t pg, svint32_t op) + /// MOVPRFX Zresult.S, Pg/Z, Zop.S; SXTH Zresult.S, Pg/M, Zop.S + /// + public static unsafe Vector SignExtend16(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svexth[_s64]_m(svint64_t inactive, svbool_t pg, svint64_t op) + /// SXTH Ztied.D, Pg/M, Zop.D + /// MOVPRFX Zresult, Zinactive; SXTH Zresult.D, Pg/M, Zop.D + /// svint64_t svexth[_s64]_x(svbool_t pg, svint64_t op) + /// SXTH Ztied.D, Pg/M, Ztied.D + /// MOVPRFX Zresult, Zop; SXTH Zresult.D, Pg/M, Zop.D + /// svint64_t svexth[_s64]_z(svbool_t pg, svint64_t op) + /// MOVPRFX Zresult.D, Pg/Z, Zop.D; SXTH Zresult.D, Pg/M, Zop.D + /// + public static unsafe Vector SignExtend16(Vector value) { throw new PlatformNotSupportedException(); } + + + /// SignExtend32 : Sign-extend the low 32 bits + + /// + /// svint64_t svextw[_s64]_m(svint64_t inactive, svbool_t pg, svint64_t op) + /// SXTW Ztied.D, Pg/M, Zop.D + /// MOVPRFX Zresult, Zinactive; SXTW Zresult.D, Pg/M, Zop.D + /// svint64_t svextw[_s64]_x(svbool_t pg, svint64_t op) + /// SXTW Ztied.D, Pg/M, Ztied.D + /// MOVPRFX Zresult, Zop; SXTW Zresult.D, Pg/M, Zop.D + /// svint64_t svextw[_s64]_z(svbool_t pg, svint64_t op) + /// MOVPRFX Zresult.D, Pg/Z, Zop.D; SXTW Zresult.D, Pg/M, Zop.D + /// + public static unsafe Vector SignExtend32(Vector value) { throw new PlatformNotSupportedException(); } + + + /// SignExtend8 : Sign-extend the low 8 bits + + /// + /// svint16_t svextb[_s16]_m(svint16_t inactive, svbool_t pg, svint16_t op) + /// SXTB Ztied.H, Pg/M, Zop.H + /// MOVPRFX Zresult, Zinactive; SXTB Zresult.H, Pg/M, Zop.H + /// svint16_t svextb[_s16]_x(svbool_t pg, svint16_t op) + /// SXTB Ztied.H, Pg/M, Ztied.H + /// MOVPRFX Zresult, Zop; SXTB Zresult.H, Pg/M, Zop.H + /// svint16_t svextb[_s16]_z(svbool_t pg, svint16_t op) + /// MOVPRFX Zresult.H, Pg/Z, Zop.H; SXTB Zresult.H, Pg/M, Zop.H + /// + public static unsafe Vector SignExtend8(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svextb[_s32]_m(svint32_t inactive, svbool_t pg, svint32_t op) + /// SXTB Ztied.S, Pg/M, Zop.S + /// MOVPRFX Zresult, Zinactive; SXTB Zresult.S, Pg/M, Zop.S + /// svint32_t svextb[_s32]_x(svbool_t pg, svint32_t op) + /// SXTB Ztied.S, Pg/M, Ztied.S + /// MOVPRFX Zresult, Zop; SXTB Zresult.S, Pg/M, Zop.S + /// svint32_t svextb[_s32]_z(svbool_t pg, svint32_t op) + /// MOVPRFX Zresult.S, Pg/Z, Zop.S; SXTB Zresult.S, Pg/M, Zop.S + /// + public static unsafe Vector SignExtend8(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svextb[_s64]_m(svint64_t inactive, svbool_t pg, svint64_t op) + /// SXTB Ztied.D, Pg/M, Zop.D + /// MOVPRFX Zresult, Zinactive; SXTB Zresult.D, Pg/M, Zop.D + /// svint64_t svextb[_s64]_x(svbool_t pg, svint64_t op) + /// SXTB Ztied.D, Pg/M, Ztied.D + /// MOVPRFX Zresult, Zop; SXTB Zresult.D, Pg/M, Zop.D + /// svint64_t svextb[_s64]_z(svbool_t pg, svint64_t op) + /// MOVPRFX Zresult.D, Pg/Z, Zop.D; SXTB Zresult.D, Pg/M, Zop.D + /// + public static unsafe Vector SignExtend8(Vector value) { throw new PlatformNotSupportedException(); } + /// Subtract : Subtract /// @@ -1248,6 +1328,84 @@ internal Arm64() { } /// public static unsafe Vector UnzipOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + /// ZeroExtend16 : Zero-extend the low 16 bits + + /// + /// svuint32_t svexth[_u32]_m(svuint32_t inactive, svbool_t pg, svuint32_t op) + /// UXTH Ztied.S, Pg/M, Zop.S + /// MOVPRFX Zresult, Zinactive; UXTH Zresult.S, Pg/M, Zop.S + /// svuint32_t svexth[_u32]_x(svbool_t pg, svuint32_t op) + /// UXTH Ztied.S, Pg/M, Ztied.S + /// AND Ztied.S, Ztied.S, #65535 + /// svuint32_t svexth[_u32]_z(svbool_t pg, svuint32_t op) + /// MOVPRFX Zresult.S, Pg/Z, Zop.S; UXTH Zresult.S, Pg/M, Zop.S + /// + public static unsafe Vector ZeroExtend16(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svexth[_u64]_m(svuint64_t inactive, svbool_t pg, svuint64_t op) + /// UXTH Ztied.D, Pg/M, Zop.D + /// MOVPRFX Zresult, Zinactive; UXTH Zresult.D, Pg/M, Zop.D + /// svuint64_t svexth[_u64]_x(svbool_t pg, svuint64_t op) + /// UXTH Ztied.D, Pg/M, Ztied.D + /// AND Ztied.D, Ztied.D, #65535 + /// svuint64_t svexth[_u64]_z(svbool_t pg, svuint64_t op) + /// MOVPRFX Zresult.D, Pg/Z, Zop.D; UXTH Zresult.D, Pg/M, Zop.D + /// + public static unsafe Vector ZeroExtend16(Vector value) { throw new PlatformNotSupportedException(); } + + + /// ZeroExtend32 : Zero-extend the low 32 bits + + /// + /// svuint64_t svextw[_u64]_m(svuint64_t inactive, svbool_t pg, svuint64_t op) + /// UXTW Ztied.D, Pg/M, Zop.D + /// MOVPRFX Zresult, Zinactive; UXTW Zresult.D, Pg/M, Zop.D + /// svuint64_t svextw[_u64]_x(svbool_t pg, svuint64_t op) + /// UXTW Ztied.D, Pg/M, Ztied.D + /// AND Ztied.D, Ztied.D, #4294967295 + /// svuint64_t svextw[_u64]_z(svbool_t pg, svuint64_t op) + /// MOVPRFX Zresult.D, Pg/Z, Zop.D; UXTW Zresult.D, Pg/M, Zop.D + /// + public static unsafe Vector ZeroExtend32(Vector value) { throw new PlatformNotSupportedException(); } + + /// ZeroExtend8 : Zero-extend the low 8 bits + + /// + /// svuint16_t svextb[_u16]_m(svuint16_t inactive, svbool_t pg, svuint16_t op) + /// UXTB Ztied.H, Pg/M, Zop.H + /// MOVPRFX Zresult, Zinactive; UXTB Zresult.H, Pg/M, Zop.H + /// svuint16_t svextb[_u16]_x(svbool_t pg, svuint16_t op) + /// UXTB Ztied.H, Pg/M, Ztied.H + /// AND Ztied.H, Ztied.H, #255 + /// svuint16_t svextb[_u16]_z(svbool_t pg, svuint16_t op) + /// MOVPRFX Zresult.H, Pg/Z, Zop.H; UXTB Zresult.H, Pg/M, Zop.H + /// + public static unsafe Vector ZeroExtend8(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svextb[_u32]_m(svuint32_t inactive, svbool_t pg, svuint32_t op) + /// UXTB Ztied.S, Pg/M, Zop.S + /// MOVPRFX Zresult, Zinactive; UXTB Zresult.S, Pg/M, Zop.S + /// svuint32_t svextb[_u32]_x(svbool_t pg, svuint32_t op) + /// UXTB Ztied.S, Pg/M, Ztied.S + /// AND Ztied.S, Ztied.S, #255 + /// svuint32_t svextb[_u32]_z(svbool_t pg, svuint32_t op) + /// MOVPRFX Zresult.S, Pg/Z, Zop.S; UXTB Zresult.S, Pg/M, Zop.S + /// + public static unsafe Vector ZeroExtend8(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svextb[_u64]_m(svuint64_t inactive, svbool_t pg, svuint64_t op) + /// UXTB Ztied.D, Pg/M, Zop.D + /// MOVPRFX Zresult, Zinactive; UXTB Zresult.D, Pg/M, Zop.D + /// svuint64_t svextb[_u64]_x(svbool_t pg, svuint64_t op) + /// UXTB Ztied.D, Pg/M, Ztied.D + /// AND Ztied.D, Ztied.D, #255 + /// svuint64_t svextb[_u64]_z(svbool_t pg, svuint64_t op) + /// MOVPRFX Zresult.D, Pg/Z, Zop.D; UXTB Zresult.D, Pg/M, Zop.D + /// + public static unsafe Vector ZeroExtend8(Vector value) { throw new PlatformNotSupportedException(); } /// ZipHigh : Interleave elements from high halves of two inputs 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 e823e36e4db2a..7c2c8a0a4e78e 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 @@ -1065,6 +1065,85 @@ internal Arm64() { } /// public static unsafe Vector Multiply(Vector left, Vector right) => Multiply(left, right); + /// SignExtend16 : Sign-extend the low 16 bits + + /// + /// svint32_t svexth[_s32]_m(svint32_t inactive, svbool_t pg, svint32_t op) + /// SXTH Ztied.S, Pg/M, Zop.S + /// MOVPRFX Zresult, Zinactive; SXTH Zresult.S, Pg/M, Zop.S + /// svint32_t svexth[_s32]_x(svbool_t pg, svint32_t op) + /// SXTH Ztied.S, Pg/M, Ztied.S + /// MOVPRFX Zresult, Zop; SXTH Zresult.S, Pg/M, Zop.S + /// svint32_t svexth[_s32]_z(svbool_t pg, svint32_t op) + /// MOVPRFX Zresult.S, Pg/Z, Zop.S; SXTH Zresult.S, Pg/M, Zop.S + /// + public static unsafe Vector SignExtend16(Vector value) => SignExtend16(value); + + /// + /// svint64_t svexth[_s64]_m(svint64_t inactive, svbool_t pg, svint64_t op) + /// SXTH Ztied.D, Pg/M, Zop.D + /// MOVPRFX Zresult, Zinactive; SXTH Zresult.D, Pg/M, Zop.D + /// svint64_t svexth[_s64]_x(svbool_t pg, svint64_t op) + /// SXTH Ztied.D, Pg/M, Ztied.D + /// MOVPRFX Zresult, Zop; SXTH Zresult.D, Pg/M, Zop.D + /// svint64_t svexth[_s64]_z(svbool_t pg, svint64_t op) + /// MOVPRFX Zresult.D, Pg/Z, Zop.D; SXTH Zresult.D, Pg/M, Zop.D + /// + public static unsafe Vector SignExtend16(Vector value) => SignExtend16(value); + + /// SignExtend32 : Sign-extend the low 32 bits + + /// + /// svint64_t svextw[_s64]_m(svint64_t inactive, svbool_t pg, svint64_t op) + /// SXTW Ztied.D, Pg/M, Zop.D + /// MOVPRFX Zresult, Zinactive; SXTW Zresult.D, Pg/M, Zop.D + /// svint64_t svextw[_s64]_x(svbool_t pg, svint64_t op) + /// SXTW Ztied.D, Pg/M, Ztied.D + /// MOVPRFX Zresult, Zop; SXTW Zresult.D, Pg/M, Zop.D + /// svint64_t svextw[_s64]_z(svbool_t pg, svint64_t op) + /// MOVPRFX Zresult.D, Pg/Z, Zop.D; SXTW Zresult.D, Pg/M, Zop.D + /// + public static unsafe Vector SignExtend32(Vector value) => SignExtend32(value); + + + /// SignExtend8 : Sign-extend the low 8 bits + + /// + /// svint16_t svextb[_s16]_m(svint16_t inactive, svbool_t pg, svint16_t op) + /// SXTB Ztied.H, Pg/M, Zop.H + /// MOVPRFX Zresult, Zinactive; SXTB Zresult.H, Pg/M, Zop.H + /// svint16_t svextb[_s16]_x(svbool_t pg, svint16_t op) + /// SXTB Ztied.H, Pg/M, Ztied.H + /// MOVPRFX Zresult, Zop; SXTB Zresult.H, Pg/M, Zop.H + /// svint16_t svextb[_s16]_z(svbool_t pg, svint16_t op) + /// MOVPRFX Zresult.H, Pg/Z, Zop.H; SXTB Zresult.H, Pg/M, Zop.H + /// + public static unsafe Vector SignExtend8(Vector value) => SignExtend8(value); + + /// + /// svint32_t svextb[_s32]_m(svint32_t inactive, svbool_t pg, svint32_t op) + /// SXTB Ztied.S, Pg/M, Zop.S + /// MOVPRFX Zresult, Zinactive; SXTB Zresult.S, Pg/M, Zop.S + /// svint32_t svextb[_s32]_x(svbool_t pg, svint32_t op) + /// SXTB Ztied.S, Pg/M, Ztied.S + /// MOVPRFX Zresult, Zop; SXTB Zresult.S, Pg/M, Zop.S + /// svint32_t svextb[_s32]_z(svbool_t pg, svint32_t op) + /// MOVPRFX Zresult.S, Pg/Z, Zop.S; SXTB Zresult.S, Pg/M, Zop.S + /// + public static unsafe Vector SignExtend8(Vector value) => SignExtend8(value); + + /// + /// svint64_t svextb[_s64]_m(svint64_t inactive, svbool_t pg, svint64_t op) + /// SXTB Ztied.D, Pg/M, Zop.D + /// MOVPRFX Zresult, Zinactive; SXTB Zresult.D, Pg/M, Zop.D + /// svint64_t svextb[_s64]_x(svbool_t pg, svint64_t op) + /// SXTB Ztied.D, Pg/M, Ztied.D + /// MOVPRFX Zresult, Zop; SXTB Zresult.D, Pg/M, Zop.D + /// svint64_t svextb[_s64]_z(svbool_t pg, svint64_t op) + /// MOVPRFX Zresult.D, Pg/Z, Zop.D; SXTB Zresult.D, Pg/M, Zop.D + /// + public static unsafe Vector SignExtend8(Vector value) => SignExtend8(value); + /// Subtract : Subtract /// @@ -1329,6 +1408,87 @@ internal Arm64() { } /// UZP2 Presult.D, Pop1.D, Pop2.D /// public static unsafe Vector UnzipOdd(Vector left, Vector right) => UnzipOdd(left, right); + + /// ZeroExtend16 : Zero-extend the low 16 bits + + /// + /// svuint32_t svexth[_u32]_m(svuint32_t inactive, svbool_t pg, svuint32_t op) + /// UXTH Ztied.S, Pg/M, Zop.S + /// MOVPRFX Zresult, Zinactive; UXTH Zresult.S, Pg/M, Zop.S + /// svuint32_t svexth[_u32]_x(svbool_t pg, svuint32_t op) + /// UXTH Ztied.S, Pg/M, Ztied.S + /// AND Ztied.S, Ztied.S, #65535 + /// svuint32_t svexth[_u32]_z(svbool_t pg, svuint32_t op) + /// MOVPRFX Zresult.S, Pg/Z, Zop.S; UXTH Zresult.S, Pg/M, Zop.S + /// + public static unsafe Vector ZeroExtend16(Vector value) => ZeroExtend16(value); + + /// + /// svuint64_t svexth[_u64]_m(svuint64_t inactive, svbool_t pg, svuint64_t op) + /// UXTH Ztied.D, Pg/M, Zop.D + /// MOVPRFX Zresult, Zinactive; UXTH Zresult.D, Pg/M, Zop.D + /// svuint64_t svexth[_u64]_x(svbool_t pg, svuint64_t op) + /// UXTH Ztied.D, Pg/M, Ztied.D + /// AND Ztied.D, Ztied.D, #65535 + /// svuint64_t svexth[_u64]_z(svbool_t pg, svuint64_t op) + /// MOVPRFX Zresult.D, Pg/Z, Zop.D; UXTH Zresult.D, Pg/M, Zop.D + /// + public static unsafe Vector ZeroExtend16(Vector value) => ZeroExtend16(value); + + + /// ZeroExtend32 : Zero-extend the low 32 bits + + /// + /// svuint64_t svextw[_u64]_m(svuint64_t inactive, svbool_t pg, svuint64_t op) + /// UXTW Ztied.D, Pg/M, Zop.D + /// MOVPRFX Zresult, Zinactive; UXTW Zresult.D, Pg/M, Zop.D + /// svuint64_t svextw[_u64]_x(svbool_t pg, svuint64_t op) + /// UXTW Ztied.D, Pg/M, Ztied.D + /// AND Ztied.D, Ztied.D, #4294967295 + /// svuint64_t svextw[_u64]_z(svbool_t pg, svuint64_t op) + /// MOVPRFX Zresult.D, Pg/Z, Zop.D; UXTW Zresult.D, Pg/M, Zop.D + /// + public static unsafe Vector ZeroExtend32(Vector value) => ZeroExtend32(value); + + + /// ZeroExtend8 : Zero-extend the low 8 bits + + /// + /// svuint16_t svextb[_u16]_m(svuint16_t inactive, svbool_t pg, svuint16_t op) + /// UXTB Ztied.H, Pg/M, Zop.H + /// MOVPRFX Zresult, Zinactive; UXTB Zresult.H, Pg/M, Zop.H + /// svuint16_t svextb[_u16]_x(svbool_t pg, svuint16_t op) + /// UXTB Ztied.H, Pg/M, Ztied.H + /// AND Ztied.H, Ztied.H, #255 + /// svuint16_t svextb[_u16]_z(svbool_t pg, svuint16_t op) + /// MOVPRFX Zresult.H, Pg/Z, Zop.H; UXTB Zresult.H, Pg/M, Zop.H + /// + public static unsafe Vector ZeroExtend8(Vector value) => ZeroExtend8(value); + + /// + /// svuint32_t svextb[_u32]_m(svuint32_t inactive, svbool_t pg, svuint32_t op) + /// UXTB Ztied.S, Pg/M, Zop.S + /// MOVPRFX Zresult, Zinactive; UXTB Zresult.S, Pg/M, Zop.S + /// svuint32_t svextb[_u32]_x(svbool_t pg, svuint32_t op) + /// UXTB Ztied.S, Pg/M, Ztied.S + /// AND Ztied.S, Ztied.S, #255 + /// svuint32_t svextb[_u32]_z(svbool_t pg, svuint32_t op) + /// MOVPRFX Zresult.S, Pg/Z, Zop.S; UXTB Zresult.S, Pg/M, Zop.S + /// + public static unsafe Vector ZeroExtend8(Vector value) => ZeroExtend8(value); + + /// + /// svuint64_t svextb[_u64]_m(svuint64_t inactive, svbool_t pg, svuint64_t op) + /// UXTB Ztied.D, Pg/M, Zop.D + /// MOVPRFX Zresult, Zinactive; UXTB Zresult.D, Pg/M, Zop.D + /// svuint64_t svextb[_u64]_x(svbool_t pg, svuint64_t op) + /// UXTB Ztied.D, Pg/M, Ztied.D + /// AND Ztied.D, Ztied.D, #255 + /// svuint64_t svextb[_u64]_z(svbool_t pg, svuint64_t op) + /// MOVPRFX Zresult.D, Pg/Z, Zop.D; UXTB Zresult.D, Pg/M, Zop.D + /// + public static unsafe Vector ZeroExtend8(Vector value) => ZeroExtend8(value); + /// ZipHigh : Interleave elements from high halves of two inputs /// 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 f67349e325b27..88839fee87dca 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -4279,6 +4279,14 @@ internal Arm64() { } public static unsafe System.Numerics.Vector LoadVectorUInt16ZeroExtendToUInt64(System.Numerics.Vector mask, ushort* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorUInt32ZeroExtendToInt64(System.Numerics.Vector mask, uint* address) { throw null; } public static unsafe System.Numerics.Vector LoadVectorUInt32ZeroExtendToUInt64(System.Numerics.Vector mask, uint* address) { throw null; } + + public static System.Numerics.Vector SignExtend16(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector SignExtend16(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector SignExtend32(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector SignExtend8(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector SignExtend8(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector SignExtend8(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector Subtract(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector Subtract(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector Subtract(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } @@ -4289,6 +4297,7 @@ internal Arm64() { } public static System.Numerics.Vector Subtract(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector Subtract(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector Subtract(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector Multiply(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector Multiply(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector Multiply(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } @@ -4299,6 +4308,7 @@ internal Arm64() { } public static System.Numerics.Vector Multiply(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector Multiply(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector Multiply(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector UnzipEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector UnzipEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector UnzipEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } @@ -4321,6 +4331,13 @@ internal Arm64() { } public static System.Numerics.Vector UnzipOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector UnzipOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector ZeroExtend16(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ZeroExtend16(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ZeroExtend32(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ZeroExtend8(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ZeroExtend8(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ZeroExtend8(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ZipHigh(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector ZipHigh(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector ZipHigh(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 9ef8602784835..589217ca968e4 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -2972,12 +2972,6 @@ ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVector_uint", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVector_ulong", ["Isa"] = "Sve", ["Method"] = "LoadVector", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorByteZeroExtendToInt16", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorByteZeroExtendToInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorByteZeroExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorByteZeroExtendToUInt16", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToUInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorByteZeroExtendToUInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), - ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorByteZeroExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorInt16SignExtendToInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorInt16SignExtendToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorInt16SignExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorInt16SignExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorInt16SignExtendToUInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorInt16SignExtendToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), @@ -2990,6 +2984,12 @@ ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorSByteSignExtendToUInt16", ["Isa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendToUInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorSByteSignExtendToUInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorSByteSignExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorSByteSignExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "(ulong)firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorByteZeroExtendToInt16", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorByteZeroExtendToInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorByteZeroExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorByteZeroExtendToUInt16", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToUInt16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorByteZeroExtendToUInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), + ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorByteZeroExtendToUInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorByteZeroExtendToUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorUInt16ZeroExtendToInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt16ZeroExtendToInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorUInt16ZeroExtendToInt64", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt16ZeroExtendToInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), ("SveLoadMaskedUnOpTest.template", new Dictionary { ["TestName"] = "SveLoadVectorUInt16ZeroExtendToUInt32", ["Isa"] = "Sve", ["Method"] = "LoadVectorUInt16ZeroExtendToUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "firstOp[i] != result[i]"}), @@ -3008,6 +3008,13 @@ ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Multiply_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Multiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "Helpers.Multiply(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Multiply(left[i], right[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_SignExtend16_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtend16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 16, false)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 16, false)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_SignExtend16_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtend16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 16, false)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 16, false)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_SignExtend32_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtend32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 32, false)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 32, false)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_SignExtend8_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtend8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 8, false)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 8, false)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_SignExtend8_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtend8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 8, false)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 8, false)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_SignExtend8_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SignExtend8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 8, false)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 8, false)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "Helpers.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve_Subtract_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "Subtract", ["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.Subtract(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.Subtract(left[i], right[i])"}), @@ -3039,7 +3046,14 @@ ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveUnzipOdd_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveUnzipOdd_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveUnzipOdd_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "UnzipOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[index] != left[i + 1] || result[index + half] != right[i + 1]"}), - + + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ZeroExtend16_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtend16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 16, true)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 16, true)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ZeroExtend16_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtend16", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "(TestLibrary.Generator.GetUInt64() & 0x3FFFFFFFFFFFFFFF)", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 16, true)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 16, true)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ZeroExtend32_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtend32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "(TestLibrary.Generator.GetUInt64() & 0x3FFFFFFFFFFFFFFF)", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 32, true)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 32, true)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ZeroExtend8_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtend8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 8, true)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 8, true)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ZeroExtend8_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtend8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 8, true)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 8, true)"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ZeroExtend8_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZeroExtend8", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "(TestLibrary.Generator.GetUInt64() & 0x3FFFFFFFFFFFFFFF)", ["ValidateIterResult"] = "result[i] != Helpers.SignExtend(firstOp[i], 8, true)", ["GetIterResult"] = "Helpers.SignExtend(leftOp[i], 8, true)"}), + ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveZipHigh_float", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveZipHigh_double", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), ("SveVecPairBinOpTest.template", new Dictionary { ["TestName"] = "SveZipHigh_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ZipHigh", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ValidateEntry"] = "result[i] != left[index + half] || result[i + 1] != right[index + half]"}), diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index 4b44b29337573..6e96c9fc080a5 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -1701,6 +1701,29 @@ private static int HighNarrowing(long op1, bool round) public static long MultiplyWideningUpperAndSubtract(long[] op1, int[] op2, int[] op3, int i) => MultiplyWideningAndSubtract(op1[i], op2[i + op2.Length / 2], op3[i + op3.Length / 2]); + public static T SignExtend(T n, int numBits, bool zeroExtend) where T : struct, IComparable, IConvertible + { + // Get the underlying integer value + dynamic value = Convert.ChangeType(n, typeof(long)); + + // Mask to extract the lowest numBits + long mask = (1L << numBits) - 1; + long lowestBits = value & mask; + + // Sign extension for signed integers + long signBitMask = 1L << (numBits - 1); + if (!zeroExtend && ((lowestBits & signBitMask) != 0)) + { + // If sign bit is set, it's a negative number + return (T)Convert.ChangeType(-((~lowestBits & mask) + 1), typeof(T)); + } + else + { + // If sign bit is not set, it's a positive number + return (T)Convert.ChangeType(lowestBits, typeof(T)); + } + } + public static int SubtractHighNarrowing(long op1, long op2) => HighNarrowing((long)(op1 - op2), round: false); public static long SubtractHighNarrowingUpper(int[] op1, long[] op2, long[] op3, int i) => i < op1.Length ? op1[i] : SubtractHighNarrowing(op2[i - op1.Length], op3[i - op1.Length]);