From a1caa7ccacf5f9853b5e3c70b4f5d112272d4900 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Sat, 17 Dec 2016 23:01:47 -0500 Subject: [PATCH] add implementations of memcpy et al behind the "mem" Cargo feature, which used to be named "weak" fixes #126 --- Cargo.toml | 9 ++------- src/arm.rs | 4 ++++ src/lib.rs | 7 +++---- src/mem.rs | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 11 deletions(-) create mode 100644 src/mem.rs diff --git a/Cargo.toml b/Cargo.toml index 9536423..8340578 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,12 +8,6 @@ version = "0.1.0" rustc-cfg = "0.2.0" gcc = "0.3.36" -[dependencies] - -[dependencies.rlibc] -git = "https://github.com/alexcrichton/rlibc" -optional = true - [dev-dependencies] quickcheck = "0.3.1" rand = "0.3.14" @@ -26,7 +20,8 @@ c = [] # Mark this crate as the #![compiler_builtins] crate compiler-builtins = [] default = ["compiler-builtins"] +# Include implementations of memory operations like memcpy +mem = [] rustbuild = ["compiler-builtins"] -weak = ["rlibc/weak"] [workspace] diff --git a/src/arm.rs b/src/arm.rs index b74458f..345ff24 100644 --- a/src/arm.rs +++ b/src/arm.rs @@ -1,5 +1,8 @@ use core::intrinsics; +#[cfg(feature = "mem")] +use mem::{memcpy, memmove, memset}; + // NOTE This function and the ones below are implemented using assembly because they using a custom // calling convention which can't be implemented using a normal Rust function #[naked] @@ -100,6 +103,7 @@ pub extern "C" fn __aeabi_uidiv(a: u32, b: u32) -> u32 { ::int::udiv::__udivsi3(a, b) } +#[cfg(not(feature = "mem"))] extern "C" { fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8; fn memmove(dest: *mut u8, src: *const u8, n: usize) -> *mut u8; diff --git a/src/lib.rs b/src/lib.rs index dc8f411..b104def 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,7 +11,6 @@ #![feature(asm)] #![feature(compiler_builtins)] #![feature(core_intrinsics)] -#![feature(linkage)] #![feature(naked_functions)] #![feature(staged_api)] #![no_builtins] @@ -102,9 +101,6 @@ extern crate compiler_rt; #[cfg(test)] extern crate rand; -#[cfg(feature = "weak")] -extern crate rlibc; - #[cfg(test)] #[macro_use] mod qc; @@ -112,6 +108,9 @@ mod qc; pub mod int; pub mod float; +#[cfg(feature = "mem")] +pub mod mem; + #[cfg(target_arch = "arm")] pub mod arm; diff --git a/src/mem.rs b/src/mem.rs new file mode 100644 index 0000000..31d6712 --- /dev/null +++ b/src/mem.rs @@ -0,0 +1,59 @@ +#[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 +} + +#[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 +} + +#[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 +} + +#[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 +}