]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Refactor i386 libm code forcing underflow exceptions.
authorJoseph Myers <joseph@codesourcery.com>
Thu, 24 Sep 2015 21:41:00 +0000 (21:41 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Thu, 24 Sep 2015 21:41:00 +0000 (21:41 +0000)
This patch refactors code in sysdeps/i386/fpu that forces underflow
exceptions to use common macros for that purpose as far as possible.
(Although some of the macros end up used in only one place, I think
it's cleanest to define all these macros together so that all the code
forcing underflow uses such macros.  Some more uses of such macros
will also be introduced when fixing remaining bugs about missing
underflow exceptions, and it would be possible to do further
refactoring of the macros in i386-math-asm.h to share more code by
using other macros internally.  Places that test for underflow by
examining the representation of the argument with integer operations,
rather that using floating-point comparisons on the argument or
result, are unchanged by this patch.)

Most of this code uses a macro MO to abstract away the differences
between PIC and non-PIC memory references to constants.  log1p
functions, however, hardcoded PIC conditionals for this.  Because the
common macros rely on the use of MO, I changed the log1p functions to
use the normal style here, and, for consistency, also made that change
to log1pl which is otherwise unaffected by this patch.

Tested for x86.

* sysdeps/i386/fpu/i386-math-asm.h (DEFINE_LDBL_MIN): New macro.
(FLT_CHECK_FORCE_UFLOW): Likewise.
(DBL_CHECK_FORCE_UFLOW): Likewise.
(FLT_CHECK_FORCE_UFLOW_NARROW): Likewise.
(DBL_CHECK_FORCE_UFLOW_NARROW): Likewise.
(LDBL_CHECK_FORCE_UFLOW_NONNEG_NAN): Likewise.
(FLT_CHECK_FORCE_UFLOW_NONNAN): Likewise.
(DBL_CHECK_FORCE_UFLOW_NONNAN): Likewise.
(FLT_CHECK_FORCE_UFLOW_NONNEG): Likewise.
(DBL_CHECK_FORCE_UFLOW_NONNEG): Likewise.
(LDBL_CHECK_FORCE_UFLOW_NONNEG): Likewise.
* sysdeps/i386/fpu/e_asin.S: Include <i386-math-asm.h>.
(dbl_min): Replace with use of DEFINE_DBL_MIN.
(__ieee754_asin): Use DBL_CHECK_FORCE_UFLOW.
* sysdeps/i386/fpu/e_asinf.S: Include <i386-math-asm.h>.
(flt_min): Replace with use of DEFINE_FLT_MIN.
(__ieee754_asinf): Use FLT_CHECK_FORCE_UFLOW.
* sysdeps/i386/fpu/e_atan2.S: Include <i386-math-asm.h>.
(dbl_min): Replace with use of DEFINE_DBL_MIN.
(__ieee754_atan2): Use DBL_CHECK_FORCE_UFLOW_NARROW.
* sysdeps/i386/fpu/e_atan2f.S: Include <i386-math-asm.h>.
(flt_min): Replace with use of DEFINE_FLT_MIN.
(__ieee754_atan2f): Use FLT_CHECK_FORCE_UFLOW_NARROW.
* sysdeps/i386/fpu/e_atanh.S: Include <i386-math-asm.h>.
(dbl_min): Replace with use of DEFINE_DBL_MIN.
(__ieee754_atanh): Use DBL_CHECK_FORCE_UFLOW_NONNEG.
* sysdeps/i386/fpu/e_atanhf.S: Include <i386-math-asm.h>.
(flt_min): Replace with use of DEFINE_FLT_MIN.
(__ieee754_atanhf): Use FLT_CHECK_FORCE_UFLOW_NONNEG.
* sysdeps/i386/fpu/e_exp2l.S: Include <i386-math-asm.h>.
(ldbl_min): Replace with use of DEFINE_LDBL_MIN.
(__ieee754_exp2l): Use LDBL_CHECK_FORCE_UFLOW_NONNEG_NAN.
* sysdeps/i386/fpu/e_expl.S: Include <i386-math-asm.h>.
[!USE_AS_EXPM1L] (cmin): Replace with use of DEFINE_LDBL_MIN.
(IEEE754_EXPL): Use LDBL_CHECK_FORCE_UFLOW_NONNEG.
* sysdeps/i386/fpu/s_atan.S: Include <i386-math-asm.h>.
(dbl_min): Replace with use of DEFINE_DBL_MIN.
(__atan): Use DBL_CHECK_FORCE_UFLOW.
* sysdeps/i386/fpu/s_atanf.S: Include <i386-math-asm.h>.
(flt_min): Replace with use of DEFINE_FLT_MIN.
(__atanf): Use FLT_CHECK_FORCE_UFLOW.
* sysdeps/i386/fpu/s_expm1.S: Include <i386-math-asm.h>.
(dbl_min): Replace with use of DEFINE_DBL_MIN.
(__expm1): Use DBL_CHECK_FORCE_UFLOW.  Move underflow check after
main computation.
* sysdeps/i386/fpu/s_expm1f.S: Include <i386-math-asm.h>.
(flt_min): Replace with use of DEFINE_FLT_MIN.
(__expm1f): Use FLT_CHECK_FORCE_UFLOW.  Move underflow check after
main computation.
* sysdeps/i386/fpu/s_log1p.S: Include <i386-math-asm.h>.
(dbl_min): Replace with use of DEFINE_DBL_MIN.
(MO): New macro.
(__log1p): Use MO.  Use DBL_CHECK_FORCE_UFLOW_NONNAN.
* sysdeps/i386/fpu/s_log1pf.S: Include <i386-math-asm.h>.
(flt_min): Replace with use of DEFINE_FLT_MIN.
(MO): New macro.
(__log1pf): Use MO.  Use FLT_CHECK_FORCE_UFLOW_NONNAN.
* sysdeps/i386/fpu/s_log1pl.S (MO): New macro.
(__log1pl): Use MO.

17 files changed:
ChangeLog
sysdeps/i386/fpu/e_asin.S
sysdeps/i386/fpu/e_asinf.S
sysdeps/i386/fpu/e_atan2.S
sysdeps/i386/fpu/e_atan2f.S
sysdeps/i386/fpu/e_atanh.S
sysdeps/i386/fpu/e_atanhf.S
sysdeps/i386/fpu/e_exp2l.S
sysdeps/i386/fpu/e_expl.S
sysdeps/i386/fpu/i386-math-asm.h
sysdeps/i386/fpu/s_atan.S
sysdeps/i386/fpu/s_atanf.S
sysdeps/i386/fpu/s_expm1.S
sysdeps/i386/fpu/s_expm1f.S
sysdeps/i386/fpu/s_log1p.S
sysdeps/i386/fpu/s_log1pf.S
sysdeps/i386/fpu/s_log1pl.S

index df079ca412d5963048d93903c41f41af4f459b65..dbe8c77d3beb469d53a96669f35822bb5f744ccc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,65 @@
 2015-09-24  Joseph Myers  <joseph@codesourcery.com>
 
+       * sysdeps/i386/fpu/i386-math-asm.h (DEFINE_LDBL_MIN): New macro.
+       (FLT_CHECK_FORCE_UFLOW): Likewise.
+       (DBL_CHECK_FORCE_UFLOW): Likewise.
+       (FLT_CHECK_FORCE_UFLOW_NARROW): Likewise.
+       (DBL_CHECK_FORCE_UFLOW_NARROW): Likewise.
+       (LDBL_CHECK_FORCE_UFLOW_NONNEG_NAN): Likewise.
+       (FLT_CHECK_FORCE_UFLOW_NONNAN): Likewise.
+       (DBL_CHECK_FORCE_UFLOW_NONNAN): Likewise.
+       (FLT_CHECK_FORCE_UFLOW_NONNEG): Likewise.
+       (DBL_CHECK_FORCE_UFLOW_NONNEG): Likewise.
+       (LDBL_CHECK_FORCE_UFLOW_NONNEG): Likewise.
+       * sysdeps/i386/fpu/e_asin.S: Include <i386-math-asm.h>.
+       (dbl_min): Replace with use of DEFINE_DBL_MIN.
+       (__ieee754_asin): Use DBL_CHECK_FORCE_UFLOW.
+       * sysdeps/i386/fpu/e_asinf.S: Include <i386-math-asm.h>.
+       (flt_min): Replace with use of DEFINE_FLT_MIN.
+       (__ieee754_asinf): Use FLT_CHECK_FORCE_UFLOW.
+       * sysdeps/i386/fpu/e_atan2.S: Include <i386-math-asm.h>.
+       (dbl_min): Replace with use of DEFINE_DBL_MIN.
+       (__ieee754_atan2): Use DBL_CHECK_FORCE_UFLOW_NARROW.
+       * sysdeps/i386/fpu/e_atan2f.S: Include <i386-math-asm.h>.
+       (flt_min): Replace with use of DEFINE_FLT_MIN.
+       (__ieee754_atan2f): Use FLT_CHECK_FORCE_UFLOW_NARROW.
+       * sysdeps/i386/fpu/e_atanh.S: Include <i386-math-asm.h>.
+       (dbl_min): Replace with use of DEFINE_DBL_MIN.
+       (__ieee754_atanh): Use DBL_CHECK_FORCE_UFLOW_NONNEG.
+       * sysdeps/i386/fpu/e_atanhf.S: Include <i386-math-asm.h>.
+       (flt_min): Replace with use of DEFINE_FLT_MIN.
+       (__ieee754_atanhf): Use FLT_CHECK_FORCE_UFLOW_NONNEG.
+       * sysdeps/i386/fpu/e_exp2l.S: Include <i386-math-asm.h>.
+       (ldbl_min): Replace with use of DEFINE_LDBL_MIN.
+       (__ieee754_exp2l): Use LDBL_CHECK_FORCE_UFLOW_NONNEG_NAN.
+       * sysdeps/i386/fpu/e_expl.S: Include <i386-math-asm.h>.
+       [!USE_AS_EXPM1L] (cmin): Replace with use of DEFINE_LDBL_MIN.
+       (IEEE754_EXPL): Use LDBL_CHECK_FORCE_UFLOW_NONNEG.
+       * sysdeps/i386/fpu/s_atan.S: Include <i386-math-asm.h>.
+       (dbl_min): Replace with use of DEFINE_DBL_MIN.
+       (__atan): Use DBL_CHECK_FORCE_UFLOW.
+       * sysdeps/i386/fpu/s_atanf.S: Include <i386-math-asm.h>.
+       (flt_min): Replace with use of DEFINE_FLT_MIN.
+       (__atanf): Use FLT_CHECK_FORCE_UFLOW.
+       * sysdeps/i386/fpu/s_expm1.S: Include <i386-math-asm.h>.
+       (dbl_min): Replace with use of DEFINE_DBL_MIN.
+       (__expm1): Use DBL_CHECK_FORCE_UFLOW.  Move underflow check after
+       main computation.
+       * sysdeps/i386/fpu/s_expm1f.S: Include <i386-math-asm.h>.
+       (flt_min): Replace with use of DEFINE_FLT_MIN.
+       (__expm1f): Use FLT_CHECK_FORCE_UFLOW.  Move underflow check after
+       main computation.
+       * sysdeps/i386/fpu/s_log1p.S: Include <i386-math-asm.h>.
+       (dbl_min): Replace with use of DEFINE_DBL_MIN.
+       (MO): New macro.
+       (__log1p): Use MO.  Use DBL_CHECK_FORCE_UFLOW_NONNAN.
+       * sysdeps/i386/fpu/s_log1pf.S: Include <i386-math-asm.h>.
+       (flt_min): Replace with use of DEFINE_FLT_MIN.
+       (MO): New macro.
+       (__log1pf): Use MO.  Use FLT_CHECK_FORCE_UFLOW_NONNAN.
+       * sysdeps/i386/fpu/s_log1pl.S (MO): New macro.
+       (__log1pl): Use MO.
+
        [BZ #19003]
        * sysdeps/x86_64/fpu/multiarch/Makefile (CFLAGS-e_pow-fma4.c): Add
        $(config-cflags-nofma).
index ea8cb6f1b2d2b1532270cf47eaef4209c754836f..39c8b47da4dc81dfd7fbdec1f090fb12b5e2a2f9 100644 (file)
@@ -4,15 +4,11 @@
  */
 
 #include <machine/asm.h>
+#include <i386-math-asm.h>
 
 RCSID("$NetBSD: e_asin.S,v 1.4 1995/05/08 23:45:40 jtc Exp $")
 
-       .section .rodata.cst8,"aM",@progbits,8
-
-       .p2align 3
-       .type dbl_min,@object
-dbl_min:       .byte 0, 0, 0, 0, 0, 0, 0x10, 0
-       ASM_SIZE_DIRECTIVE(dbl_min)
+DEFINE_DBL_MIN
 
 #ifdef PIC
 # define MO(op) op##@GOTOFF(%ecx)
@@ -36,20 +32,7 @@ ENTRY(__ieee754_asin)
        fmulp                           /* 1 - x^2 */
        fsqrt                           /* sqrt (1 - x^2) */
        fpatan
-       fldl    MO(dbl_min)
-       fld     %st(1)
-       fabs
-       fucompp
-       fnstsw
-       sahf
-       jnc     1f
-       subl    $8, %esp
-       cfi_adjust_cfa_offset (8)
-       fld     %st(0)
-       fmul    %st(0)
-       fstpl   (%esp)
-       addl    $8, %esp
-       cfi_adjust_cfa_offset (-8)
-1:     ret
+       DBL_CHECK_FORCE_UFLOW
+       ret
 END (__ieee754_asin)
 strong_alias (__ieee754_asin, __asin_finite)
index f7bda77fa60a1d51644caa67a7c6ef6bba275264..1102bdedfd327d3b31b8dcdb0974789a9a55cb99 100644 (file)
@@ -5,15 +5,13 @@
  */
 
 #include <machine/asm.h>
+#include <i386-math-asm.h>
 
 RCSID("$NetBSD: $")
 
        .section .rodata.cst4,"aM",@progbits,4
 
-       .p2align 2
-       .type flt_min,@object
-flt_min:       .byte 0, 0, 0x80, 0
-       ASM_SIZE_DIRECTIVE(flt_min)
+DEFINE_FLT_MIN
 
 #ifdef PIC
 # define MO(op) op##@GOTOFF(%ecx)
@@ -35,20 +33,7 @@ ENTRY(__ieee754_asinf)
        fsubp                           /* 1 - x^2 */
        fsqrt                           /* sqrt (1 - x^2) */
        fpatan
-       flds    MO(flt_min)
-       fld     %st(1)
-       fabs
-       fucompp
-       fnstsw
-       sahf
-       jnc     1f
-       subl    $4, %esp
-       cfi_adjust_cfa_offset (4)
-       fld     %st(0)
-       fmul    %st(0)
-       fstps   (%esp)
-       addl    $4, %esp
-       cfi_adjust_cfa_offset (-4)
-1:     ret
+       FLT_CHECK_FORCE_UFLOW
+       ret
 END (__ieee754_asinf)
 strong_alias (__ieee754_asinf, __asinf_finite)
index 6f5481fb5c1affa5da9ee46f31b0ffeebbcc82f3..25f43bb5a12a5a20514eb5b4b07bb690c2e758da 100644 (file)
@@ -4,15 +4,11 @@
  */
 
 #include <machine/asm.h>
+#include <i386-math-asm.h>
 
 RCSID("$NetBSD: e_atan2.S,v 1.4 1995/05/08 23:46:28 jtc Exp $")
 
-       .section .rodata.cst8,"aM",@progbits,8
-
-       .p2align 3
-       .type dbl_min,@object
-dbl_min:       .byte 0, 0, 0, 0, 0, 0, 0x10, 0
-       ASM_SIZE_DIRECTIVE(dbl_min)
+DEFINE_DBL_MIN
 
 #ifdef PIC
 # define MO(op) op##@GOTOFF(%ecx)
@@ -28,22 +24,7 @@ ENTRY(__ieee754_atan2)
        fldl     4(%esp)
        fldl    12(%esp)
        fpatan
-       fldl    MO(dbl_min)
-       fld     %st(1)
-       fabs
-       fucompp
-       fnstsw
-       sahf
-       jnc 1f
-       subl    $8, %esp
-       cfi_adjust_cfa_offset (8)
-       fld     %st(0)
-       fmul    %st(0)
-       fstpl   (%esp)
-       fstpl   (%esp)
-       fldl    (%esp)
-       addl    $8, %esp
-       cfi_adjust_cfa_offset (-8)
-1:     ret
+       DBL_CHECK_FORCE_UFLOW_NARROW
+       ret
 END (__ieee754_atan2)
 strong_alias (__ieee754_atan2, __atan2_finite)
index ec0eb3fd71c9966ce5d9d860935778f217f447ad..2bc909a76288a412bd30492cea5cccd1e0e72941 100644 (file)
@@ -4,15 +4,11 @@
  */
 
 #include <machine/asm.h>
+#include <i386-math-asm.h>
 
 RCSID("$NetBSD: e_atan2f.S,v 1.1 1995/05/08 23:35:10 jtc Exp $")
 
-       .section .rodata.cst4,"aM",@progbits,4
-
-       .p2align 2
-       .type flt_min,@object
-flt_min:       .byte 0, 0, 0x80, 0
-       ASM_SIZE_DIRECTIVE(flt_min)
+DEFINE_FLT_MIN
 
 #ifdef PIC
 # define MO(op) op##@GOTOFF(%ecx)
@@ -28,22 +24,7 @@ ENTRY(__ieee754_atan2f)
        flds    4(%esp)
        flds    8(%esp)
        fpatan
-       flds    MO(flt_min)
-       fld     %st(1)
-       fabs
-       fucompp
-       fnstsw
-       sahf
-       jnc 1f
-       subl    $4, %esp
-       cfi_adjust_cfa_offset (4)
-       fld     %st(0)
-       fmul    %st(0)
-       fstps   (%esp)
-       fstps   (%esp)
-       flds    (%esp)
-       addl    $4, %esp
-       cfi_adjust_cfa_offset (-4)
-1:     ret
+       FLT_CHECK_FORCE_UFLOW_NARROW
+       ret
 END (__ieee754_atan2f)
 strong_alias (__ieee754_atan2f, __atan2f_finite)
index 90d19bc9d62d1cc63a8862b5748116e570365eb0..5772bbf8025ab76255550997e41a454204a81a9b 100644 (file)
@@ -18,6 +18,7 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <machine/asm.h>
+#include <i386-math-asm.h>
 
        .section .rodata
 
@@ -35,12 +36,7 @@ limit:       .double 0.29
 ln2_2: .tfloat 0.3465735902799726547086160
        ASM_SIZE_DIRECTIVE(ln2_2)
 
-       .section .rodata.cst8,"aM",@progbits,8
-
-       .p2align 3
-       .type dbl_min,@object
-dbl_min:       .byte 0, 0, 0, 0, 0, 0, 0x10, 0
-       ASM_SIZE_DIRECTIVE(dbl_min)
+DEFINE_DBL_MIN
 
 #ifdef PIC
 #define MO(op) op##@GOTOFF(%edx)
@@ -88,18 +84,8 @@ ENTRY(__ieee754_atanh)
        sahf
        jae     4f
        fyl2xp1                 // 0.5*ln2*ld(1+2*|x|+(2*|x|^2)/(1-|x|))
-       fcoml   MO(dbl_min)
-       fnstsw
-       sahf
-       jae     8f
-       subl    $8, %esp
-       cfi_adjust_cfa_offset (8)
-       fld     %st(0)
-       fmul    %st(0)
-       fstpl   (%esp)
-       addl    $8, %esp
-       cfi_adjust_cfa_offset (-8)
-8:     jecxz   3f
+       DBL_CHECK_FORCE_UFLOW_NONNEG
+       jecxz   3f
        fchs                    // 0.5*ln2*ld(1+2*x+(2*x^2)/(1-x))
 3:     ret
 
index 1c8969e5ec135b176af5e6396a20bb6e535f289f..6e4184908eb2ff8f8b4568ab73484a980eaa504e 100644 (file)
@@ -18,6 +18,7 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <machine/asm.h>
+#include <i386-math-asm.h>
 
        .section .rodata
 
@@ -36,12 +37,7 @@ limit:       .double 0.29
 ln2_2: .tfloat 0.3465735902799726547086160
        ASM_SIZE_DIRECTIVE(ln2_2)
 
-       .section .rodata.cst4,"aM",@progbits,4
-
-       .p2align 2
-       .type flt_min,@object
-flt_min:       .byte 0, 0, 0x80, 0
-       ASM_SIZE_DIRECTIVE(flt_min)
+DEFINE_FLT_MIN
 
 #ifdef PIC
 #define MO(op) op##@GOTOFF(%edx)
@@ -84,18 +80,8 @@ ENTRY(__ieee754_atanhf)
        sahf
        jae     4f
        fyl2xp1                 // 0.5*ln2*ld(1+2*|x|+(2*|x|^2)/(1-|x|))
-       fcoms   MO(flt_min)
-       fnstsw
-       sahf
-       jae     6f
-       subl    $4, %esp
-       cfi_adjust_cfa_offset (4)
-       fld     %st(0)
-       fmul    %st(0)
-       fstps   (%esp)
-       addl    $4, %esp
-       cfi_adjust_cfa_offset (-4)
-6:     jecxz   3f
+       FLT_CHECK_FORCE_UFLOW_NONNEG
+       jecxz   3f
        fchs                    // 0.5*ln2*ld(1+2*x+(2*x^2)/(1-x))
 3:     ret
 
index 9a5ff95a6cc1c58144b116e640b04499595ddd55..c4cb73d589b09627c718e989e37db57194311ceb 100644 (file)
@@ -5,13 +5,9 @@
  */
 
 #include <machine/asm.h>
+#include <i386-math-asm.h>
 
-       .section .rodata.cst16,"aM",@progbits,16
-       .p2align 4
-       .type ldbl_min,@object
-ldbl_min:      .byte 0, 0, 0, 0, 0, 0, 0, 0x80, 0x1, 0
-       .byte 0, 0, 0, 0, 0, 0
-       ASM_SIZE_DIRECTIVE(ldbl_min)
+DEFINE_LDBL_MIN
 
 #ifdef PIC
 # define MO(op) op##@GOTOFF(%ecx)
@@ -52,17 +48,8 @@ ENTRY(__ieee754_exp2l)
        faddp                           /* 2^(fract(x)) */
        fscale                          /* e^x */
        fstp    %st(1)
-       /* Ensure underflow for tiny result.  */
-       fldt    MO(ldbl_min)
-       fld     %st(1)
-       fucompp
-       fnstsw
-       sahf
-       jnc     4f
-       fld     %st
-       fmul    %st
-       fstp    %st
-4:     ret
+       LDBL_CHECK_FORCE_UFLOW_NONNEG_NAN
+       ret
 
 1:     testl   $0x200, %eax            /* Test sign.  */
        jz      2f                      /* If positive, jump.  */
index 711c86a6e8cf9a5ef63357f82bd6006eb2160d04..64e0d96839f678b1180d5f243c3ccad2d8cadc20 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <machine/asm.h>
+#include <i386-math-asm.h>
 
 #ifdef USE_AS_EXP10L
 # define IEEE754_EXPL __ieee754_exp10l
@@ -65,10 +66,7 @@ c1:  .byte 0x20, 0xfa, 0xee, 0xc2, 0x5f, 0x70, 0xa5, 0xec, 0xed, 0x3f
 csat:  .byte 0, 0, 0, 0, 0, 0, 0, 0x80, 0x0e, 0x40
        .byte 0, 0, 0, 0, 0, 0
        ASM_SIZE_DIRECTIVE(csat)
-       .type cmin,@object
-cmin:  .byte 0, 0, 0, 0, 0, 0, 0, 0x80, 0x1, 0
-       .byte 0, 0, 0, 0, 0, 0
-       ASM_SIZE_DIRECTIVE(cmin)
+DEFINE_LDBL_MIN
 #endif
 
 #ifdef PIC
@@ -199,18 +197,9 @@ ENTRY(IEEE754_EXPL)
        fstp    %st(1)          /* 2  */
        fscale                  /* 2 scale factor is st(1); base^x */
        fstp    %st(1)          /* 1  */
-       /* Ensure underflow for tiny result.  */
-       fldt    MO(cmin)        /* 2 cmin  */
-       fld     %st(1)          /* 3  */
-       fcompp                  /* 1  */
-       fnstsw
-       sahf
-       jnc     6f
-       fld     %st
-       fmul    %st
-       fstp    %st
+       LDBL_CHECK_FORCE_UFLOW_NONNEG
 #endif
-6:     fstp    %st(1)          /* 0  */
+       fstp    %st(1)          /* 0  */
        jmp     2f
 1:
 #ifdef USE_AS_EXPM1L
index c15029d2eee72742d46e4cf3a320cbf074eec6b9..5d8d847cc3666bfb56cb74abc305384e2b8b46bf 100644 (file)
@@ -52,6 +52,14 @@ flt_min:                                     \
 dbl_min:                                       \
        .byte 0, 0, 0, 0, 0, 0, 0x10, 0;        \
        .size dbl_min, .-dbl_min;
+#define DEFINE_LDBL_MIN                                        \
+       .section .rodata.cst16,"aM",@progbits,16;       \
+       .p2align 4;                                     \
+       .type ldbl_min,@object;                         \
+ldbl_min:                                              \
+       .byte 0, 0, 0, 0, 0, 0, 0, 0x80, 0x1, 0;        \
+       .byte 0, 0, 0, 0, 0, 0;                         \
+       .size ldbl_min, .-ldbl_min;
 
 /* Remove excess range and precision by storing a value on the stack
    and loading it back.  The value is given to be nonnegative or NaN;
@@ -123,4 +131,164 @@ dbl_min:                                  \
        addl    $8, %esp;                       \
        cfi_adjust_cfa_offset (-8);
 
+/* Force an underflow exception if the given value is subnormal.  The
+   relevant constant for the minimum of the type must have been
+   defined, the MO macro must have been defined for access to memory
+   operands, and, if PIC, the PIC register must have been loaded.  */
+#define FLT_CHECK_FORCE_UFLOW                  \
+       flds    MO(flt_min);                    \
+       fld     %st(1);                         \
+       fabs;                                   \
+       fucompp;                                \
+       fnstsw;                                 \
+       sahf;                                   \
+       jnc 6424f;                              \
+       subl    $4, %esp;                       \
+       cfi_adjust_cfa_offset (4);              \
+       fld     %st(0);                         \
+       fmul    %st(0);                         \
+       fstps   (%esp);                         \
+       addl    $4, %esp;                       \
+       cfi_adjust_cfa_offset (-4);             \
+6424:
+#define DBL_CHECK_FORCE_UFLOW                  \
+       fldl    MO(dbl_min);                    \
+       fld     %st(1);                         \
+       fabs;                                   \
+       fucompp;                                \
+       fnstsw;                                 \
+       sahf;                                   \
+       jnc 6453f;                              \
+       subl    $8, %esp;                       \
+       cfi_adjust_cfa_offset (8);              \
+       fld     %st(0);                         \
+       fmul    %st(0);                         \
+       fstpl   (%esp);                         \
+       addl    $8, %esp;                       \
+       cfi_adjust_cfa_offset (-8);             \
+6453:
+
+/* Likewise, but also remove excess range and precision if the value
+   is subnormal.  */
+#define FLT_CHECK_FORCE_UFLOW_NARROW           \
+       flds    MO(flt_min);                    \
+       fld     %st(1);                         \
+       fabs;                                   \
+       fucompp;                                \
+       fnstsw;                                 \
+       sahf;                                   \
+       jnc 6424f;                              \
+       subl    $4, %esp;                       \
+       cfi_adjust_cfa_offset (4);              \
+       fld     %st(0);                         \
+       fmul    %st(0);                         \
+       fstps   (%esp);                         \
+       fstps   (%esp);                         \
+       flds    (%esp);                         \
+       addl    $4, %esp;                       \
+       cfi_adjust_cfa_offset (-4);             \
+6424:
+#define DBL_CHECK_FORCE_UFLOW_NARROW           \
+       fldl    MO(dbl_min);                    \
+       fld     %st(1);                         \
+       fabs;                                   \
+       fucompp;                                \
+       fnstsw;                                 \
+       sahf;                                   \
+       jnc 6453f;                              \
+       subl    $8, %esp;                       \
+       cfi_adjust_cfa_offset (8);              \
+       fld     %st(0);                         \
+       fmul    %st(0);                         \
+       fstpl   (%esp);                         \
+       fstpl   (%esp);                         \
+       fldl    (%esp);                         \
+       addl    $8, %esp;                       \
+       cfi_adjust_cfa_offset (-8);             \
+6453:
+
+/* Likewise, but the argument is nonnegative or NaN.  */
+#define LDBL_CHECK_FORCE_UFLOW_NONNEG_NAN      \
+       fldt    MO(ldbl_min);                   \
+       fld     %st(1);                         \
+       fucompp;                                \
+       fnstsw;                                 \
+       sahf;                                   \
+       jnc 6464f;                              \
+       fld     %st(0);                         \
+       fmul    %st(0);                         \
+       fstp    %st(0);                         \
+6464:
+
+/* Likewise, but the argument is not a NaN.  */
+#define FLT_CHECK_FORCE_UFLOW_NONNAN           \
+       fld %st(0);                             \
+       fabs;                                   \
+       fcomps  MO(flt_min);                    \
+       fnstsw;                                 \
+       sahf;                                   \
+       jnc 6424f;                              \
+       subl    $4, %esp;                       \
+       cfi_adjust_cfa_offset (4);              \
+       fld     %st(0);                         \
+       fmul    %st(0);                         \
+       fstps   (%esp);                         \
+       addl    $4, %esp;                       \
+       cfi_adjust_cfa_offset (-4);             \
+6424:
+#define DBL_CHECK_FORCE_UFLOW_NONNAN           \
+       fld %st(0);                             \
+       fabs;                                   \
+       fcompl  MO(dbl_min);                    \
+       fnstsw;                                 \
+       sahf;                                   \
+       jnc 6453f;                              \
+       subl    $8, %esp;                       \
+       cfi_adjust_cfa_offset (8);              \
+       fld     %st(0);                         \
+       fmul    %st(0);                         \
+       fstpl   (%esp);                         \
+       addl    $8, %esp;                       \
+       cfi_adjust_cfa_offset (-8);             \
+6453:
+
+/* Likewise, but the argument is nonnegative and not a NaN.  */
+#define FLT_CHECK_FORCE_UFLOW_NONNEG           \
+       fcoms   MO(flt_min);                    \
+       fnstsw;                                 \
+       sahf;                                   \
+       jnc 6424f;                              \
+       subl    $4, %esp;                       \
+       cfi_adjust_cfa_offset (4);              \
+       fld     %st(0);                         \
+       fmul    %st(0);                         \
+       fstps   (%esp);                         \
+       addl    $4, %esp;                       \
+       cfi_adjust_cfa_offset (-4);             \
+6424:
+#define DBL_CHECK_FORCE_UFLOW_NONNEG           \
+       fcoml   MO(dbl_min);                    \
+       fnstsw;                                 \
+       sahf;                                   \
+       jnc 6453f;                              \
+       subl    $8, %esp;                       \
+       cfi_adjust_cfa_offset (8);              \
+       fld     %st(0);                         \
+       fmul    %st(0);                         \
+       fstpl   (%esp);                         \
+       addl    $8, %esp;                       \
+       cfi_adjust_cfa_offset (-8);             \
+6453:
+#define LDBL_CHECK_FORCE_UFLOW_NONNEG          \
+       fldt    MO(ldbl_min);                   \
+       fld     %st(1);                         \
+       fcompp;                                 \
+       fnstsw;                                 \
+       sahf;                                   \
+       jnc 6464f;                              \
+       fld     %st(0);                         \
+       fmul    %st(0);                         \
+       fstp    %st(0);                         \
+6464:
+
 #endif /* i386-math-asm.h.  */
index c28b73ce75c95838ad24159280301e269676c402..644de78febf1d4388cb24bb3f6f342496ce6a1dd 100644 (file)
@@ -4,15 +4,11 @@
  */
 
 #include <machine/asm.h>
+#include <i386-math-asm.h>
 
 RCSID("$NetBSD: s_atan.S,v 1.4 1995/05/08 23:50:41 jtc Exp $")
 
-       .section .rodata.cst8,"aM",@progbits,8
-
-       .p2align 3
-       .type dbl_min,@object
-dbl_min:       .byte 0, 0, 0, 0, 0, 0, 0x10, 0
-       ASM_SIZE_DIRECTIVE(dbl_min)
+DEFINE_DBL_MIN
 
 #ifdef PIC
 # define MO(op) op##@GOTOFF(%ecx)
@@ -28,20 +24,7 @@ ENTRY(__atan)
        fldl    4(%esp)
        fld1
        fpatan
-       fldl    MO(dbl_min)
-       fld     %st(1)
-       fabs
-       fucompp
-       fnstsw
-       sahf
-       jnc 1f
-       subl    $8, %esp
-       cfi_adjust_cfa_offset (8)
-       fld     %st(0)
-       fmul    %st(0)
-       fstpl   (%esp)
-       addl    $8, %esp
-       cfi_adjust_cfa_offset (-8)
-1:     ret
+       DBL_CHECK_FORCE_UFLOW
+       ret
 END (__atan)
 weak_alias (__atan, atan)
index da3c2a64b558cc1b638aac1d31a8610e757f66c8..0589c1135eacc04e9fd2da17de360353f211e127 100644 (file)
@@ -4,15 +4,11 @@
  */
 
 #include <machine/asm.h>
+#include <i386-math-asm.h>
 
 RCSID("$NetBSD: s_atanf.S,v 1.3 1995/05/08 23:51:33 jtc Exp $")
 
-       .section .rodata.cst4,"aM",@progbits,4
-
-       .p2align 2
-       .type flt_min,@object
-flt_min:       .byte 0, 0, 0x80, 0
-       ASM_SIZE_DIRECTIVE(flt_min)
+DEFINE_FLT_MIN
 
 #ifdef PIC
 # define MO(op) op##@GOTOFF(%ecx)
@@ -28,20 +24,7 @@ ENTRY(__atanf)
        flds    4(%esp)
        fld1
        fpatan
-       flds    MO(flt_min)
-       fld     %st(1)
-       fabs
-       fucompp
-       fnstsw
-       sahf
-       jnc 1f
-       subl    $4, %esp
-       cfi_adjust_cfa_offset (4)
-       fld     %st(0)
-       fmul    %st(0)
-       fstps   (%esp)
-       addl    $4, %esp
-       cfi_adjust_cfa_offset (-4)
-1:     ret
+       FLT_CHECK_FORCE_UFLOW
+       ret
 END (__atanf)
 weak_alias (__atanf, atanf)
index 05e5285d7bb560ffde57424c6ca6210676450cb3..b4694c8e37ec9f1ad4acebb4924ba8c11df3ffd8 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <sysdep.h>
 #include <machine/asm.h>
+#include <i386-math-asm.h>
 
        .section .rodata
 
@@ -37,12 +38,7 @@ one: .double 1.0
 l2e:   .tfloat 1.442695040888963407359924681002
        ASM_SIZE_DIRECTIVE(l2e)
 
-       .section .rodata.cst8,"aM",@progbits,8
-
-       .p2align 3
-       .type dbl_min,@object
-dbl_min:       .byte 0, 0, 0, 0, 0, 0, 0x10, 0
-       ASM_SIZE_DIRECTIVE(dbl_min)
+DEFINE_DBL_MIN
 
 #ifdef PIC
 #define MO(op) op##@GOTOFF(%edx)
@@ -81,21 +77,6 @@ ENTRY(__expm1)
 #ifdef PIC
        LOAD_PIC_REG (dx)
 #endif
-       fld     %st
-       fabs
-       fcoml   MO(dbl_min)
-       fstp    %st
-       fnstsw
-       sahf
-       jae     5f
-       subl    $8, %esp
-       cfi_adjust_cfa_offset (8)
-       fld     %st(0)
-       fmul    %st(0)
-       fstpl   (%esp)
-       addl    $8, %esp
-       cfi_adjust_cfa_offset (-8)
-       ret
 
 5:     fldt    MO(l2e)         // log2(e) : x
        fmulp                   // log2(e)*x
@@ -122,6 +103,7 @@ ENTRY(__expm1)
        fsubrl  MO(one)         // 1-2^int(log2(e)*x) : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
        fstp    %st(1)          // 1-2^int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
        fsubrp  %st, %st(1)     // 2^(log2(e)*x)
+       DBL_CHECK_FORCE_UFLOW
        ret
 
 2:     fstp    %st
index a83e435e2270e6551e7f01eb3bda43aaa9c2a947..5522902527131223af5323e4d182f138d42d3725 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <sysdep.h>
 #include <machine/asm.h>
+#include <i386-math-asm.h>
 
        .section .rodata
 
@@ -37,12 +38,7 @@ one: .double 1.0
 l2e:   .tfloat 1.442695040888963407359924681002
        ASM_SIZE_DIRECTIVE(l2e)
 
-       .section .rodata.cst4,"aM",@progbits,4
-
-       .p2align 2
-       .type flt_min,@object
-flt_min:       .byte 0, 0, 0x80, 0
-       ASM_SIZE_DIRECTIVE(flt_min)
+DEFINE_FLT_MIN
 
 #ifdef PIC
 #define MO(op) op##@GOTOFF(%edx)
@@ -81,21 +77,6 @@ ENTRY(__expm1f)
 #ifdef PIC
        LOAD_PIC_REG (dx)
 #endif
-       fld     %st
-       fabs
-       fcoms   MO(flt_min)
-       fstp    %st
-       fnstsw
-       sahf
-       jae     5f
-       subl    $4, %esp
-       cfi_adjust_cfa_offset (4)
-       fld     %st(0)
-       fmul    %st(0)
-       fstps   (%esp)
-       addl    $4, %esp
-       cfi_adjust_cfa_offset (-4)
-       ret
 
 5:     fldt    MO(l2e)         // log2(e) : x
        fmulp                   // log2(e)*x
@@ -122,6 +103,7 @@ ENTRY(__expm1f)
        fsubrl  MO(one)         // 1-2^int(log2(e)*x) : int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
        fstp    %st(1)          // 1-2^int(log2(e)*x) : 2^(log2(e)*x)-2^int(log2(e)*x)
        fsubrp  %st, %st(1)     // 2^(log2(e)*x)
+       FLT_CHECK_FORCE_UFLOW
        ret
 
 2:     fstp    %st
index c2559a3f1899f610287d77b12947110292af9f0d..7978e76095bff0731a0f40cfcb36b1d75870a857 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <machine/asm.h>
+#include <i386-math-asm.h>
 
 RCSID("$NetBSD: s_log1p.S,v 1.7 1995/05/09 00:10:58 jtc Exp $")
 
@@ -17,12 +18,13 @@ RCSID("$NetBSD: s_log1p.S,v 1.7 1995/05/09 00:10:58 jtc Exp $")
 limit: .double 0.29
 one:   .double 1.0
 
-       .section .rodata.cst8,"aM",@progbits,8
+DEFINE_DBL_MIN
 
-       .p2align 3
-       .type dbl_min,@object
-dbl_min:       .byte 0, 0, 0, 0, 0, 0, 0x10, 0
-       ASM_SIZE_DIRECTIVE(dbl_min)
+#ifdef PIC
+# define MO(op) op##@GOTOFF(%edx)
+#else
+# define MO(op) op
+#endif
 
 /*
  * Use the fyl2xp1 function when the argument is in the range -0.29 to 0.29,
@@ -44,43 +46,18 @@ ENTRY(__log1p)
        sahf
        jc      3f              // in case x is NaN or ±Inf
 4:     fabs
-#ifdef PIC
-       fcompl  limit@GOTOFF(%edx)
-#else
-       fcompl  limit
-#endif
+       fcompl  MO(limit)
        fnstsw
        sahf
        jc      2f
 
-#ifdef PIC
-       faddl   one@GOTOFF(%edx)
-#else
-       faddl   one
-#endif
+       faddl   MO(one)
        fyl2x
        ret
 
 2:     fyl2xp1
-#ifdef PIC
-       fldl    dbl_min@GOTOFF(%edx)
-#else
-       fldl    dbl_min
-#endif
-       fld     %st(1)
-       fabs
-       fucompp
-       fnstsw
-       sahf
-       jnc     1f
-       subl    $8, %esp
-       cfi_adjust_cfa_offset (8)
-       fld     %st(0)
-       fmul    %st(0)
-       fstpl   (%esp)
-       addl    $8, %esp
-       cfi_adjust_cfa_offset (-8)
-1:     ret
+       DBL_CHECK_FORCE_UFLOW_NONNAN
+       ret
 
 3:     jp      4b              // in case x is ±Inf
        fstp    %st(1)
index 8fca22e4ff9bc99643e0805fa1aceb0821b67484..acaa299d94835fd250961b61586c367aa0fc028a 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <machine/asm.h>
+#include <i386-math-asm.h>
 
 RCSID("$NetBSD: s_log1pf.S,v 1.4 1995/05/09 00:13:05 jtc Exp $")
 
@@ -17,12 +18,13 @@ RCSID("$NetBSD: s_log1pf.S,v 1.4 1995/05/09 00:13:05 jtc Exp $")
 limit: .float 0.29
 one:   .float 1.0
 
-       .section .rodata.cst4,"aM",@progbits,4
+DEFINE_FLT_MIN
 
-       .p2align 2
-       .type flt_min,@object
-flt_min:       .byte 0, 0, 0x80, 0
-       ASM_SIZE_DIRECTIVE(flt_min)
+#ifdef PIC
+# define MO(op) op##@GOTOFF(%edx)
+#else
+# define MO(op) op
+#endif
 
 /*
  * Use the fyl2xp1 function when the argument is in the range -0.29 to 0.29,
@@ -44,43 +46,18 @@ ENTRY(__log1pf)
        sahf
        jc      3f              // in case x is NaN or ±Inf
 4:     fabs
-#ifdef PIC
-       fcomps  limit@GOTOFF(%edx)
-#else
-       fcomps  limit
-#endif
+       fcomps  MO(limit)
        fnstsw
        sahf
        jc      2f
 
-#ifdef PIC
-       fadds   one@GOTOFF(%edx)
-#else
-       fadds   one
-#endif
+       fadds   MO(one)
        fyl2x
        ret
 
 2:     fyl2xp1
-#ifdef PIC
-       flds    flt_min@GOTOFF(%edx)
-#else
-       flds    flt_min
-#endif
-       fld     %st(1)
-       fabs
-       fucompp
-       fnstsw
-       sahf
-       jnc     1f
-       subl    $4, %esp
-       cfi_adjust_cfa_offset (4)
-       fld     %st(0)
-       fmul    %st(0)
-       fstps   (%esp)
-       addl    $4, %esp
-       cfi_adjust_cfa_offset (-4)
-1:     ret
+       FLT_CHECK_FORCE_UFLOW_NONNAN
+       ret
 
 3:     jp      4b              // in case x is ±Inf
        fstp    %st(1)
index 8f87cf61c62487ab28ed1f4d80873abb13001f1c..98965fa48ce432e6faa749297b3cc916445f1a68 100644 (file)
@@ -22,6 +22,12 @@ limit:       .tfloat 0.29
           but it helps to optimize the code.  */
 one:   .double 1.0
 
+#ifdef PIC
+# define MO(op) op##@GOTOFF(%edx)
+#else
+# define MO(op) op
+#endif
+
 /*
  * Use the fyl2xp1 function when the argument is in the range -0.29 to 0.29,
  * otherwise fyl2x with the needed extra computation.
@@ -43,11 +49,7 @@ ENTRY(__log1pl)
        jc      3f              // in case x is NaN or ±Inf
 4:
        fabs
-#ifdef PIC
-       fldt    limit@GOTOFF(%edx)
-#else
-       fldt    limit
-#endif
+       fldt    MO(limit)
        fcompp
        fnstsw
        sahf
@@ -58,11 +60,7 @@ ENTRY(__log1pl)
        cmpl    $0xc040, %eax
        jae     5f
 
-#ifdef PIC
-       faddl   one@GOTOFF(%edx)
-#else
-       faddl   one
-#endif
+       faddl   MO(one)
 5:     fyl2x
        ret