@@ -1503,7 +1503,7 @@ private static bool VectorContainsNonAsciiChar(Vector128<byte> asciiVector)
15031503            // prefer architecture specific intrinsic as they offer better perf 
15041504            if  ( Sse41 . IsSupported ) 
15051505            { 
1506-                 return  ! Sse41 . TestZ ( asciiVector ,   Vector128 . Create ( ( byte ) 0x80 ) ) ; 
1506+                 return  ( asciiVector   &   Vector128 . Create ( ( byte ) 0x80 ) )   !=   Vector128 < byte > . Zero ; 
15071507            } 
15081508            else  if  ( AdvSimd . Arm64 . IsSupported ) 
15091509            { 
@@ -1520,22 +1520,13 @@ private static bool VectorContainsNonAsciiChar(Vector128<byte> asciiVector)
15201520        private  static  bool VectorContainsNonAsciiChar( Vector128 < ushort >  utf16Vector ) 
15211521        { 
15221522            // prefer architecture specific intrinsic as they offer better perf 
1523-             if  ( Sse2 . IsSupported ) 
1523+             if  ( Sse2 . IsSupported   &&   ! Sse41 . IsSupported ) 
15241524            { 
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 ; 
15391530            } 
15401531            else  if  ( AdvSimd . Arm64 . IsSupported ) 
15411532            { 
@@ -1556,18 +1547,10 @@ private static bool VectorContainsNonAsciiChar(Vector128<ushort> utf16Vector)
15561547        [ MethodImpl( MethodImplOptions. AggressiveInlining) ] 
15571548        private static  bool  VectorContainsNonAsciiChar( Vector256< ushort >  utf16Vector) 
15581549        { 
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; 
15711554        } 
15721555
15731556        [ MethodImpl( MethodImplOptions. AggressiveInlining) ] 
@@ -1600,14 +1583,13 @@ private static bool AllCharsInVectorAreAscii<T>(Vector128<T> vector)
16001583            if  ( typeof ( T)  ==  typeof ( byte ) ) 
16011584            { 
16021585                return 
1603-                     Sse41. IsSupported ?  Sse41 . TestZ ( vector. AsByte( ) ,  Vector128 . Create ( ( byte ) 0x80 ) )  : 
1586+                     Sse41. IsSupported ?  ( vector. AsByte( ) ,  Vector128 . Create ( ( byte ) 0x80 ) )   !=   Vector128 < byte > . Zero  : 
16041587                    AdvSimd . Arm64 . IsSupported  ?  AllBytesInUInt64AreAscii ( AdvSimd . Arm64 . MaxPairwise ( vector . AsByte ( ) ,  vector . AsByte ( ) ) . AsUInt64 ( ) . ToScalar ( ) )  : 
16051588                    vector . AsByte ( ) . ExtractMostSignificantBits ( )  ==  0 ; 
16061589            } 
16071590            else 
16081591            { 
16091592                return 
1610-                     Sse41 . IsSupported  ?  Sse41 . TestZ ( vector . AsUInt16 ( ) ,  Vector128 . Create ( ( ushort ) 0xFF80 ) )  : 
16111593                    AdvSimd . Arm64 . IsSupported  ?  AllCharsInUInt64AreAscii ( AdvSimd . Arm64 . MaxPairwise ( vector . AsUInt16 ( ) ,  vector . AsUInt16 ( ) ) . AsUInt64 ( ) . ToScalar ( ) )  : 
16121594                    ( vector . AsUInt16 ( )  &  Vector128 . Create ( ( ushort ) 0xFF80 ) )  ==  Vector128 < ushort > . Zero ; 
16131595            } 
@@ -1623,14 +1605,12 @@ private static bool AllCharsInVectorAreAscii<T>(Vector256<T> vector)
16231605            if  ( typeof ( T )  ==  typeof ( byte ) ) 
16241606            { 
16251607                return 
1626-                     Avx . IsSupported  ?  Avx . TestZ ( vector . AsByte ( ) ,   Vector256 . Create ( ( byte ) 0x80 ) )  : 
1608+                     Avx . IsSupported  ?  ( vector . AsByte ( )   &   Vector256 . Create ( ( byte ) 0x80 ) )  ==   Vector256 < byte > . Zero : 
16271609                    vector . AsByte ( ) . ExtractMostSignificantBits ( )  ==  0 ; 
16281610            } 
16291611            else 
16301612            { 
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 : 
16341614            } 
16351615        } 
16361616
0 commit comments