Skip to content

Commit 2a67ad7

Browse files
authored
Specialize strlen for x86_64.
1 parent 5511f30 commit 2a67ad7

File tree

3 files changed

+40
-7
lines changed

3 files changed

+40
-7
lines changed

src/mem/impls.rs

+10
Original file line numberDiff line numberDiff line change
@@ -279,3 +279,13 @@ pub unsafe fn compare_bytes(s1: *const u8, s2: *const u8, n: usize) -> i32 {
279279
}
280280
0
281281
}
282+
283+
#[inline(always)]
284+
pub unsafe fn c_string_length(mut s: *const core::ffi::c_char) -> usize {
285+
let mut n = 0;
286+
while *s != 0 {
287+
n += 1;
288+
s = s.add(1);
289+
}
290+
n
291+
}

src/mem/mod.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,7 @@ intrinsics! {
6363
#[mem_builtin]
6464
#[cfg_attr(not(all(target_os = "windows", target_env = "gnu")), linkage = "weak")]
6565
pub unsafe extern "C" fn strlen(s: *const core::ffi::c_char) -> usize {
66-
let mut n = 0;
67-
let mut s = s;
68-
while *s != 0 {
69-
n += 1;
70-
s = s.offset(1);
71-
}
72-
n
66+
impls::c_string_length(s)
7367
}
7468
}
7569

src/mem/x86_64.rs

+29
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,35 @@ pub unsafe fn compare_bytes(a: *const u8, b: *const u8, n: usize) -> i32 {
173173
c16(a.cast(), b.cast(), n)
174174
}
175175

176+
#[inline(always)]
177+
pub unsafe fn c_string_length(s: *const std::ffi::c_char) -> usize {
178+
let mut n: usize;
179+
180+
std::arch::asm!(
181+
// search for a zero byte
182+
"xor al, al",
183+
184+
// unbounded memory region
185+
"xor rcx, rcx",
186+
"not rcx",
187+
188+
// forward direction
189+
"cld",
190+
191+
// perform search
192+
"repne scasb",
193+
194+
// extract length
195+
"not rcx",
196+
"dec rcx",
197+
inout("rdi") s => _,
198+
out("rcx") n,
199+
options(nostack),
200+
);
201+
202+
n
203+
}
204+
176205
/// Determine optimal parameters for a `rep` instruction.
177206
fn rep_param(dest: *mut u8, mut count: usize) -> (usize, usize, usize) {
178207
// Unaligned writes are still slow on modern processors, so align the destination address.

0 commit comments

Comments
 (0)