Use a C-safe return type for __rust_[ui]128_* overflowing intrinsics
Most of our Rust-specific overflowing intrinsics currently return `(i128, bool)`, which is not guaranteed to have a stable ABI. Switch to returning the overflow via a mutable parameter and only directly returning the integer result. `__rust_i128_mulo` now matches the function signature of `__muloti4`, but they do not share the same ABI on Windows so we cannot easily deduplicate them.
This commit is contained in:
parent
57dde638b9
commit
7a87cdbae5
4 changed files with 39 additions and 24 deletions
|
|
@ -66,31 +66,39 @@ intrinsics! {
|
|||
AddSub::add(a,b)
|
||||
}
|
||||
|
||||
pub extern "C" fn __rust_i128_addo(a: i128, b: i128) -> (i128, bool) {
|
||||
a.addo(b)
|
||||
pub extern "C" fn __rust_i128_addo(a: i128, b: i128, oflow: &mut i32) -> i128 {
|
||||
let (add, o) = a.addo(b);
|
||||
*oflow = o.into();
|
||||
add
|
||||
}
|
||||
|
||||
pub extern "C" fn __rust_u128_add(a: u128, b: u128) -> u128 {
|
||||
AddSub::add(a,b)
|
||||
}
|
||||
|
||||
pub extern "C" fn __rust_u128_addo(a: u128, b: u128) -> (u128, bool) {
|
||||
a.addo(b)
|
||||
pub extern "C" fn __rust_u128_addo(a: u128, b: u128, oflow: &mut i32) -> u128 {
|
||||
let (add, o) = a.addo(b);
|
||||
*oflow = o.into();
|
||||
add
|
||||
}
|
||||
|
||||
pub extern "C" fn __rust_i128_sub(a: i128, b: i128) -> i128 {
|
||||
AddSub::sub(a,b)
|
||||
}
|
||||
|
||||
pub extern "C" fn __rust_i128_subo(a: i128, b: i128) -> (i128, bool) {
|
||||
a.subo(b)
|
||||
pub extern "C" fn __rust_i128_subo(a: i128, b: i128, oflow: &mut i32) -> i128 {
|
||||
let (sub, o) = a.subo(b);
|
||||
*oflow = o.into();
|
||||
sub
|
||||
}
|
||||
|
||||
pub extern "C" fn __rust_u128_sub(a: u128, b: u128) -> u128 {
|
||||
AddSub::sub(a,b)
|
||||
}
|
||||
|
||||
pub extern "C" fn __rust_u128_subo(a: u128, b: u128) -> (u128, bool) {
|
||||
a.subo(b)
|
||||
pub extern "C" fn __rust_u128_subo(a: u128, b: u128, oflow: &mut i32) -> u128 {
|
||||
let (sub, o) = a.subo(b);
|
||||
*oflow = o.into();
|
||||
sub
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,11 +128,15 @@ intrinsics! {
|
|||
mul
|
||||
}
|
||||
|
||||
pub extern "C" fn __rust_i128_mulo(a: i128, b: i128) -> (i128, bool) {
|
||||
i128_overflowing_mul(a, b)
|
||||
pub extern "C" fn __rust_i128_mulo(a: i128, b: i128, oflow: &mut i32) -> i128 {
|
||||
let (mul, o) = i128_overflowing_mul(a, b);
|
||||
*oflow = o.into();
|
||||
mul
|
||||
}
|
||||
|
||||
pub extern "C" fn __rust_u128_mulo(a: u128, b: u128) -> (u128, bool) {
|
||||
a.mulo(b)
|
||||
pub extern "C" fn __rust_u128_mulo(a: u128, b: u128, oflow: &mut i32) -> u128 {
|
||||
let (mul, o) = a.mulo(b);
|
||||
*oflow = o.into();
|
||||
mul
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,20 +44,22 @@ mod int_addsub {
|
|||
use compiler_builtins::int::addsub::{$fn_add, $fn_sub};
|
||||
|
||||
fuzz_2(N, |x: $i, y: $i| {
|
||||
let add0 = x.overflowing_add(y);
|
||||
let sub0 = x.overflowing_sub(y);
|
||||
let add1: ($i, bool) = $fn_add(x, y);
|
||||
let sub1: ($i, bool) = $fn_sub(x, y);
|
||||
if add0.0 != add1.0 || add0.1 != add1.1 {
|
||||
let (add0, add_o0)= x.overflowing_add(y);
|
||||
let (sub0, sub_o0)= x.overflowing_sub(y);
|
||||
let mut add_o1 = 0;
|
||||
let mut sub_o1 = 0;
|
||||
let add1: $i = $fn_add(x, y, &mut add_o1);
|
||||
let sub1: $i = $fn_sub(x, y, &mut sub_o1);
|
||||
if add0 != add1 || i32::from(add_o0) != add_o1 {
|
||||
panic!(
|
||||
"{}({}, {}): std: {:?}, builtins: {:?}",
|
||||
stringify!($fn_add), x, y, add0, add1
|
||||
stringify!($fn_add), x, y, (add0, add_o0) , (add1, add_o1)
|
||||
);
|
||||
}
|
||||
if sub0.0 != sub1.0 || sub0.1 != sub1.1 {
|
||||
if sub0 != sub1 || i32::from(sub_o0) != sub_o1 {
|
||||
panic!(
|
||||
"{}({}, {}): std: {:?}, builtins: {:?}",
|
||||
stringify!($fn_sub), x, y, sub0, sub1
|
||||
stringify!($fn_sub), x, y, (sub0, sub_o0) , (sub1, sub_o1)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -73,9 +73,10 @@ mod int_overflowing_mul {
|
|||
use compiler_builtins::int::mul::{__rust_i128_mulo, __rust_u128_mulo};
|
||||
|
||||
fuzz_2(N, |x: u128, y: u128| {
|
||||
let mut o1 = 0;
|
||||
let (mul0, o0) = x.overflowing_mul(y);
|
||||
let (mul1, o1) = __rust_u128_mulo(x, y);
|
||||
if mul0 != mul1 || o0 != o1 {
|
||||
let mul1 = __rust_u128_mulo(x, y, &mut o1);
|
||||
if mul0 != mul1 || i32::from(o0) != o1 {
|
||||
panic!(
|
||||
"__rust_u128_mulo({}, {}): std: ({}, {}), builtins: ({}, {})",
|
||||
x, y, mul0, o0, mul1, o1
|
||||
|
|
@ -84,8 +85,8 @@ mod int_overflowing_mul {
|
|||
let x = x as i128;
|
||||
let y = y as i128;
|
||||
let (mul0, o0) = x.overflowing_mul(y);
|
||||
let (mul1, o1) = __rust_i128_mulo(x, y);
|
||||
if mul0 != mul1 || o0 != o1 {
|
||||
let mul1 = __rust_i128_mulo(x, y, &mut o1);
|
||||
if mul0 != mul1 || i32::from(o0) != o1 {
|
||||
panic!(
|
||||
"__rust_i128_mulo({}, {}): std: ({}, {}), builtins: ({}, {})",
|
||||
x, y, mul0, o0, mul1, o1
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue