diff --git a/src/lib.rs b/src/lib.rs index 823170a..a802d1b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,10 +1,12 @@ #![allow(unused_features)] #![feature(asm)] #![feature(core_intrinsics)] +#![feature(linkage)] #![feature(naked_functions)] #![cfg_attr(not(test), no_std)] // TODO(rust-lang/rust#35021) uncomment when that PR lands // #![feature(rustc_builtins)] +#![no_builtins] // We disable #[no_mangle] for tests so that we can verify the test results // against the native compiler-rt implementations of the builtins. @@ -20,6 +22,7 @@ extern crate core; pub mod arm; pub mod udiv; +pub mod mem; pub mod mul; pub mod shift; diff --git a/src/mem.rs b/src/mem.rs new file mode 100644 index 0000000..7a94034 --- /dev/null +++ b/src/mem.rs @@ -0,0 +1,60 @@ +// NOTE Copied verbatim from the rlibc crate +// cf. https://crates.io/crates/rlibc + +#[linkage = "weak"] +#[no_mangle] +pub unsafe extern "C" fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 { + let mut i = 0; + while i < n { + *dest.offset(i as isize) = *src.offset(i as isize); + i += 1; + } + dest +} + +#[linkage = "weak"] +#[no_mangle] +pub unsafe extern "C" fn memmove(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 { + if src < dest as *const u8 { + // copy from end + let mut i = n; + while i != 0 { + i -= 1; + *dest.offset(i as isize) = *src.offset(i as isize); + } + } else { + // copy from beginning + let mut i = 0; + while i < n { + *dest.offset(i as isize) = *src.offset(i as isize); + i += 1; + } + } + dest +} + +#[linkage = "weak"] +#[no_mangle] +pub unsafe extern "C" fn memset(s: *mut u8, c: i32, n: usize) -> *mut u8 { + let mut i = 0; + while i < n { + *s.offset(i as isize) = c as u8; + i += 1; + } + s +} + +#[linkage = "weak"] +#[no_mangle] +pub unsafe extern "C" fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 { + let mut i = 0; + while i < n { + let a = *s1.offset(i as isize); + let b = *s2.offset(i as isize); + if a != b { + return a as i32 - b as i32; + } + i += 1; + } + 0 +}