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