Skip to content

Commit 6fac66d

Browse files
committed
SVE2 API for AddCarryWideningLower
Change-Id: I24b0cc3474dcfaee40ad735d3ec274ed48e97035
1 parent c8403e6 commit 6fac66d

File tree

6 files changed

+82
-0
lines changed

6 files changed

+82
-0
lines changed

src/coreclr/jit/hwintrinsiclistarm64sve.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ HARDWARE_INTRINSIC(Sve2, AbsoluteDifferenceAddWideningLower,
318318
HARDWARE_INTRINSIC(Sve2, AbsoluteDifferenceAddWideningUpper, -1, 3, {INS_invalid, INS_invalid, INS_sve_sabalt, INS_sve_uabalt, INS_sve_sabalt, INS_sve_uabalt, INS_sve_sabalt, INS_sve_uabalt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_HasRMWSemantics)
319319
HARDWARE_INTRINSIC(Sve2, AbsoluteDifferenceWideningLower, -1, 2, {INS_invalid, INS_invalid, INS_sve_sabdlb, INS_sve_uabdlb, INS_sve_sabdlb, INS_sve_uabdlb, INS_sve_sabdlb, INS_sve_uabdlb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable)
320320
HARDWARE_INTRINSIC(Sve2, AbsoluteDifferenceWideningUpper, -1, 2, {INS_invalid, INS_invalid, INS_sve_sabdlt, INS_sve_uabdlt, INS_sve_sabdlt, INS_sve_uabdlt, INS_sve_sabdlt, INS_sve_uabdlt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable)
321+
HARDWARE_INTRINSIC(Sve2, AddCarryWideningLower, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_adclb, INS_invalid, INS_sve_adclb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics)
321322
HARDWARE_INTRINSIC(Sve2, BitwiseClearXor, -1, 3, {INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_sve_bcax, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics)
322323
HARDWARE_INTRINSIC(Sve2, BitwiseSelect, -1, 3, {INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_sve_bsl, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics)
323324
HARDWARE_INTRINSIC(Sve2, BitwiseSelectLeftInverted, -1, 3, {INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics)

src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.PlatformNotSupported.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,20 @@ internal Arm64() { }
230230
/// </summary>
231231
public static Vector<ulong> AbsoluteDifferenceWideningUpper(Vector<uint> left, Vector<uint> right) { throw new PlatformNotSupportedException(); }
232232

233+
// Add with carry long (bottom)
234+
235+
/// <summary>
236+
/// svuint32_t svadclb[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3)
237+
/// ADCLB Ztied1.S, Zop2.S, Zop3.S
238+
/// </summary>
239+
public static unsafe Vector<uint> AddCarryWideningLower(Vector<uint> op1, Vector<uint> op2, Vector<uint> op3) { throw new PlatformNotSupportedException(); }
240+
241+
/// <summary>
242+
/// svuint64_t svadclb[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3)
243+
/// ADCLB Ztied1.D, Zop2.D, Zop3.D
244+
/// </summary>
245+
public static unsafe Vector<ulong> AddCarryWideningLower(Vector<ulong> op1, Vector<ulong> op2, Vector<ulong> op3) { throw new PlatformNotSupportedException(); }
246+
233247
// Bitwise clear and exclusive OR
234248

235249
/// <summary>

src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,20 @@ internal Arm64() { }
230230
/// </summary>
231231
public static Vector<ulong> AbsoluteDifferenceWideningUpper(Vector<uint> left, Vector<uint> right) => AbsoluteDifferenceWideningUpper(left, right);
232232

233+
// Add with carry long (bottom)
234+
235+
/// <summary>
236+
/// svuint32_t svadclb[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3)
237+
/// ADCLB Ztied1.S, Zop2.S, Zop3.S
238+
/// </summary>
239+
public static unsafe Vector<uint> AddCarryWideningLower(Vector<uint> op1, Vector<uint> op2, Vector<uint> op3) => AddCarryWideningLower(op1, op2, op3);
240+
241+
/// <summary>
242+
/// svuint64_t svadclb[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3)
243+
/// ADCLB Ztied1.D, Zop2.D, Zop3.D
244+
/// </summary>
245+
public static unsafe Vector<ulong> AddCarryWideningLower(Vector<ulong> op1, Vector<ulong> op2, Vector<ulong> op3) => AddCarryWideningLower(op1, op2, op3);
246+
233247
// Bitwise clear and exclusive OR
234248

235249
/// <summary>

src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6116,6 +6116,9 @@ internal Arm64() { }
61166116
public static System.Numerics.Vector<uint> AbsoluteDifferenceWideningUpper(System.Numerics.Vector<ushort> left, System.Numerics.Vector<ushort> right) { throw null; }
61176117
public static System.Numerics.Vector<ulong> AbsoluteDifferenceWideningUpper(System.Numerics.Vector<uint> left, System.Numerics.Vector<uint> right) { throw null; }
61186118

6119+
public static System.Numerics.Vector<uint> AddCarryWideningLower(System.Numerics.Vector<uint> op1, System.Numerics.Vector<uint> op2, System.Numerics.Vector<uint> op3) { throw null; }
6120+
public static System.Numerics.Vector<ulong> AddCarryWideningLower(System.Numerics.Vector<ulong> op1, System.Numerics.Vector<ulong> op2, System.Numerics.Vector<ulong> op3) { throw null; }
6121+
61196122
public static System.Numerics.Vector<byte> BitwiseClearXor(System.Numerics.Vector<byte> xor, System.Numerics.Vector<byte> value, System.Numerics.Vector<byte> mask) { throw null; }
61206123
public static System.Numerics.Vector<short> BitwiseClearXor(System.Numerics.Vector<short> xor, System.Numerics.Vector<short> value, System.Numerics.Vector<short> mask) { throw null; }
61216124
public static System.Numerics.Vector<int> BitwiseClearXor(System.Numerics.Vector<int> xor, System.Numerics.Vector<int> value, System.Numerics.Vector<int> mask) { throw null; }

src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4817,6 +4817,9 @@
48174817
("SveVecBinOpDifferentRetType.template", new Dictionary<string, string> {["TestName"] = "Sve2_AbsoluteDifferenceWideningUpper_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningOdd(left, right, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AbsoluteDifferenceWideningOdd(left, right, i)"}),
48184818
("SveVecBinOpDifferentRetType.template", new Dictionary<string, string> {["TestName"] = "Sve2_AbsoluteDifferenceWideningUpper_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AbsoluteDifferenceWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AbsoluteDifferenceWideningOdd(left, right, i) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AbsoluteDifferenceWideningOdd(left, right, i)"}),
48194819

4820+
("SveVecTernOpTest.template", new Dictionary<string, string> { ["TestName"] = "Sve2_AddCarryWideningLower_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddCarryWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddCarryWideningEven(firstOp, secondOp, thirdOp, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddCarryWideningEven(first, second, third, i)"}),
4821+
("SveVecTernOpTest.template", new Dictionary<string, string> { ["TestName"] = "Sve2_AddCarryWideningLower_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddCarryWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddCarryWideningEven(firstOp, secondOp, thirdOp, i) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddCarryWideningEven(first, second, third, i)"}),
4822+
48204823
("SveVecTernOpTest.template", new Dictionary<string, string> { ["TestName"] = "Sve2_BitwiseClearXor_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseClearXor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))", ["GetIterResult"] = "(SByte) (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))"}),
48214824
("SveVecTernOpTest.template", new Dictionary<string, string> { ["TestName"] = "Sve2_BitwiseClearXor_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseClearXor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))", ["GetIterResult"] = "(Int16) (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))"}),
48224825
("SveVecTernOpTest.template", new Dictionary<string, string> { ["TestName"] = "Sve2_BitwiseClearXor_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "BitwiseClearXor", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))", ["GetIterResult"] = "(Int32) (firstOp[i] ^ (secondOp[i] &~ thirdOp[i]))"}),

src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2293,6 +2293,27 @@ private static long Reduce(Func<long, sbyte, long> reduceOp, sbyte[] op1)
22932293

22942294
public static int AddPairwiseWideningAndAdd(int[] op1, short[] op2, int i) => (int)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1]));
22952295

2296+
public static uint AddCarryWideningEven(uint[] op1, uint[] op2, uint[] op3, int i)
2297+
{
2298+
uint lsb;
2299+
ulong res;
2300+
2301+
if (i % 2 == 0)
2302+
{
2303+
lsb = op3[i + 1] & 1u;
2304+
res = (ulong)op1[i] + op2[i] + lsb;
2305+
return (uint)res;
2306+
}
2307+
else
2308+
{
2309+
lsb = op3[i] & 1u;
2310+
res = (ulong)op1[i - 1] + op2[i - 1] + lsb;
2311+
2312+
// Shift result to get the carry bit
2313+
return (uint)(res >> 32);
2314+
}
2315+
}
2316+
22962317
private static short HighNarrowing(int op1, bool round)
22972318
{
22982319
uint roundConst = 0;
@@ -2415,6 +2436,32 @@ private static long Reduce(Func<long, short, long> reduceOp, short[] op1)
24152436

24162437
public static long AddPairwiseWideningAndAdd(long[] op1, int[] op2, int i) => (long)(op1[i] + AddWidening(op2[2 * i], op2[2 * i + 1]));
24172438

2439+
public static ulong AddCarryWideningEven(ulong[] op1, ulong[] op2, ulong[] op3, int i)
2440+
{
2441+
ulong lsb;
2442+
ulong res;
2443+
2444+
if (i % 2 == 0)
2445+
{
2446+
lsb = op3[i + 1] & 1UL;
2447+
res = op1[i] + op2[i] + lsb;
2448+
return res;
2449+
}
2450+
else
2451+
{
2452+
lsb = op3[i] & 1UL;
2453+
2454+
// Look for an overflow in the addition to get the carry bit
2455+
ulong sum1 = op1[i - 1] + op2[i - 1];
2456+
bool overflow1 = sum1 < op1[i - 1];
2457+
2458+
ulong sum2 = sum1 + lsb;
2459+
bool overflow2 = sum2 < sum1;
2460+
2461+
return (overflow1 || overflow2) ? 1UL : 0UL;
2462+
}
2463+
}
2464+
24182465
private static int HighNarrowing(long op1, bool round)
24192466
{
24202467
ulong roundConst = 0;

0 commit comments

Comments
 (0)