@@ -1405,7 +1405,7 @@ private static (Vector128<byte>, Vector128<byte>, Vector128<byte>) FormatGuidVec
1405
1405
1406
1406
if ( useDashes )
1407
1407
{
1408
- // We divide 16 bytes into 3 x Vector128<byte>:
1408
+ // We divide 32 bytes into 3 x Vector128<byte>:
1409
1409
//
1410
1410
// ________-____-____-____-____________
1411
1411
// xxxxxxxxxxxxxxxx
@@ -1421,14 +1421,29 @@ private static (Vector128<byte>, Vector128<byte>, Vector128<byte>) FormatGuidVec
1421
1421
Vector128 . Create ( 0x7060504FF030201 , 0xF0E0D0C0B0A0908 ) . AsByte ( ) ) ;
1422
1422
1423
1423
// 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
+
1432
1447
return ( vecX , vecY , vecZ ) ;
1433
1448
}
1434
1449
0 commit comments