diff options
Diffstat (limited to 'src/System.Private.CoreLib/shared/System/Text/ASCIIUtility.cs')
-rw-r--r-- | src/System.Private.CoreLib/shared/System/Text/ASCIIUtility.cs | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/src/System.Private.CoreLib/shared/System/Text/ASCIIUtility.cs b/src/System.Private.CoreLib/shared/System/Text/ASCIIUtility.cs index b37b01779d..bf2bccf879 100644 --- a/src/System.Private.CoreLib/shared/System/Text/ASCIIUtility.cs +++ b/src/System.Private.CoreLib/shared/System/Text/ASCIIUtility.cs @@ -1009,10 +1009,14 @@ namespace System.Text { Debug.Assert(AllCharsInUInt64AreAscii(value)); - if (Bmi2.X64.IsSupported) + if (Sse2.X64.IsSupported) { - // BMI2 will work regardless of the processor's endianness. - Unsafe.WriteUnaligned(ref outputBuffer, (uint)Bmi2.X64.ParallelBitExtract(value, 0x00FF00FF_00FF00FFul)); + // Narrows a vector of words [ w0 w1 w2 w3 ] to a vector of bytes + // [ b0 b1 b2 b3 b0 b1 b2 b3 ], then writes 4 bytes (32 bits) to the destination. + + Vector128<short> vecWide = Sse2.X64.ConvertScalarToVector128UInt64(value).AsInt16(); + Vector128<uint> vecNarrow = Sse2.PackUnsignedSaturate(vecWide, vecWide).AsUInt32(); + Unsafe.WriteUnaligned<uint>(ref outputBuffer, Sse2.ConvertToUInt32(vecNarrow)); } else { @@ -1694,14 +1698,16 @@ namespace System.Text /// writes them to the output buffer with machine endianness. /// </summary> [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void WidenFourAsciiBytesToUtf16AndWriteToBuffer(ref char outputBuffer, uint value) + internal static void WidenFourAsciiBytesToUtf16AndWriteToBuffer(ref char outputBuffer, uint value) { Debug.Assert(AllBytesInUInt32AreAscii(value)); - if (Bmi2.X64.IsSupported) + if (Sse2.X64.IsSupported) { - // BMI2 will work regardless of the processor's endianness. - Unsafe.WriteUnaligned(ref Unsafe.As<char, byte>(ref outputBuffer), Bmi2.X64.ParallelBitDeposit(value, 0x00FF00FF_00FF00FFul)); + Debug.Assert(BitConverter.IsLittleEndian, "SSE2 widening assumes little-endian."); + Vector128<byte> vecNarrow = Sse2.ConvertScalarToVector128UInt32(value).AsByte(); + Vector128<ulong> vecWide = Sse2.UnpackLow(vecNarrow, Vector128<byte>.Zero).AsUInt64(); + Unsafe.WriteUnaligned<ulong>(ref Unsafe.As<char, byte>(ref outputBuffer), Sse2.X64.ConvertToUInt64(vecWide)); } else { |