4 * Generic implementation for each of the ISO-C99 fmod(), fmodl(),
5 * fmodf(), remainder(), remainderl(), and remainderf() functions.
9 * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
10 * Copyright (C) 2021, MinGW.org Project
12 * Adapted from original code written by J. T. Conklin <jtc@netbsd.org>.
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:
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
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.
35 .intel_syntax noprefix
40 #if defined _%name%_source
41 /* Preamble to load the FPU registers from the arguments passed in
42 * any call to either of the functions:
44 * double fmod (double, double);
45 * double remainder (double, double);
48 .def _%name%; .scl 2; .type 32; .endef
49 .def ___x87cvt; .scl 2; .type 32; .endef
52 fld QWORD ptr 12[esp] /* FPU TOS = y */
53 fld QWORD ptr 4[esp] /* FPU TOS = x, y */
55 #elif defined _%name%f_source
56 /* Preamble to load the FPU registers from the arguments passed in
57 * any call to either of the functions:
59 * float fmodf (float, float);
60 * float remainderf (float, float);
63 .def _%name%f; .scl 2; .type 32; .endef
64 .def ___x87cvtf; .scl 2; .type 32; .endef
67 fld DWORD ptr 8[esp] /* FPU TOS = y */
68 fld DWORD ptr 4[esp] /* FPU TOS = x, y */
70 #else /* _%name%l_source assumed */
71 #ifndef _%name%l_source
72 #define _%name%l_source
74 /* Preamble to load the FPU registers from the arguments passed in
75 * any call to either of the functions:
77 * long double fmodl (long double, long double);
78 * long double remainderl (long double, long double);
81 .def _%name%l; .scl 2; .type 32; .endef
84 fld TBYTE ptr 16[esp] /* FPU TOS = y */
85 fld TBYTE ptr 4[esp] /* FPU TOS = x, y */
88 /* Fall through to compute the remainder; this is an iterative procedure...
90 10: %fprem% /* compute interim result */
91 fstsw ax /* copy resultant FPU status... */
92 sahf /* ...into CPU flags, for testing... */
93 jp 10b /* ...until completion */
95 /* We now have the computed remainder (r), and the original value of y,
96 * in FPU registers st(0), and st(1) respectively; we no longer have any
97 * use for y, so discard it...
99 fstp st(1) /* ...saving just 'r' for return */
101 #if defined _%name%l_source
102 /* For the %name%l() function, there is no more to do...
104 ret /* ...but return the REAL10 result... */
106 #elif defined _%name%f_source
107 /* ...whereas for %name%f(), we must...
109 jmp ___x87cvtf /* ...convert to REAL4... */
111 #else /* _%name%_source */
112 /* ...while for %name%(), we must...
114 jmp ___x87cvt /* ...convert to REAL8 */
118 /* vim: set autoindent filetype=asm formatoptions=croqlj: */
119 /* $RCSfile$: end of file */