The previous assembly implementation did the truncation by converting to a 32 bit integer inbetween, which significantly limited the usable range of the function, both for larger floats, and in particular for doubles.
Signed-off-by: Martin Storsjö <[email protected]> --- mingw-w64-crt/Makefile.am | 4 +- mingw-w64-crt/math/arm/s_trunc.c | 61 +++++++++++++++++++++++++++++++ mingw-w64-crt/math/arm/s_truncf.c | 51 ++++++++++++++++++++++++++ mingw-w64-crt/math/arm/trunc.S | 28 -------------- mingw-w64-crt/math/arm/truncf.S | 28 -------------- 5 files changed, 114 insertions(+), 58 deletions(-) create mode 100644 mingw-w64-crt/math/arm/s_trunc.c create mode 100644 mingw-w64-crt/math/arm/s_truncf.c delete mode 100644 mingw-w64-crt/math/arm/trunc.S delete mode 100644 mingw-w64-crt/math/arm/truncf.S diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am index 9b23050cc..dc52cd6f0 100644 --- a/mingw-w64-crt/Makefile.am +++ b/mingw-w64-crt/Makefile.am @@ -272,8 +272,8 @@ src_msvcrtarm32+=\ math/arm/nearbyint.S \ math/arm/nearbyintf.S \ math/arm/nearbyintl.S \ - math/arm/trunc.S \ - math/arm/truncf.S \ + math/arm/s_trunc.c \ + math/arm/s_truncf.c \ math/arm-common/acosh.c \ math/arm-common/acoshf.c \ math/arm-common/acoshl.c \ diff --git a/mingw-w64-crt/math/arm/s_trunc.c b/mingw-w64-crt/math/arm/s_trunc.c new file mode 100644 index 000000000..a7798df9c --- /dev/null +++ b/mingw-w64-crt/math/arm/s_trunc.c @@ -0,0 +1,61 @@ +/* @(#)s_floor.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include <sys/cdefs.h> + +/* + * trunc(x) + * Return x rounded toward 0 to integral value + * Method: + * Bit twiddling. + * Exception: + * Inexact flag raised if x not equal to trunc(x). + */ + +#include <float.h> + +#include "../bsd_private_base.h" + +static const double huge = 1.0e300; + +double +trunc(double x) +{ + int32_t i0,i1,j0; + u_int32_t i; + EXTRACT_WORDS(i0,i1,x); + j0 = ((i0>>20)&0x7ff)-0x3ff; + if(j0<20) { + if(j0<0) { /* raise inexact if x != 0 */ + if(huge+x>0.0) {/* |x|<1, so return 0*sign(x) */ + i0 &= 0x80000000U; + i1 = 0; + } + } else { + i = (0x000fffff)>>j0; + if(((i0&i)|i1)==0) return x; /* x is integral */ + if(huge+x>0.0) { /* raise inexact flag */ + i0 &= (~i); i1=0; + } + } + } else if (j0>51) { + if(j0==0x400) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } else { + i = ((u_int32_t)(0xffffffff))>>(j0-20); + if((i1&i)==0) return x; /* x is integral */ + if(huge+x>0.0) /* raise inexact flag */ + i1 &= (~i); + } + INSERT_WORDS(x,i0,i1); + return x; +} diff --git a/mingw-w64-crt/math/arm/s_truncf.c b/mingw-w64-crt/math/arm/s_truncf.c new file mode 100644 index 000000000..8d66c5fbf --- /dev/null +++ b/mingw-w64-crt/math/arm/s_truncf.c @@ -0,0 +1,51 @@ +/* @(#)s_floor.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include <sys/cdefs.h> + +/* + * truncf(x) + * Return x rounded toward 0 to integral value + * Method: + * Bit twiddling. + * Exception: + * Inexact flag raised if x not equal to truncf(x). + */ + +#include "../bsd_private_base.h" + +static const float huge = 1.0e30F; + +float +truncf(float x) +{ + int32_t i0,j0; + u_int32_t i; + GET_FLOAT_WORD(i0,x); + j0 = ((i0>>23)&0xff)-0x7f; + if(j0<23) { + if(j0<0) { /* raise inexact if x != 0 */ + if(huge+x>0.0F) /* |x|<1, so return 0*sign(x) */ + i0 &= 0x80000000; + } else { + i = (0x007fffff)>>j0; + if((i0&i)==0) return x; /* x is integral */ + if(huge+x>0.0F) /* raise inexact flag */ + i0 &= (~i); + } + } else { + if(j0==0x80) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } + SET_FLOAT_WORD(x,i0); + return x; +} diff --git a/mingw-w64-crt/math/arm/trunc.S b/mingw-w64-crt/math/arm/trunc.S deleted file mode 100644 index 3b297cbf0..000000000 --- a/mingw-w64-crt/math/arm/trunc.S +++ /dev/null @@ -1,28 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ -#include <_mingw_mac.h> - - .file "trunc.S" - .text - .p2align 4,,15 - .globl __MINGW_USYMBOL(trunc) - .def __MINGW_USYMBOL(trunc); .scl 2; .type 32; .endef - -__MINGW_USYMBOL(trunc): - vmov r2, r3, d0 - lsr r3, r3, #20 - bic r3, r3, #0x800 - movw r2, #0x7ff - cmp r2, r3 /* Check for INF/NAN, just return the input in those cases */ - it eq - bxeq lr - vmrs r1, fpscr - orr r0, r1, #0x00c00000 /* Round towards Zero */ - vmsr fpscr, r0 - vcvtr.s32.f64 s0, d0 - vcvt.f64.s32 d0, s0 - vmsr fpscr, r1 - bx lr diff --git a/mingw-w64-crt/math/arm/truncf.S b/mingw-w64-crt/math/arm/truncf.S deleted file mode 100644 index 9c1f0cda1..000000000 --- a/mingw-w64-crt/math/arm/truncf.S +++ /dev/null @@ -1,28 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ -#include <_mingw_mac.h> - - .file "truncf.S" - .text - .p2align 4,,15 - .globl __MINGW_USYMBOL(truncf) - .def __MINGW_USYMBOL(truncf); .scl 2; .type 32; .endef - -__MINGW_USYMBOL(truncf): - vmov r2, r3, d0 - lsr r3, r3, #20 - bic r3, r3, #0x800 - movw r2, #0x7ff - cmp r2, r3 /* Check for INF/NAN, just return the input in those cases */ - it eq - bxeq lr - vmrs r1, fpscr - orr r0, r1, #0x00c00000 /* Round towards Zero */ - vmsr fpscr, r0 - vcvt.s32.f32 s0, s0 - vcvt.f32.s32 s0, s0 - vmsr fpscr, r1 - bx lr -- 2.17.1 _______________________________________________ Mingw-w64-public mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
