1#![no_std]
2#[cfg(target_arch="x86_64")]
3use core::arch::x86_64::*;
4#[cfg(all(target_arch="x86", target_feature="sse2"))]
5use core::arch::x86::*;
6
7pub fn count_newlines(slice: &[u8]) -> usize {
9 let mut count = 0;
10 let mut slice = slice;
11 #[cfg(target_feature="sse2")] {
12 unsafe {
13 let splat = _mm_set1_epi8(b'\n' as _);
14 while slice.len() >= 64 {
15 let ptr = slice.as_ptr().cast::<__m128i>();
16 for i in 0..4 {
17 let simd = _mm_loadu_si128(ptr.add(i));
18 count += _mm_movemask_epi8(_mm_cmpeq_epi8(splat, simd)).count_ones() as usize;
19 }
20 slice = &slice[64..];
21 }
22 while slice.len() >= 16 {
23 let bytes = _mm_loadu_si128(slice.as_ptr().cast());
24 count += _mm_movemask_epi8(_mm_cmpeq_epi8(splat, bytes)).count_ones() as usize;
25 slice = &slice[16..];
26 }
27 }
28 }
29 for c in slice {
30 if *c == b'\n' {
31 count += 1;
32 }
33 }
34 count
35}