From 0827ad0216c804f1a610297c38dcb9802c077b52 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Thu, 27 Oct 2022 04:59:44 +0100 Subject: [PATCH] rust: replace `__aeabi_uldivmod` stub with actual implementation Rust's libcore genuinely needs 64-bit division for formatting, but we can't change these to use kernel's division routine; so `__aeabi_uldivmod` calls will be generated. Instead of redirecting these calls to a panicking stub, forward them to `div64_u64_rem`. Signed-off-by: Gary Guo --- rust/compiler_builtins.rs | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/rust/compiler_builtins.rs b/rust/compiler_builtins.rs index 59e70aea99cdd9..5165d43b758104 100644 --- a/rust/compiler_builtins.rs +++ b/rust/compiler_builtins.rs @@ -20,6 +20,7 @@ //! [`compiler-rt`]: https://compiler-rt.llvm.org/ #![feature(compiler_builtins)] +#![feature(naked_functions)] #![compiler_builtins] #![no_builtins] #![no_std] @@ -74,6 +75,24 @@ define_panicking_intrinsics!("`f64` should not be used", { }); #[cfg(target_arch = "arm")] -define_panicking_intrinsics!("`u64` division/modulo should not be used", { - __aeabi_uldivmod, -}); +#[doc(hidden)] +#[naked] +#[no_mangle] +pub unsafe extern "C" fn rust_aeabi_uldivmod() { + // Adapted from compiler-rt: + // https://github.com/llvm/llvm-project/blob/a80e65e00ada7a9c16acf17a5fd40b4f12ced3a8/compiler-rt/lib/builtins/arm/aeabi_uldivmod.S + unsafe { + core::arch::asm!( + "push {{r6, lr}}", + "sub sp, sp, #16", + "add r6, sp, #8", + "str r6, [sp]", + "bl div64_u64_rem", + "ldr r2, [sp, #8]", + "ldr r3, [sp, #12]", + "add sp, sp, #16", + "pop {{r6, pc}}", + options(noreturn) + ); + } +}