add gamma function shims
This commit is contained in:
parent
2e14f25c9b
commit
9281ddc644
@ -1,4 +1,5 @@
|
|||||||
#![feature(rustc_private)]
|
#![feature(rustc_private)]
|
||||||
|
#![feature(float_gamma)]
|
||||||
#![feature(map_try_insert)]
|
#![feature(map_try_insert)]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![feature(try_blocks)]
|
#![feature(try_blocks)]
|
||||||
|
@ -815,6 +815,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||||||
| "atanf"
|
| "atanf"
|
||||||
| "log1pf"
|
| "log1pf"
|
||||||
| "expm1f"
|
| "expm1f"
|
||||||
|
| "tgammaf"
|
||||||
=> {
|
=> {
|
||||||
let [f] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
let [f] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||||
// FIXME: Using host floats.
|
// FIXME: Using host floats.
|
||||||
@ -830,6 +831,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||||||
"atanf" => f.atan(),
|
"atanf" => f.atan(),
|
||||||
"log1pf" => f.ln_1p(),
|
"log1pf" => f.ln_1p(),
|
||||||
"expm1f" => f.exp_m1(),
|
"expm1f" => f.exp_m1(),
|
||||||
|
"tgammaf" => f.gamma(),
|
||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
};
|
};
|
||||||
this.write_scalar(Scalar::from_u32(res.to_bits()), dest)?;
|
this.write_scalar(Scalar::from_u32(res.to_bits()), dest)?;
|
||||||
@ -866,6 +868,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||||||
| "atan"
|
| "atan"
|
||||||
| "log1p"
|
| "log1p"
|
||||||
| "expm1"
|
| "expm1"
|
||||||
|
| "tgamma"
|
||||||
=> {
|
=> {
|
||||||
let [f] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
let [f] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||||
// FIXME: Using host floats.
|
// FIXME: Using host floats.
|
||||||
@ -881,6 +884,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||||||
"atan" => f.atan(),
|
"atan" => f.atan(),
|
||||||
"log1p" => f.ln_1p(),
|
"log1p" => f.ln_1p(),
|
||||||
"expm1" => f.exp_m1(),
|
"expm1" => f.exp_m1(),
|
||||||
|
"tgamma" => f.gamma(),
|
||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
};
|
};
|
||||||
this.write_scalar(Scalar::from_u64(res.to_bits()), dest)?;
|
this.write_scalar(Scalar::from_u64(res.to_bits()), dest)?;
|
||||||
@ -917,6 +921,26 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||||||
let res = x.scalbn(exp);
|
let res = x.scalbn(exp);
|
||||||
this.write_scalar(Scalar::from_f64(res), dest)?;
|
this.write_scalar(Scalar::from_f64(res), dest)?;
|
||||||
}
|
}
|
||||||
|
"lgammaf_r" => {
|
||||||
|
let [x, signp] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||||
|
// FIXME: Using host floats.
|
||||||
|
let x = f32::from_bits(this.read_scalar(x)?.to_u32()?);
|
||||||
|
let signp = this.deref_pointer(signp)?;
|
||||||
|
|
||||||
|
let (res, sign) = x.ln_gamma();
|
||||||
|
this.write_int(sign, &signp)?;
|
||||||
|
this.write_scalar(Scalar::from_u32(res.to_bits()), dest)?;
|
||||||
|
}
|
||||||
|
"lgamma_r" => {
|
||||||
|
let [x, signp] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||||
|
// FIXME: Using host floats.
|
||||||
|
let x = f64::from_bits(this.read_scalar(x)?.to_u64()?);
|
||||||
|
let signp = this.deref_pointer(signp)?;
|
||||||
|
|
||||||
|
let (res, sign) = x.ln_gamma();
|
||||||
|
this.write_int(sign, &signp)?;
|
||||||
|
this.write_scalar(Scalar::from_u64(res.to_bits()), dest)?;
|
||||||
|
}
|
||||||
|
|
||||||
// Architecture-specific shims
|
// Architecture-specific shims
|
||||||
"llvm.x86.addcarry.64" if this.tcx.sess.target.arch == "x86_64" => {
|
"llvm.x86.addcarry.64" if this.tcx.sess.target.arch == "x86_64" => {
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
#![feature(float_gamma)]
|
||||||
// SPDX-FileCopyrightText: The Rust Project Developers (see https://thanks.rust-lang.org)
|
|
||||||
|
|
||||||
macro_rules! assert_approx_eq {
|
macro_rules! assert_approx_eq {
|
||||||
($a:expr, $b:expr) => {{
|
($a:expr, $b:expr) => {{
|
||||||
@ -130,4 +129,20 @@ pub fn main() {
|
|||||||
);
|
);
|
||||||
assert_approx_eq!(0.5f32.atanh(), 0.54930614433405484569762261846126285f32);
|
assert_approx_eq!(0.5f32.atanh(), 0.54930614433405484569762261846126285f32);
|
||||||
assert_approx_eq!(0.5f64.atanh(), 0.54930614433405484569762261846126285f64);
|
assert_approx_eq!(0.5f64.atanh(), 0.54930614433405484569762261846126285f64);
|
||||||
|
|
||||||
|
assert_approx_eq!(5.0f32.gamma(), 24.0);
|
||||||
|
assert_approx_eq!(5.0f64.gamma(), 24.0);
|
||||||
|
// These fail even on the host, precision seems to be terrible.
|
||||||
|
//assert_approx_eq!(-0.5f32.gamma(), -2.0 * f32::consts::PI.sqrt());
|
||||||
|
//assert_approx_eq!(-0.5f64.gamma(), -2.0 * f64::consts::PI.sqrt());
|
||||||
|
|
||||||
|
assert_eq!(2.0f32.ln_gamma(), (0.0, 1));
|
||||||
|
assert_eq!(2.0f64.ln_gamma(), (0.0, 1));
|
||||||
|
// Gamma(-0.5) = -2*sqrt(π)
|
||||||
|
let (val, sign) = (-0.5f32).ln_gamma();
|
||||||
|
assert_approx_eq!(val, (2.0 * f32::consts::PI.sqrt()).ln());
|
||||||
|
assert_eq!(sign, -1);
|
||||||
|
let (val, sign) = (-0.5f64).ln_gamma();
|
||||||
|
assert_approx_eq!(val, (2.0 * f64::consts::PI.sqrt()).ln());
|
||||||
|
assert_eq!(sign, -1);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user