From b2a64460ba9aca39e92731da67cc6344acb483bc Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Thu, 24 Sep 2015 22:25:30 +0000 Subject: 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 . (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 . [!USE_AS_EXPM1L] (cmin): Replace with use of DEFINE_LDBL_MIN. (IEEE754_EXPL): Use LDBL_CHECK_FORCE_UFLOW_NONNEG. --- ChangeLog | 8 +++++ sysdeps/x86_64/fpu/e_exp2l.S | 20 +++--------- sysdeps/x86_64/fpu/e_expl.S | 18 +++-------- sysdeps/x86_64/fpu/x86_64-math-asm.h | 61 ++++++++++++++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 30 deletions(-) create mode 100644 sysdeps/x86_64/fpu/x86_64-math-asm.h diff --git a/ChangeLog b/ChangeLog index 851dfc0..4105a9e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2015-09-24 Joseph Myers + * sysdeps/x86_64/fpu/x86_64-math-asm.h: New file. + * sysdeps/x86_64/fpu/e_exp2l.S: Include . + (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 . + [!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 +#include - .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 +#include #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 + . */ + +#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. */ -- cgit v1.1