diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 78a1cb7..cb7d680 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -224,6 +224,10 @@ jobs: uses: actions/checkout@v4 - name: Install Just uses: taiki-e/install-action@just + - name: Install GCC and libclang1 + run: | + sudo apt-get update + sudo apt-get install -y gcc-arm-none-eabi libclang1 - name: Install Rust run: | rustup toolchain install 1.92 @@ -288,7 +292,7 @@ jobs: - name: Install Dependencies run: | sudo apt-get -y update - sudo apt-get -y install libpixman-1-0 libfdt1 libglib2.0-0t64 + sudo apt-get -y install libpixman-1-0 libfdt1 libglib2.0-0t64 gcc-arm-none-eabi libclang1 - name: Install custom QEMU into /opt run: | curl -sSL https://github.com/jonathanpallant/qemu9-for-ubuntu-2404/releases/download/qemu-9.2.3%2Bbuild0/qemu-9.2.3-ubuntu-24.04.tar.gz | sudo tar xvzf - -C / @@ -310,7 +314,7 @@ jobs: - name: Install Dependencies run: | sudo apt-get -y update - sudo apt-get -y install libpixman-1-0 libfdt1 libglib2.0-0t64 + sudo apt-get -y install libpixman-1-0 libfdt1 libglib2.0-0t64 gcc-arm-none-eabi libclang1 - name: Install custom QEMU into /opt run: | curl -sSL https://github.com/jonathanpallant/qemu9-for-ubuntu-2404/releases/download/qemu-9.2.3%2Bbuild0/qemu-9.2.3-ubuntu-24.04.tar.gz | sudo tar xvzf - -C / @@ -332,7 +336,7 @@ jobs: - name: Install Dependencies run: | sudo apt-get -y update - sudo apt-get -y install libpixman-1-0 libfdt1 libglib2.0-0t64 + sudo apt-get -y install libpixman-1-0 libfdt1 libglib2.0-0t64 gcc-arm-none-eabi libclang1 - name: Install custom QEMU into /opt run: | curl -sSL https://github.com/jonathanpallant/qemu9-for-ubuntu-2404/releases/download/qemu-9.2.3%2Bbuild0/qemu-9.2.3-ubuntu-24.04.tar.gz | sudo tar xvzf - -C / @@ -354,7 +358,7 @@ jobs: - name: Install Dependencies run: | sudo apt-get -y update - sudo apt-get -y install libpixman-1-0 libfdt1 libglib2.0-0t64 + sudo apt-get -y install libpixman-1-0 libfdt1 libglib2.0-0t64 gcc-arm-none-eabi libclang1 - name: Install custom QEMU into /opt run: | curl -sSL https://github.com/jonathanpallant/qemu9-for-ubuntu-2404/releases/download/qemu-9.2.3%2Bbuild0/qemu-9.2.3-ubuntu-24.04.tar.gz | sudo tar xvzf - -C / @@ -376,7 +380,7 @@ jobs: - name: Install Dependencies run: | sudo apt-get -y update - sudo apt-get -y install libpixman-1-0 libfdt1 libglib2.0-0t64 + sudo apt-get -y install libpixman-1-0 libfdt1 libglib2.0-0t64 gcc-arm-none-eabi libclang1 - name: Install custom QEMU into /opt run: | curl -sSL https://github.com/jonathanpallant/qemu9-for-ubuntu-2404/releases/download/qemu-9.2.3%2Bbuild0/qemu-9.2.3-ubuntu-24.04.tar.gz | sudo tar xvzf - -C / @@ -398,7 +402,7 @@ jobs: - name: Install Dependencies run: | sudo apt-get -y update - sudo apt-get -y install libpixman-1-0 libfdt1 libglib2.0-0t64 + sudo apt-get -y install libpixman-1-0 libfdt1 libglib2.0-0t64 gcc-arm-none-eabi libclang1 - name: Install custom QEMU into /opt run: | curl -sSL https://github.com/jonathanpallant/qemu9-for-ubuntu-2404/releases/download/qemu-9.2.3%2Bbuild0/qemu-9.2.3-ubuntu-24.04.tar.gz | sudo tar xvzf - -C / @@ -420,7 +424,7 @@ jobs: - name: Install Dependencies run: | sudo apt-get -y update - sudo apt-get -y install libpixman-1-0 libfdt1 libglib2.0-0t64 + sudo apt-get -y install libpixman-1-0 libfdt1 libglib2.0-0t64 gcc-arm-none-eabi libclang1 - name: Install custom QEMU into /opt run: | curl -sSL https://github.com/jonathanpallant/qemu9-for-ubuntu-2404/releases/download/qemu-9.2.3%2Bbuild0/qemu-9.2.3-ubuntu-24.04.tar.gz | sudo tar xvzf - -C / @@ -442,7 +446,7 @@ jobs: - name: Install Dependencies run: | sudo apt-get -y update - sudo apt-get -y install libpixman-1-0 libfdt1 libglib2.0-0t64 + sudo apt-get -y install libpixman-1-0 libfdt1 libglib2.0-0t64 gcc-arm-none-eabi libclang1 - name: Install custom QEMU into /opt run: | curl -sSL https://github.com/jonathanpallant/qemu9-for-ubuntu-2404/releases/download/qemu-9.2.3%2Bbuild0/qemu-9.2.3-ubuntu-24.04.tar.gz | sudo tar xvzf - -C / diff --git a/Cargo.toml b/Cargo.toml index 61edd8f..4525181 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ exclude = [ "examples/mps3-an536", "examples/mps3-an536-smp", "examples/mps3-an536-el2", + "examples/c-code", ] members = [ "aarch32-cpu", diff --git a/examples/c-code/Cargo.toml b/examples/c-code/Cargo.toml new file mode 100644 index 0000000..c8fe333 --- /dev/null +++ b/examples/c-code/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "c-code" +version = "0.1.0" +edition = "2024" + +[dependencies] + +[build-dependencies] +bindgen = "0.72.1" +cc = "1.2.64" diff --git a/examples/c-code/README.md b/examples/c-code/README.md new file mode 100644 index 0000000..0a3baef --- /dev/null +++ b/examples/c-code/README.md @@ -0,0 +1,5 @@ +# Example C Code + +This folder contains some example C code, which the other examples will link against and call. + +This tests the EABI support in Rust/LLVM. diff --git a/examples/c-code/build.rs b/examples/c-code/build.rs new file mode 100644 index 0000000..2bf92c6 --- /dev/null +++ b/examples/c-code/build.rs @@ -0,0 +1,19 @@ +fn main() { + // Build the C code into libc_code.a + cc::Build::new().file("src/library.c").compile("c_code"); + // Ensure the C library isn't stale + println!("cargo:rerun-if-changed=src/library.c"); + println!("cargo:rerun-if-changed=src/library.h"); + // Make Rust bindings to library.h + let bindings = bindgen::Builder::default() + .header("src/library.h") + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) + .use_core() + .clang_arg("-fshort-enums") + .generate() + .expect("Unable to generate bindings"); + let out_path = std::path::PathBuf::from(std::env::var("OUT_DIR").unwrap()); + bindings + .write_to_file(out_path.join("bindings.rs")) + .expect("Couldn't write bindings.rs"); +} diff --git a/examples/c-code/src/lib.rs b/examples/c-code/src/lib.rs new file mode 100644 index 0000000..f43437e --- /dev/null +++ b/examples/c-code/src/lib.rs @@ -0,0 +1,5 @@ +#![no_std] +#![allow(non_camel_case_types)] +#![allow(non_upper_case_globals)] + +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); diff --git a/examples/c-code/src/library.c b/examples/c-code/src/library.c new file mode 100644 index 0000000..ec6d041 --- /dev/null +++ b/examples/c-code/src/library.c @@ -0,0 +1,98 @@ +/** +Example C functions for testing Rust/C integration. +*/ + +#include "library.h" + +char c_code_char_check(char x) { + return x + 1; +} + +signed char c_code_signed_char_check(signed char x) { + return x + 1; +} + +unsigned char c_code_unsigned_char_check(unsigned char x) { + return x + 1; +} + +short c_code_short_check(short x) { + return x + 1; +} + +unsigned short c_code_unsigned_short_check(unsigned short x) { + return x + 1; +} + +int c_code_int_check(int x) { + return x + 1; +} + +unsigned int c_code_unsigned_int_check(unsigned int x) { + return x + 1; +} + +long c_code_long_check(long x) { + return x + 1; +} + +unsigned long c_code_unsigned_long_check(unsigned long x) { + return x + 1; +} + +int* c_code_int_ptr_check(int* p) { + return p + 1; +} + +float c_code_float_check(float x) { + return x * 2.0; +} + +double c_code_double_check(double x) { + return x * 2.0; +} + +/* +The enum check function converts ITEM_ONE to ITEM_TWO, ITEM_TWO to ITEM_THREE and ITEM_THREE to ITEM_ONE. +*/ + +enum c_code_sample_enum_t c_code_enum_rotate(enum c_code_sample_enum_t x) { + if (x == ITEM_ONE) { + return ITEM_TWO; + } else if (x == ITEM_TWO) { + return ITEM_THREE; + } else { + return ITEM_ONE; + } +} + +struct c_code_data_t c_code_struct_check(struct c_code_data_t x) { + struct c_code_data_t result = { + .c = c_code_char_check(x.c), + .s = c_code_short_check(x.s), + .i = c_code_int_check(x.i), + .l = c_code_long_check(x.l), + .f = c_code_float_check(x.f), + .d = c_code_double_check(x.d), + .e = c_code_enum_rotate(x.e), + }; + return result; +} + +/* +This struct check function adds one to every field in the structure, by modifying the given structure. +*/ + +void c_code_struct_ref_check(struct c_code_data_t* p) { + p->c = c_code_char_check(p->c); + p->s = c_code_short_check(p->s); + p->i = c_code_int_check(p->i); + p->l = c_code_long_check(p->l); + p->f = c_code_float_check(p->f); + p->d = c_code_double_check(p->d); + p->e = c_code_enum_rotate(p->e); +} + +/* +End of file +*/ diff --git a/examples/c-code/src/library.h b/examples/c-code/src/library.h new file mode 100644 index 0000000..02084d0 --- /dev/null +++ b/examples/c-code/src/library.h @@ -0,0 +1,80 @@ +/** +Example C functions for testing Rust/C integration. + +All functions start with `c_code_`. +*/ + +/* +These types are used in the functions below +*/ + +enum c_code_sample_enum_t { + ITEM_ONE, + ITEM_TWO, + ITEM_THREE +}; + +struct c_code_data_t { + char c; + short s; + int i; + long l; + float f; + double d; + enum c_code_sample_enum_t e; +}; + +/* +These integer `c_code_xxx_check` functions take a value and return `value + 1`. +*/ + +char c_code_char_check(char x); +signed char c_code_signed_char_check(signed char x); +unsigned char c_code_unsigned_char_check(unsigned char x); +short c_code_short_check(short x); +unsigned short c_code_unsigned_short_check(unsigned short x); +int c_code_int_check(int x); +unsigned int c_code_unsigned_int_check(unsigned int x); +long c_code_long_check(long x); +unsigned long c_code_unsigned_long_check(unsigned long x); + +/* +This pointer check function takes a pointer to two ints, and returns a pointer to the second. + +If passed NULL, it returns NULL. + +If passed a pointer to one int, the result is undefined. +*/ + +int* c_code_int_ptr_check(int* p); + +/* +These floating-point `c_code_xxx_check` functions take a value and return `value * 2.0`. +*/ + +float c_code_float_check(float x); +double c_code_double_check(double x); + +/* +The enum check function converts ITEM_ONE to ITEM_TWO, ITEM_TWO to ITEM_THREE and ITEM_THREE to ITEM_ONE. +*/ + +enum c_code_sample_enum_t c_code_enum_rotate(enum c_code_sample_enum_t x); + +/* +This struct check function adds one to every field in the structure, and returns a new structure. +*/ + + + +struct c_code_data_t c_code_struct_check(struct c_code_data_t x); + +/* +This struct check function adds one to every field in the structure, by modifying the given structure. +*/ + +void c_code_struct_ref_check(struct c_code_data_t* p); + +/* +End of file +*/ diff --git a/examples/mps3-an536-el2/build.rs b/examples/mps3-an536-el2/build.rs index b0b9f09..0ae5789 100644 --- a/examples/mps3-an536-el2/build.rs +++ b/examples/mps3-an536-el2/build.rs @@ -9,7 +9,7 @@ use std::io::Write; fn main() { arm_targets::process(); write("memory.x", include_bytes!("memory.x")); - // Use the cortex-m-rt linker script + // Use the aarch32-rt linker script println!("cargo:rustc-link-arg=-Tlink.x"); } diff --git a/examples/mps3-an536-smp/build.rs b/examples/mps3-an536-smp/build.rs index b0b9f09..0ae5789 100644 --- a/examples/mps3-an536-smp/build.rs +++ b/examples/mps3-an536-smp/build.rs @@ -9,7 +9,7 @@ use std::io::Write; fn main() { arm_targets::process(); write("memory.x", include_bytes!("memory.x")); - // Use the cortex-m-rt linker script + // Use the aarch32-rt linker script println!("cargo:rustc-link-arg=-Tlink.x"); } diff --git a/examples/mps3-an536/Cargo.toml b/examples/mps3-an536/Cargo.toml index 835f500..c02c6ba 100644 --- a/examples/mps3-an536/Cargo.toml +++ b/examples/mps3-an536/Cargo.toml @@ -18,6 +18,7 @@ version = "0.0.0" aarch32-cpu = { path = "../../aarch32-cpu", features = ["critical-section-multi-core"] } aarch32-rt = { path = "../../aarch32-rt" } arm-gic = "0.8.1" +c-code = { version = "0.1.0", path = "../c-code" } critical-section = "1.2.0" heapless = "0.9.1" libm = "0.2.15" diff --git a/examples/mps3-an536/build.rs b/examples/mps3-an536/build.rs index b0b9f09..0ae5789 100644 --- a/examples/mps3-an536/build.rs +++ b/examples/mps3-an536/build.rs @@ -9,7 +9,7 @@ use std::io::Write; fn main() { arm_targets::process(); write("memory.x", include_bytes!("memory.x")); - // Use the cortex-m-rt linker script + // Use the aarch32-rt linker script println!("cargo:rustc-link-arg=-Tlink.x"); } diff --git a/examples/mps3-an536/reference/c_test-armv8r-none-eabihf.out b/examples/mps3-an536/reference/c_test-armv8r-none-eabihf.out new file mode 100644 index 0000000..4c625b6 --- /dev/null +++ b/examples/mps3-an536/reference/c_test-armv8r-none-eabihf.out @@ -0,0 +1,15 @@ +c_code_char_check(p) -> 2 +c_code_unsigned_char_check(p) -> 2 +c_code_signed_char_check(p) -> 2 +c_code_short_check(p) -> 2 +c_code_unsigned_short_check(p) -> 2 +c_code_int_check(p) -> 2 +c_code_unsigned_int_check(p) -> 2 +c_code_long_check(p) -> 2 +c_code_unsigned_long_check(p) -> 2 +c_code_int_ptr_check(p) -> 2 +c_code_float_check(p) -> 2 +c_code_double_check(p) -> 2 +data_in: c_code_data_t { c: 1, s: 1, i: 1, l: 1, f: 1.0, d: 1.0, e: 1 } +c_code_struct_check(data_in) -> c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } +called c_code_struct_ref_check, data_in is c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } diff --git a/examples/mps3-an536/reference/c_test-thumbv8r-none-eabihf.out b/examples/mps3-an536/reference/c_test-thumbv8r-none-eabihf.out new file mode 100644 index 0000000..4c625b6 --- /dev/null +++ b/examples/mps3-an536/reference/c_test-thumbv8r-none-eabihf.out @@ -0,0 +1,15 @@ +c_code_char_check(p) -> 2 +c_code_unsigned_char_check(p) -> 2 +c_code_signed_char_check(p) -> 2 +c_code_short_check(p) -> 2 +c_code_unsigned_short_check(p) -> 2 +c_code_int_check(p) -> 2 +c_code_unsigned_int_check(p) -> 2 +c_code_long_check(p) -> 2 +c_code_unsigned_long_check(p) -> 2 +c_code_int_ptr_check(p) -> 2 +c_code_float_check(p) -> 2 +c_code_double_check(p) -> 2 +data_in: c_code_data_t { c: 1, s: 1, i: 1, l: 1, f: 1.0, d: 1.0, e: 1 } +c_code_struct_check(data_in) -> c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } +called c_code_struct_ref_check, data_in is c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } diff --git a/examples/mps3-an536/src/bin/c_test.rs b/examples/mps3-an536/src/bin/c_test.rs new file mode 100644 index 0000000..ecbeac7 --- /dev/null +++ b/examples/mps3-an536/src/bin/c_test.rs @@ -0,0 +1,73 @@ +//! EABI checking example program + +#![no_std] +#![no_main] + +use aarch32_rt::entry; +use semihosting::println; + +use mps3_an536 as _; + +/// The entry-point to the Rust application. +/// +/// It is called by the start-up code in `aarch32-rt`. +#[entry] +fn main() -> ! { + println!("c_code_char_check(p) -> {}", unsafe { + c_code::c_code_char_check(1) + }); + println!("c_code_unsigned_char_check(p) -> {}", unsafe { + c_code::c_code_unsigned_char_check(1) + }); + println!("c_code_signed_char_check(p) -> {}", unsafe { + c_code::c_code_signed_char_check(1) + }); + println!("c_code_short_check(p) -> {}", unsafe { + c_code::c_code_short_check(1) + }); + println!("c_code_unsigned_short_check(p) -> {}", unsafe { + c_code::c_code_unsigned_short_check(1) + }); + println!("c_code_int_check(p) -> {}", unsafe { + c_code::c_code_int_check(1) + }); + println!("c_code_unsigned_int_check(p) -> {}", unsafe { + c_code::c_code_unsigned_int_check(1) + }); + println!("c_code_long_check(p) -> {}", unsafe { + c_code::c_code_long_check(1) + }); + println!("c_code_unsigned_long_check(p) -> {}", unsafe { + c_code::c_code_unsigned_long_check(1) + }); + let mut integers = [1, 2]; + println!("c_code_int_ptr_check(p) -> {}", unsafe { + *c_code::c_code_int_ptr_check(integers.as_mut_ptr()) + }); + println!("c_code_float_check(p) -> {}", unsafe { + c_code::c_code_float_check(1.0) + }); + println!("c_code_double_check(p) -> {}", unsafe { + c_code::c_code_double_check(1.0) + }); + + let mut data_in = c_code::c_code_data_t { + c: 1, + s: 1, + i: 1, + l: 1, + f: 1.0, + d: 1.0, + e: c_code::c_code_sample_enum_t_ITEM_TWO, + }; + println!("data_in: {:x?}", data_in); + + println!("c_code_struct_check(data_in) -> {:x?}", unsafe { + c_code::c_code_struct_check(data_in) + }); + + unsafe { c_code::c_code_struct_ref_check(&mut data_in) }; + println!("called c_code_struct_ref_check, data_in is {:x?}", data_in); + + mps3_an536::exit(0); +} diff --git a/examples/versatileab/Cargo.toml b/examples/versatileab/Cargo.toml index d46ab1b..e673784 100644 --- a/examples/versatileab/Cargo.toml +++ b/examples/versatileab/Cargo.toml @@ -18,6 +18,7 @@ version = "0.0.0" aarch32-cpu = { path = "../../aarch32-cpu", features = ["critical-section-single-core"] } aarch32-rt = { path = "../../aarch32-rt" } arbitrary-int = "2.1.1" +c-code = { version = "0.1.0", path = "../c-code" } derive-mmio = "0.6.1" libm = "0.2.15" pl190-vic = "0.1.2" diff --git a/examples/versatileab/build.rs b/examples/versatileab/build.rs index 7871f45..ef2fdad 100644 --- a/examples/versatileab/build.rs +++ b/examples/versatileab/build.rs @@ -9,7 +9,7 @@ use std::io::Write; fn main() { arm_targets::process(); write("memory.x", include_bytes!("memory.x")); - // Use the cortex-m-rt linker script + // Use the aarch32-rt linker script println!("cargo:rustc-link-arg=-Tlink.x"); } diff --git a/examples/versatileab/reference/c_test-armv4t-none-eabi.out b/examples/versatileab/reference/c_test-armv4t-none-eabi.out new file mode 100644 index 0000000..4c625b6 --- /dev/null +++ b/examples/versatileab/reference/c_test-armv4t-none-eabi.out @@ -0,0 +1,15 @@ +c_code_char_check(p) -> 2 +c_code_unsigned_char_check(p) -> 2 +c_code_signed_char_check(p) -> 2 +c_code_short_check(p) -> 2 +c_code_unsigned_short_check(p) -> 2 +c_code_int_check(p) -> 2 +c_code_unsigned_int_check(p) -> 2 +c_code_long_check(p) -> 2 +c_code_unsigned_long_check(p) -> 2 +c_code_int_ptr_check(p) -> 2 +c_code_float_check(p) -> 2 +c_code_double_check(p) -> 2 +data_in: c_code_data_t { c: 1, s: 1, i: 1, l: 1, f: 1.0, d: 1.0, e: 1 } +c_code_struct_check(data_in) -> c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } +called c_code_struct_ref_check, data_in is c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } diff --git a/examples/versatileab/reference/c_test-armv5te-none-eabi.out b/examples/versatileab/reference/c_test-armv5te-none-eabi.out new file mode 100644 index 0000000..4c625b6 --- /dev/null +++ b/examples/versatileab/reference/c_test-armv5te-none-eabi.out @@ -0,0 +1,15 @@ +c_code_char_check(p) -> 2 +c_code_unsigned_char_check(p) -> 2 +c_code_signed_char_check(p) -> 2 +c_code_short_check(p) -> 2 +c_code_unsigned_short_check(p) -> 2 +c_code_int_check(p) -> 2 +c_code_unsigned_int_check(p) -> 2 +c_code_long_check(p) -> 2 +c_code_unsigned_long_check(p) -> 2 +c_code_int_ptr_check(p) -> 2 +c_code_float_check(p) -> 2 +c_code_double_check(p) -> 2 +data_in: c_code_data_t { c: 1, s: 1, i: 1, l: 1, f: 1.0, d: 1.0, e: 1 } +c_code_struct_check(data_in) -> c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } +called c_code_struct_ref_check, data_in is c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } diff --git a/examples/versatileab/reference/c_test-armv6-none-eabi.out b/examples/versatileab/reference/c_test-armv6-none-eabi.out new file mode 100644 index 0000000..4c625b6 --- /dev/null +++ b/examples/versatileab/reference/c_test-armv6-none-eabi.out @@ -0,0 +1,15 @@ +c_code_char_check(p) -> 2 +c_code_unsigned_char_check(p) -> 2 +c_code_signed_char_check(p) -> 2 +c_code_short_check(p) -> 2 +c_code_unsigned_short_check(p) -> 2 +c_code_int_check(p) -> 2 +c_code_unsigned_int_check(p) -> 2 +c_code_long_check(p) -> 2 +c_code_unsigned_long_check(p) -> 2 +c_code_int_ptr_check(p) -> 2 +c_code_float_check(p) -> 2 +c_code_double_check(p) -> 2 +data_in: c_code_data_t { c: 1, s: 1, i: 1, l: 1, f: 1.0, d: 1.0, e: 1 } +c_code_struct_check(data_in) -> c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } +called c_code_struct_ref_check, data_in is c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } diff --git a/examples/versatileab/reference/c_test-armv6-none-eabihf.out b/examples/versatileab/reference/c_test-armv6-none-eabihf.out new file mode 100644 index 0000000..4c625b6 --- /dev/null +++ b/examples/versatileab/reference/c_test-armv6-none-eabihf.out @@ -0,0 +1,15 @@ +c_code_char_check(p) -> 2 +c_code_unsigned_char_check(p) -> 2 +c_code_signed_char_check(p) -> 2 +c_code_short_check(p) -> 2 +c_code_unsigned_short_check(p) -> 2 +c_code_int_check(p) -> 2 +c_code_unsigned_int_check(p) -> 2 +c_code_long_check(p) -> 2 +c_code_unsigned_long_check(p) -> 2 +c_code_int_ptr_check(p) -> 2 +c_code_float_check(p) -> 2 +c_code_double_check(p) -> 2 +data_in: c_code_data_t { c: 1, s: 1, i: 1, l: 1, f: 1.0, d: 1.0, e: 1 } +c_code_struct_check(data_in) -> c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } +called c_code_struct_ref_check, data_in is c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } diff --git a/examples/versatileab/reference/c_test-armv7a-none-eabi.out b/examples/versatileab/reference/c_test-armv7a-none-eabi.out new file mode 100644 index 0000000..4c625b6 --- /dev/null +++ b/examples/versatileab/reference/c_test-armv7a-none-eabi.out @@ -0,0 +1,15 @@ +c_code_char_check(p) -> 2 +c_code_unsigned_char_check(p) -> 2 +c_code_signed_char_check(p) -> 2 +c_code_short_check(p) -> 2 +c_code_unsigned_short_check(p) -> 2 +c_code_int_check(p) -> 2 +c_code_unsigned_int_check(p) -> 2 +c_code_long_check(p) -> 2 +c_code_unsigned_long_check(p) -> 2 +c_code_int_ptr_check(p) -> 2 +c_code_float_check(p) -> 2 +c_code_double_check(p) -> 2 +data_in: c_code_data_t { c: 1, s: 1, i: 1, l: 1, f: 1.0, d: 1.0, e: 1 } +c_code_struct_check(data_in) -> c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } +called c_code_struct_ref_check, data_in is c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } diff --git a/examples/versatileab/reference/c_test-armv7a-none-eabihf.out b/examples/versatileab/reference/c_test-armv7a-none-eabihf.out new file mode 100644 index 0000000..4c625b6 --- /dev/null +++ b/examples/versatileab/reference/c_test-armv7a-none-eabihf.out @@ -0,0 +1,15 @@ +c_code_char_check(p) -> 2 +c_code_unsigned_char_check(p) -> 2 +c_code_signed_char_check(p) -> 2 +c_code_short_check(p) -> 2 +c_code_unsigned_short_check(p) -> 2 +c_code_int_check(p) -> 2 +c_code_unsigned_int_check(p) -> 2 +c_code_long_check(p) -> 2 +c_code_unsigned_long_check(p) -> 2 +c_code_int_ptr_check(p) -> 2 +c_code_float_check(p) -> 2 +c_code_double_check(p) -> 2 +data_in: c_code_data_t { c: 1, s: 1, i: 1, l: 1, f: 1.0, d: 1.0, e: 1 } +c_code_struct_check(data_in) -> c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } +called c_code_struct_ref_check, data_in is c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } diff --git a/examples/versatileab/reference/c_test-armv7r-none-eabi.out b/examples/versatileab/reference/c_test-armv7r-none-eabi.out new file mode 100644 index 0000000..4c625b6 --- /dev/null +++ b/examples/versatileab/reference/c_test-armv7r-none-eabi.out @@ -0,0 +1,15 @@ +c_code_char_check(p) -> 2 +c_code_unsigned_char_check(p) -> 2 +c_code_signed_char_check(p) -> 2 +c_code_short_check(p) -> 2 +c_code_unsigned_short_check(p) -> 2 +c_code_int_check(p) -> 2 +c_code_unsigned_int_check(p) -> 2 +c_code_long_check(p) -> 2 +c_code_unsigned_long_check(p) -> 2 +c_code_int_ptr_check(p) -> 2 +c_code_float_check(p) -> 2 +c_code_double_check(p) -> 2 +data_in: c_code_data_t { c: 1, s: 1, i: 1, l: 1, f: 1.0, d: 1.0, e: 1 } +c_code_struct_check(data_in) -> c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } +called c_code_struct_ref_check, data_in is c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } diff --git a/examples/versatileab/reference/c_test-armv7r-none-eabihf.out b/examples/versatileab/reference/c_test-armv7r-none-eabihf.out new file mode 100644 index 0000000..4c625b6 --- /dev/null +++ b/examples/versatileab/reference/c_test-armv7r-none-eabihf.out @@ -0,0 +1,15 @@ +c_code_char_check(p) -> 2 +c_code_unsigned_char_check(p) -> 2 +c_code_signed_char_check(p) -> 2 +c_code_short_check(p) -> 2 +c_code_unsigned_short_check(p) -> 2 +c_code_int_check(p) -> 2 +c_code_unsigned_int_check(p) -> 2 +c_code_long_check(p) -> 2 +c_code_unsigned_long_check(p) -> 2 +c_code_int_ptr_check(p) -> 2 +c_code_float_check(p) -> 2 +c_code_double_check(p) -> 2 +data_in: c_code_data_t { c: 1, s: 1, i: 1, l: 1, f: 1.0, d: 1.0, e: 1 } +c_code_struct_check(data_in) -> c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } +called c_code_struct_ref_check, data_in is c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } diff --git a/examples/versatileab/reference/c_test-thumbv4t-none-eabi.out b/examples/versatileab/reference/c_test-thumbv4t-none-eabi.out new file mode 100644 index 0000000..4c625b6 --- /dev/null +++ b/examples/versatileab/reference/c_test-thumbv4t-none-eabi.out @@ -0,0 +1,15 @@ +c_code_char_check(p) -> 2 +c_code_unsigned_char_check(p) -> 2 +c_code_signed_char_check(p) -> 2 +c_code_short_check(p) -> 2 +c_code_unsigned_short_check(p) -> 2 +c_code_int_check(p) -> 2 +c_code_unsigned_int_check(p) -> 2 +c_code_long_check(p) -> 2 +c_code_unsigned_long_check(p) -> 2 +c_code_int_ptr_check(p) -> 2 +c_code_float_check(p) -> 2 +c_code_double_check(p) -> 2 +data_in: c_code_data_t { c: 1, s: 1, i: 1, l: 1, f: 1.0, d: 1.0, e: 1 } +c_code_struct_check(data_in) -> c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } +called c_code_struct_ref_check, data_in is c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } diff --git a/examples/versatileab/reference/c_test-thumbv5te-none-eabi.out b/examples/versatileab/reference/c_test-thumbv5te-none-eabi.out new file mode 100644 index 0000000..4c625b6 --- /dev/null +++ b/examples/versatileab/reference/c_test-thumbv5te-none-eabi.out @@ -0,0 +1,15 @@ +c_code_char_check(p) -> 2 +c_code_unsigned_char_check(p) -> 2 +c_code_signed_char_check(p) -> 2 +c_code_short_check(p) -> 2 +c_code_unsigned_short_check(p) -> 2 +c_code_int_check(p) -> 2 +c_code_unsigned_int_check(p) -> 2 +c_code_long_check(p) -> 2 +c_code_unsigned_long_check(p) -> 2 +c_code_int_ptr_check(p) -> 2 +c_code_float_check(p) -> 2 +c_code_double_check(p) -> 2 +data_in: c_code_data_t { c: 1, s: 1, i: 1, l: 1, f: 1.0, d: 1.0, e: 1 } +c_code_struct_check(data_in) -> c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } +called c_code_struct_ref_check, data_in is c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } diff --git a/examples/versatileab/reference/c_test-thumbv6-none-eabi.out b/examples/versatileab/reference/c_test-thumbv6-none-eabi.out new file mode 100644 index 0000000..4c625b6 --- /dev/null +++ b/examples/versatileab/reference/c_test-thumbv6-none-eabi.out @@ -0,0 +1,15 @@ +c_code_char_check(p) -> 2 +c_code_unsigned_char_check(p) -> 2 +c_code_signed_char_check(p) -> 2 +c_code_short_check(p) -> 2 +c_code_unsigned_short_check(p) -> 2 +c_code_int_check(p) -> 2 +c_code_unsigned_int_check(p) -> 2 +c_code_long_check(p) -> 2 +c_code_unsigned_long_check(p) -> 2 +c_code_int_ptr_check(p) -> 2 +c_code_float_check(p) -> 2 +c_code_double_check(p) -> 2 +data_in: c_code_data_t { c: 1, s: 1, i: 1, l: 1, f: 1.0, d: 1.0, e: 1 } +c_code_struct_check(data_in) -> c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } +called c_code_struct_ref_check, data_in is c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } diff --git a/examples/versatileab/reference/c_test-thumbv7a-none-eabi.out b/examples/versatileab/reference/c_test-thumbv7a-none-eabi.out new file mode 100644 index 0000000..4c625b6 --- /dev/null +++ b/examples/versatileab/reference/c_test-thumbv7a-none-eabi.out @@ -0,0 +1,15 @@ +c_code_char_check(p) -> 2 +c_code_unsigned_char_check(p) -> 2 +c_code_signed_char_check(p) -> 2 +c_code_short_check(p) -> 2 +c_code_unsigned_short_check(p) -> 2 +c_code_int_check(p) -> 2 +c_code_unsigned_int_check(p) -> 2 +c_code_long_check(p) -> 2 +c_code_unsigned_long_check(p) -> 2 +c_code_int_ptr_check(p) -> 2 +c_code_float_check(p) -> 2 +c_code_double_check(p) -> 2 +data_in: c_code_data_t { c: 1, s: 1, i: 1, l: 1, f: 1.0, d: 1.0, e: 1 } +c_code_struct_check(data_in) -> c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } +called c_code_struct_ref_check, data_in is c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } diff --git a/examples/versatileab/reference/c_test-thumbv7a-none-eabihf.out b/examples/versatileab/reference/c_test-thumbv7a-none-eabihf.out new file mode 100644 index 0000000..4c625b6 --- /dev/null +++ b/examples/versatileab/reference/c_test-thumbv7a-none-eabihf.out @@ -0,0 +1,15 @@ +c_code_char_check(p) -> 2 +c_code_unsigned_char_check(p) -> 2 +c_code_signed_char_check(p) -> 2 +c_code_short_check(p) -> 2 +c_code_unsigned_short_check(p) -> 2 +c_code_int_check(p) -> 2 +c_code_unsigned_int_check(p) -> 2 +c_code_long_check(p) -> 2 +c_code_unsigned_long_check(p) -> 2 +c_code_int_ptr_check(p) -> 2 +c_code_float_check(p) -> 2 +c_code_double_check(p) -> 2 +data_in: c_code_data_t { c: 1, s: 1, i: 1, l: 1, f: 1.0, d: 1.0, e: 1 } +c_code_struct_check(data_in) -> c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } +called c_code_struct_ref_check, data_in is c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } diff --git a/examples/versatileab/reference/c_test-thumbv7r-none-eabi.out b/examples/versatileab/reference/c_test-thumbv7r-none-eabi.out new file mode 100644 index 0000000..4c625b6 --- /dev/null +++ b/examples/versatileab/reference/c_test-thumbv7r-none-eabi.out @@ -0,0 +1,15 @@ +c_code_char_check(p) -> 2 +c_code_unsigned_char_check(p) -> 2 +c_code_signed_char_check(p) -> 2 +c_code_short_check(p) -> 2 +c_code_unsigned_short_check(p) -> 2 +c_code_int_check(p) -> 2 +c_code_unsigned_int_check(p) -> 2 +c_code_long_check(p) -> 2 +c_code_unsigned_long_check(p) -> 2 +c_code_int_ptr_check(p) -> 2 +c_code_float_check(p) -> 2 +c_code_double_check(p) -> 2 +data_in: c_code_data_t { c: 1, s: 1, i: 1, l: 1, f: 1.0, d: 1.0, e: 1 } +c_code_struct_check(data_in) -> c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } +called c_code_struct_ref_check, data_in is c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } diff --git a/examples/versatileab/reference/c_test-thumbv7r-none-eabihf.out b/examples/versatileab/reference/c_test-thumbv7r-none-eabihf.out new file mode 100644 index 0000000..4c625b6 --- /dev/null +++ b/examples/versatileab/reference/c_test-thumbv7r-none-eabihf.out @@ -0,0 +1,15 @@ +c_code_char_check(p) -> 2 +c_code_unsigned_char_check(p) -> 2 +c_code_signed_char_check(p) -> 2 +c_code_short_check(p) -> 2 +c_code_unsigned_short_check(p) -> 2 +c_code_int_check(p) -> 2 +c_code_unsigned_int_check(p) -> 2 +c_code_long_check(p) -> 2 +c_code_unsigned_long_check(p) -> 2 +c_code_int_ptr_check(p) -> 2 +c_code_float_check(p) -> 2 +c_code_double_check(p) -> 2 +data_in: c_code_data_t { c: 1, s: 1, i: 1, l: 1, f: 1.0, d: 1.0, e: 1 } +c_code_struct_check(data_in) -> c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } +called c_code_struct_ref_check, data_in is c_code_data_t { c: 2, s: 2, i: 2, l: 2, f: 2.0, d: 2.0, e: 2 } diff --git a/examples/versatileab/src/bin/c_test.rs b/examples/versatileab/src/bin/c_test.rs new file mode 100644 index 0000000..84c4dc8 --- /dev/null +++ b/examples/versatileab/src/bin/c_test.rs @@ -0,0 +1,73 @@ +//! EABI checking example program + +#![no_std] +#![no_main] + +use aarch32_rt::entry; +use semihosting::println; +use versatileab as _; + +/// The entry-point to the Rust application. +/// +/// It is called by the start-up. +#[entry] +fn my_main() -> ! { + versatileab::init(); + println!("c_code_char_check(p) -> {}", unsafe { + c_code::c_code_char_check(1) + }); + println!("c_code_unsigned_char_check(p) -> {}", unsafe { + c_code::c_code_unsigned_char_check(1) + }); + println!("c_code_signed_char_check(p) -> {}", unsafe { + c_code::c_code_signed_char_check(1) + }); + println!("c_code_short_check(p) -> {}", unsafe { + c_code::c_code_short_check(1) + }); + println!("c_code_unsigned_short_check(p) -> {}", unsafe { + c_code::c_code_unsigned_short_check(1) + }); + println!("c_code_int_check(p) -> {}", unsafe { + c_code::c_code_int_check(1) + }); + println!("c_code_unsigned_int_check(p) -> {}", unsafe { + c_code::c_code_unsigned_int_check(1) + }); + println!("c_code_long_check(p) -> {}", unsafe { + c_code::c_code_long_check(1) + }); + println!("c_code_unsigned_long_check(p) -> {}", unsafe { + c_code::c_code_unsigned_long_check(1) + }); + let mut integers = [1, 2]; + println!("c_code_int_ptr_check(p) -> {}", unsafe { + *c_code::c_code_int_ptr_check(integers.as_mut_ptr()) + }); + println!("c_code_float_check(p) -> {}", unsafe { + c_code::c_code_float_check(1.0) + }); + println!("c_code_double_check(p) -> {}", unsafe { + c_code::c_code_double_check(1.0) + }); + + let mut data_in = c_code::c_code_data_t { + c: 1, + s: 1, + i: 1, + l: 1, + f: 1.0, + d: 1.0, + e: c_code::c_code_sample_enum_t_ITEM_TWO, + }; + println!("data_in: {:x?}", data_in); + + println!("c_code_struct_check(data_in) -> {:x?}", unsafe { + c_code::c_code_struct_check(data_in) + }); + + unsafe { c_code::c_code_struct_ref_check(&mut data_in) }; + println!("called c_code_struct_ref_check, data_in is {:x?}", data_in); + + versatileab::exit(0); +}