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"
|
rustc-cfg = "0.2.0"
|
||||||
gcc = "0.3.36"
|
gcc = "0.3.36"
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
|
|
||||||
[dependencies.rlibc]
|
|
||||||
git = "https://github.com/alexcrichton/rlibc"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
quickcheck = "0.3.1"
|
quickcheck = "0.3.1"
|
||||||
rand = "0.3.14"
|
rand = "0.3.14"
|
||||||
|
@ -26,7 +20,8 @@ c = []
|
||||||
# Mark this crate as the #![compiler_builtins] crate
|
# Mark this crate as the #![compiler_builtins] crate
|
||||||
compiler-builtins = []
|
compiler-builtins = []
|
||||||
default = ["compiler-builtins"]
|
default = ["compiler-builtins"]
|
||||||
|
# Include implementations of memory operations like memcpy
|
||||||
|
mem = []
|
||||||
rustbuild = ["compiler-builtins"]
|
rustbuild = ["compiler-builtins"]
|
||||||
weak = ["rlibc/weak"]
|
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
use core::intrinsics;
|
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
|
// 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
|
// calling convention which can't be implemented using a normal Rust function
|
||||||
#[naked]
|
#[naked]
|
||||||
|
@ -100,6 +103,7 @@ pub extern "C" fn __aeabi_uidiv(a: u32, b: u32) -> u32 {
|
||||||
::int::udiv::__udivsi3(a, b)
|
::int::udiv::__udivsi3(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mem"))]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8;
|
fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8;
|
||||||
fn memmove(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(asm)]
|
||||||
#![feature(compiler_builtins)]
|
#![feature(compiler_builtins)]
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
#![feature(linkage)]
|
|
||||||
#![feature(naked_functions)]
|
#![feature(naked_functions)]
|
||||||
#![feature(staged_api)]
|
#![feature(staged_api)]
|
||||||
#![no_builtins]
|
#![no_builtins]
|
||||||
|
@ -102,9 +101,6 @@ extern crate compiler_rt;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
|
|
||||||
#[cfg(feature = "weak")]
|
|
||||||
extern crate rlibc;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod qc;
|
mod qc;
|
||||||
|
@ -112,6 +108,9 @@ mod qc;
|
||||||
pub mod int;
|
pub mod int;
|
||||||
pub mod float;
|
pub mod float;
|
||||||
|
|
||||||
|
#[cfg(feature = "mem")]
|
||||||
|
pub mod mem;
|
||||||
|
|
||||||
#[cfg(target_arch = "arm")]
|
#[cfg(target_arch = "arm")]
|
||||||
pub mod 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