@@ -1501,10 +1501,10 @@ private static bool VectorContainsNonAsciiChar(Vector128<byte> asciiVector)
1501
1501
{
1502
1502
// max ASCII character is 0b_0111_1111, so the most significant bit (0x80) tells whether it contains non ascii
1503
1503
1504
- // prefer architecture specific intrinsic as they offer better perf
1504
+ // For performance, prefer architecture specific implementation
1505
1505
if ( Sse41 . IsSupported )
1506
1506
{
1507
- return ! Sse41 . TestZ ( asciiVector , Vector128 . Create ( ( byte ) 0x80 ) ) ;
1507
+ return ( asciiVector & Vector128 . Create ( ( byte ) 0x80 ) ) != Vector128 < byte > . Zero ;
1508
1508
}
1509
1509
else if ( AdvSimd . Arm64 . IsSupported )
1510
1510
{
@@ -1520,23 +1520,21 @@ private static bool VectorContainsNonAsciiChar(Vector128<byte> asciiVector)
1520
1520
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
1521
1521
internal static bool VectorContainsNonAsciiChar( Vector128 < ushort > utf16Vector )
1522
1522
{
1523
- // prefer architecture specific intrinsic as they offer better perf
1524
- if ( Sse2 . IsSupported )
1523
+ // For performance, prefer architecture specific implementation
1524
+ if ( Sse41 . IsSupported )
1525
1525
{
1526
- if ( Sse41 . IsSupported )
1527
- {
1528
- Vector128 < ushort > asciiMaskForTestZ = Vector128. Create( ( ushort ) 0xFF80 ) ;
1529
- // If a non-ASCII bit is set in any WORD of the vector, we have seen non-ASCII data.
1530
- return ! Sse41 . TestZ ( utf16Vector . AsInt16 ( ) , asciiMaskForTestZ . AsInt16 ( ) ) ;
1531
- }
1532
- else
1533
- {
1534
- Vector128 < ushort > asciiMaskForAddSaturate = Vector128. Create( ( ushort ) 0x7F80 ) ;
1535
- // The operation below forces the 0x8000 bit of each WORD to be set iff the WORD element
1536
- // has value >= 0x0800 (non-ASCII). Then we'll treat the vector as a BYTE vector in order
1537
- // to extract the mask. Reminder: the 0x0080 bit of each WORD should be ignored.
1538
- return ( Sse2 . MoveMask ( Sse2 . AddSaturate ( utf16Vector , asciiMaskForAddSaturate ) . AsByte ( ) ) & 0b_1010_1010_1010_1010 ) != 0 ;
1539
- }
1526
+ const ushort asciiMask = ushort . MaxValue - 127 ; // 0xFF80
1527
+ Vector128 < ushort > zeroIsAscii = utf16Vector & Vector128. Create( asciiMask) ;
1528
+ // If a non-ASCII bit is set in any WORD of the vector, we have seen non-ASCII data.
1529
+ return zeroIsAscii != Vector128< ushort > . Zero;
1530
+ }
1531
+ else if ( Sse2 . IsSupported )
1532
+ {
1533
+ Vector128 < ushort > asciiMaskForAddSaturate = Vector128. Create( ( ushort ) 0x7F80 ) ;
1534
+ // The operation below forces the 0x8000 bit of each WORD to be set iff the WORD element
1535
+ // has value >= 0x0800 (non-ASCII). Then we'll treat the vector as a BYTE vector in order
1536
+ // to extract the mask. Reminder: the 0x0080 bit of each WORD should be ignored.
1537
+ return ( Sse2 . MoveMask ( Sse2 . AddSaturate ( utf16Vector , asciiMaskForAddSaturate ) . AsByte ( ) ) & 0b_1010_1010_1010_1010 ) != 0 ;
1540
1538
}
1541
1539
else if ( AdvSimd . Arm64 . IsSupported )
1542
1540
{
@@ -1557,18 +1555,10 @@ internal static bool VectorContainsNonAsciiChar(Vector128<ushort> utf16Vector)
1557
1555
[ MethodImpl( MethodImplOptions. AggressiveInlining) ]
1558
1556
internal static bool VectorContainsNonAsciiChar( Vector256< ushort > utf16Vector)
1559
1557
{
1560
- if ( Avx. IsSupported)
1561
- {
1562
- Vector256< ushort > asciiMaskForTestZ = Vector256. Create( ( ushort ) 0xFF80 ) ;
1563
- return ! Avx. TestZ( utf16Vector. AsInt16( ) , asciiMaskForTestZ . AsInt16 ( ) ) ;
1564
- }
1565
- else
1566
- {
1567
- const ushort asciiMask = ushort . MaxValue - 127 ; // 0xFF80
1568
- Vector256< ushort > zeroIsAscii = utf16Vector & Vector256. Create( asciiMask) ;
1569
- // If a non-ASCII bit is set in any WORD of the vector, we have seen non-ASCII data.
1570
- return zeroIsAscii != Vector256< ushort > . Zero;
1571
- }
1558
+ const ushort asciiMask = ushort . MaxValue - 127 ; // 0xFF80
1559
+ Vector256< ushort > zeroIsAscii = utf16Vector & Vector256. Create( asciiMask) ;
1560
+ // If a non-ASCII bit is set in any WORD of the vector, we have seen non-ASCII data.
1561
+ return zeroIsAscii != Vector256< ushort > . Zero;
1572
1562
}
1573
1563
1574
1564
[ MethodImpl( MethodImplOptions. AggressiveInlining) ]
@@ -1601,14 +1591,13 @@ private static bool AllCharsInVectorAreAscii<T>(Vector128<T> vector)
1601
1591
if ( typeof ( T) == typeof ( byte ) )
1602
1592
{
1603
1593
return
1604
- Sse41. IsSupported ? Sse41 . TestZ ( vector. AsByte( ) , Vector128 . Create ( ( byte ) 0x80 ) ) :
1594
+ Sse41. IsSupported ? ( vector. AsByte( ) & Vector128. Create( ( byte ) 0x80 ) ) == Vector128 < byte > . Zero :
1605
1595
AdvSimd. Arm64. IsSupported ? AllBytesInUInt64AreAscii( AdvSimd. Arm64. MaxPairwise( vector. AsByte( ) , vector . AsByte ( ) ) . AsUInt64( ) . ToScalar( ) ) :
1606
1596
vector. AsByte( ) . ExtractMostSignificantBits( ) == 0 ;
1607
1597
}
1608
1598
else
1609
1599
{
1610
1600
return
1611
- Sse41 . IsSupported ? Sse41 . TestZ ( vector . AsUInt16 ( ) , Vector128 . Create ( ( ushort ) 0xFF80 ) ) :
1612
1601
AdvSimd. Arm64. IsSupported ? AllCharsInUInt64AreAscii( AdvSimd. Arm64. MaxPairwise( vector. AsUInt16( ) , vector . AsUInt16 ( ) ) . AsUInt64( ) . ToScalar( ) ) :
1613
1602
( vector. AsUInt16( ) & Vector128. Create( ( ushort ) 0xFF80 ) ) == Vector128< ushort > . Zero;
1614
1603
}
@@ -1624,14 +1613,12 @@ private static bool AllCharsInVectorAreAscii<T>(Vector256<T> vector)
1624
1613
if ( typeof ( T) == typeof ( byte ) )
1625
1614
{
1626
1615
return
1627
- Avx . IsSupported ? Avx . TestZ ( vector . AsByte ( ) , Vector256 . Create ( ( byte ) 0x80 ) ) :
1616
+ Avx. IsSupported ? ( vector. AsByte( ) & Vector256. Create( ( byte ) 0x80 ) ) == Vector256 < byte > . Zero :
1628
1617
vector. AsByte( ) . ExtractMostSignificantBits( ) == 0 ;
1629
1618
}
1630
1619
else
1631
1620
{
1632
- return
1633
- Avx . IsSupported ? Avx . TestZ ( vector . AsUInt16 ( ) , Vector256 . Create ( ( ushort ) 0xFF80 ) ) :
1634
- ( vector . AsUInt16 ( ) & Vector256 . Create ( ( ushort ) 0xFF80 ) ) == Vector256 < ushort > . Zero ;
1621
+ return ( vector. AsUInt16( ) & Vector256. Create( ( ushort ) 0xFF80 ) ) == Vector256< ushort > . Zero;
1635
1622
}
1636
1623
}
1637
1624
0 commit comments