@@ -526,7 +526,7 @@ public static unsafe int IndexOf(ref char searchSpace, char value, int length)
526526 {
527527 // Input isn't char aligned, we won't be able to align it to a Vector
528528 }
529- else if ( Sse2 . IsSupported || AdvSimd . Arm64 . IsSupported )
529+ else if ( Vector128 . IsHardwareAccelerated )
530530 {
531531 // Avx2 branch also operates on Sse2 sizes, so check is combined.
532532 // Needs to be double length to allow us to align the data first.
@@ -575,13 +575,14 @@ public static unsafe int IndexOf(ref char searchSpace, char value, int length)
575575 lengthToExamine -- ;
576576 }
577577
578- // We get past SequentialScan only if IsHardwareAccelerated or intrinsic .IsSupported is true. However, we still have the redundant check to allow
578+ // We get past SequentialScan only if IsHardwareAccelerated is true. However, we still have the redundant check to allow
579579 // the JIT to see that the code is unreachable and eliminate it when the platform does not have hardware accelerated.
580- if ( Avx2 . IsSupported )
580+ if ( Vector256 . IsHardwareAccelerated )
581581 {
582582 if ( offset < length )
583583 {
584584 Debug . Assert ( length - offset >= Vector128 < ushort > . Count ) ;
585+ ref ushort ushortSearchSpace = ref Unsafe . As < char , ushort > ( ref searchSpace ) ;
585586 if ( ( ( nint ) Unsafe . AsPointer ( ref Unsafe . Add ( ref searchSpace , ( nint ) offset ) ) & ( nint ) ( Vector256 < byte > . Count - 1 ) ) != 0 )
586587 {
587588 // Not currently aligned to Vector256 (is aligned to Vector128); this can cause a problem for searches
@@ -600,10 +601,10 @@ public static unsafe int IndexOf(ref char searchSpace, char value, int length)
600601 // the misalignment that may occur after; to we default to giving the GC a free hand to relocate and
601602 // its up to the caller whether they are operating over fixed data.
602603 Vector128 < ushort > values = Vector128 . Create ( ( ushort ) value ) ;
603- Vector128 < ushort > search = LoadVector128 ( ref searchSpace , offset ) ;
604+ Vector128 < ushort > search = Vector128 . LoadUnsafe ( ref ushortSearchSpace , ( nuint ) offset ) ;
604605
605606 // Same method as below
606- int matches = Sse2 . MoveMask ( Sse2 . CompareEqual ( values , search ) . AsByte ( ) ) ;
607+ uint matches = Vector128 . Equals ( values , search ) . AsByte ( ) . ExtractMostSignificantBits ( ) ;
607608 if ( matches == 0 )
608609 {
609610 // Zero flags set so no matches
@@ -624,8 +625,8 @@ public static unsafe int IndexOf(ref char searchSpace, char value, int length)
624625 {
625626 Debug . Assert ( lengthToExamine >= Vector256 < ushort > . Count ) ;
626627
627- Vector256 < ushort > search = LoadVector256 ( ref searchSpace , offset ) ;
628- int matches = Avx2 . MoveMask ( Avx2 . CompareEqual ( values , search ) . AsByte ( ) ) ;
628+ Vector256 < ushort > search = Vector256 . LoadUnsafe ( ref ushortSearchSpace , ( nuint ) offset ) ;
629+ uint matches = Vector256 . Equals ( values , search ) . AsByte ( ) . ExtractMostSignificantBits ( ) ;
629630 // Note that MoveMask has converted the equal vector elements into a set of bit flags,
630631 // So the bit position in 'matches' corresponds to the element offset.
631632 if ( matches == 0 )
@@ -648,10 +649,10 @@ public static unsafe int IndexOf(ref char searchSpace, char value, int length)
648649 Debug . Assert ( lengthToExamine >= Vector128 < ushort > . Count ) ;
649650
650651 Vector128 < ushort > values = Vector128 . Create ( ( ushort ) value ) ;
651- Vector128 < ushort > search = LoadVector128 ( ref searchSpace , offset ) ;
652+ Vector128 < ushort > search = Vector128 . LoadUnsafe ( ref ushortSearchSpace , ( nuint ) offset ) ;
652653
653654 // Same method as above
654- int matches = Sse2 . MoveMask ( Sse2 . CompareEqual ( values , search ) . AsByte ( ) ) ;
655+ uint matches = Vector128 . Equals ( values , search ) . AsByte ( ) . ExtractMostSignificantBits ( ) ;
655656 if ( matches == 0 )
656657 {
657658 // Zero flags set so no matches
@@ -673,11 +674,12 @@ public static unsafe int IndexOf(ref char searchSpace, char value, int length)
673674 }
674675 }
675676 }
676- else if ( Sse2 . IsSupported )
677+ else if ( Vector128 . IsHardwareAccelerated )
677678 {
678679 if ( offset < length )
679680 {
680681 Debug . Assert ( length - offset >= Vector128 < ushort > . Count ) ;
682+ ref ushort ushortSearchSpace = ref Unsafe . As < char , ushort > ( ref searchSpace ) ;
681683
682684 lengthToExamine = GetCharVector128SpanLength ( offset , length ) ;
683685 if ( lengthToExamine > 0 )
@@ -687,11 +689,11 @@ public static unsafe int IndexOf(ref char searchSpace, char value, int length)
687689 {
688690 Debug . Assert ( lengthToExamine >= Vector128 < ushort > . Count ) ;
689691
690- Vector128 < ushort > search = LoadVector128 ( ref searchSpace , offset ) ;
692+ Vector128 < ushort > search = Vector128 . LoadUnsafe ( ref ushortSearchSpace , ( uint ) offset ) ;
691693
692694 // Same method as above
693- int matches = Sse2 . MoveMask ( Sse2 . CompareEqual ( values , search ) . AsByte ( ) ) ;
694- if ( matches == 0 )
695+ Vector128 < ushort > compareResult = Vector128 . Equals ( values , search ) ;
696+ if ( compareResult == Vector128 < ushort > . Zero )
695697 {
696698 // Zero flags set so no matches
697699 offset += Vector128 < ushort > . Count ;
@@ -701,6 +703,7 @@ public static unsafe int IndexOf(ref char searchSpace, char value, int length)
701703
702704 // Find bitflag offset of first match and add to current offset,
703705 // flags are in bytes so divide for chars
706+ uint matches = compareResult . AsByte ( ) . ExtractMostSignificantBits ( ) ;
704707 return ( int ) ( offset + ( ( uint ) BitOperations . TrailingZeroCount ( matches ) / sizeof ( char ) ) ) ;
705708 } while ( lengthToExamine > 0 ) ;
706709 }
@@ -712,41 +715,6 @@ public static unsafe int IndexOf(ref char searchSpace, char value, int length)
712715 }
713716 }
714717 }
715- else if ( AdvSimd . Arm64 . IsSupported )
716- {
717- if ( offset < length )
718- {
719- Debug . Assert ( length - offset >= Vector128 < ushort > . Count ) ;
720-
721- lengthToExamine = GetCharVector128SpanLength ( offset , length ) ;
722- if ( lengthToExamine > 0 )
723- {
724- Vector128 < ushort > values = Vector128 . Create ( ( ushort ) value ) ;
725- do
726- {
727- Debug . Assert ( lengthToExamine >= Vector128 < ushort > . Count ) ;
728-
729- Vector128 < ushort > search = LoadVector128 ( ref searchSpace , offset ) ;
730- Vector128 < ushort > compareResult = AdvSimd . CompareEqual ( values , search ) ;
731-
732- if ( compareResult == Vector128 < ushort > . Zero )
733- {
734- offset += Vector128 < ushort > . Count ;
735- lengthToExamine -= Vector128 < ushort > . Count ;
736- continue ;
737- }
738-
739- return ( int ) ( offset + FindFirstMatchedLane ( compareResult ) ) ;
740- } while ( lengthToExamine > 0 ) ;
741- }
742-
743- if ( offset < length )
744- {
745- lengthToExamine = length - offset ;
746- goto SequentialScan ;
747- }
748- }
749- }
750718 else if ( Vector . IsHardwareAccelerated )
751719 {
752720 if ( offset < length )
0 commit comments