Skip to content

Commit bec3b04

Browse files
Combine two table lookups into one while formatting Guid on Arm64 (#87126)
* Combine two table lookups into one while formatting Guid on Arm64 * Add a comment to explain the combined table look-up and hex indices
1 parent 8fb25a8 commit bec3b04

File tree

1 file changed

+24
-9
lines changed
  • src/libraries/System.Private.CoreLib/src/System

1 file changed

+24
-9
lines changed

src/libraries/System.Private.CoreLib/src/System/Guid.cs

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1405,7 +1405,7 @@ private static (Vector128<byte>, Vector128<byte>, Vector128<byte>) FormatGuidVec
14051405

14061406
if (useDashes)
14071407
{
1408-
// We divide 16 bytes into 3 x Vector128<byte>:
1408+
// We divide 32 bytes into 3 x Vector128<byte>:
14091409
//
14101410
// ________-____-____-____-____________
14111411
// xxxxxxxxxxxxxxxx
@@ -1421,14 +1421,29 @@ private static (Vector128<byte>, Vector128<byte>, Vector128<byte>) FormatGuidVec
14211421
Vector128.Create(0x7060504FF030201, 0xF0E0D0C0B0A0908).AsByte());
14221422

14231423
// Vector "z" - we need to merge some elements of hexLow with hexHigh and add 4 dashes.
1424-
Vector128<byte> mid1 = Vector128.Shuffle(hexLow,
1425-
Vector128.Create(0x0D0CFF0B0A0908FF, 0xFFFFFFFFFFFF0F0E).AsByte());
1426-
Vector128<byte> mid2 = Vector128.Shuffle(hexHigh,
1427-
Vector128.Create(0xFFFFFFFFFFFFFFFF, 0xFF03020100FFFFFF).AsByte());
1428-
Vector128<byte> dashesMask = Vector128.Shuffle(Vector128.CreateScalarUnsafe((byte)'-'),
1429-
Vector128.Create(0xFFFF00FFFFFFFF00, 0x00FFFFFFFF00FFFF).AsByte());
1430-
1431-
Vector128<byte> vecZ = (mid1 | mid2 | dashesMask);
1424+
Vector128<byte> vecZ;
1425+
Vector128<byte> dashesMask = Vector128.Create(0x00002D000000002D, 0x2D000000002D0000).AsByte();
1426+
if (AdvSimd.Arm64.IsSupported)
1427+
{
1428+
// Arm64 allows shuffling values using a 32-byte wide look-up table consisting of two 128-bit registers.
1429+
// Each byte in the second arg represents a value between 0 to 31 that acts as an index in the look-up table.
1430+
// Now we can create a "z" vector by selecting 12 values starting from the 9th element (index 0x08) and
1431+
// leaving gaps for dashes. Thus, the wider look-up table allows combining two shuffles, as used in the
1432+
// generic else-case, into a single instruction on Arm64.
1433+
// TODO: Check if the JIT can merge the consecutive table look-ups and avoid the Arm64 specific if-case.
1434+
Vector128<byte> mid = AdvSimd.Arm64.VectorTableLookup((hexLow, hexHigh),
1435+
Vector128.Create(0x0D0CFF0B0A0908FF, 0xFF13121110FF0F0E).AsByte());
1436+
vecZ = (mid | dashesMask);
1437+
}
1438+
else
1439+
{
1440+
Vector128<byte> mid1 = Vector128.Shuffle(hexLow,
1441+
Vector128.Create(0x0D0CFF0B0A0908FF, 0xFFFFFFFFFFFF0F0E).AsByte());
1442+
Vector128<byte> mid2 = Vector128.Shuffle(hexHigh,
1443+
Vector128.Create(0xFFFFFFFFFFFFFFFF, 0xFF03020100FFFFFF).AsByte());
1444+
vecZ = (mid1 | mid2 | dashesMask);
1445+
}
1446+
14321447
return (vecX, vecY, vecZ);
14331448
}
14341449

0 commit comments

Comments
 (0)