diff --git a/src/shims/foreign_items.rs b/src/shims/foreign_items.rs index bcfcda2fd0..3e3266b74a 100644 --- a/src/shims/foreign_items.rs +++ b/src/shims/foreign_items.rs @@ -603,6 +603,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx }; this.write_scalar(Scalar::from_u64(n.to_bits()), dest)?; } + // underscore case for windows + "_ldexp" | "ldexp" => { + // FIXME: Using host floats. + let x = f64::from_bits(this.read_scalar(args[0])?.to_u64()?); + let exp = this.read_scalar(args[1])?.to_i32()?; + // FIXME: We should use cmath if there are any imprecisions. + let n = x * 2.0f64.powi(exp); + this.write_scalar(Scalar::from_u64(n.to_bits()), dest)?; + } // Some things needed for `sys::thread` initialization to go through. "signal" | "sigaction" | "sigaltstack" => { @@ -973,4 +982,4 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx } return Ok(None); } -} \ No newline at end of file +} diff --git a/tests/run-pass/intrinsics-math.rs b/tests/run-pass/intrinsics-math.rs index 20c0f67494..9a7a70bd00 100644 --- a/tests/run-pass/intrinsics-math.rs +++ b/tests/run-pass/intrinsics-math.rs @@ -85,4 +85,8 @@ pub fn main() { assert_approx_eq!(1.0f32.tan(), 1.557408f32); assert_approx_eq!(1.0f64.tan(), 1.557408f64); + extern { + fn ldexp(x: f64, n: i32) -> f64; + } + unsafe { assert_approx_eq!(ldexp(0.65f64, 3i32), 5.2f64); } }