Skip to content

Commit e42dfe7

Browse files
committed
mem: Add REP MOVSB/STOSB implementations
The assembly generated seems correct: https://rust.godbolt.org/z/GGnec8 Signed-off-by: Joe Richey <[email protected]>
1 parent ae638e3 commit e42dfe7

File tree

3 files changed

+45
-0
lines changed

3 files changed

+45
-0
lines changed

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![cfg_attr(feature = "compiler-builtins", compiler_builtins)]
22
#![feature(abi_unadjusted)]
3+
#![feature(asm)]
34
#![feature(llvm_asm)]
45
#![feature(global_asm)]
56
#![feature(cfg_target_has_atomic)]

src/mem/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use core::mem;
1010
use core::ops::{BitOr, Shl};
1111

1212
// memcpy/memmove/memset have optimized implementations on some architectures
13+
#[cfg_attr(target_arch = "x86_64", path = "x86_64.rs")]
1314
mod memcpy;
1415
pub use self::memcpy::*;
1516

src/mem/x86_64.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
use super::c_int;
2+
3+
#[cfg_attr(all(feature = "mem", not(feature = "mangled-names")), no_mangle)]
4+
pub unsafe extern "C" fn memcpy(dest: *mut u8, src: *const u8, count: usize) -> *mut u8 {
5+
asm!(
6+
"rep movsb [rdi], [rsi]",
7+
inout("rcx") count => _,
8+
inout("rdi") dest => _,
9+
inout("rsi") src => _,
10+
options(nostack, preserves_flags)
11+
);
12+
dest
13+
}
14+
15+
#[cfg_attr(all(feature = "mem", not(feature = "mangled-names")), no_mangle)]
16+
pub unsafe extern "C" fn memmove(dest: *mut u8, src: *const u8, count: usize) -> *mut u8 {
17+
if src >= dest as *const u8 {
18+
return memcpy(dest, src, count);
19+
}
20+
// copy backwards
21+
asm!(
22+
"std",
23+
"rep movsb [rdi], [rsi]",
24+
"cld",
25+
inout("rcx") count => _,
26+
inout("rdi") dest.add(count).sub(1) => _,
27+
inout("rsi") src.add(count).sub(1) => _,
28+
options(nostack, preserves_flags)
29+
);
30+
dest
31+
}
32+
33+
#[cfg_attr(all(feature = "mem", not(feature = "mangled-names")), no_mangle)]
34+
pub unsafe extern "C" fn memset(dest: *mut u8, c: c_int, count: usize) -> *mut u8 {
35+
asm!(
36+
"rep stosb [rdi], al",
37+
inout("rcx") count => _,
38+
inout("rdi") dest => _,
39+
in("al") c as u8,
40+
options(nostack, preserves_flags)
41+
);
42+
dest
43+
}

0 commit comments

Comments
 (0)