Skip to content

Commit 7321f5c

Browse files
committed
WIP: use quad-word rep string instructions
1 parent 0d90538 commit 7321f5c

File tree

1 file changed

+26
-7
lines changed

1 file changed

+26
-7
lines changed

src/mem/x86_64.rs

+26-7
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,14 @@ use super::c_int;
99

1010
#[cfg_attr(all(feature = "mem", not(feature = "mangled-names")), no_mangle)]
1111
pub unsafe extern "C" fn memcpy(dest: *mut u8, src: *const u8, count: usize) -> *mut u8 {
12+
let qword_count = count >> 3;
13+
let byte_count = count & 0b111;
1214
asm!(
15+
"rep movsq [rdi], [rsi]",
16+
"mov ecx, {byte_count:e}",
1317
"rep movsb [rdi], [rsi]",
14-
inout("rcx") count => _,
18+
byte_count = in(reg) byte_count,
19+
inout("rcx") qword_count => _,
1520
inout("rdi") dest => _,
1621
inout("rsi") src => _,
1722
options(nostack, preserves_flags)
@@ -21,29 +26,43 @@ pub unsafe extern "C" fn memcpy(dest: *mut u8, src: *const u8, count: usize) ->
2126

2227
#[cfg_attr(all(feature = "mem", not(feature = "mangled-names")), no_mangle)]
2328
pub unsafe extern "C" fn memmove(dest: *mut u8, src: *const u8, count: usize) -> *mut u8 {
24-
if src >= dest as *const u8 {
29+
let dest_end = dest.offset(count as isize);
30+
let src_end = src.offset(count as isize);
31+
if src >= dest as *const u8 || src_end <= dest as *const u8 {
2532
return memcpy(dest, src, count);
2633
}
2734
// copy backwards
35+
let qword_count = count >> 3;
36+
let byte_count = count & 0b111;
2837
asm!(
2938
"std",
39+
"rep movsq [rdi], [rsi]",
40+
"mov ecx, {byte_count:e}",
41+
"add rdi, 7",
42+
"add rsi, 7",
3043
"rep movsb [rdi], [rsi]",
3144
"cld",
32-
inout("rcx") count => _,
33-
inout("rdi") dest.add(count).sub(1) => _,
34-
inout("rsi") src.add(count).sub(1) => _,
45+
byte_count = in(reg) byte_count,
46+
inout("rcx") qword_count => _,
47+
inout("rdi") dest_end.sub(8) => _,
48+
inout("rsi") src_end.sub(8) => _,
3549
options(nostack, preserves_flags)
3650
);
3751
dest
3852
}
3953

4054
#[cfg_attr(all(feature = "mem", not(feature = "mangled-names")), no_mangle)]
4155
pub unsafe extern "C" fn memset(dest: *mut u8, c: c_int, count: usize) -> *mut u8 {
56+
let qword_count = count >> 3;
57+
let byte_count = count & 0b111;
4258
asm!(
59+
"rep stosq [rdi], rax",
60+
"mov ecx, {byte_count:e}",
4361
"rep stosb [rdi], al",
44-
inout("rcx") count => _,
62+
byte_count = in(reg) byte_count,
63+
inout("rcx") qword_count => _,
4564
inout("rdi") dest => _,
46-
in("al") c as u8,
65+
in("rax") (c as u8 as u64) * 0b0101010101010101,
4766
options(nostack, preserves_flags)
4867
);
4968
dest

0 commit comments

Comments
 (0)