Refactor i386 libm code forcing underflow exceptions.

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.
This commit is contained in:
Joseph Myers 2015-09-24 21:41:00 +00:00
parent 51df260506
commit 37825319ee
17 changed files with 304 additions and 316 deletions

View File

@ -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).

View 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)

View 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)

View 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)

View 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)

View 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

View 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

View 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. */

View 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

View 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. */

View 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)

View 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)

View 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

View 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

View 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)

View 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)

View 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