Skip to content

Commit

Permalink
Merge pull request #17 from Starry-OS/guoweikang/aarch64_vfp_fix
Browse files Browse the repository at this point in the history
Guoweikang/aarch64 vfp fix for #16
  • Loading branch information
Azure-stars authored Jul 31, 2024
2 parents 5642cdd + aba94e9 commit a8a3df3
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 44 deletions.
6 changes: 1 addition & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,7 @@ ifeq ($(ARCH), x86_64)
else ifeq ($(ARCH), riscv64)
TARGET := riscv64gc-unknown-none-elf
else ifeq ($(ARCH), aarch64)
ifeq ($(findstring fp_simd,$(FEATURES)),)
TARGET := aarch64-unknown-none-softfloat
else
TARGET := aarch64-unknown-none
endif
TARGET := aarch64-unknown-none-softfloat
endif

export AX_ARCH=$(ARCH)
Expand Down
42 changes: 42 additions & 0 deletions tools/axlibc/build.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
use std::env;
use std::process::Command;
use std::path::PathBuf;

fn main() {
fn gen_c_to_rust_bindings(in_file: &str, out_file: &str) {
println!("cargo:rerun-if-changed={in_file}");
Expand All @@ -21,4 +25,42 @@ fn main() {
}

gen_c_to_rust_bindings("ctypes.h", "src/libctypes_gen.rs");

let arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap();
if arch == "aarch64" {
aarch64_vfp_compile();
}
}

fn aarch64_vfp_compile() {
// 获取当前 crate 输出目录
let out_dir = env::var("OUT_DIR").unwrap();
// 指定汇编文件路径
let asm_file = PathBuf::from("src/vfp_setjmp.S");
let asm_out_file = PathBuf::from(&out_dir).join("vfp_setjmp.o");

// 编译汇编文件,增加 target-feature 选项
let status = Command::new("clang")
.args(&[
"-c", asm_file.to_str().unwrap(),
"-o", asm_out_file.to_str().unwrap(),
"-target", "aarch64-unknown-none",
"-mfpu=neon"
])
.status()
.expect("failed to execute clang");
assert!(status.success(), "clang failed to compile assembly file");

// 打包对象文件为静态库
let lib_out_file = PathBuf::from(&out_dir).join("libvfp_setjmp.a");
let status = Command::new("ar")
.args(&["crus", lib_out_file.to_str().unwrap(), asm_out_file.to_str().unwrap()])
.status()
.expect("failed to execute ar");
assert!(status.success(), "ar failed to create static library");

// 指示 rustc 链接器链接汇编对象文件
println!("cargo:rerun-if-changed=src/vfp_setjmp.S");
println!("cargo:rustc-link-search={}", out_dir);
println!("cargo:rustc-link-lib=static=vfp_setjmp");
}
59 changes: 20 additions & 39 deletions tools/axlibc/src/setjmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,23 @@ use core::ffi::c_int;

use crate::ctypes;

#[cfg(all(target_arch = "aarch64", feature = "fp_simd"))]
extern "C" {
fn vfp_setjmp(buf: *mut ctypes::__jmp_buf_tag);
fn vfp_longjmp(buf: *mut ctypes::__jmp_buf_tag, _val: c_int) -> !;
}

#[cfg(all(target_arch = "aarch64", feature = "fp_simd"))]
#[no_mangle]
pub unsafe extern "C" fn setjmp(_buf: *mut ctypes::__jmp_buf_tag) {
vfp_setjmp(_buf);
}

/// `setjmp` implementation
#[cfg(all(not(target_arch = "aarch64"), not(feature = "fp_simd")))]
#[naked]
#[no_mangle]
pub unsafe extern "C" fn setjmp(_buf: *mut ctypes::__jmp_buf_tag) {
#[cfg(all(target_arch = "aarch64", feature = "fp_simd"))]
core::arch::asm!(
"
stp x19, x20, [x0,#0]
stp x21, x22, [x0,#16]
stp x23, x24, [x0,#32]
stp x25, x26, [x0,#48]
stp x27, x28, [x0,#64]
stp x29, x30, [x0,#80]
mov x2, sp
str x2, [x0,#104]
stp d8, d9, [x0,#112]
stp d10, d11, [x0,#128]
stp d12, d13, [x0,#144]
stp d14, d15, [x0,#160]
mov x0, #0
ret",
options(noreturn),
);
#[cfg(all(target_arch = "aarch64", not(feature = "fp_simd")))]
core::arch::asm!(
"
Expand Down Expand Up @@ -119,30 +113,17 @@ pub unsafe extern "C" fn setjmp(_buf: *mut ctypes::__jmp_buf_tag) {
core::arch::asm!("ret", options(noreturn))
}

#[cfg(all(target_arch = "aarch64", feature = "fp_simd"))]
#[no_mangle]
pub unsafe extern "C" fn longjmp(_buf: *mut ctypes::__jmp_buf_tag, _val: c_int) {
vfp_longjmp(_buf, _val);
}

/// `longjmp` implementation
#[cfg(all(not(target_arch = "aarch64"), not(feature = "fp_simd")))]
#[naked]
#[no_mangle]
pub unsafe extern "C" fn longjmp(_buf: *mut ctypes::__jmp_buf_tag, _val: c_int) -> ! {
#[cfg(all(target_arch = "aarch64", feature = "fp_simd"))]
core::arch::asm!(
"ldp x19, x20, [x0,#0]
ldp x21, x22, [x0,#16]
ldp x23, x24, [x0,#32]
ldp x25, x26, [x0,#48]
ldp x27, x28, [x0,#64]
ldp x29, x30, [x0,#80]
ldr x2, [x0,#104]
mov sp, x2
ldp d8 , d9, [x0,#112]
ldp d10, d11, [x0,#128]
ldp d12, d13, [x0,#144]
ldp d14, d15, [x0,#160]
cmp w1, 0
csinc w0, w1, wzr, ne
br x30",
options(noreturn),
);
#[cfg(all(target_arch = "aarch64", not(feature = "fp_simd")))]
core::arch::asm!(
"ldp x19, x20, [x0,#0]
Expand Down
37 changes: 37 additions & 0 deletions tools/axlibc/src/vfp_setjmp.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
.section .text
.global vfp_setjmp
vfp_setjmp:
stp x19, x20, [x0,#0]
stp x21, x22, [x0,#16]
stp x23, x24, [x0,#32]
stp x25, x26, [x0,#48]
stp x27, x28, [x0,#64]
stp x29, x30, [x0,#80]
mov x2, sp
str x2, [x0,#104]
stp d8, d9, [x0,#112]
stp d10, d11, [x0,#128]
stp d12, d13, [x0,#144]
stp d14, d15, [x0,#160]
mov x0, #0
ret

.section .text
.global vfp_longjmp
vfp_longjmp:
ldp x19, x20, [x0,#0]
ldp x21, x22, [x0,#16]
ldp x23, x24, [x0,#32]
ldp x25, x26, [x0,#48]
ldp x27, x28, [x0,#64]
ldp x29, x30, [x0,#80]
ldr x2, [x0,#104]
mov sp, x2
ldp d8 , d9, [x0,#112]
ldp d10, d11, [x0,#128]
ldp d12, d13, [x0,#144]
ldp d14, d15, [x0,#160]

cmp w1, 0
csinc w0, w1, wzr, ne
br x30

0 comments on commit a8a3df3

Please sign in to comment.