arm7tdmi_aeabi

Implements runtime support functions according to ARM's AEABI. All functions are specialized to the ARM7TDMI CPU. They should work with any later ARM CPU as well, but because of instruction pipeline differences they might have less than optimal performance.

These functions are intended to support Rust development on the GBA, but they're written in assembly so they should work with any language and any ARMv4T or later device.

Current Support

Currently the code uses slightly alternate names from the "real" names so that it can be compiled into tests without clashing with the system version of each symbol.

The following functions are currently provided:

```rust extern "C" { pub fn libcmemcpy(d: *mut u8, s: *const u8, bytes: usize) -> *mut u8; pub fn aeabimemcpy(d: *mut u8, s: *const u8, bytes: usize); pub fn aeabimemcpy4(d: *mut u8, s: *const u8, bytes: usize); pub fn aeabimemcpy8(d: *mut u8, s: *const u8, bytes: usize); pub fn gbamemcpysram(d: *mut u8, s: *const u8, bytes: usize);

pub fn libcmemmove(d: *mut u8, s: *const u8, bytes: usize) -> *mut u8; pub fn aeabimemmove(d: *mut u8, s: *const u8, bytes: usize); pub fn aeabimemmove4(d: *mut u8, s: *const u8, bytes: usize); pub fn aeabimemmove8(d: *mut u8, s: *const u8, bytes: usize);

pub fn libcmemset(d: *mut u8, val: i32, bytes: usize) -> *mut u8; pub fn aeabimemset(d: *mut u8, bytes: usize, val: i32); pub fn aeabimemset4(d: *mut u8, bytes: usize, val: i32); pub fn aeabimemset8(d: *mut u8, bytes: usize, val: i32);

pub fn aeabimemclr(d: *mut u8, bytes: usize); pub fn aeabimemclr4(d: *mut u8, bytes: usize); pub fn aeabi_memclr8(d: *mut u8, bytes: usize);

pub fn aeabiuread4(address: *const u32) -> u32; pub fn aeabiuread8(address: *const u64) -> u64; pub fn aeabiuwrite4(value: u32, address: *mut u32) -> u32; pub fn aeabiuwrite8(value: u64, address: *mut u64) -> u64;

pub fn aeabiidiv(n: i32, d: i32) -> i32; pub fn aeabiuidiv(n: u32, d: u32) -> u32; pub fn aeabiidivmod(n: i32, d: i32) -> u64; pub fn aeabiuidivmod(n: u32, d: u32) -> u64; } ```

Functions with a 4 or 8 on the end require that input pointers be aligned to that much. The bytes value does not need to be an even multiple of the alignment requirement.

All libc_ functions give the original destination pointer they were passed as their return value. All aeabi_ functions return nothing at all (and this is more efficient, so use them when possible).

Use

Unfortunately, crates can't specify what link section they want a dependency's code to use. Since my main use for this assembly is to have it in a special section on the GBA so that the code is in RAM at runtime, I can't just publish it to crates.io and then use it as a normal dependency and have it go where I want. Or, I could, but then no one else could use it outside of that specific GBA context, which is also not great.

In the future this crate will be published as a proc-macro that accepts a section name and emits a global_asm! with the right contents. Until then, if you want to use these functions just vendor the files into your project.

Testing

Testing of this crate is generally easiest using cross.

cross test --target arm-unknown-linux-gnueabi

Or, if you're running on an ARM device (eg: rpi with the 32-bit OS) then you can probably test natively I guess.

License

All the code here is released under CCO.

OR (if you really want to use the standard Rust project licenses) Apache-2.0 OR MIT can also be used.