@@ -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