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) + ); + } +}