The MinGW.org Windows System Libraries
Revision | 38a2db63d60bf01e2549443f3b8a5b381b716390 (tree) |
---|---|
Time | 2021-02-25 07:17:34 |
Author | Keith Marshall <keith@user...> |
Commiter | Keith Marshall |
Correct remquo() quotient computation; cf. MinGW-Bug #41597
@@ -1,3 +1,13 @@ | ||
1 | +2021-02-24 Keith Marshall <keith@users.osdn.me> | |
2 | + | |
3 | + Correct remquo() quotient computation; cf. MinGW-Bug #41597 | |
4 | + | |
5 | + * mingwex/math/remquo_generic.sx: New file; it replaces... | |
6 | + * mingwex/math/remquo.s mingwex/math/remquof.s: ...these, and also... | |
7 | + * mingwex/math/remquol.s: ...this; delete them. | |
8 | + | |
9 | + * Makefile.in (libmingwex.a): Add "x87remquo.$OBJEXT" requirement. | |
10 | + | |
1 | 11 | 2021-01-26 Keith Marshall <keith@users.osdn.me> |
2 | 12 | |
3 | 13 | Avoid proliferation of static snprintf() implementations. |
@@ -1,5 +1,5 @@ | ||
1 | 1 | # @configure_input@ |
2 | -# $Id: Makefile.in,v 5f021e118870 2020/07/20 19:17:27 keith $ | |
2 | +# $Id$ | |
3 | 3 | # |
4 | 4 | # Makefile template for MinGW.org Runtime Library Package |
5 | 5 |
@@ -420,7 +420,7 @@ libmingwex.a: $(addsuffix .$(OBJEXT), cosf cosl acosf acosl sinf sinl asinf \ | ||
420 | 420 | powf powl powi powif powil remainder remainderf remainderl remquo remquof \ |
421 | 421 | remquol rint rintf rintl round roundf roundl scalbn scalbnf scalbnl signbit \ |
422 | 422 | signbitf signbitl sqrtf sqrtl tgamma tgammaf tgammal trunc truncf truncl \ |
423 | - x87cvt x87cvtf x87log x87log1p x87pow) | |
423 | + x87cvt x87cvtf x87log x87log1p x87pow x87remquo) | |
424 | 424 | |
425 | 425 | # Replacement I/O functions in libmingwex.a, providing better POSIX |
426 | 426 | # compatibility than their Microsoft equivalents. |
@@ -1028,4 +1028,4 @@ maintainer-clean-local: maintainer-clean-warning distclean-local | ||
1028 | 1028 | |
1029 | 1029 | clean mostlyclean distclean maintainer-clean: %clean: %clean-local |
1030 | 1030 | |
1031 | -# $RCSfile: Makefile.in,v $: end of file | |
1031 | +# $RCSfile$: end of file |
@@ -1,38 +0,0 @@ | ||
1 | -/* | |
2 | - * Written by Ulrich Drepper <drepper@cygnus.com>. | |
3 | - * Based on e_remainder by J.T. Conklin <jtc@netbsd.org>. | |
4 | - * Removed header file dependency for use in libmingwex.a by | |
5 | - * Danny Smith <dannysmith@users.sourceforge.ne | |
6 | - * Public domain. | |
7 | - */ | |
8 | - | |
9 | - .file "remquo.s" | |
10 | - .text | |
11 | - .align 4; | |
12 | -.globl _remquo; | |
13 | -_remquo: | |
14 | - fldl 4 +8(%esp) | |
15 | - fldl 4(%esp) | |
16 | -1: fprem1 | |
17 | - fstsw %ax | |
18 | - sahf | |
19 | - jp 1b | |
20 | - fstp %st(1) | |
21 | - movl %eax, %ecx | |
22 | - shrl $8, %eax | |
23 | - shrl $12, %ecx | |
24 | - andl $4, %ecx | |
25 | - andl $3, %eax | |
26 | - orl %eax, %ecx | |
27 | - movl $0xef2960, %eax | |
28 | - shrl %cl, %eax | |
29 | - andl $3, %eax | |
30 | - movl 4 +8 +8(%esp), %ecx | |
31 | - movl 4 +4(%esp), %edx | |
32 | - xorl 4 +8 +4(%esp), %edx | |
33 | - testl $0x80000000, %edx | |
34 | - jz 1f | |
35 | - negl %eax | |
36 | -1: movl %eax, (%ecx) | |
37 | - | |
38 | - ret |
@@ -0,0 +1,167 @@ | ||
1 | +/* | |
2 | + * remquo_generic.sx | |
3 | + * | |
4 | + * Generic implementation for each of the ISO-C99 remquo(), remquol(), | |
5 | + * and remquof() functions. | |
6 | + * | |
7 | + * $Id$ | |
8 | + * | |
9 | + * Written by Keith Marshall <keithmarshall@users.sourceforge.net> | |
10 | + * Copyright (C) 2021, MinGW.org Project | |
11 | + * | |
12 | + * Adapted from original code written by J. T. Conklin <jtc@netbsd.org>. | |
13 | + * | |
14 | + * | |
15 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
16 | + * copy of this software and associated documentation files (the "Software"), | |
17 | + * to deal in the Software without restriction, including without limitation | |
18 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
19 | + * and/or sell copies of the Software, and to permit persons to whom the | |
20 | + * Software is furnished to do so, subject to the following conditions: | |
21 | + * | |
22 | + * The above copyright notice and this permission notice (including the next | |
23 | + * paragraph) shall be included in all copies or substantial portions of the | |
24 | + * Software. | |
25 | + * | |
26 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
27 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
28 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
29 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
30 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
31 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
32 | + * DEALINGS IN THE SOFTWARE. | |
33 | + * | |
34 | + */ | |
35 | +.intel_syntax noprefix | |
36 | + | |
37 | +.text | |
38 | +.align 4 | |
39 | +.def ___x87remquo; .scl 2; .type 32; .endef | |
40 | + | |
41 | +#if defined _remquo_source | |
42 | +/* Preamble to load the FPU registers, and EDX register, from the | |
43 | + * arguments passed in any call to the function: | |
44 | + * | |
45 | + * double remquo (double, double, int *); | |
46 | + */ | |
47 | +.globl _remquo | |
48 | +.def _remquo; .scl 2; .type 32; .endef | |
49 | +.def ___x87cvt; .scl 2; .type 32; .endef | |
50 | + | |
51 | +_remquo: | |
52 | + fld QWORD ptr 4[esp] /* FPU TOS = x */ | |
53 | + fld QWORD ptr 12[esp] /* FPU TOS = y, x */ | |
54 | + mov edx, DWORD ptr 20[esp] /* EDX = *q */ | |
55 | + | |
56 | +/* Hand off the preloaded register set, to the shared computational | |
57 | + * back-end routine, before ultimately converting its REAL10 result | |
58 | + * to the required REAL8. | |
59 | + */ | |
60 | + call ___x87remquo /* compute REAL10 result */ | |
61 | + jmp ___x87cvt /* convert to REAL8 */ | |
62 | + | |
63 | +#elif defined _remquof_source | |
64 | +/* Preamble to load the FPU registers, and EDX register, from the | |
65 | + * arguments passed in any call to the function: | |
66 | + * | |
67 | + * float remquof (float, float, int *); | |
68 | + */ | |
69 | +.globl _remquof | |
70 | +.def _remquof; .scl 2; .type 32; .endef | |
71 | +.def ___x87cvtf; .scl 2; .type 32; .endef | |
72 | + | |
73 | +_remquof: | |
74 | + fld DWORD ptr 4[esp] /* FPU TOS = x */ | |
75 | + fld DWORD ptr 8[esp] /* FPU TOS = y, x */ | |
76 | + mov edx, DWORD ptr 12[esp] /* EDX = *q */ | |
77 | + | |
78 | +/* Hand off the preloaded register set, to the shared computational | |
79 | + * back-end routine, before ultimately converting its REAL10 result | |
80 | + * to the required REAL4. | |
81 | + */ | |
82 | + call ___x87remquo /* compute REAL10 result */ | |
83 | + jmp ___x87cvtf /* convert to REAL4 */ | |
84 | + | |
85 | +#elif defined _remquol_source | |
86 | +/* Preamble to load the FPU registers, and EDX register, from the | |
87 | + * arguments passed in any call to the function: | |
88 | + * | |
89 | + * long double remquo (long double, long double, int *); | |
90 | + */ | |
91 | +.globl _remquol | |
92 | +.def _remquol; .scl 2; .type 32; .endef | |
93 | + | |
94 | +_remquol: | |
95 | + fld TBYTE ptr 4[esp] /* FPU TOS = x */ | |
96 | + fld TBYTE ptr 16[esp] /* FPU TOS = y, x */ | |
97 | + mov edx, DWORD ptr 28[esp] /* EDX = *q */ | |
98 | + | |
99 | +/* Hand off the preloaded register set, to the shared computational | |
100 | + * back-end routine, to... | |
101 | + */ | |
102 | + jmp ___x87remquo /* ...compute REAL10 result */ | |
103 | + | |
104 | +#else | |
105 | +/* No specific function entry point identified; implement the generic | |
106 | + * back-end code, which is shared by all three entry points. | |
107 | + */ | |
108 | +.globl ___x87remquo | |
109 | + | |
110 | +___x87remquo: | |
111 | +/* Assuming that the entry point preamble has stored the pointer to the | |
112 | + * storage location for the returned integer quotient, in the EDX register, | |
113 | + * and has loaded the floating point divisor (y), and dividend (x), values | |
114 | + * into the FPU st(0) and st(1) registers, respectively, this computes the | |
115 | + * remainder, and floating point quotient, to the full IEEE-754 extended | |
116 | + * (80-bit) precision of the FPU, before ultimately reducing the quotient | |
117 | + * to an integer, storing as many of itsleast-significant bits as can be | |
118 | + * accommodated in an "int", at the address pointed to by EDX, and | |
119 | + * returning the remainder in FPU register st(0). | |
120 | + */ | |
121 | + fst st(2) /* save a copy of 'y'... */ | |
122 | + fld st(1) /* ...and of 'x' */ | |
123 | + | |
124 | +/* Computation of the remainder requires an iterative procedure... | |
125 | + */ | |
126 | +10: fprem1 /* compute interim result */ | |
127 | + fstsw ax /* copy resultant FPU status... */ | |
128 | + sahf /* ...into CPU flags, for testing... */ | |
129 | + jp 10b /* ...until completion */ | |
130 | + | |
131 | +/* We now have the computed remainder (r), and the original saved x and y, | |
132 | + * in FPU registers st(0), st(1), and st(2) respectively; the next step is | |
133 | + * to compute the floating point quotient, (leaving the remainder in place | |
134 | + * as a fractional part, to ensure that eventual truncation rounds in the | |
135 | + * correct direction)... | |
136 | + */ | |
137 | + fstp st(3) /* ...after saving 'r' for return... */ | |
138 | + fdivp st(1), st /* ...divide 'x' by 'y' */ | |
139 | + | |
140 | +/* This now leaves the integer-valued floating point quotient (q) in st(0), | |
141 | + * and the saved remainder in st(1); the computed value of the quotient may | |
142 | + * exceed the maximum which can be represented as an "int", so we reduce it | |
143 | + * modulo "INT_MAX + 1", to retain the least significant bits with absolute | |
144 | + * value not exceeding INT_MAX. | |
145 | + */ | |
146 | + fld DWORD ptr ___int_max_1 /* load equivalent of (INT_MAX + 1) */ | |
147 | + fxch st(1) /* bring 'q' to top of FPU stack */ | |
148 | +20: fprem /* compute interim modulus value */ | |
149 | + fstsw ax /* copy resultant FPU status... */ | |
150 | + sahf /* ...into CPU flags, for testing... */ | |
151 | + jp 20b /* ...until completion */ | |
152 | + | |
153 | +/* Finally, we are left with the residual quotient in st(0), the remainder | |
154 | + * in st(2), and st(1) still retaining the "INT_MAX + 1" value, (which is of | |
155 | + * no further use to us). | |
156 | + */ | |
157 | + fstp st(1) /* pop FPU stack, discarding st(1) */ | |
158 | + fistp DWORD ptr [edx] /* store reduced quotient, leaving... */ | |
159 | + ret /* ...just the remainder, to return */ | |
160 | + | |
161 | +.section .rdata, "dr" | |
162 | +.align 4 | |
163 | +___int_max_1: .long 0x4F000000 /* (1 + INT_MAX) as float */ | |
164 | +#endif | |
165 | + | |
166 | +/* vim: set autoindent filetype=asm formatoptions=croqlj: */ | |
167 | +/* $RCSfile$: end of file */ |
@@ -1,38 +0,0 @@ | ||
1 | -/* | |
2 | - * Written by Ulrich Drepper <drepper@cygnus.com>. | |
3 | - * Based on e_remainder by J.T. Conklin <jtc@netbsd.org>. | |
4 | - * Removed header file dependency for use in libmingwex.a by | |
5 | - * Danny Smith <dannysmith@users.sourceforge.ne | |
6 | - * Public domain. | |
7 | - */ | |
8 | - | |
9 | - .file "remquo.s" | |
10 | - .text | |
11 | - .align 4; | |
12 | -.globl _remquof; | |
13 | -_remquof: | |
14 | - flds 4 +4(%esp) | |
15 | - flds 4(%esp) | |
16 | -1: fprem1 | |
17 | - fstsw %ax | |
18 | - sahf | |
19 | - jp 1b | |
20 | - fstp %st(1) | |
21 | - movl %eax, %ecx | |
22 | - shrl $8, %eax | |
23 | - shrl $12, %ecx | |
24 | - andl $4, %ecx | |
25 | - andl $3, %eax | |
26 | - orl %eax, %ecx | |
27 | - movl $0xef2960, %eax | |
28 | - shrl %cl, %eax | |
29 | - andl $3, %eax | |
30 | - movl 4 +4 +4(%esp), %ecx | |
31 | - movl 4(%esp), %edx | |
32 | - xorl 4 +4(%esp), %edx | |
33 | - testl $0x80000000, %edx | |
34 | - jz 1f | |
35 | - negl %eax | |
36 | -1: movl %eax, (%ecx) | |
37 | - | |
38 | - ret |
@@ -1,36 +0,0 @@ | ||
1 | -/* | |
2 | - * Written by Ulrich Drepper <drepper@cygnus.com>. | |
3 | - * Based on e_remainder by J.T. Conklin <jtc@netbsd.org>. | |
4 | - * Removed header file dependency for use in libmingwex.a by | |
5 | - * Danny Smith <dannysmith@users.sourceforge.net> | |
6 | - * Public domain. | |
7 | - */ | |
8 | - .text | |
9 | - .align 4; | |
10 | -.globl _remquol; | |
11 | - _remquol: | |
12 | - fldt 4 +12(%esp) | |
13 | - fldt 4(%esp) | |
14 | -1: fprem1 | |
15 | - fstsw %ax | |
16 | - sahf | |
17 | - jp 1b | |
18 | - fstp %st(1) | |
19 | - movl %eax, %ecx | |
20 | - shrl $8, %eax | |
21 | - shrl $12, %ecx | |
22 | - andl $4, %ecx | |
23 | - andl $3, %eax | |
24 | - orl %eax, %ecx | |
25 | - movl $0xef2960, %eax | |
26 | - shrl %cl, %eax | |
27 | - andl $3, %eax | |
28 | - movl 4 +12 +12(%esp), %ecx | |
29 | - movl 4 +8(%esp), %edx | |
30 | - xorl 4 +12 +8(%esp), %edx | |
31 | - testl $0x8000, %edx | |
32 | - jz 1f | |
33 | - negl %eax | |
34 | -1: movl %eax, (%ecx) | |
35 | - | |
36 | - ret |