diff --git a/src/arm.rs b/src/arm.rs index 0be06a4..d2544f5 100644 --- a/src/arm.rs +++ b/src/arm.rs @@ -1,67 +1,74 @@ -use core::intrinsics; - -macro_rules! defer { - ($($symbol:ident),+ -> $routine:ident) => { - $( - #[naked] - #[no_mangle] - pub extern "C" fn $symbol() { - unsafe { - asm!(concat!("b ", stringify!($routine))); - intrinsics::unreachable(); - } - } - )+ - } +extern "C" { + fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32; + 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 memset(dest: *mut u8, c: i32, n: usize) -> *mut u8; } -// FIXME only `__aeabi_memcmp` should be defined like this. The `*4` and `*8` variants should be -// defined as aliases of `__aeabi_memcmp` -defer!(__aeabi_memcmp, __aeabi_memcmp4, __aeabi_memcmp8 -> memcmp); +// FIXME: The `*4` and `*8` variants should be defined as aliases. -// FIXME same issue as `__aeabi_memcmp*` -defer!(__aeabi_memcpy, __aeabi_memcpy4, __aeabi_memcpy8 -> memcpy); - -// FIXME same issue as `__aeabi_memcmp*` -defer!(__aeabi_memmove, __aeabi_memmove4, __aeabi_memmove8 -> memmove); - -macro_rules! memset { - ($($symbol:ident),+) => { - $( - #[naked] - #[no_mangle] - pub extern "C" fn $symbol() { - unsafe { - asm!("mov r3, r1 - mov r1, r2 - mov r2, r3 - b memset"); - intrinsics::unreachable(); - } - } - )+ - } +#[no_mangle] +pub unsafe extern "aapcs" fn __aeabi_memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 { + memcmp(s1, s2, n) +} +#[no_mangle] +pub unsafe extern "aapcs" fn __aeabi_memcmp4(s1: *const u8, s2: *const u8, n: usize) -> i32 { + memcmp(s1, s2, n) +} +#[no_mangle] +pub unsafe extern "aapcs" fn __aeabi_memcmp8(s1: *const u8, s2: *const u8, n: usize) -> i32 { + memcmp(s1, s2, n) } -// FIXME same issue as `__aeabi_memcmp*` -memset!(__aeabi_memset, __aeabi_memset4, __aeabi_memset8); - -macro_rules! memclr { - ($($symbol:ident),+) => { - $( - #[naked] - #[no_mangle] - pub extern "C" fn $symbol() { - unsafe { - asm!("mov r2, r1 - mov r1, #0 - b memset"); - intrinsics::unreachable(); - } - } - )+ - } +#[no_mangle] +pub unsafe extern "aapcs" fn __aeabi_memcpy(dest: *mut u8, src: *const u8, n: usize) { + memcpy(dest, src, n); +} +#[no_mangle] +pub unsafe extern "aapcs" fn __aeabi_memcpy4(dest: *mut u8, src: *const u8, n: usize) { + memcpy(dest, src, n); +} +#[no_mangle] +pub unsafe extern "aapcs" fn __aeabi_memcpy8(dest: *mut u8, src: *const u8, n: usize) { + memcpy(dest, src, n); } -// FIXME same issue as `__aeabi_memcmp*` -memclr!(__aeabi_memclr, __aeabi_memclr4, __aeabi_memclr8); +#[no_mangle] +pub unsafe extern "aapcs" fn __aeabi_memmove(dest: *mut u8, src: *const u8, n: usize) { + memmove(dest, src, n); +} +#[no_mangle] +pub unsafe extern "aapcs" fn __aeabi_memmove4(dest: *mut u8, src: *const u8, n: usize) { + memmove(dest, src, n); +} +#[no_mangle] +pub unsafe extern "aapcs" fn __aeabi_memmove8(dest: *mut u8, src: *const u8, n: usize) { + memmove(dest, src, n); +} + +// Note the different argument order +#[no_mangle] +pub unsafe extern "aapcs" fn __aeabi_memset(dest: *mut u8, n: usize, c: i32) { + memset(dest, c, n); +} +#[no_mangle] +pub unsafe extern "aapcs" fn __aeabi_memset4(dest: *mut u8, n: usize, c: i32) { + memset(dest, c, n); +} +#[no_mangle] +pub unsafe extern "aapcs" fn __aeabi_memset8(dest: *mut u8, n: usize, c: i32) { + memset(dest, c, n); +} + +#[no_mangle] +pub unsafe extern "aapcs" fn __aeabi_memclr(dest: *mut u8, n: usize) { + memset(dest, 0, n); +} +#[no_mangle] +pub unsafe extern "aapcs" fn __aeabi_memclr4(dest: *mut u8, n: usize) { + memset(dest, 0, n); +} +#[no_mangle] +pub unsafe extern "aapcs" fn __aeabi_memclr8(dest: *mut u8, n: usize) { + memset(dest, 0, n); +}