(reader: &mut Reader, len: usize)
| 879 | |
| 880 | #[inline] |
| 881 | pub fn read_latin1_simd(reader: &mut Reader, len: usize) -> Result<String, Error> { |
| 882 | if len == 0 { |
| 883 | return Ok(String::new()); |
| 884 | } |
| 885 | let src = reader.sub_slice(reader.get_cursor(), reader.get_cursor() + len)?; |
| 886 | |
| 887 | // Pessimistic allocation: Latin1 0x80-0xFF expands to 2 bytes in UTF-8 |
| 888 | let mut out: Vec<u8> = Vec::with_capacity(len * 2); |
| 889 | |
| 890 | unsafe { |
| 891 | let out_ptr = out.as_mut_ptr(); |
| 892 | let mut out_len = 0usize; |
| 893 | let mut i = 0usize; |
| 894 | |
| 895 | // ---- AVX2 fast-path: process 32 ASCII bytes at once ---- |
| 896 | #[cfg(target_arch = "x86_64")] |
| 897 | { |
| 898 | if std::arch::is_x86_feature_detected!("avx2") { |
| 899 | use std::arch::x86_64::*; |
| 900 | while i + 32 <= len { |
| 901 | let ptr = src.as_ptr().add(i) as *const __m256i; |
| 902 | let chunk = _mm256_loadu_si256(ptr); |
| 903 | let mask = _mm256_movemask_epi8(chunk); |
| 904 | if mask == 0 { |
| 905 | // All ASCII: direct copy (no conversion needed) |
| 906 | _mm256_storeu_si256(out_ptr.add(out_len) as *mut __m256i, chunk); |
| 907 | out_len += 32; |
| 908 | i += 32; |
| 909 | continue; |
| 910 | } else { |
| 911 | // Contains Latin1 bytes, break to scalar |
| 912 | break; |
| 913 | } |
| 914 | } |
| 915 | } |
| 916 | } |
| 917 | |
| 918 | // ---- SSE2 fast-path: process 16 ASCII bytes at once ---- |
| 919 | #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] |
| 920 | { |
| 921 | if std::arch::is_x86_feature_detected!("sse2") { |
| 922 | use std::arch::x86_64::*; |
| 923 | while i + 16 <= len { |
| 924 | let ptr = src.as_ptr().add(i) as *const __m128i; |
| 925 | let chunk = _mm_loadu_si128(ptr); |
| 926 | let mask = _mm_movemask_epi8(chunk); |
| 927 | if mask == 0 { |
| 928 | // All ASCII: direct copy |
| 929 | _mm_storeu_si128(out_ptr.add(out_len) as *mut __m128i, chunk); |
| 930 | out_len += 16; |
| 931 | i += 16; |
| 932 | continue; |
| 933 | } else { |
| 934 | break; |
| 935 | } |
| 936 | } |
| 937 | } |
| 938 | } |
no test coverage detected