diff options
Diffstat (limited to 'vendor/libm-0.1.4/src/math/fmaf.rs')
-rw-r--r-- | vendor/libm-0.1.4/src/math/fmaf.rs | 107 |
1 files changed, 0 insertions, 107 deletions
diff --git a/vendor/libm-0.1.4/src/math/fmaf.rs b/vendor/libm-0.1.4/src/math/fmaf.rs deleted file mode 100644 index e77e0fa4a..000000000 --- a/vendor/libm-0.1.4/src/math/fmaf.rs +++ /dev/null @@ -1,107 +0,0 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/s_fmaf.c */ -/*- - * Copyright (c) 2005-2011 David Schultz <das@FreeBSD.ORG> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -use core::f32; -use core::ptr::read_volatile; - -use super::fenv::{ - feclearexcept, fegetround, feraiseexcept, fesetround, fetestexcept, FE_INEXACT, FE_TONEAREST, - FE_TOWARDZERO, FE_UNDERFLOW, -}; - -/* - * Fused multiply-add: Compute x * y + z with a single rounding error. - * - * A double has more than twice as much precision than a float, so - * direct double-precision arithmetic suffices, except where double - * rounding occurs. - */ - -/// Floating multiply add (f32) -/// -/// Computes `(x*y)+z`, rounded as one ternary operation: -/// Computes the value (as if) to infinite precision and rounds once to the result format, -/// according to the rounding mode characterized by the value of FLT_ROUNDS. -#[inline] -#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] -pub fn fmaf(x: f32, y: f32, mut z: f32) -> f32 { - let xy: f64; - let mut result: f64; - let mut ui: u64; - let e: i32; - - xy = x as f64 * y as f64; - result = xy + z as f64; - ui = result.to_bits(); - e = (ui >> 52) as i32 & 0x7ff; - /* Common case: The double precision result is fine. */ - if ( - /* not a halfway case */ - ui & 0x1fffffff) != 0x10000000 || - /* NaN */ - e == 0x7ff || - /* exact */ - (result - xy == z as f64 && result - z as f64 == xy) || - /* not round-to-nearest */ - fegetround() != FE_TONEAREST - { - /* - underflow may not be raised correctly, example: - fmaf(0x1p-120f, 0x1p-120f, 0x1p-149f) - */ - if e < 0x3ff - 126 && e >= 0x3ff - 149 && fetestexcept(FE_INEXACT) != 0 { - feclearexcept(FE_INEXACT); - // prevent `xy + vz` from being CSE'd with `xy + z` above - let vz: f32 = unsafe { read_volatile(&z) }; - result = xy + vz as f64; - if fetestexcept(FE_INEXACT) != 0 { - feraiseexcept(FE_UNDERFLOW); - } else { - feraiseexcept(FE_INEXACT); - } - } - z = result as f32; - return z; - } - - /* - * If result is inexact, and exactly halfway between two float values, - * we need to adjust the low-order bit in the direction of the error. - */ - fesetround(FE_TOWARDZERO); - // prevent `vxy + z` from being CSE'd with `xy + z` above - let vxy: f64 = unsafe { read_volatile(&xy) }; - let mut adjusted_result: f64 = vxy + z as f64; - fesetround(FE_TONEAREST); - if result == adjusted_result { - ui = adjusted_result.to_bits(); - ui += 1; - adjusted_result = f64::from_bits(ui); - } - z = adjusted_result as f32; - z -} |