Refactor x86_64 libm code forcing underflow exceptions.

This patch refactors code in sysdeps/x86_64/fpu that forces underflow
exceptions and closely follows corresponding i386 code to use common
macros in x86_64-math-asm.h for that purpose.  This is mainly about
keeping the code similar to the i386 code as far as possible, since
each macro apart from DEFINE_LDBL_MIN ends up used only once.  It
would be possible to do a further refactoring to share these macros
between i386 and x86_64 (with i386 using the fcomip / fucomip versions
when building for i686 and above), but I have no immediate plans to do
so.

Tested for x86_64.

	* sysdeps/x86_64/fpu/x86_64-math-asm.h: New file.
	* sysdeps/x86_64/fpu/e_exp2l.S: Include <x86_64-math-asm.h>.
	(ldbl_min): Replace with use of DEFINE_LDBL_MIN.
	(__ieee754_exp2l): Use LDBL_CHECK_FORCE_UFLOW_NONNEG_NAN.
	* sysdeps/x86_64/fpu/e_expl.S: Include <x86_64-math-asm.h>.
	[!USE_AS_EXPM1L] (cmin): Replace with use of DEFINE_LDBL_MIN.
	(IEEE754_EXPL): Use LDBL_CHECK_FORCE_UFLOW_NONNEG.
This commit is contained in:
Joseph Myers 2015-09-24 22:25:30 +00:00
parent 1a19b8894f
commit b2a64460ba
4 changed files with 77 additions and 30 deletions

View File

@ -1,5 +1,13 @@
2015-09-24 Joseph Myers <joseph@codesourcery.com>
* sysdeps/x86_64/fpu/x86_64-math-asm.h: New file.
* sysdeps/x86_64/fpu/e_exp2l.S: Include <x86_64-math-asm.h>.
(ldbl_min): Replace with use of DEFINE_LDBL_MIN.
(__ieee754_exp2l): Use LDBL_CHECK_FORCE_UFLOW_NONNEG_NAN.
* sysdeps/x86_64/fpu/e_expl.S: Include <x86_64-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/e_atanh.S (__ieee754_atanh) [PIC]: Use
LOAD_PIC_REG.

View File

@ -6,13 +6,9 @@
*/
#include <machine/asm.h>
#include <x86_64-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##(%rip)
@ -50,16 +46,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)
fucomip %st(1), %st
fstp %st
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 <x86_64-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
@ -192,17 +190,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 */
fcomip %st(1), %st /* 2 */
fstp %st /* 1 */
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

@ -0,0 +1,61 @@
/* Helper macros for x86_64 libm functions.
Copyright (C) 2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef _X86_64_MATH_ASM_H
#define _X86_64_MATH_ASM_H 1
/* Define constants for the minimum value of a floating-point
type. */
#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;
/* Force an underflow exception if the given value (nonnegative or
NaN) 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 LDBL_CHECK_FORCE_UFLOW_NONNEG_NAN \
fldt MO(ldbl_min); \
fld %st(1); \
fucomip %st(1), %st(0); \
fstp %st(0); \
jnc 6464f; \
fld %st(0); \
fmul %st(0); \
fstp %st(0); \
6464:
/* Likewise, but the argument is nonnegative and not a NaN. */
#define LDBL_CHECK_FORCE_UFLOW_NONNEG \
fldt MO(ldbl_min); \
fld %st(1); \
fcomip %st(1), %st(0); \
fstp %st(0); \
jnc 6464f; \
fld %st(0); \
fmul %st(0); \
fstp %st(0); \
6464:
#endif /* x86_64-math-asm.h. */