aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2015-09-24 22:25:30 +0000
committerJoseph Myers <joseph@codesourcery.com>2015-09-24 22:25:30 +0000
commitb2a64460ba9aca39e92731da67cc6344acb483bc (patch)
tree213e279495212accf939a0d03c10e16c131963cc
parent1a19b8894f93878f99025096ec1d3b6af7db6f78 (diff)
downloadglibc-b2a64460ba9aca39e92731da67cc6344acb483bc.zip
glibc-b2a64460ba9aca39e92731da67cc6344acb483bc.tar.gz
glibc-b2a64460ba9aca39e92731da67cc6344acb483bc.tar.bz2
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.
-rw-r--r--ChangeLog8
-rw-r--r--sysdeps/x86_64/fpu/e_exp2l.S20
-rw-r--r--sysdeps/x86_64/fpu/e_expl.S18
-rw-r--r--sysdeps/x86_64/fpu/x86_64-math-asm.h61
4 files changed, 77 insertions, 30 deletions
diff --git a/ChangeLog b/ChangeLog
index 851dfc0..4105a9e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/sysdeps/x86_64/fpu/e_exp2l.S b/sysdeps/x86_64/fpu/e_exp2l.S
index d634ad3..0e059b7 100644
--- a/sysdeps/x86_64/fpu/e_exp2l.S
+++ b/sysdeps/x86_64/fpu/e_exp2l.S
@@ -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. */
diff --git a/sysdeps/x86_64/fpu/e_expl.S b/sysdeps/x86_64/fpu/e_expl.S
index 14dd29d..8b3ddae 100644
--- a/sysdeps/x86_64/fpu/e_expl.S
+++ b/sysdeps/x86_64/fpu/e_expl.S
@@ -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
diff --git a/sysdeps/x86_64/fpu/x86_64-math-asm.h b/sysdeps/x86_64/fpu/x86_64-math-asm.h
new file mode 100644
index 0000000..07eecf7
--- /dev/null
+++ b/sysdeps/x86_64/fpu/x86_64-math-asm.h
@@ -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. */