From dc40b1a95487de09173b7186eeb63b15ec17c145 Mon Sep 17 00:00:00 2001 From: Keith Marshall Date: Mon, 14 Nov 2016 17:57:05 +0000 Subject: [PATCH] Add POSIX compliant errno assignments to log functions. --- mingwrt/ChangeLog | 41 ++++++ mingwrt/Makefile.in | 19 ++- mingwrt/include/errno.h | 15 +- mingwrt/mingwex/math/errno.sx | 51 +++++++ mingwrt/mingwex/math/log10_generic.sx | 78 +++++++++++ mingwrt/mingwex/math/log10f.s | 48 ------- mingwrt/mingwex/math/log10l.s | 52 ------- mingwrt/mingwex/math/log1p.s | 47 ------- mingwrt/mingwex/math/log1p_generic.sx | 86 ++++++++++++ mingwrt/mingwex/math/log1pf.s | 47 ------- mingwrt/mingwex/math/log1pl.s | 54 -------- mingwrt/mingwex/math/log2.s | 51 ------- mingwrt/mingwex/math/log2_generic.sx | 77 +++++++++++ mingwrt/mingwex/math/log2f.s | 51 ------- mingwrt/mingwex/math/log2l.s | 48 ------- mingwrt/mingwex/math/log_generic.sx | 242 +++++++++++++++++++++++++++++++++ mingwrt/mingwex/math/logf.s | 39 ------ mingwrt/mingwex/math/logl.s | 40 ------ mingwrt/mingwex/math/x87cvt_generic.sx | 113 +++++++++++++++ 19 files changed, 718 insertions(+), 481 deletions(-) create mode 100644 mingwrt/mingwex/math/errno.sx create mode 100644 mingwrt/mingwex/math/log10_generic.sx delete mode 100644 mingwrt/mingwex/math/log10f.s delete mode 100644 mingwrt/mingwex/math/log10l.s delete mode 100644 mingwrt/mingwex/math/log1p.s create mode 100644 mingwrt/mingwex/math/log1p_generic.sx delete mode 100644 mingwrt/mingwex/math/log1pf.s delete mode 100644 mingwrt/mingwex/math/log1pl.s delete mode 100644 mingwrt/mingwex/math/log2.s create mode 100644 mingwrt/mingwex/math/log2_generic.sx delete mode 100644 mingwrt/mingwex/math/log2f.s delete mode 100644 mingwrt/mingwex/math/log2l.s create mode 100644 mingwrt/mingwex/math/log_generic.sx delete mode 100644 mingwrt/mingwex/math/logf.s delete mode 100644 mingwrt/mingwex/math/logl.s create mode 100644 mingwrt/mingwex/math/x87cvt_generic.sx diff --git a/mingwrt/ChangeLog b/mingwrt/ChangeLog index afd0b85..2ae49ab 100644 --- a/mingwrt/ChangeLog +++ b/mingwrt/ChangeLog @@ -1,3 +1,44 @@ +2016-11-14 Keith Marshall + + Add POSIX compliant errno assignments to log functions. + + * include/errno.h: Make it assembly language compatible. + [__ASSEMBLER__]: Omit <_mingw.h>; do not declare prototype for... + (_errno): ...this accessor function; the declaration is syntactically + invalid, in assembly language code. + + * mingwex/math/errno.sx: New file; when included by other assembly + language files, it provides bindings for assignement of any constant + defined in to the global errno variable, facilitated by... + (errno): ...this new GAS macro. + + * mingwex/math/log_generic.sx: New file; it provides a generic back + end implementation for multiple logarithmic functions, accessed via... + (___x87log, ___x87log_chk): ...this pair of entry points, serving... + (log, logf, log): ...each of these primary functions; it replaces... + * mingwex/math/logf.s mingwex/math/logl.s: ...these; delete them. + + * mingwex/math/log1p_generic.sx mingwex/math/log10_generic.sx + * mingwex/math/log2_generic.sx: New files; each acts as a wrapper for + log_generic.sx, providing the front end entry stubs for each of... + (log1p, log1pf, log1pl, log10, log10f, log10l, log2, log2f, log2l): + ...these functions; thus, they provide complete replacements for... + * mingwex/math/log1p.s mingwex/math/log1pf.s mingwex/math/log1pl.s + * mingwex/math/log10f.s mingwex/math/log10l.s mingwex/math/log2.s + * mingwex/math/log2f.s mingwex/math/log2l.s: ...these; delete them. + + * mingwex/math/x87cvt_generic.sx: New file; it implements... + (___x87cvt, ___x87cvtf): ...this pair of return value conversion + routines, for conversion from the FPU's internal REAL10 data format, + to REAL8 and REAL4, for double and float functions respectively. + + * Makefile.in (libmingwex.a): Add dependencies on... + (x87cvt.$OBJEXT), x87cvtf.$OBJEXT), x87log.$OBJEXT), x87logf.$OBJEXT): + ...these object modules; implement pattern rule to build them from... + (x87cvt_generic.sx, log_generic.sx): ...these generic sources; also + provide for building the respective log function entry stubs from + their respective generic sources. + 2016-11-08 Keith Marshall Implement unit tests for logarithmic functions. diff --git a/mingwrt/Makefile.in b/mingwrt/Makefile.in index f9cd502..bf5a702 100644 --- a/mingwrt/Makefile.in +++ b/mingwrt/Makefile.in @@ -178,6 +178,7 @@ INCLUDES = -nostdinc -I . -I ${top_srcdir}/include -I ${w32api_srcdir}/include \ -I ${top_srcdir} -I ${top_srcdir}/profile -iwithprefixbefore include ALL_CFLAGS = $(CFLAGS) $(DEPFLAGS) $(INCLUDES) $(NTDDI_VERSION_SPEC) +ALL_CPPFLAGS = $(CPPFLAGS) $(DEPFLAGS) $(INCLUDES) $(NTDDI_VERSION_SPEC) # The general case, for compiling object files from C source, # requires a small adjustment to the default implicit rule. @@ -460,7 +461,8 @@ libmingwex.a: $(addsuffix .$(OBJEXT), cosf cosl acosf acosl sinf sinl asinf \ nearbyint nearbyintf nearbyintl nextafterf nextafterl nexttoward nexttowardf \ powf powl powi powif powil remainder remainderf remainderl remquo remquof \ remquol rint rintf rintl round roundf roundl scalbn scalbnf scalbnl signbit \ - signbitf signbitl sqrtf sqrtl tgamma tgammaf tgammal trunc truncf truncl) + signbitf signbitl sqrtf sqrtl tgamma tgammaf tgammal trunc truncf truncl \ + x87cvt x87cvtf x87log x87log1p) # Replacement I/O functions in libmingwex.a, providing better POSIX # compatibility than their Microsoft equivalents. @@ -521,6 +523,21 @@ $(addsuffix .$(OBJEXT), % %f %l): %_generic.c $(addsuffix .$(OBJEXT), llround llroundf llroundl): %.$(OBJEXT): lround_generic.c $(CC) -c -D FUNCTION=$* $(CPPFLAGS) $(ALL_CFLAGS) -o $@ $< +# Similarly, we may need to compile quux.o, quuxf.o, and quuxl.o +# variants from a common quux_generic.sx assembly language file. +# +vpath %.sx ${mingwrt_srcdir}/mingwex/math +$(addsuffix .$(OBJEXT), % %f %l): %_generic.sx + $(CC) -c -D_$*_source $(ALL_CPPFLAGS) $(ASFLAGS) -o $*.$(OBJEXT) $< + $(CC) -c -D_$*f_source $(ALL_CPPFLAGS) $(ASFLAGS) -o $*f.$(OBJEXT) $< + $(CC) -c -D_$*l_source $(ALL_CPPFLAGS) $(ASFLAGS) -o $*l.$(OBJEXT) $< + +# Several generically implemented functions also require separate +# assembly of their generic back-end support routines. +# +x87%.$(OBJEXT): %_generic.sx + $(CC) -c $(ALL_CPPFLAGS) $(ASFLAGS) -o $@ $< + # Historically, MinGW.org's libm.a has been a dummy, delivering # nothing of value; FIXME: IMO, this sucks; it should deliver the # non-MSVCRT.DLL math functions, as noted above. diff --git a/mingwrt/include/errno.h b/mingwrt/include/errno.h index ad58267..8db04f3 100644 --- a/mingwrt/include/errno.h +++ b/mingwrt/include/errno.h @@ -32,9 +32,14 @@ #ifndef _ERRNO_H #define _ERRNO_H -/* All MinGW headers are expected to include <_mingw.h> +/* All MinGW headers are expected to include <_mingw.h>; however... + */ +#ifndef __ASSEMBLER__ +/* ...the overhead of doing so is unwarranted, when has been + * included directly in preprocessed assembly language code. */ #include <_mingw.h> +#endif /* Error code numbers. * @@ -89,7 +94,11 @@ #define ENOTEMPTY 41 /* Directory not empty (90 in Cyg?) */ #define EILSEQ 42 /* Illegal byte sequence */ -#ifndef RC_INVOKED +/* C language function prototype declarations are unnecessary, when + * compiling resource files, and they actually represent syntactically + * invalid statements, in preprocessed assembly language code. + */ +#if ! defined RC_INVOKED && ! defined __ASSEMBLER__ _BEGIN_C_DECLS @@ -106,7 +115,7 @@ _CRTIMP int* __cdecl __MINGW_NOTHROW _errno(void); _END_C_DECLS -#endif /* ! RC_INVOKED */ +#endif /* ! RC_INVOKED && !__ASSEMBLY__ */ #if defined __PTW32_H && ! defined _PTW32_ERRNO_H /* As a courtesy to users of pthreads-win32, ensure that the appropriate diff --git a/mingwrt/mingwex/math/errno.sx b/mingwrt/mingwex/math/errno.sx new file mode 100644 index 0000000..1e87892 --- /dev/null +++ b/mingwrt/mingwex/math/errno.sx @@ -0,0 +1,51 @@ +/* + * errno.sx + * + * Assembly language wrapper for , also providing macros + * for manipulation of the "errno" global variable from within any + * preprocessed assembly language source file. + * + * $Id$ + * + * Written by Keith Marshall + * Copyright (C) 2016, MinGW.org Project + * + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +.globl __errno +.def __errno; .scl 2; .type 32; .endef + +#ifdef __MINGW64__ +# define eax rax +#endif + +.macro errno code +/* Assign a specified error code to the global "errno" variable. + */ + call __errno /* get address of "errno" variable */ + movl $\code, (%eax) /* store specified "errno" value */ +.endm + +#include /* for symbolic error code definitions */ + +/* vim: set autoindent filetype=asm formatoptions=croql: */ +/* $RCSfile$: end of file */ diff --git a/mingwrt/mingwex/math/log10_generic.sx b/mingwrt/mingwex/math/log10_generic.sx new file mode 100644 index 0000000..829f036 --- /dev/null +++ b/mingwrt/mingwex/math/log10_generic.sx @@ -0,0 +1,78 @@ +/* + * log10_generic.sx + * + * Generic wrapper for implementation entry stubs for each of the log10(), + * log10l(), and log10f() functions. + * + * $Id$ + * + * Written by Keith Marshall + * Copyright (C) 2016, MinGW.org Project + * + * Adapted from original code written by J. T. Conklin , + * with modifications by Ulrich Drepper , to improve + * accuracy in the computation of log10(x) as x --> 1.0. This wrapper + * provides only definitions for derivation of the implementations by + * inclusion of the log_generic.sx source file. + * + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +#undef ___function + +/* Each of the log10(), log10f(), and log10l() functions returns a common + * (base-10) logarithm; this may be computed directly, using either the FYL2X, + * or the FYL2X1P instruction, by setting the scaling factor (y) to the common + * logarithm of two. + */ +#define __fldy fldlg2 + +/* The first step is to identify the primary entry point name, and associated + * back-end names, for each of the three supported functions, (each of which + * to be assembled separately, using a GCC command of the form: + * + * gcc -c -D__source log10_generic.sx -o .o + * + * to create the three entry stubs, with appropriate mappings to the back-end + * implementation provided by log_generic.sx + */ +#if defined _log10_source +# define ___function _log10 /* log10() function entry point name */ +# define ___x87cvt ___x87cvt /* return value conversion helper */ +# define __fldx fldl /* FLD instruction to load x value */ + +#elif defined _log10l_source +# define ___function _log10l /* log10l() function entry point name */ +# define __fldx fldt /* FLD instruction to load x value */ + +#elif defined _log10f_source +# define ___function _log10f /* log10f() function entry point name */ +# define ___x87cvt ___x87cvtf /* return value conversion helper */ +# define __fldx flds /* FLD instruction to load x value */ +#endif + +/* Actual implementation of the entry point stubs, in terms of the preceding + * definitions, is delegated to the log_generic.sx source file. + */ +#include "log_generic.sx" + +/* vim: set autoindent filetype=asm formatoptions=croql: */ +/* $RCSfile$: end of file */ diff --git a/mingwrt/mingwex/math/log10f.s b/mingwrt/mingwex/math/log10f.s deleted file mode 100644 index c36297a..0000000 --- a/mingwrt/mingwex/math/log10f.s +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Written by J.T. Conklin . - * Public domain. - * Adapted for float type by Ulrich Drepper . - * - * Changed to use fyl2xp1 for values near 1, . - */ - - .file "log10f.s" - .text - .align 4 -one: .double 1.0 - /* It is not important that this constant is precise. It is only - a value which is known to be on the safe side for using the - fyl2xp1 instruction. */ -limit: .double 0.29 - - .text - .align 4 -.globl _log10f - .def _log10f; .scl 2; .type 32; .endef -_log10f: - fldlg2 /* log10(2) */ - flds 4(%esp) /* x : log10(2) */ - fxam - fnstsw - fld %st /* x : x : log10(2) */ - sahf - jc 3f /* in case x is NaN or ±Inf */ -4: fsubl one /* x-1 : x : log10(2) */ - fld %st /* x-1 : x-1 : x : log10(2) */ - fabs /* |x-1| : x-1 : x : log10(2) */ - fcompl limit /* x-1 : x : log10(2) */ - fnstsw /* x-1 : x : log10(2) */ - andb $0x45, %ah - jz 2f - fstp %st(1) /* x-1 : log10(2) */ - fyl2xp1 /* log10(x) */ - ret - -2: fstp %st(0) /* x : log10(2) */ - fyl2x /* log10(x) */ - ret - -3: jp 4b /* in case x is ±Inf */ - fstp %st(1) - fstp %st(1) - ret diff --git a/mingwrt/mingwex/math/log10l.s b/mingwrt/mingwex/math/log10l.s deleted file mode 100644 index cc99e1c..0000000 --- a/mingwrt/mingwex/math/log10l.s +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Written by J.T. Conklin . - * Public domain. - * - * Adapted for `long double' by Ulrich Drepper . - * - * Changed to use fyl2xp1 for values near 1, . - * - * Removed header file dependency for use in libmingwex.a by - * Danny Smith - */ - - .file "log10l.s" - .text - .align 4 -one: .double 1.0 - /* It is not important that this constant is precise. It is only - a value which is known to be on the safe side for using the - fyl2xp1 instruction. */ -limit: .double 0.29 - - .text - .align 4 -.globl _log10l - .def _log10l; .scl 2; .type 32; .endef -_log10l: - fldlg2 /* log10(2) */ - fldt 4(%esp) /* x : log10(2) */ - fxam - fnstsw - fld %st /* x : x : log10(2) */ - sahf - jc 3f /* in case x is NaN or ±Inf */ -4: fsubl one /* x-1 : x : log10(2) */ - fld %st /* x-1 : x-1 : x : log10(2) */ - fabs /* |x-1| : x-1 : x : log10(2) */ - fcompl limit /* x-1 : x : log10(2) */ - fnstsw /* x-1 : x : log10(2) */ - andb $0x45, %ah - jz 2f - fstp %st(1) /* x-1 : log10(2) */ - fyl2xp1 /* log10(x) */ - ret - -2: fstp %st(0) /* x : log10(2) */ - fyl2x /* log10(x) */ - ret - -3: jp 4b /* in case x is ±Inf */ - fstp %st(1) - fstp %st(1) - ret diff --git a/mingwrt/mingwex/math/log1p.s b/mingwrt/mingwex/math/log1p.s deleted file mode 100644 index ff795d4..0000000 --- a/mingwrt/mingwex/math/log1p.s +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Written by J.T. Conklin . - * Public domain. - * Removed header file dependency for use in libmingwex.a by - * Danny Smith - */ - - .file "log1p.s" - .text - .align 4 - /* The fyl2xp1 can only be used for values in - -1 + sqrt(2) / 2 <= x <= 1 - sqrt(2) / 2 - 0.29 is a safe value. - */ -limit: .double 0.29 -one: .double 1.0 -/* - * Use the fyl2xp1 function when the argument is in the range -0.29 to 0.29, - * otherwise fyl2x with the needed extra computation. - */ -.globl _log1p; - .def _log1p; .scl 2; .type 32; .endef -_log1p: - fldln2 - fldl 4(%esp) - fxam - fnstsw - fld %st - sahf - jc 3f /* in case x is NaN or ±Inf */ - -4: fabs - fcompl limit - fnstsw - sahf - jc 2f - faddl one - fyl2x - ret - -2: fyl2xp1 - ret - -3: jp 4b /* in case x is ±Inf */ - fstp %st(1) - fstp %st(1) - ret diff --git a/mingwrt/mingwex/math/log1p_generic.sx b/mingwrt/mingwex/math/log1p_generic.sx new file mode 100644 index 0000000..e03c76d --- /dev/null +++ b/mingwrt/mingwex/math/log1p_generic.sx @@ -0,0 +1,86 @@ +/* + * log1p_generic.sx + * + * Generic wrapper for implementation entry stubs for each of the log1p(), + * log1pl(), and log1pf() functions. + * + * $Id$ + * + * Written by Keith Marshall + * Copyright (C) 2016, MinGW.org Project + * + * Adapted from original code written by J. T. Conklin , + * with modifications by Ulrich Drepper , to improve + * accuracy in the computation of log1p(x) as x --> 0.0. This wrapper + * provides only definitions for derivation of the implementations by + * inclusion of the log_generic.sx source file. + * + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +#undef ___function + +/* Each of the log1p(), log1pf(), and log1pl() functions returns a natural + * logarithm; this may be computed directly, using either the FYL2X, or the + * FYL2X1P instruction, by setting the scaling factor (y) to the natural + * logarithm of two. + */ +#define __fldy fldln2 + +/* The first step is to identify the primary entry point name, and associated + * back-end names, for each of the three supported functions, (each of which is + * to be assembled separately, using a GCC command of the form: + * + * gcc -c -D__source log1p_generic.sx -o .o + * + * to create the three entry stubs, with appropriate mappings to the back-end + * implementation provided by log_generic.sx + */ +#if defined _log1p_source +# define ___function _log1p /* log1p() function entry point name */ +# define ___x87cvt ___x87cvt /* return value conversion helper */ +# define __fldx fldl /* FLD instruction to load x value */ + +#elif defined _log1pl_source +# define ___function _log1pl /* log1pl() function entry point name */ +# define __fldx fldt /* FLD instruction to load x value */ + +#elif defined _log1pf_source +# define ___function _log1pf /* log1pf() function entry point name */ +# define ___x87cvt ___x87cvtf /* return value conversion helper */ +# define __fldx flds /* FLD instruction to load x value */ +#endif + +/* Each of the log1p(), log1pf(), and log1pl() functions shares a common + * back-end implementation, which is distinct from the log_generic.sx default; + * redirect it accordingly. + */ +#define ___x87log ___x87log1p /* redirected back-end implementation */ +#define ___x87log_chk ___x87log1p_chk /* input value validation helper */ + +/* Actual implementation of the entry point stubs, and corresponding back-end + * implementation in terms of the preceding definitions, is delegated to the + * log_generic.sx source file. + */ +#include "log_generic.sx" + +/* vim: set autoindent filetype=asm formatoptions=croql: */ +/* $RCSfile$: end of file */ diff --git a/mingwrt/mingwex/math/log1pf.s b/mingwrt/mingwex/math/log1pf.s deleted file mode 100644 index 17aee6e..0000000 --- a/mingwrt/mingwex/math/log1pf.s +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Written by J.T. Conklin . - * Public domain. - * Removed header file dependency for use in libmingwex.a by - * Danny Smith - */ - - .file "log1pf.s" - .text - .align 4 - /* The fyl2xp1 can only be used for values in - -1 + sqrt(2) / 2 <= x <= 1 - sqrt(2) / 2 - 0.29 is a safe value. - */ -limit: .float 0.29 -one: .float 1.0 -/* - * Use the fyl2xp1 function when the argument is in the range -0.29 to 0.29, - * otherwise fyl2x with the needed extra computation. - */ -.globl _log1pf; - .def _log1pf; .scl 2; .type 32; .endef -_log1pf: - fldln2 - flds 4(%esp) - fxam - fnstsw - fld %st - sahf - jc 3f /* in case x is NaN or ±Inf */ - -4: fabs - fcomps limit - fnstsw - sahf - jc 2f - fadds one - fyl2x - ret - -2: fyl2xp1 - ret - -3: jp 4b /* in case x is ±Inf */ - fstp %st(1) - fstp %st(1) - ret diff --git a/mingwrt/mingwex/math/log1pl.s b/mingwrt/mingwex/math/log1pl.s deleted file mode 100644 index 65e1d0a..0000000 --- a/mingwrt/mingwex/math/log1pl.s +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Written by J.T. Conklin . - * Public domain. - * - * Adapted for `long double' by Ulrich Drepper . -* Removed header file dependency for use in libmingwex.a by - * Danny Smith - */ - - .file "log1pl.s" - .text - .align 4 - /* The fyl2xp1 can only be used for values in - -1 + sqrt(2) / 2 <= x <= 1 - sqrt(2) / 2 - 0.29 is a safe value. - */ -limit: .tfloat 0.29 - /* Please note: we use a double value here. Since 1.0 has - an exact representation this does not effect the accuracy - but it helps to optimize the code. */ -one: .double 1.0 - -/* - * Use the fyl2xp1 function when the argument is in the range -0.29 to 0.29, - * otherwise fyl2x with the needed extra computation. - */ -.globl _log1pl; - .def _log1pl; .scl 2; .type 32; .endef -_log1pl: - fldln2 - fldt 4(%esp) - fxam - fnstsw - fld %st - sahf - jc 3f /* in case x is NaN or ±Inf */ -4: - fabs - fldt limit - fcompp - fnstsw - sahf - jnc 2f - faddl one - fyl2x - ret - -2: fyl2xp1 - ret - -3: jp 4b /* in case x is ±Inf */ - fstp %st(1) - fstp %st(1) - ret diff --git a/mingwrt/mingwex/math/log2.s b/mingwrt/mingwex/math/log2.s deleted file mode 100644 index 10bdc2b..0000000 --- a/mingwrt/mingwex/math/log2.s +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Written by J.T. Conklin . - * Adapted for use as log2 by Ulrich Drepper . - * Public domain. - * - * Changed to use fyl2xp1 for values near 1, . - * - * Removed header file dependency for use in libmingwex.a by - * Danny Smith - */ - - .file "log2.s" - .text - .align 4 -one: .double 1.0 - /* It is not important that this constant is precise. It is only - a value which is known to be on the safe side for using the - fyl2xp1 instruction. */ -limit: .double 0.29 - - .text - .align 4 -.globl _log2 - .def _log2; .scl 2; .type 32; .endef -_log2: - fldl one - fldl 4(%esp) /* x : 1 */ - fxam - fnstsw - fld %st /* x : x : 1 */ - sahf - jc 3f /* in case x is NaN or ±Inf */ -4: fsub %st(2), %st /* x-1 : x : 1 */ - fld %st /* x-1 : x-1 : x : 1 */ - fabs /* |x-1| : x-1 : x : 1 */ - fcompl limit /* x-1 : x : 1 */ - fnstsw /* x-1 : x : 1 */ - andb $0x45, %ah - jz 2f - fstp %st(1) /* x-1 : 1 */ - fyl2xp1 /* log(x) */ - ret - -2: fstp %st(0) /* x : 1 */ - fyl2x /* log(x) */ - ret - -3: jp 4b /* in case x is ±Inf */ - fstp %st(1) - fstp %st(1) - ret diff --git a/mingwrt/mingwex/math/log2_generic.sx b/mingwrt/mingwex/math/log2_generic.sx new file mode 100644 index 0000000..97c2844 --- /dev/null +++ b/mingwrt/mingwex/math/log2_generic.sx @@ -0,0 +1,77 @@ +/* + * log2_generic.sx + * + * Generic wrapper for implementation entry stubs for each of the log2(), + * log2l(), and log2f() functions. + * + * $Id$ + * + * Written by Keith Marshall + * Copyright (C) 2016, MinGW.org Project + * + * Adapted from original code written by J. T. Conklin , + * with modifications by Ulrich Drepper , to improve + * accuracy in the computation of log2(x) as x --> 1.0. This wrapper + * provides only definitions for derivation of the implementations by + * inclusion of the log_generic.sx source file. + * + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +#undef ___function + +/* Each of the log2(), log2f(), and log2l() functions returns a base-2 + * logarithm; this may be computed directly, using either the FYL2X, or + * the FYL2X1P instruction, by setting the scaling factor (y) to one. + */ +#define __fldy fld1 + +/* The first step is to identify the primary entry point name, and associated + * back-end names, for each of the three supported functions, (each of which + * to be assembled separately, using a GCC command of the form: + * + * gcc -c -D__source log10_generic.sx -o .o + * + * to create the three entry stubs, with appropriate mappings to the back-end + * implementation provided by log_generic.sx + */ +#if defined _log2_source +# define ___function _log2 /* log2() function entry point name */ +# define ___x87cvt ___x87cvt /* return value conversion helper */ +# define __fldx fldl /* FLD instruction to load x value */ + +#elif defined _log2l_source +# define ___function _log2l /* log2l() function entry point name */ +# define __fldx fldt /* FLD instruction to load x value */ + +#elif defined _log2f_source +# define ___function _log2f /* log2f() function entry point name */ +# define ___x87cvt ___x87cvtf /* return value conversion helper */ +# define __fldx flds /* FLD instruction to load x value */ +#endif + +/* Actual implementation of the entry point stubs, in terms of the preceding + * definitions, is delegated to the log_generic.sx source file. + */ +#include "log_generic.sx" + +/* vim: set autoindent filetype=asm formatoptions=croql: */ +/* $RCSfile$: end of file */ diff --git a/mingwrt/mingwex/math/log2f.s b/mingwrt/mingwex/math/log2f.s deleted file mode 100644 index 3b52a9b..0000000 --- a/mingwrt/mingwex/math/log2f.s +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Written by J.T. Conklin . - * Adapted for use as log2 by Ulrich Drepper . - * Public domain. - * - * Changed to use fyl2xp1 for values near 1, . - * - * Removed header file dependency for use in libmingwex.a by - * Danny Smith - */ - - .file "log2f.s" - .text - .align 4 -one: .double 1.0 - /* It is not important that this constant is precise. It is only - a value which is known to be on the safe side for using the - fyl2xp1 instruction. */ -limit: .double 0.29 - - .text - .align 4 -.globl _log2f - .def _log2f; .scl 2; .type 32; .endef -_log2f: - fldl one - flds 4(%esp) /* x : 1 */ - fxam - fnstsw - fld %st /* x : x : 1 */ - sahf - jc 3f /* in case x is NaN or ±Inf */ -4: fsub %st(2), %st /* x-1 : x : 1 */ - fld %st /* x-1 : x-1 : x : 1 */ - fabs /* |x-1| : x-1 : x : 1 */ - fcompl limit /* x-1 : x : 1 */ - fnstsw /* x-1 : x : 1 */ - andb $0x45, %ah - jz 2f - fstp %st(1) /* x-1 : 1 */ - fyl2xp1 /* log(x) */ - ret - -2: fstp %st(0) /* x : 1 */ - fyl2x /* log(x) */ - ret - -3: jp 4b /* in case x is ±Inf */ - fstp %st(1) - fstp %st(1) - ret diff --git a/mingwrt/mingwex/math/log2l.s b/mingwrt/mingwex/math/log2l.s deleted file mode 100644 index 044b67c..0000000 --- a/mingwrt/mingwex/math/log2l.s +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Written by J.T. Conklin . - * Adapted for use as log2 by Ulrich Drepper . - * Public domain. - * - * Changed to use fyl2xp1 for values near 1, . - */ - - .file "log2l.s" - .text - .align 4 -one: .double 1.0 - /* It is not important that this constant is precise. It is only - a value which is known to be on the safe side for using the - fyl2xp1 instruction. */ -limit: .double 0.29 - - .text - .align 4 -.globl _log2l - .def _log2l; .scl 2; .type 32; .endef -_log2l: - fldl one - fldt 4(%esp) /* x : 1 */ - fxam - fnstsw - fld %st /* x : x : 1 */ - sahf - jc 3f /* in case x is NaN or ±Inf */ -4: fsub %st(2), %st /* x-1 : x : 1 */ - fld %st /* x-1 : x-1 : x : 1 */ - fabs /* |x-1| : x-1 : x : 1 */ - fcompl limit /* x-1 : x : 1 */ - fnstsw /* x-1 : x : 1 */ - andb $0x45, %ah - jz 2f - fstp %st(1) /* x-1 : 1 */ - fyl2xp1 /* log(x) */ - ret - -2: fstp %st(0) /* x : 1 */ - fyl2x /* log(x) */ - ret - -3: jp 4b /* in case x is ±Inf */ - fstp %st(1) - fstp %st(1) - ret diff --git a/mingwrt/mingwex/math/log_generic.sx b/mingwrt/mingwex/math/log_generic.sx new file mode 100644 index 0000000..176b7df --- /dev/null +++ b/mingwrt/mingwex/math/log_generic.sx @@ -0,0 +1,242 @@ +/* + * log_generic.sx + * + * Generic implementation for each of the log(), logl(), logf(), log1p(), + * log1pl(), log1pf(), log2(), log2l(), log2f(), log10(), log10l(), and + * log10f() functions. + * + * $Id$ + * + * Written by Keith Marshall + * Copyright (C) 2016, MinGW.org Project + * + * Adapted from original code written by J. T. Conklin , + * with modifications by Ulrich Drepper , to improve + * accuracy in the computation of log(x) as x --> 1.0. This adaptation + * folds several similar sources into a single generic unit, and adds + * assignment of errno on exception, as prescribed by POSIX.1-2008. + * + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +#ifndef ___function + +/* Each of the log(), logf(), and logl() functions returns a natural + * logarithm; this may be computed directly, using either the FYL2X, or + * the FYL2X1P instruction, by setting the scaling factor (y) to the + * natural logarithm of two. + */ +#define __fldy fldln2 + +/* The first step is to identify the primary entry point name, and associated + * back-end names, for each of the twelve supported functions, (each of which + * is to be assembled separately, using a GCC command of the form: + * + * gcc -c -D__source log_generic.sx -o .o + * + */ +#if defined _log_source +# define ___function _log /* log() function entry point name */ +# define ___x87cvt ___x87cvt /* return value conversion helper */ +# define __fldx fldl /* FLD instruction to load x value */ + +#elif defined _logl_source +# define ___function _logl /* logl() function entry point name */ +# define __fldx fldt /* FLD instruction to load x value */ + +#elif defined _logf_source +# define ___function _logf /* logf() function entry point name */ +# define ___x87cvt ___x87cvtf /* return value conversion helper */ +# define __fldx flds /* FLD instruction to load x value */ + +#endif +#endif +#ifdef __MINGW64__ +/* On 64-bit machine architecture... + */ +# define __xarg 8(%rsp) /* x is 8 bytes above return address */ +#else +/* ...whereas, on 32-bit architecture... + */ +# define __xarg 4(%esp) /* x is 4 bytes above return address */ +#endif + +.text +.align 4 +#ifdef ___function +/* A function entry point name has been specified; assemble the corresponding + * entry point stub function. + */ +.globl ___function +.def ___function; .scl 2; .type 32; .endef + +___function: +/* Primary function entry point (generically named). + */ + __fldy /* load scaling factor (y) for FYL2X */ + __fldx __xarg /* push x value on top of FPU stack --> x : y */ + +#ifdef ___x87cvt +/* A return value conversion routine has been specified, (thus, this is the + * entry point stub for one of the float/REAL4 or double/REAL8 functions); we + * must call the appropriate back-end, then return to our own caller via the + * specified conversion routine. + */ + call ___x87log_chk /* get REAL10 representation of return value */ + jmp ___x87cvt /* convert to REAL8 or REAL4, and return it */ + +#else +/* No return value conversion specified, (thus this is a REAL10/long double + * function entry point stub); allow the back-end to return directly to our + * own caller. + */ + jmp ___x87log_chk /* compute and return REAL10 result */ + +#endif +#else +/* No specific function entry point identified; implement one of the generic + * back-ends, each of which is common to some subset of supported front-end + * entry points, and also provides the error reporting API. + */ +#include "errno.sx" + +/* This constant need not be precise; it serves only as a known safe maximum + * absolute value of x - 1, for which the FYL2XP1 instruction provides greater + * accuracy than the FYL2X instruction. + */ +limit: .float 0.29 + +.align 4 +.globl ___x87log_chk +.def ___x87log_chk; .scl 2; .type 32; .endef + +___x87log_chk: +/* Common back-end entry point for all supported functions; identical in each + * of its ___x87log_chk and ___x87log1p_chk incarnations, it provides initial + * input value validation, to filter out NaN input values. + */ + fxam /* classify x */ + fnstsw %ax /* copy FPU condition codes... */ + sahf /* ...into CPU flags register */ + jnc 20f /* x is neither NaN nor infinite */ + jp 11f /* x is infinite: handle accordingly */ +10: fstp %st(1) /* x is NaN; discard scale factor */ + ret /* return x as NaN */ + +/* In the case when the input value of x is infinite, we must handle it + * appropriately, depending on whether it is +ve or -ve. + */ +11: testb $2, %ah /* examine the sign bit */ + jnz 20f /* x is -ve infinity: process it */ + jmp 10b /* x is +ve infinity: just return it */ + +.align 4 +.globl ___x87log +.def ___x87log; .scl 2; .type 32; .endef + +___x87log: +#ifdef ___x87log +/* Implementation specific to the ___x87log1p redirection of the back-end; it + * computes the REAL10 representation of log(x+1), scaled as appropriate to + * the required logarithm base. + */ +20: fld %st /* x : x : y */ + fabs /* |x| : x : y */ + fcomps limit /* x : y */ + fnstsw %ax /* copy FPU condition codes... */ + sahf /* ...into CPU flags register */ + jb 24f /* -0.29 < x < +0.29 */ + +/* The value of x lies outside the -0.29 < x < +0.29 range, within which the + * FYL2X1P instruction may be used legitimately, to compute log2(x+1) directly; + * instead, we must explicitly add one, and use the FYL2X instruction. + */ + fld1 /* 1 : x : y */ + faddp %st, %st(1) /* x+1 : y */ + fyl2x /* y*log(x+1) */ +#else +/* Implementation specific to the default ___x87log form of the back-end; it + * computes the REAL10 representation of log(x), scaled as appropriate to the + * required logarithm base. In this case, we begin by computing x - 1, and + * checking if it lies in the -0.29 < x - 1 < +0.29 range, within which we + * prefer to use FYL2X1P, rather than FYL2X, (for improved accuracy). + */ +20: fld1 /* 1 : x : y */ + fld %st(1) /* x : 1 : x : y */ + fsub %st(1), %st /* x-1 : 1 : x : y */ + fst %st(1) /* x-1 : x-1 : x : y */ + fabs /* |x-1| : x-1 : x : y */ + fcomps limit /* x-1 : x : y */ + fnstsw %ax /* copy FPU condition codes... */ + sahf /* ...into CPU flags register */ + jb 24f /* +0.71 < x < +1.29 */ + +/* The value of x lies outside the 0.71 < x < 1.29 range, (within which the + * best accuracy is achieved by use of FYL2XP1 with the x - 1 value on the + * top of the FPU stack); we must use FYL2X with the original value of x. + */ + fstp %st(0) /* drop x-1; keep x : y */ + fyl2x /* y*log(x) */ +#endif +/* Fall through to check for pole errors, or domain errors, which may have + * been detected during computation of the logarithm; (this code is common + * to both ___x87log and ___x87logp1 back-end implementations). + */ +21: fxam /* classify computed logarithm */ + fnstsw %ax /* copy FPU condition codes... */ + sahf /* ...into CPU flags register */ + jnc 22f /* result is finite; go return it */ + jp 23f /* result is infinite ==> pole error */ + +/* Fall through when result is NaN; this implies an attempt to compute the + * logarithm of a number which is less than zero, which is a domain error. + */ + errno EDOM /* set errno = EDOM */ +22: ret /* return computed result */ + +/* Handle the case of an infinite computed result; (it must be -inf, which + * results from attempting to compute the logarithm of zero). POSIX calls + * this a pole error, to be identified thus: + */ +23: errno ERANGE /* set errno = ERANGE */ + ret /* return computed -inf result */ + +#ifdef ___x87log +/* This is the final part of the ___x87log1p back-end implementation; this + * is used when -0.29 < x < +0.29, to compute log(x+1) directly, using the + * FYL2XP1 instruction. + */ +24: fyl2xp1 /* y * log2(x+1) */ +#else +/* This is the final part of the default ___x87log back-end implementation; + * this is used when +0.71 < x < +1.29, to compute log(x) indirectly, from + * the previously computed x - 1 value, using the FYL2XP1 instruction. + */ +24: fstp %st(1) /* drop x; keep x-1 : y */ + fyl2xp1 /* y * log2(x) */ +#endif +/* For both back-end implementations, we finish off by executing the common + * result validation routine, as implemented above. + */ + jmp 21b /* go validate and return result */ +#endif +/* vim: set autoindent filetype=asm formatoptions=croql: */ +/* $RCSfile$: end of file */ diff --git a/mingwrt/mingwex/math/logf.s b/mingwrt/mingwex/math/logf.s deleted file mode 100644 index f622b27..0000000 --- a/mingwrt/mingwex/math/logf.s +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Written by J.T. Conklin . - * Public domain. - * Adapted for float by Ulrich Drepper . - * - * Changed to use fyl2xp1 for values near 1, . - */ - - .file "logf.s" - .text - .align 4 -one: .double 1.0 - /* It is not important that this constant is precise. It is only - a value which is known to be on the safe side for using the - fyl2xp1 instruction. */ -limit: .double 0.29 - - .text - .align 4 -.globl _logf - .def _logf; .scl 2; .type 32; .endef -_logf: - fldln2 /* log(2) */ - flds 4(%esp) /* x : log(2) */ - fld %st /* x : x : log(2) */ - fsubl one /* x-1 : x : log(2) */ - fld %st /* x-1 : x-1 : x : log(2) */ - fabs /* |x-1| : x-1 : x : log(2) */ - fcompl limit /* x-1 : x : log(2) */ - fnstsw /* x-1 : x : log(2) */ - andb $0x45, %ah - jz 2f - fstp %st(1) /* x-1 : log(2) */ - fyl2xp1 /* log(x) */ - ret - -2: fstp %st(0) /* x : log(2) */ - fyl2x /* log(x) */ - ret diff --git a/mingwrt/mingwex/math/logl.s b/mingwrt/mingwex/math/logl.s deleted file mode 100644 index 6672f9d..0000000 --- a/mingwrt/mingwex/math/logl.s +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Written by J.T. Conklin . - * Public domain. - * - * Adapted for `long double' by Ulrich Drepper . - * - * Removed header file dependency for use in libmingwex.a by - * Danny Smith - */ - .file "logl.s" - .text - .align 4 -one: .double 1.0 - /* It is not important that this constant is precise. It is only - a value which is known to be on the safe side for using the - fyl2xp1 instruction. */ -limit: .double 0.29 - - .text - .align 4 -.globl _logl - .def _logl; .scl 2; .type 32; .endef -_logl: - fldln2 /* log(2) */ - fldt 4(%esp) /* x : log(2) */ - fld %st /* x : x : log(2) */ - fsubl one /* x-1 : x : log(2) */ - fld %st /* x-1 : x-1 : x : log(2) */ - fabs /* |x-1| : x-1 : x : log(2) */ - fcompl limit /* x-1 : x : log(2) */ - fnstsw /* x-1 : x : log(2) */ - andb $0x45, %ah - jz 2f - fstp %st(1) /* x-1 : log(2) */ - fyl2xp1 /* log(x) */ - ret - -2: fstp %st(0) /* x : log(2) */ - fyl2x /* log(x) */ - ret diff --git a/mingwrt/mingwex/math/x87cvt_generic.sx b/mingwrt/mingwex/math/x87cvt_generic.sx new file mode 100644 index 0000000..50f9778 --- /dev/null +++ b/mingwrt/mingwex/math/x87cvt_generic.sx @@ -0,0 +1,113 @@ +/* + * x87cvt_generic.sx + * + * Generic helper routine to convert a REAL10 return value, in FPU st(0) + * register, to REAL8 or REAL4; also sets errno to ERANGE, if overflow or + * underflow occurs during conversion. + * + * $Id$ + * + * Written by Keith Marshall + * Copyright (C) 2016, MinGW.org Project + * + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ +#undef __function + +#if defined _x87cvtf_source +/* This represents the configuration for conversion from REAL10 to REAL4, + * (equivalent to C's float type); the function entry point is designated + * as __x87cvtf(), and the converting/validating store is performed using + * the FSTPS instruction... + */ +# define __function ___x87cvtf +# define __fstp fstps +# define __fld flds + +#else +/* ...whereas the anonymous alternative represents conversion from REAL10 + * to REAL8, (equivalent to C's double type; note that no conversion is + * required for C's long double type, since the original REAL10 value is + * already equivalent to it). In this case, the function entry point is + * designated as ___x87cvt(), and the store uses the FSTPL instruction. + */ +# define __function ___x87cvt +# define __fstp fstpl +# define __fld fldl +#endif + +#ifdef __MINGW64__ +# define esp rsp +#endif + +.macro fjnbe dest +/* Examine the value currently stored in the FPU st(0) register; jump to + * the specified "dest" label, if this value is finite and non-zero. + */ + fxam /* examine st(0) register */ + fnstsw %ax /* copy FPU status flags... */ + sahf /* ...to CPU flags register */ + jnbe \dest /* jump if finite non-zero */ +.endm + +#include "errno.sx" + +.globl __function +.def __function; .scl 2; .type 32; .endef + +.text +.align 4 +__function: +/* Fastcall helper function, equivalent to: + * + * double ___x87cvt (long double = REAL10 in FPU st(0)); + * float ___x87cvtf (long double = REAL10 in FPU st(0)); + * + * Check that the intermediate REAL10 result, passed in FPU register + * st(0), is both finite and non-zero, and that it will remain so when + * converted to REAL8 (when invoked as ___x87cvt), or to REAL4 (when + * invoked as ___x87cvtf); returns converted result, and sets errno + * if either overflow or underflow occurs during conversion. + */ + fjnbe 20f /* proceed if finite non-zero */ +10: ret /* else return result as-is */ + +/* Proceed when the original REAL10 value is both finite and non-zero; + * convert to the ultimately designated REAL8 or REAL4 result, by saving + * it temporarily to scratch memory immediately below the current stack, + * returning immediately when the converted result remains finite and + * non-zero. + */ +20: sub $12, %esp /* create scratch pad */ + __fstp (%esp) /* convert and store REAL10 value */ + __fld (%esp) /* reload converted result value */ + add $12, %esp /* discard scratch pad */ + fjnbe 10b /* return if finite non-zero result */ + +/* Fall through to here when the conversion either overflows, becoming + * infinite, or underflows to zero; set errno prior to returning. + */ + errno ERANGE /* else set errno = ERANGE */ + ret /* and return augmented value */ + +/* vim: set autoindent filetype=asm formatoptions=croql: */ +/* $RCSfile$: end of file */ -- 2.11.0