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

Reply via email to