mirror of
git://sourceware.org/git/glibc.git
synced 2025-02-23 13:09:58 +08:00
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:
parent
1a19b8894f
commit
b2a64460ba
@ -1,5 +1,13 @@
|
|||||||
2015-09-24 Joseph Myers <joseph@codesourcery.com>
|
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
|
* sysdeps/i386/fpu/e_atanh.S (__ieee754_atanh) [PIC]: Use
|
||||||
LOAD_PIC_REG.
|
LOAD_PIC_REG.
|
||||||
|
|
||||||
|
@ -6,13 +6,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <machine/asm.h>
|
#include <machine/asm.h>
|
||||||
|
#include <x86_64-math-asm.h>
|
||||||
|
|
||||||
.section .rodata.cst16,"aM",@progbits,16
|
DEFINE_LDBL_MIN
|
||||||
.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)
|
|
||||||
|
|
||||||
#ifdef PIC
|
#ifdef PIC
|
||||||
# define MO(op) op##(%rip)
|
# define MO(op) op##(%rip)
|
||||||
@ -50,16 +46,8 @@ ENTRY(__ieee754_exp2l)
|
|||||||
faddp /* 2^(fract(x)) */
|
faddp /* 2^(fract(x)) */
|
||||||
fscale /* e^x */
|
fscale /* e^x */
|
||||||
fstp %st(1)
|
fstp %st(1)
|
||||||
/* Ensure underflow for tiny result. */
|
LDBL_CHECK_FORCE_UFLOW_NONNEG_NAN
|
||||||
fldt MO(ldbl_min)
|
ret
|
||||||
fld %st(1)
|
|
||||||
fucomip %st(1), %st
|
|
||||||
fstp %st
|
|
||||||
jnc 4f
|
|
||||||
fld %st
|
|
||||||
fmul %st
|
|
||||||
fstp %st
|
|
||||||
4: ret
|
|
||||||
|
|
||||||
1: testl $0x200, %eax /* Test sign. */
|
1: testl $0x200, %eax /* Test sign. */
|
||||||
jz 2f /* If positive, jump. */
|
jz 2f /* If positive, jump. */
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <machine/asm.h>
|
#include <machine/asm.h>
|
||||||
|
#include <x86_64-math-asm.h>
|
||||||
|
|
||||||
#ifdef USE_AS_EXP10L
|
#ifdef USE_AS_EXP10L
|
||||||
# define IEEE754_EXPL __ieee754_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
|
csat: .byte 0, 0, 0, 0, 0, 0, 0, 0x80, 0x0e, 0x40
|
||||||
.byte 0, 0, 0, 0, 0, 0
|
.byte 0, 0, 0, 0, 0, 0
|
||||||
ASM_SIZE_DIRECTIVE(csat)
|
ASM_SIZE_DIRECTIVE(csat)
|
||||||
.type cmin,@object
|
DEFINE_LDBL_MIN
|
||||||
cmin: .byte 0, 0, 0, 0, 0, 0, 0, 0x80, 0x1, 0
|
|
||||||
.byte 0, 0, 0, 0, 0, 0
|
|
||||||
ASM_SIZE_DIRECTIVE(cmin)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PIC
|
#ifdef PIC
|
||||||
@ -192,17 +190,9 @@ ENTRY(IEEE754_EXPL)
|
|||||||
fstp %st(1) /* 2 */
|
fstp %st(1) /* 2 */
|
||||||
fscale /* 2 scale factor is st(1); base^x */
|
fscale /* 2 scale factor is st(1); base^x */
|
||||||
fstp %st(1) /* 1 */
|
fstp %st(1) /* 1 */
|
||||||
/* Ensure underflow for tiny result. */
|
LDBL_CHECK_FORCE_UFLOW_NONNEG
|
||||||
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
|
|
||||||
#endif
|
#endif
|
||||||
6: fstp %st(1) /* 0 */
|
fstp %st(1) /* 0 */
|
||||||
jmp 2f
|
jmp 2f
|
||||||
1:
|
1:
|
||||||
#ifdef USE_AS_EXPM1L
|
#ifdef USE_AS_EXPM1L
|
||||||
|
61
sysdeps/x86_64/fpu/x86_64-math-asm.h
Normal file
61
sysdeps/x86_64/fpu/x86_64-math-asm.h
Normal 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. */
|
Loading…
Reference in New Issue
Block a user