add implementations of memcpy et al
behind the "mem" Cargo feature, which used to be named "weak" fixes #126
This commit is contained in:
parent
70009a311c
commit
a1caa7ccac
|
@ -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]
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue