diff options
Diffstat (limited to 'winsup/mingw/mingwex/math/llroundf.c')
-rw-r--r-- | winsup/mingw/mingwex/math/llroundf.c | 36 |
1 files changed, 16 insertions, 20 deletions
diff --git a/winsup/mingw/mingwex/math/llroundf.c b/winsup/mingw/mingwex/math/llroundf.c index b6c431f9d..6a6e9b51e 100644 --- a/winsup/mingw/mingwex/math/llroundf.c +++ b/winsup/mingw/mingwex/math/llroundf.c @@ -1,23 +1,19 @@ -#include <fenv.h> #include <math.h> +#include <limits.h> +#include <errno.h> long long -llroundf (float x) { - long long retval; - unsigned short saved_cw, _cw; - __asm__ ( - "fnstcw %0;" : "=m" (saved_cw) - ); /* save control word */ - _cw = ~(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO) - | (x > 0.0 ? FE_UPWARD : FE_DOWNWARD); /* round away from zero */ - __asm__ ( - "fldcw %0;" : : "m" (_cw) - ); /* load the rounding control */ - __asm__ __volatile__ ( - "fistpll %0" : "=m" (retval) : "t" (x) : "st" - ); - __asm__ ( - "fldcw %0;" : : "m" (saved_cw) - ); /* restore control word */ - return retval; -} +llroundf (float x) +{ + /* Add +/- 0.5, then round towards zero. */ + float tmp = truncf (x + (x >= 0.0F ? 0.5F : -0.5F)); + if (!isfinite (tmp) + || tmp > (float)LONG_LONG_MAX + || tmp < (float)LONG_LONG_MIN) + { + errno = ERANGE; + /* Undefined behaviour, so we could return anything. */ + /* return tmp > 0.0F ? LONG_LONG_MAX : LONG_LONG_MIN; */ + } + return (long long)tmp; +} |