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

◆ GetIndexOfFirstNonAsciiChar_Sse2()

static unsafe nuint System.Text.ASCIIUtility.GetIndexOfFirstNonAsciiChar_Sse2 ( char * pBuffer,
nuint bufferLength )
inlinestaticprivate

Definition at line 379 of file ASCIIUtility.cs.

380 {
381 if (bufferLength == 0)
382 {
383 return 0u;
384 }
385 uint num = (uint)Unsafe.SizeOf<Vector128<byte>>();
386 uint num2 = num / 2;
387 char* ptr = pBuffer;
388 Vector128<ushort> right;
389 Vector128<ushort> right2;
391 uint num3;
392 if (bufferLength >= num2)
393 {
394 right = Vector128.Create((ushort)65408);
395 right2 = Vector128.Create((ushort)32640);
396 left = Sse2.LoadVector128((ushort*)pBuffer);
397 num3 = (uint)Sse2.MoveMask(Sse2.AddSaturate(left, right2).AsByte());
398 if ((num3 & 0xAAAA) == 0)
399 {
400 bufferLength <<= 1;
401 if (bufferLength < 2 * num)
402 {
403 goto IL_013e;
404 }
405 pBuffer = (char*)((nuint)((byte*)pBuffer + num) & ~(nuint)(num - 1));
406 bufferLength = (nuint)(bufferLength + (byte*)ptr);
407 bufferLength -= (nuint)pBuffer;
408 if (bufferLength < 2 * num)
409 {
410 goto IL_00fa;
411 }
412 char* ptr2 = (char*)((byte*)pBuffer + bufferLength - 2 * num);
413 Vector128<ushort> vector;
414 while (true)
415 {
416 left = Sse2.LoadAlignedVector128((ushort*)pBuffer);
417 vector = Sse2.LoadAlignedVector128((ushort*)(pBuffer + num2));
418 Vector128<ushort> left2 = Sse2.Or(left, vector);
419 if (Sse41.IsSupported)
420 {
421 if (!Sse41.TestZ(left2, right))
422 {
423 break;
424 }
425 }
426 else
427 {
428 num3 = (uint)Sse2.MoveMask(Sse2.AddSaturate(left2, right2).AsByte());
429 if ((num3 & 0xAAAAu) != 0)
430 {
431 break;
432 }
433 }
434 pBuffer += 2 * num2;
435 if (pBuffer <= ptr2)
436 {
437 continue;
438 }
439 goto IL_00fa;
440 }
441 if (Sse41.IsSupported)
442 {
443 if (!Sse41.TestZ(left, right))
444 {
445 goto IL_01e6;
446 }
447 }
448 else
449 {
450 num3 = (uint)Sse2.MoveMask(Sse2.AddSaturate(left, right2).AsByte());
451 if ((num3 & 0xAAAAu) != 0)
452 {
453 goto IL_01fa;
454 }
455 }
456 pBuffer += num2;
457 left = vector;
458 goto IL_01e6;
459 }
460 goto IL_01fa;
461 }
462 if ((bufferLength & 4) != 0)
463 {
464 _ = UIntPtr.Size;
465 ulong num4 = Unsafe.ReadUnaligned<ulong>(pBuffer);
466 if (!AllCharsInUInt64AreAscii(num4))
467 {
468 num4 &= 0xFF80FF80FF80FF80uL;
469 pBuffer = (char*)((byte*)pBuffer + (nuint)((BitOperations.TrailingZeroCount(num4) >> 3) & ~(nint)1));
470 goto IL_01a1;
471 }
472 pBuffer += 4;
473 }
474 if ((bufferLength & 2) != 0)
475 {
476 uint value = Unsafe.ReadUnaligned<uint>(pBuffer);
478 {
480 {
481 pBuffer++;
482 }
483 goto IL_01a1;
484 }
485 pBuffer += 2;
486 }
487 if ((bufferLength & 1) != 0 && *pBuffer <= '\u007f')
488 {
489 pBuffer++;
490 }
491 goto IL_01a1;
492 IL_00fa:
493 if ((bufferLength & num) != 0)
494 {
495 left = Sse2.LoadAlignedVector128((ushort*)pBuffer);
496 if (Sse41.IsSupported)
497 {
498 if (!Sse41.TestZ(left, right))
499 {
500 goto IL_01e6;
501 }
502 }
503 else
504 {
505 num3 = (uint)Sse2.MoveMask(Sse2.AddSaturate(left, right2).AsByte());
506 if ((num3 & 0xAAAAu) != 0)
507 {
508 goto IL_01fa;
509 }
510 }
511 goto IL_013e;
512 }
513 goto IL_0148;
514 IL_01fa:
515 num3 &= 0xAAAAu;
516 pBuffer = (char*)((byte*)pBuffer + (uint)BitOperations.TrailingZeroCount(num3) - 1);
517 goto IL_01a1;
518 IL_0148:
519 if (((byte)bufferLength & (num - 1)) != 0)
520 {
521 pBuffer = (char*)((byte*)pBuffer + (bufferLength & (num - 1)) - num);
522 left = Sse2.LoadVector128((ushort*)pBuffer);
523 if (Sse41.IsSupported)
524 {
525 if (!Sse41.TestZ(left, right))
526 {
527 goto IL_01e6;
528 }
529 }
530 else
531 {
532 num3 = (uint)Sse2.MoveMask(Sse2.AddSaturate(left, right2).AsByte());
533 if ((num3 & 0xAAAAu) != 0)
534 {
535 goto IL_01fa;
536 }
537 }
538 pBuffer += num2;
539 }
540 goto IL_01a1;
541 IL_01e6:
542 num3 = (uint)Sse2.MoveMask(Sse2.AddSaturate(left, right2).AsByte());
543 goto IL_01fa;
544 IL_013e:
545 pBuffer += num2;
546 goto IL_0148;
547 IL_01a1:
548 return (nuint)(pBuffer - ptr);
549 }
static int TrailingZeroCount(int value)
static Vector128< byte > Create(byte value)
Definition Vector128.cs:138
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 AllCharsInUInt32AreAscii(uint value)
static bool AllCharsInUInt64AreAscii(ulong value)
static bool FirstCharInUInt32IsAscii(uint value)

References System.Runtime.Intrinsics.X86.Sse2.AddSaturate(), System.Text.ASCIIUtility.AllCharsInUInt32AreAscii(), System.Text.ASCIIUtility.AllCharsInUInt64AreAscii(), System.Runtime.Intrinsics.Vector128< T >.Create(), System.Text.ASCIIUtility.FirstCharInUInt32IsAscii(), 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.UIntPtr.Size, System.Runtime.Intrinsics.X86.Sse41.TestZ(), System.Numerics.BitOperations.TrailingZeroCount(), and System.value.

Referenced by System.Text.ASCIIUtility.GetIndexOfFirstNonAsciiChar().