136 lines
6.8 KiB
Rust
136 lines
6.8 KiB
Rust
// Bitwise differential against rustc 1.97.1 wasm32 compiler-builtins, including
|
|
// A single canonical NaN avoids unspecified selection between NaN payloads.
|
|
// Every distinct function in Relax core::libm (48 declarations, 46 names).
|
|
#![allow(dead_code, unexpected_cfgs)]
|
|
use std::fmt::Write;
|
|
extern "C" { fn js_console_log(ptr: *const u8, len: usize); }
|
|
fn out(s: &str) { unsafe { js_console_log(s.as_ptr(), s.len()) } }
|
|
macro_rules! say {
|
|
($($t:tt)*) => {{ let mut s = String::new(); let _ = writeln!(s, $($t)*); out(&s); }};
|
|
}
|
|
#[cfg(not(libm_reference))]
|
|
use core::libm as math;
|
|
#[cfg(libm_reference)]
|
|
mod math {
|
|
pub fn sin(x: f64) -> f64 { x.sin() }
|
|
pub fn cos(x: f64) -> f64 { x.cos() }
|
|
pub fn tan(x: f64) -> f64 { x.tan() }
|
|
pub fn asin(x: f64) -> f64 { x.asin() }
|
|
pub fn acos(x: f64) -> f64 { x.acos() }
|
|
pub fn atan(x: f64) -> f64 { x.atan() }
|
|
pub fn atan2(x: f64, y: f64) -> f64 { x.atan2(y) }
|
|
pub fn sinh(x: f64) -> f64 { x.sinh() }
|
|
pub fn cosh(x: f64) -> f64 { x.cosh() }
|
|
pub fn tanh(x: f64) -> f64 { x.tanh() }
|
|
pub fn exp(x: f64) -> f64 { x.exp() }
|
|
pub fn exp2(x: f64) -> f64 { x.exp2() }
|
|
pub fn expm1(x: f64) -> f64 { x.exp_m1() }
|
|
pub fn log(x: f64) -> f64 { x.ln() }
|
|
pub fn log2(x: f64) -> f64 { x.log2() }
|
|
pub fn log10(x: f64) -> f64 { x.log10() }
|
|
pub fn log1p(x: f64) -> f64 { x.ln_1p() }
|
|
pub fn pow(x: f64, y: f64) -> f64 { x.powf(y) }
|
|
pub fn cbrt(x: f64) -> f64 { x.cbrt() }
|
|
pub fn hypot(x: f64, y: f64) -> f64 { x.hypot(y) }
|
|
pub fn round(x: f64) -> f64 { x.round() }
|
|
pub fn fma(x: f64, y: f64, z: f64) -> f64 { x.mul_add(y, z) }
|
|
pub fn fmod(x: f64, y: f64) -> f64 { x % y }
|
|
pub fn sinf(x: f32) -> f32 { x.sin() }
|
|
pub fn cosf(x: f32) -> f32 { x.cos() }
|
|
pub fn tanf(x: f32) -> f32 { x.tan() }
|
|
pub fn asinf(x: f32) -> f32 { x.asin() }
|
|
pub fn acosf(x: f32) -> f32 { x.acos() }
|
|
pub fn atanf(x: f32) -> f32 { x.atan() }
|
|
pub fn atan2f(x: f32, y: f32) -> f32 { x.atan2(y) }
|
|
pub fn sinhf(x: f32) -> f32 { x.sinh() }
|
|
pub fn coshf(x: f32) -> f32 { x.cosh() }
|
|
pub fn tanhf(x: f32) -> f32 { x.tanh() }
|
|
pub fn expf(x: f32) -> f32 { x.exp() }
|
|
pub fn exp2f(x: f32) -> f32 { x.exp2() }
|
|
pub fn expm1f(x: f32) -> f32 { x.exp_m1() }
|
|
pub fn logf(x: f32) -> f32 { x.ln() }
|
|
pub fn log2f(x: f32) -> f32 { x.log2() }
|
|
pub fn log10f(x: f32) -> f32 { x.log10() }
|
|
pub fn log1pf(x: f32) -> f32 { x.ln_1p() }
|
|
pub fn powf(x: f32, y: f32) -> f32 { x.powf(y) }
|
|
pub fn cbrtf(x: f32) -> f32 { x.cbrt() }
|
|
pub fn hypotf(x: f32, y: f32) -> f32 { x.hypot(y) }
|
|
pub fn roundf(x: f32) -> f32 { x.round() }
|
|
pub fn fmaf(x: f32, y: f32, z: f32) -> f32 { x.mul_add(y, z) }
|
|
pub fn fmodf(x: f32, y: f32) -> f32 { x % y }
|
|
}
|
|
fn body() {
|
|
let xs: [f64; 22] = [0.0, -0.0, 1.0, -1.0, 0.5, -0.5, 1.5, -1.5,
|
|
2.0, -2.0, 3.141592653589793, 10.0, -10.0, 1e20, -1e20,
|
|
f64::MAX, f64::MIN_POSITIVE, f64::from_bits(1), -f64::from_bits(1),
|
|
f64::INFINITY, f64::NEG_INFINITY, f64::NAN];
|
|
for (i, x) in xs.iter().copied().enumerate() {
|
|
let x = std::hint::black_box(x);
|
|
say!("sin {} {:x}", i, math::sin(x).to_bits());
|
|
say!("cos {} {:x}", i, math::cos(x).to_bits());
|
|
say!("tan {} {:x}", i, math::tan(x).to_bits());
|
|
say!("asin {} {:x}", i, math::asin(x).to_bits());
|
|
say!("acos {} {:x}", i, math::acos(x).to_bits());
|
|
say!("atan {} {:x}", i, math::atan(x).to_bits());
|
|
say!("sinh {} {:x}", i, math::sinh(x).to_bits());
|
|
say!("cosh {} {:x}", i, math::cosh(x).to_bits());
|
|
say!("tanh {} {:x}", i, math::tanh(x).to_bits());
|
|
say!("exp {} {:x}", i, math::exp(x).to_bits());
|
|
say!("exp2 {} {:x}", i, math::exp2(x).to_bits());
|
|
say!("expm1 {} {:x}", i, math::expm1(x).to_bits());
|
|
say!("log {} {:x}", i, math::log(x).to_bits());
|
|
say!("log2 {} {:x}", i, math::log2(x).to_bits());
|
|
say!("log10 {} {:x}", i, math::log10(x).to_bits());
|
|
say!("log1p {} {:x}", i, math::log1p(x).to_bits());
|
|
say!("cbrt {} {:x}", i, math::cbrt(x).to_bits());
|
|
say!("round {} {:x}", i, math::round(x).to_bits());
|
|
for (j, y) in xs.iter().copied().enumerate() {
|
|
let y = std::hint::black_box(y);
|
|
say!("pow {} {} {:x}", i, j, math::pow(x, y).to_bits());
|
|
say!("hypot {} {} {:x}", i, j, math::hypot(x, y).to_bits());
|
|
say!("atan2 {} {} {:x}", i, j, math::atan2(x, y).to_bits());
|
|
say!("fmod {} {} {:x}", i, j, (x % y).to_bits());
|
|
for (k, z) in [0.0, -0.0, 1.0, -1.0, f64::from_bits(1), f64::INFINITY, f64::NAN].iter().copied().enumerate() {
|
|
say!("fma {} {} {} {:x}", i, j, k, math::fma(x, y, std::hint::black_box(z)).to_bits());
|
|
}
|
|
}
|
|
}
|
|
let xs: [f32; 22] = [0.0, -0.0, 1.0, -1.0, 0.5, -0.5, 1.5, -1.5,
|
|
2.0, -2.0, 3.141592653589793, 10.0, -10.0, 1e20, -1e20,
|
|
f32::MAX, f32::MIN_POSITIVE, f32::from_bits(1), -f32::from_bits(1),
|
|
f32::INFINITY, f32::NEG_INFINITY, f32::NAN];
|
|
for (i, x) in xs.iter().copied().enumerate() {
|
|
let x = std::hint::black_box(x);
|
|
say!("sinf {} {:x}", i, math::sinf(x).to_bits());
|
|
say!("cosf {} {:x}", i, math::cosf(x).to_bits());
|
|
say!("tanf {} {:x}", i, math::tanf(x).to_bits());
|
|
say!("asinf {} {:x}", i, math::asinf(x).to_bits());
|
|
say!("acosf {} {:x}", i, math::acosf(x).to_bits());
|
|
say!("atanf {} {:x}", i, math::atanf(x).to_bits());
|
|
say!("sinhf {} {:x}", i, math::sinhf(x).to_bits());
|
|
say!("coshf {} {:x}", i, math::coshf(x).to_bits());
|
|
say!("tanhf {} {:x}", i, math::tanhf(x).to_bits());
|
|
say!("expf {} {:x}", i, math::expf(x).to_bits());
|
|
say!("exp2f {} {:x}", i, math::exp2f(x).to_bits());
|
|
say!("expm1f {} {:x}", i, math::expm1f(x).to_bits());
|
|
say!("logf {} {:x}", i, math::logf(x).to_bits());
|
|
say!("log2f {} {:x}", i, math::log2f(x).to_bits());
|
|
say!("log10f {} {:x}", i, math::log10f(x).to_bits());
|
|
say!("log1pf {} {:x}", i, math::log1pf(x).to_bits());
|
|
say!("cbrtf {} {:x}", i, math::cbrtf(x).to_bits());
|
|
say!("roundf {} {:x}", i, math::roundf(x).to_bits());
|
|
for (j, y) in xs.iter().copied().enumerate() {
|
|
let y = std::hint::black_box(y);
|
|
say!("powf {} {} {:x}", i, j, math::powf(x, y).to_bits());
|
|
say!("hypotf {} {} {:x}", i, j, math::hypotf(x, y).to_bits());
|
|
say!("atan2f {} {} {:x}", i, j, math::atan2f(x, y).to_bits());
|
|
say!("fmodf {} {} {:x}", i, j, (x % y).to_bits());
|
|
for (k, z) in [0.0, -0.0, 1.0, -1.0, f32::from_bits(1), f32::INFINITY, f32::NAN].iter().copied().enumerate() {
|
|
say!("fmaf {} {} {} {:x}", i, j, k, math::fmaf(x, y, std::hint::black_box(z)).to_bits());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#[no_mangle]
|
|
pub extern "C" fn run() { body() }
|
|
fn main() { body() }
|