@@ -1615,7 +1615,20 @@ private void MakeSeparatorList(ReadOnlySpan<char> separators, ref ValueListBuild
16151615 sep0 = separators [ 0 ] ;
16161616 sep1 = separators . Length > 1 ? separators [ 1 ] : sep0 ;
16171617 sep2 = separators . Length > 2 ? separators [ 2 ] : sep1 ;
1618- MakeSeparatorListVectorized ( ref sepListBuilder , sep0 , sep1 , sep2 ) ;
1618+ if ( Vector128 . IsHardwareAccelerated && Length >= Vector128 < ushort > . Count * 2 )
1619+ {
1620+ MakeSeparatorListVectorized ( ref sepListBuilder , sep0 , sep1 , sep2 ) ;
1621+ return ;
1622+ }
1623+
1624+ for ( int i = 0 ; i < Length ; i ++ )
1625+ {
1626+ char c = this [ i ] ;
1627+ if ( c == sep0 || c == sep1 || c == sep2 )
1628+ {
1629+ sepListBuilder . Append ( i ) ;
1630+ }
1631+ }
16191632 }
16201633
16211634 // Handle > 3 separators with a probabilistic map, ala IndexOfAny.
@@ -1644,95 +1657,41 @@ private void MakeSeparatorList(ReadOnlySpan<char> separators, ref ValueListBuild
16441657
16451658 private void MakeSeparatorListVectorized ( ref ValueListBuilder < int > sepListBuilder , char c , char c2 , char c3 )
16461659 {
1660+ if ( ! Vector128 . IsHardwareAccelerated )
1661+ {
1662+ throw new PlatformNotSupportedException ( ) ;
1663+ }
1664+
16471665 nuint offset = 0 ;
16481666 nuint lengthToExamine = ( nuint ) ( uint ) Length ;
16491667
16501668 ref ushort source = ref Unsafe . As < char , ushort > ( ref _firstChar ) ;
16511669
1652- if ( Vector256 . IsHardwareAccelerated )
1653- {
1654- if ( lengthToExamine >= ( nuint ) Vector256 < ushort > . Count )
1655- {
1656- Vector256 < ushort > v1 = Vector256 . Create ( ( ushort ) c ) ;
1657- Vector256 < ushort > v2 = Vector256 . Create ( ( ushort ) c2 ) ;
1658- Vector256 < ushort > v3 = Vector256 . Create ( ( ushort ) c3 ) ;
1659-
1660- do
1661- {
1662- Vector256 < ushort > vector = Vector256 . LoadUnsafe ( ref source , offset ) ;
1663- Vector256 < ushort > v1Eq = Vector256 . Equals ( vector , v1 ) ;
1664- Vector256 < ushort > v2Eq = Vector256 . Equals ( vector , v2 ) ;
1665- Vector256 < ushort > v3Eq = Vector256 . Equals ( vector , v3 ) ;
1666- Vector256 < byte > cmp = ( v1Eq | v2Eq | v3Eq ) . AsByte ( ) ;
1670+ Vector128 < ushort > v1 = Vector128 . Create ( ( ushort ) c ) ;
1671+ Vector128 < ushort > v2 = Vector128 . Create ( ( ushort ) c2 ) ;
1672+ Vector128 < ushort > v3 = Vector128 . Create ( ( ushort ) c3 ) ;
16671673
1668- if ( cmp != Vector256 < byte > . Zero )
1669- {
1670- uint mask = cmp . ExtractMostSignificantBits ( ) & 0x55555555 ;
1671- do
1672- {
1673- uint bitPos = ( uint ) BitOperations . TrailingZeroCount ( mask ) / sizeof ( char ) ;
1674- sepListBuilder . Append ( ( int ) ( offset + bitPos ) ) ;
1675- mask = BitOperations . ResetLowestSetBit ( mask ) ;
1676- } while ( mask != 0 ) ;
1677- }
1678-
1679- offset += ( nuint ) Vector256 < ushort > . Count ;
1680- } while ( offset <= lengthToExamine - ( nuint ) Vector256 < ushort > . Count ) ;
1681-
1682- // See if we fit another 128 bit vector
1683- if ( offset <= lengthToExamine - ( nuint ) Vector128 < ushort > . Count )
1684- {
1685- Vector128 < ushort > vector = Vector128 . LoadUnsafe ( ref source , offset ) ;
1686- Vector128 < ushort > v1Eq = Vector128 . Equals ( vector , v1 . GetLower ( ) ) ;
1687- Vector128 < ushort > v2Eq = Vector128 . Equals ( vector , v2 . GetLower ( ) ) ;
1688- Vector128 < ushort > v3Eq = Vector128 . Equals ( vector , v3 . GetLower ( ) ) ;
1689- Vector128 < byte > cmp = ( v1Eq | v2Eq | v3Eq ) . AsByte ( ) ;
1690-
1691- if ( cmp != Vector128 < byte > . Zero )
1692- {
1693- uint mask = cmp . ExtractMostSignificantBits ( ) & 0x5555 ;
1694- do
1695- {
1696- uint bitPos = ( uint ) BitOperations . TrailingZeroCount ( mask ) / sizeof ( char ) ;
1697- sepListBuilder . Append ( ( int ) ( offset + bitPos ) ) ;
1698- mask = BitOperations . ResetLowestSetBit ( mask ) ;
1699- } while ( mask != 0 ) ;
1700- }
1701-
1702- offset += ( nuint ) Vector128 < ushort > . Count ;
1703- }
1704- }
1705- }
1706- else if ( Vector128 . IsHardwareAccelerated )
1674+ while ( offset <= lengthToExamine - ( nuint ) Vector128 < ushort > . Count )
17071675 {
1708- if ( lengthToExamine >= ( nuint ) Vector128 < ushort > . Count * 2 )
1709- {
1710- Vector128 < ushort > v1 = Vector128 . Create ( ( ushort ) c ) ;
1711- Vector128 < ushort > v2 = Vector128 . Create ( ( ushort ) c2 ) ;
1712- Vector128 < ushort > v3 = Vector128 . Create ( ( ushort ) c3 ) ;
1676+ Vector128 < ushort > vector = Vector128 . LoadUnsafe ( ref source , offset ) ;
1677+ Vector128 < ushort > v1Eq = Vector128 . Equals ( vector , v1 ) ;
1678+ Vector128 < ushort > v2Eq = Vector128 . Equals ( vector , v2 ) ;
1679+ Vector128 < ushort > v3Eq = Vector128 . Equals ( vector , v3 ) ;
1680+ Vector128 < byte > cmp = ( v1Eq | v2Eq | v3Eq ) . AsByte ( ) ;
17131681
1682+ if ( cmp != Vector128 < byte > . Zero )
1683+ {
1684+ // Skip every other bit
1685+ uint mask = cmp . ExtractMostSignificantBits ( ) & 0x5555 ;
17141686 do
17151687 {
1716- Vector128 < ushort > vector = Vector128 . LoadUnsafe ( ref source , offset ) ;
1717- Vector128 < ushort > v1Eq = Vector128 . Equals ( vector , v1 ) ;
1718- Vector128 < ushort > v2Eq = Vector128 . Equals ( vector , v2 ) ;
1719- Vector128 < ushort > v3Eq = Vector128 . Equals ( vector , v3 ) ;
1720- Vector128 < byte > cmp = ( v1Eq | v2Eq | v3Eq ) . AsByte ( ) ;
1721-
1722- if ( cmp != Vector128 < byte > . Zero )
1723- {
1724- uint mask = cmp . ExtractMostSignificantBits ( ) & 0x5555 ;
1725- do
1726- {
1727- uint bitPos = ( uint ) BitOperations . TrailingZeroCount ( mask ) / sizeof ( char ) ;
1728- sepListBuilder . Append ( ( int ) ( offset + bitPos ) ) ;
1729- mask = BitOperations . ResetLowestSetBit ( mask ) ;
1730- } while ( mask != 0 ) ;
1731- }
1732-
1733- offset += ( nuint ) Vector128 < ushort > . Count ;
1734- } while ( offset <= lengthToExamine - ( nuint ) Vector128 < ushort > . Count ) ;
1688+ uint bitPos = ( uint ) BitOperations . TrailingZeroCount ( mask ) / sizeof ( char ) ;
1689+ sepListBuilder . Append ( ( int ) ( offset + bitPos ) ) ;
1690+ mask = BitOperations . ResetLowestSetBit ( mask ) ;
1691+ } while ( mask != 0 ) ;
17351692 }
1693+
1694+ offset += ( nuint ) Vector128 < ushort > . Count ;
17361695 }
17371696
17381697 while ( offset < lengthToExamine )
0 commit comments