diff --git a/src/coreclr/jit/hwintrinsiclistarm64sve.h b/src/coreclr/jit/hwintrinsiclistarm64sve.h index 31b406bf2656d..01f33ea480f9c 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64sve.h +++ b/src/coreclr/jit/hwintrinsiclistarm64sve.h @@ -168,6 +168,7 @@ HARDWARE_INTRINSIC(Sve, PrefetchBytes, HARDWARE_INTRINSIC(Sve, PrefetchInt16, -1, 3, false, {INS_invalid, INS_invalid, INS_invalid, INS_sve_prfh, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_BaseTypeFromFirstArg|HW_Flag_HasImmediateOperand|HW_Flag_HasEnumOperand) HARDWARE_INTRINSIC(Sve, PrefetchInt32, -1, 3, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_prfw, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_BaseTypeFromFirstArg|HW_Flag_HasImmediateOperand|HW_Flag_HasEnumOperand) HARDWARE_INTRINSIC(Sve, PrefetchInt64, -1, 3, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_prfd, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_BaseTypeFromFirstArg|HW_Flag_HasImmediateOperand|HW_Flag_HasEnumOperand) +HARDWARE_INTRINSIC(Sve, ReverseBits, -1, -1, false, {INS_sve_rbit, INS_sve_rbit, INS_sve_rbit, INS_sve_rbit, INS_sve_rbit, INS_sve_rbit, INS_sve_rbit, INS_sve_rbit, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, ReverseElement, -1, 1, true, {INS_sve_rev, INS_sve_rev, INS_sve_rev, INS_sve_rev, INS_sve_rev, INS_sve_rev, INS_sve_rev, INS_sve_rev, INS_sve_rev, INS_sve_rev}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Sve, ReverseElement16, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_revh, INS_sve_revh, INS_sve_revh, INS_sve_revh, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, ReverseElement32, -1, -1, false, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_revw, INS_sve_revw, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|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 fb07d8a6a8fe6..fa3d9d0b23abf 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 @@ -4445,6 +4445,57 @@ internal Arm64() { } public static unsafe void PrefetchInt64(Vector mask, void* address, [ConstantExpected] SvePrefetchType prefetchType) { throw new PlatformNotSupportedException(); } + /// Reverse bits + + /// + /// svuint8_t svrbit[_u8]_m(svuint8_t inactive, svbool_t pg, svuint8_t op) + /// RBIT Ztied.B, Pg/M, Zop.B + /// + public static unsafe Vector ReverseBits(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svrbit[_s16]_m(svint16_t inactive, svbool_t pg, svint16_t op) + /// RBIT Ztied.H, Pg/M, Zop.H + /// + public static unsafe Vector ReverseBits(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svrbit[_s32]_m(svint32_t inactive, svbool_t pg, svint32_t op) + /// RBIT Ztied.S, Pg/M, Zop.S + /// + public static unsafe Vector ReverseBits(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svrbit[_s64]_m(svint64_t inactive, svbool_t pg, svint64_t op) + /// RBIT Ztied.D, Pg/M, Zop.D + /// + public static unsafe Vector ReverseBits(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svrbit[_s8]_m(svint8_t inactive, svbool_t pg, svint8_t op) + /// RBIT Ztied.B, Pg/M, Zop.B + /// + public static unsafe Vector ReverseBits(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svrbit[_u16]_m(svuint16_t inactive, svbool_t pg, svuint16_t op) + /// RBIT Ztied.H, Pg/M, Zop.H + /// + public static unsafe Vector ReverseBits(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svrbit[_u32]_m(svuint32_t inactive, svbool_t pg, svuint32_t op) + /// RBIT Ztied.S, Pg/M, Zop.S + /// + public static unsafe Vector ReverseBits(Vector value) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svrbit[_u64]_m(svuint64_t inactive, svbool_t pg, svuint64_t op) + /// RBIT Ztied.D, Pg/M, Zop.D + /// + public static unsafe Vector ReverseBits(Vector value) { throw new PlatformNotSupportedException(); } + + /// Reverse all elements /// 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 ac3b7dd98b88b..81e8bacb2eb9a 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 @@ -4499,6 +4499,57 @@ internal Arm64() { } /// public static unsafe void PrefetchInt64(Vector mask, void* address, [ConstantExpected] SvePrefetchType prefetchType) => PrefetchInt64(mask, address, prefetchType); + /// Reverse bits + + /// + /// svuint8_t svrbit[_u8]_x(svbool_t pg, svuint8_t op) + /// RBIT Ztied.B, Pg/M, Ztied.B + /// + public static unsafe Vector ReverseBits(Vector value) => ReverseBits(value); + + /// + /// svint16_t svrbit[_s16]_m(svint16_t inactive, svbool_t pg, svint16_t op) + /// RBIT Ztied.H, Pg/M, Zop.H + /// + public static unsafe Vector ReverseBits(Vector value) => ReverseBits(value); + + /// + /// svint32_t svrbit[_s32]_m(svint32_t inactive, svbool_t pg, svint32_t op) + /// RBIT Ztied.S, Pg/M, Zop.S + /// + public static unsafe Vector ReverseBits(Vector value) => ReverseBits(value); + + /// + /// svint64_t svrbit[_s64]_m(svint64_t inactive, svbool_t pg, svint64_t op) + /// RBIT Ztied.D, Pg/M, Zop.D + /// + public static unsafe Vector ReverseBits(Vector value) => ReverseBits(value); + + /// + /// svint8_t svrbit[_s8]_m(svint8_t inactive, svbool_t pg, svint8_t op) + /// RBIT Ztied.B, Pg/M, Zop.B + /// + public static unsafe Vector ReverseBits(Vector value) => ReverseBits(value); + + /// + /// svuint16_t svrbit[_u16]_m(svuint16_t inactive, svbool_t pg, svuint16_t op) + /// RBIT Ztied.H, Pg/M, Zop.H + /// + public static unsafe Vector ReverseBits(Vector value) => ReverseBits(value); + + /// + /// svuint32_t svrbit[_u32]_m(svuint32_t inactive, svbool_t pg, svuint32_t op) + /// RBIT Ztied.S, Pg/M, Zop.S + /// + public static unsafe Vector ReverseBits(Vector value) => ReverseBits(value); + + /// + /// svuint64_t svrbit[_u64]_m(svuint64_t inactive, svbool_t pg, svuint64_t op) + /// RBIT Ztied.D, Pg/M, Zop.D + /// + public static unsafe Vector ReverseBits(Vector value) => ReverseBits(value); + + /// Reverse all elements /// 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 d297de265fc74..7cddb481cab24 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -4826,6 +4826,15 @@ internal Arm64() { } public static unsafe void PrefetchInt32(System.Numerics.Vector mask, void* address, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void PrefetchInt64(System.Numerics.Vector mask, void* address, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } + public static System.Numerics.Vector ReverseBits(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ReverseBits(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ReverseBits(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ReverseBits(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ReverseBits(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ReverseBits(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ReverseBits(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ReverseBits(System.Numerics.Vector value) { throw null; } + public static System.Numerics.Vector ReverseElement(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector ReverseElement(System.Numerics.Vector value) { throw null; } public static System.Numerics.Vector ReverseElement(System.Numerics.Vector value) { throw null; } diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs index a566595555487..32d6a38b60c08 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -3616,6 +3616,15 @@ ("SvePrefetchTest.template", new Dictionary { ["TestName"] = "Sve_PrefetchInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "PrefetchInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL3Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)20"}), ("SvePrefetchTest.template", new Dictionary { ["TestName"] = "Sve_PrefetchInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "PrefetchInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL1NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)87"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseBits_byte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseBits", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElementBits(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElementBits(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseBits_short", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseBits", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElementBits(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElementBits(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseBits_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseBits", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElementBits(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElementBits(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseBits_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseBits", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElementBits(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElementBits(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseBits_sbyte", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseBits", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElementBits(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElementBits(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseBits_ushort", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseBits", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElementBits(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElementBits(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseBits_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseBits", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElementBits(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElementBits(leftOp[i])"}), + ("SveSimpleVecOpTest.template", new Dictionary { ["TestName"] = "Sve_ReverseBits_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "ReverseBits", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["ValidateIterResult"] = "result[i] != Helpers.ReverseElementBits(firstOp[i])", ["GetIterResult"] = "Helpers.ReverseElementBits(leftOp[i])"}), + ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy16BitElementCount_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy16BitElementCount", ["RetBaseType"] = "Int32", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["Imm"] = "(Byte)2", ["Imm2"] = "SveMaskPattern.LargestPowerOf2", ["InvalidImm"] = "(Byte)0", ["InvalidImm2"] = "(SveMaskPattern)35", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((int)data, (int)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2))));",}), ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy16BitElementCount_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy16BitElementCount", ["RetBaseType"] = "Int64", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["Imm"] = "(Byte)12", ["Imm2"] = "SveMaskPattern.VectorCount1", ["InvalidImm"] = "(Byte)19", ["InvalidImm2"] = "(SveMaskPattern)37", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((long)data, (long)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2))));",}), ("ScalarImm2UnOpTest.template", new Dictionary {["TestName"] = "Sve_SaturatingDecrementBy16BitElementCount_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "SaturatingDecrementBy16BitElementCount", ["RetBaseType"] = "UInt32", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "Byte", ["Op3BaseType"] = "SveMaskPattern", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["Imm"] = "(Byte)5", ["Imm2"] = "SveMaskPattern.VectorCount2", ["InvalidImm"] = "(Byte)25", ["InvalidImm2"] = "(SveMaskPattern)46", ["ValidateResult"] = "isUnexpectedResult = (result != Helpers.SubtractSaturate((uint)data, (uint)(imm1 * Helpers.NumberOfElementsInVectorInt16(imm2))));",}), diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index 17238a8c16870..52b12a112a2f6 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -323,6 +323,24 @@ public static byte ReverseElementBits(byte op1) return (byte)result; } + public static short ReverseElementBits(short op1) + { + short val = (short)op1; + short result = 0; + const int bitsize = sizeof(short) * 8; + const short cst_one = 1; + + for (int i = 0; i < bitsize; i++) + { + if ((val & (cst_one << i)) != 0) + { + result |= (short)(cst_one << (bitsize - 1 - i)); + } + } + + return (short)result; + } + public static int ReverseElementBits(int op1) { uint val = (uint)op1; @@ -377,6 +395,24 @@ public static sbyte ReverseElementBits(sbyte op1) return (sbyte)result; } + public static ushort ReverseElementBits(ushort op1) + { + ushort val = (ushort)op1; + ushort result = 0; + const int bitsize = sizeof(ushort) * 8; + const ushort cst_one = 1; + + for (int i = 0; i < bitsize; i++) + { + if ((val & (cst_one << i)) != 0) + { + result |= (ushort)(cst_one << (bitsize - 1 - i)); + } + } + + return (ushort)result; + } + public static uint ReverseElementBits(uint op1) { uint val = (uint)op1;