i128 mul intrinsics
This commit is contained in:
parent
b356429374
commit
3055aa21b6
@ -206,8 +206,8 @@ These builtins are needed to support 128-bit integers, which are in the process
|
|||||||
- [ ] floatuntisf.c
|
- [ ] floatuntisf.c
|
||||||
- [ ] lshrti3.c
|
- [ ] lshrti3.c
|
||||||
- [ ] modti3.c
|
- [ ] modti3.c
|
||||||
- [ ] muloti4.c
|
- [x] muloti4.c
|
||||||
- [ ] multi3.c
|
- [x] multi3.c
|
||||||
- [ ] udivmodti4.c
|
- [ ] udivmodti4.c
|
||||||
- [ ] udivti3.c
|
- [ ] udivti3.c
|
||||||
- [ ] umodti3.c
|
- [ ] umodti3.c
|
||||||
|
2
build.rs
2
build.rs
@ -150,7 +150,6 @@ fn main() {
|
|||||||
"int_util.c",
|
"int_util.c",
|
||||||
"muldc3.c",
|
"muldc3.c",
|
||||||
"muldf3.c",
|
"muldf3.c",
|
||||||
"muloti4.c",
|
|
||||||
"mulsc3.c",
|
"mulsc3.c",
|
||||||
"mulsf3.c",
|
"mulsf3.c",
|
||||||
"mulvdi3.c",
|
"mulvdi3.c",
|
||||||
@ -202,7 +201,6 @@ fn main() {
|
|||||||
"lshrti3.c",
|
"lshrti3.c",
|
||||||
"modti3.c",
|
"modti3.c",
|
||||||
"multf3.c",
|
"multf3.c",
|
||||||
"multi3.c",
|
|
||||||
"mulvti3.c",
|
"mulvti3.c",
|
||||||
"negti2.c",
|
"negti2.c",
|
||||||
"negvti2.c",
|
"negvti2.c",
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
#[cfg(not(all(feature = "c", target_arch = "x86")))]
|
|
||||||
use int::LargeInt;
|
use int::LargeInt;
|
||||||
use int::Int;
|
use int::Int;
|
||||||
|
|
||||||
macro_rules! mul {
|
macro_rules! mul {
|
||||||
($intrinsic:ident: $ty:ty) => {
|
($intrinsic:ident: $ty:ty, $tyh:ty) => {
|
||||||
/// Returns `a * b`
|
/// Returns `a * b`
|
||||||
#[cfg_attr(not(test), no_mangle)]
|
#[cfg_attr(not(test), no_mangle)]
|
||||||
pub extern "C" fn $intrinsic(a: $ty, b: $ty) -> $ty {
|
pub extern "C" fn $intrinsic(a: $ty, b: $ty) -> $ty {
|
||||||
@ -14,14 +13,15 @@ macro_rules! mul {
|
|||||||
low &= lower_mask;
|
low &= lower_mask;
|
||||||
t += (a.low() >> half_bits).wrapping_mul(b.low() & lower_mask);
|
t += (a.low() >> half_bits).wrapping_mul(b.low() & lower_mask);
|
||||||
low += (t & lower_mask) << half_bits;
|
low += (t & lower_mask) << half_bits;
|
||||||
let mut high = t >> half_bits;
|
let mut high = (t >> half_bits) as $tyh;
|
||||||
t = low >> half_bits;
|
t = low >> half_bits;
|
||||||
low &= lower_mask;
|
low &= lower_mask;
|
||||||
t += (b.low() >> half_bits).wrapping_mul(a.low() & lower_mask);
|
t += (b.low() >> half_bits).wrapping_mul(a.low() & lower_mask);
|
||||||
low += (t & lower_mask) << half_bits;
|
low += (t & lower_mask) << half_bits;
|
||||||
high += t >> half_bits;
|
high += (t >> half_bits) as $tyh;
|
||||||
high += (a.low() >> half_bits).wrapping_mul(b.low() >> half_bits);
|
high += (a.low() >> half_bits).wrapping_mul(b.low() >> half_bits) as $tyh;
|
||||||
high = high.wrapping_add(a.high().wrapping_mul(b.low()).wrapping_add(a.low().wrapping_mul(b.high())));
|
high = high.wrapping_add(a.high().wrapping_mul(b.low() as $tyh))
|
||||||
|
.wrapping_add((a.low() as $tyh).wrapping_mul(b.high()));
|
||||||
<$ty>::from_parts(low, high)
|
<$ty>::from_parts(low, high)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -29,9 +29,13 @@ macro_rules! mul {
|
|||||||
|
|
||||||
macro_rules! mulo {
|
macro_rules! mulo {
|
||||||
($intrinsic:ident: $ty:ty) => {
|
($intrinsic:ident: $ty:ty) => {
|
||||||
|
// Default is "C" ABI
|
||||||
|
mulo!($intrinsic: $ty, "C");
|
||||||
|
};
|
||||||
|
($intrinsic:ident: $ty:ty, $abi:tt) => {
|
||||||
/// Returns `a * b` and sets `*overflow = 1` if `a * b` overflows
|
/// Returns `a * b` and sets `*overflow = 1` if `a * b` overflows
|
||||||
#[cfg_attr(not(test), no_mangle)]
|
#[cfg_attr(not(test), no_mangle)]
|
||||||
pub extern "C" fn $intrinsic(a: $ty, b: $ty, overflow: &mut i32) -> $ty {
|
pub extern $abi fn $intrinsic(a: $ty, b: $ty, overflow: &mut i32) -> $ty {
|
||||||
*overflow = 0;
|
*overflow = 0;
|
||||||
let result = a.wrapping_mul(b);
|
let result = a.wrapping_mul(b);
|
||||||
if a == <$ty>::min_value() {
|
if a == <$ty>::min_value() {
|
||||||
@ -69,11 +73,18 @@ macro_rules! mulo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(all(feature = "c", target_arch = "x86")))]
|
#[cfg(not(all(feature = "c", target_arch = "x86")))]
|
||||||
mul!(__muldi3: u64);
|
mul!(__muldi3: u64, u32);
|
||||||
|
|
||||||
|
mul!(__multi3: i128, i64);
|
||||||
|
|
||||||
mulo!(__mulosi4: i32);
|
mulo!(__mulosi4: i32);
|
||||||
mulo!(__mulodi4: i64);
|
mulo!(__mulodi4: i64);
|
||||||
|
|
||||||
|
#[cfg(all(windows, target_pointer_width="64"))]
|
||||||
|
mulo!(__muloti4: i128, "unadjusted");
|
||||||
|
#[cfg(not(all(windows, target_pointer_width="64")))]
|
||||||
|
mulo!(__muloti4: i128);
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use qc::{I32, I64, U64};
|
use qc::{I32, I64, U64};
|
||||||
|
@ -14,6 +14,9 @@
|
|||||||
#![feature(naked_functions)]
|
#![feature(naked_functions)]
|
||||||
#![feature(staged_api)]
|
#![feature(staged_api)]
|
||||||
#![feature(i128_type)]
|
#![feature(i128_type)]
|
||||||
|
#![feature(repr_simd)]
|
||||||
|
#![feature(abi_unadjusted)]
|
||||||
|
#![allow(unused_features)]
|
||||||
#![no_builtins]
|
#![no_builtins]
|
||||||
#![unstable(feature = "compiler_builtins_lib",
|
#![unstable(feature = "compiler_builtins_lib",
|
||||||
reason = "Compiler builtins. Will never become stable.",
|
reason = "Compiler builtins. Will never become stable.",
|
||||||
|
Loading…
Reference in New Issue
Block a user