From b945767d46fdc26a64ac8bc7f4dcd3bfb50ce2e2 Mon Sep 17 00:00:00 2001 From: Johannes Stoelp Date: Mon, 2 May 2022 23:00:12 +0200 Subject: [PATCH 1/2] rv64 implement muldi3 intrinsic Implement the __muldi3 intrinsic to prevent infinite recursion during multiplication on rv64 without the 'm' extension. --- src/int/mul.rs | 1 + src/lib.rs | 4 ++-- src/{riscv32.rs => riscv.rs} | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) rename src/{riscv32.rs => riscv.rs} (54%) diff --git a/src/int/mul.rs b/src/int/mul.rs index a5238eeac..37eb03ec0 100644 --- a/src/int/mul.rs +++ b/src/int/mul.rs @@ -100,6 +100,7 @@ impl_signed_mulo!(i128_overflowing_mul, i128, u128); intrinsics! { #[maybe_use_optimized_c_shim] #[arm_aeabi_alias = __aeabi_lmul] + #[cfg(not(target_arch = "riscv64"))] pub extern "C" fn __muldi3(a: u64, b: u64) -> u64 { a.mul(b) } diff --git a/src/lib.rs b/src/lib.rs index 9ca72bc20..009923d27 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -60,8 +60,8 @@ pub mod arm; ))] pub mod arm_linux; -#[cfg(any(target_arch = "riscv32"))] -pub mod riscv32; +#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] +pub mod riscv; #[cfg(target_arch = "x86")] pub mod x86; diff --git a/src/riscv32.rs b/src/riscv.rs similarity index 54% rename from src/riscv32.rs rename to src/riscv.rs index 9a3c1714c..d9a65e200 100644 --- a/src/riscv32.rs +++ b/src/riscv.rs @@ -1,6 +1,7 @@ intrinsics! { // Implementation from gcc // https://raw.githubusercontent.com/gcc-mirror/gcc/master/libgcc/config/epiphany/mulsi3.c + #[cfg(target_arch = "riscv32")] pub extern "C" fn __mulsi3(a: u32, b: u32) -> u32 { let (mut a, mut b) = (a, b); let mut r = 0; @@ -15,4 +16,20 @@ intrinsics! { r } + + #[cfg(target_arch = "riscv64")] + pub extern "C" fn __muldi3(a: u64, b: u64) -> u64 { + let (mut a, mut b) = (a, b); + let mut r = 0; + + while a > 0 { + if a & 1 > 0 { + r += b; + } + a >>= 1; + b <<= 1; + } + + r + } } From 4baa36e2d49178fc4be7ae64c3a92d15f99585fa Mon Sep 17 00:00:00 2001 From: Johannes Stoelp Date: Thu, 12 May 2022 00:34:49 +0200 Subject: [PATCH 2/2] rv32 rv64: adapt conditional compilation Adapt conditional compilation as: rv32i : riscv:__mulsi3, riscv:__muldi3 rv32im: riscv:__mulsi3, int/mul:__muldi3 rv64i : riscv:__mulsi3, riscv:__muldi3 rv64im: riscv:__mulsi3, int/mul:__muldi3 --- src/int/mul.rs | 2 +- src/riscv.rs | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/int/mul.rs b/src/int/mul.rs index 37eb03ec0..07ce061c9 100644 --- a/src/int/mul.rs +++ b/src/int/mul.rs @@ -100,7 +100,7 @@ impl_signed_mulo!(i128_overflowing_mul, i128, u128); intrinsics! { #[maybe_use_optimized_c_shim] #[arm_aeabi_alias = __aeabi_lmul] - #[cfg(not(target_arch = "riscv64"))] + #[cfg(any(not(any(target_arch = "riscv32", target_arch = "riscv64")), target_feature = "m"))] pub extern "C" fn __muldi3(a: u64, b: u64) -> u64 { a.mul(b) } diff --git a/src/riscv.rs b/src/riscv.rs index d9a65e200..ee78b9dba 100644 --- a/src/riscv.rs +++ b/src/riscv.rs @@ -1,7 +1,6 @@ intrinsics! { // Implementation from gcc // https://raw.githubusercontent.com/gcc-mirror/gcc/master/libgcc/config/epiphany/mulsi3.c - #[cfg(target_arch = "riscv32")] pub extern "C" fn __mulsi3(a: u32, b: u32) -> u32 { let (mut a, mut b) = (a, b); let mut r = 0; @@ -17,7 +16,7 @@ intrinsics! { r } - #[cfg(target_arch = "riscv64")] + #[cfg(not(target_feature = "m"))] pub extern "C" fn __muldi3(a: u64, b: u64) -> u64 { let (mut a, mut b) = (a, b); let mut r = 0;