Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches

◆ GetIndexOfFirstNonLatin1Char_Sse2()

static unsafe nuint System.Text.Latin1Utility.GetIndexOfFirstNonLatin1Char_Sse2 ( char * pBuffer,
nuint bufferLength )
inlinestaticprivate

Definition at line 89 of file Latin1Utility.cs.

90 {
91 if (bufferLength == 0)
92 {
93 return 0u;
94 }
95 uint num = (uint)Unsafe.SizeOf<Vector128<byte>>();
96 uint num2 = num / 2;
97 char* ptr = pBuffer;
99 Vector128<ushort> right2;
101 uint num3;
102 if (bufferLength >= num2)
103 {
104 right = Vector128.Create((ushort)65280);
105 right2 = Vector128.Create((ushort)32512);
106 left = Sse2.LoadVector128((ushort*)pBuffer);
107 num3 = (uint)Sse2.MoveMask(Sse2.AddSaturate(left, right2).AsByte());
108 if ((num3 & 0xAAAA) == 0)
109 {
110 bufferLength <<= 1;
111 if (bufferLength < 2 * num)
112 {
113 goto IL_013e;
114 }
115 pBuffer = (char*)((nuint)((byte*)pBuffer + num) & ~(nuint)(num - 1));
116 bufferLength = (nuint)(bufferLength + (byte*)ptr);
117 bufferLength -= (nuint)pBuffer;
118 if (bufferLength < 2 * num)
119 {
120 goto IL_00fa;
121 }
122 char* ptr2 = (char*)((byte*)pBuffer + bufferLength - 2 * num);
123 Vector128<ushort> vector;
124 while (true)
125 {
126 left = Sse2.LoadAlignedVector128((ushort*)pBuffer);
127 vector = Sse2.LoadAlignedVector128((ushort*)(pBuffer + num2));
128 Vector128<ushort> left2 = Sse2.Or(left, vector);
129 if (Sse41.IsSupported)
130 {
131 if (!Sse41.TestZ(left2, right))
132 {
133 break;
134 }
135 }
136 else
137 {
138 num3 = (uint)Sse2.MoveMask(Sse2.AddSaturate(left2, right2).AsByte());
139 if ((num3 & 0xAAAAu) != 0)
140 {
141 break;
142 }
143 }
144 pBuffer += 2 * num2;
145 if (pBuffer <= ptr2)
146 {
147 continue;
148 }
149 goto IL_00fa;
150 }
151 if (Sse41.IsSupported)
152 {
153 if (!Sse41.TestZ(left, right))
154 {
155 goto IL_01e6;
156 }
157 }
158 else
159 {
160 num3 = (uint)Sse2.MoveMask(Sse2.AddSaturate(left, right2).AsByte());
161 if ((num3 & 0xAAAAu) != 0)
162 {
163 goto IL_01fa;
164 }
165 }
166 pBuffer += num2;
167 left = vector;
168 goto IL_01e6;
169 }
170 goto IL_01fa;
171 }
172 uint num5;
173 if ((bufferLength & 4) != 0)
174 {
175 if (Bmi1.X64.IsSupported)
176 {
177 ulong num4 = Unsafe.ReadUnaligned<ulong>(pBuffer);
178 if (!AllCharsInUInt64AreLatin1(num4))
179 {
180 num4 &= 0xFF00FF00FF00FF00uL;
181 pBuffer = (char*)((byte*)pBuffer + (nuint)((nint)(Bmi1.X64.TrailingZeroCount(num4) / 8) & ~(nint)1));
182 goto IL_01a1;
183 }
184 }
185 else
186 {
187 num5 = Unsafe.ReadUnaligned<uint>(pBuffer);
188 uint num6 = Unsafe.ReadUnaligned<uint>(pBuffer + 2);
189 if (!AllCharsInUInt32AreLatin1(num5 | num6))
190 {
192 {
193 num5 = num6;
194 pBuffer += 2;
195 }
196 goto IL_0214;
197 }
198 }
199 pBuffer += 4;
200 }
201 if ((bufferLength & 2) != 0)
202 {
203 num5 = Unsafe.ReadUnaligned<uint>(pBuffer);
204 if (!AllCharsInUInt32AreLatin1(num5))
205 {
206 goto IL_0214;
207 }
208 pBuffer += 2;
209 }
210 if ((bufferLength & 1) != 0 && *pBuffer <= 'ΓΏ')
211 {
212 pBuffer++;
213 }
214 goto IL_01a1;
215 IL_01e6:
216 num3 = (uint)Sse2.MoveMask(Sse2.AddSaturate(left, right2).AsByte());
217 goto IL_01fa;
218 IL_0214:
220 {
221 pBuffer++;
222 }
223 goto IL_01a1;
224 IL_01a1:
225 return (nuint)(pBuffer - ptr);
226 IL_0148:
227 if (((byte)bufferLength & (num - 1)) != 0)
228 {
229 pBuffer = (char*)((byte*)pBuffer + (bufferLength & (num - 1)) - num);
230 left = Sse2.LoadVector128((ushort*)pBuffer);
231 if (Sse41.IsSupported)
232 {
233 if (!Sse41.TestZ(left, right))
234 {
235 goto IL_01e6;
236 }
237 }
238 else
239 {
240 num3 = (uint)Sse2.MoveMask(Sse2.AddSaturate(left, right2).AsByte());
241 if ((num3 & 0xAAAAu) != 0)
242 {
243 goto IL_01fa;
244 }
245 }
246 pBuffer += num2;
247 }
248 goto IL_01a1;
249 IL_00fa:
250 if ((bufferLength & num) != 0)
251 {
252 left = Sse2.LoadAlignedVector128((ushort*)pBuffer);
253 if (Sse41.IsSupported)
254 {
255 if (!Sse41.TestZ(left, right))
256 {
257 goto IL_01e6;
258 }
259 }
260 else
261 {
262 num3 = (uint)Sse2.MoveMask(Sse2.AddSaturate(left, right2).AsByte());
263 if ((num3 & 0xAAAAu) != 0)
264 {
265 goto IL_01fa;
266 }
267 }
268 goto IL_013e;
269 }
270 goto IL_0148;
271 IL_01fa:
272 num3 &= 0xAAAAu;
273 pBuffer = (char*)((byte*)pBuffer + (uint)BitOperations.TrailingZeroCount(num3) - 1);
274 goto IL_01a1;
275 IL_013e:
276 pBuffer += num2;
277 goto IL_0148;
278 }
static int TrailingZeroCount(int value)
static Vector128< byte > Create(byte value)
Definition Vector128.cs:138
static ulong TrailingZeroCount(ulong value)
Definition Bmi1.cs:44
static unsafe Vector128< sbyte > LoadVector128(sbyte *address)
Definition Sse2.cs:582
static int MoveMask(Vector128< sbyte > value)
Definition Sse2.cs:772
static unsafe Vector128< sbyte > LoadAlignedVector128(sbyte *address)
Definition Sse2.cs:632
static Vector128< byte > Or(Vector128< byte > left, Vector128< byte > right)
Definition Sse2.cs:837
static Vector128< sbyte > AddSaturate(Vector128< sbyte > left, Vector128< sbyte > right)
Definition Sse2.cs:112
static bool TestZ(Vector128< sbyte > left, Vector128< sbyte > right)
Definition Sse41.cs:692
static bool FirstCharInUInt32IsLatin1(uint value)
static bool AllCharsInUInt32AreLatin1(uint value)
static bool AllCharsInUInt64AreLatin1(ulong value)

References System.Runtime.Intrinsics.X86.Sse2.AddSaturate(), System.Text.Latin1Utility.AllCharsInUInt32AreLatin1(), System.Text.Latin1Utility.AllCharsInUInt64AreLatin1(), System.Runtime.Intrinsics.Vector128< T >.Create(), System.Text.Latin1Utility.FirstCharInUInt32IsLatin1(), System.Runtime.Intrinsics.X86.Bmi1.X64.IsSupported, System.Runtime.Intrinsics.X86.Sse41.IsSupported, System.Runtime.Intrinsics.X86.Sse2.LoadAlignedVector128(), System.Runtime.Intrinsics.X86.Sse2.LoadVector128(), System.Runtime.Intrinsics.X86.Sse2.MoveMask(), System.Runtime.Intrinsics.X86.Sse2.Or(), System.Runtime.Intrinsics.X86.Sse41.TestZ(), System.Numerics.BitOperations.TrailingZeroCount(), and System.Runtime.Intrinsics.X86.Bmi1.X64.TrailingZeroCount().

Referenced by System.Text.Latin1Utility.GetIndexOfFirstNonLatin1Char().