@@ -1504,7 +1504,7 @@ private static bool VectorContainsNonAsciiChar(Vector128<byte> asciiVector)
1504
1504
// prefer architecture specific intrinsic as they offer better perf
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
{
@@ -1521,22 +1521,13 @@ private static bool VectorContainsNonAsciiChar(Vector128<byte> asciiVector)
1521
1521
internal static bool VectorContainsNonAsciiChar( Vector128 < ushort > utf16Vector )
1522
1522
{
1523
1523
// prefer architecture specific intrinsic as they offer better perf
1524
- if ( Sse2 . IsSupported )
1524
+ if ( Sse2 . IsSupported && ! 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
+ Vector128 < ushort > asciiMaskForAddSaturate = Vector128. Create( ( ushort ) 0x7F80 ) ;
1527
+ // The operation below forces the 0x8000 bit of each WORD to be set iff the WORD element
1528
+ // has value >= 0x0800 (non-ASCII). Then we'll treat the vector as a BYTE vector in order
1529
+ // to extract the mask. Reminder: the 0x0080 bit of each WORD should be ignored.
1530
+ return ( Sse2 . MoveMask ( Sse2 . AddSaturate ( utf16Vector , asciiMaskForAddSaturate ) . AsByte ( ) ) & 0b_1010_1010_1010_1010 ) != 0 ;
1540
1531
}
1541
1532
else if ( AdvSimd . Arm64 . IsSupported )
1542
1533
{
@@ -1557,18 +1548,10 @@ internal static bool VectorContainsNonAsciiChar(Vector128<ushort> utf16Vector)
1557
1548
[ MethodImpl( MethodImplOptions. AggressiveInlining) ]
1558
1549
internal static bool VectorContainsNonAsciiChar( Vector256< ushort > utf16Vector)
1559
1550
{
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
- }
1551
+ const ushort asciiMask = ushort . MaxValue - 127 ; // 0xFF80
1552
+ Vector256< ushort > zeroIsAscii = utf16Vector & Vector256. Create( asciiMask) ;
1553
+ // If a non-ASCII bit is set in any WORD of the vector, we have seen non-ASCII data.
1554
+ return zeroIsAscii != Vector256< ushort > . Zero;
1572
1555
}
1573
1556
1574
1557
[ MethodImpl( MethodImplOptions. AggressiveInlining) ]
@@ -1601,14 +1584,13 @@ private static bool AllCharsInVectorAreAscii<T>(Vector128<T> vector)
1601
1584
if ( typeof ( T) == typeof ( byte ) )
1602
1585
{
1603
1586
return
1604
- Sse41. IsSupported ? Sse41 . TestZ ( vector. AsByte( ) , Vector128 . Create ( ( byte ) 0x80 ) ) :
1587
+ Sse41. IsSupported ? ( vector. AsByte( ) & Vector128. Create( ( byte ) 0x80 ) ) != Vector128 < byte > . Zero :
1605
1588
AdvSimd. Arm64. IsSupported ? AllBytesInUInt64AreAscii( AdvSimd. Arm64. MaxPairwise( vector. AsByte( ) , vector . AsByte ( ) ) . AsUInt64( ) . ToScalar( ) ) :
1606
1589
vector. AsByte( ) . ExtractMostSignificantBits( ) == 0 ;
1607
1590
}
1608
1591
else
1609
1592
{
1610
1593
return
1611
- Sse41 . IsSupported ? Sse41 . TestZ ( vector . AsUInt16 ( ) , Vector128 . Create ( ( ushort ) 0xFF80 ) ) :
1612
1594
AdvSimd. Arm64. IsSupported ? AllCharsInUInt64AreAscii( AdvSimd. Arm64. MaxPairwise( vector. AsUInt16( ) , vector . AsUInt16 ( ) ) . AsUInt64( ) . ToScalar( ) ) :
1613
1595
( vector. AsUInt16( ) & Vector128. Create( ( ushort ) 0xFF80 ) ) == Vector128< ushort > . Zero;
1614
1596
}
@@ -1624,14 +1606,12 @@ private static bool AllCharsInVectorAreAscii<T>(Vector256<T> vector)
1624
1606
if ( typeof ( T) == typeof ( byte ) )
1625
1607
{
1626
1608
return
1627
- Avx . IsSupported ? Avx . TestZ ( vector . AsByte ( ) , Vector256 . Create ( ( byte ) 0x80 ) ) :
1609
+ Avx. IsSupported ? ( vector. AsByte( ) & Vector256. Create( ( byte ) 0x80 ) ) == Vector256 < byte > . Zero :
1628
1610
vector. AsByte( ) . ExtractMostSignificantBits( ) == 0 ;
1629
1611
}
1630
1612
else
1631
1613
{
1632
- return
1633
- Avx . IsSupported ? Avx . TestZ ( vector . AsUInt16 ( ) , Vector256 . Create ( ( ushort ) 0xFF80 ) ) :
1634
- ( vector . AsUInt16 ( ) & Vector256 . Create ( ( ushort ) 0xFF80 ) ) == Vector256 < ushort > . Zero ;
1614
+ return ( vector. AsUInt16( ) & Vector256. Create( ( ushort ) 0xFF80 ) ) == Vector256< ushort > . Zero;
1635
1615
}
1636
1616
}
1637
1617
0 commit comments