OSDN Git Service

Consolidate fmod() and remainder() source code.
[mingw/mingw-org-wsl.git] / mingwrt / mingwex / math / fmod_generic.sx.in
1 /*
2  * %name%_generic.sx
3  *
4  * Generic implementation for each of the ISO-C99 fmod(), fmodl(),
5  * fmodf(), remainder(), remainderl(), and remainderf() 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
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:
43  *
44  *   double fmod (double, double);
45  *   double remainder (double, double);
46  */
47 .globl  _%name%
48 .def    _%name%; .scl 2; .type 32; .endef
49 .def    ___x87cvt; .scl 2; .type 32; .endef
50
51 _%name%:
52         fld     QWORD ptr 12[esp]       /* FPU TOS = y */
53         fld     QWORD ptr 4[esp]        /* FPU TOS = x, y */
54
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:
58  *
59  *   float fmodf (float, float);
60  *   float remainderf (float, float);
61  */
62 .globl  _%name%f
63 .def    _%name%f; .scl 2; .type 32; .endef
64 .def    ___x87cvtf; .scl 2; .type 32; .endef
65
66 _%name%f:
67         fld     DWORD ptr 8[esp]        /* FPU TOS = y */
68         fld     DWORD ptr 4[esp]        /* FPU TOS = x, y */
69
70 #else /* _%name%l_source assumed */
71 #ifndef _%name%l_source
72 #define _%name%l_source
73 #endif
74 /* Preamble to load the FPU registers from the arguments passed in
75  * any call to either of the functions:
76  *
77  *   long double fmodl (long double, long double);
78  *   long double remainderl (long double, long double);
79  */
80 .globl  _%name%l
81 .def    _%name%l; .scl 2; .type 32; .endef
82
83 _%name%l:
84         fld     TBYTE ptr 16[esp]       /* FPU TOS = y */
85         fld     TBYTE ptr 4[esp]        /* FPU TOS = x, y */
86
87 #endif
88 /* Fall through to compute the remainder; this is an iterative procedure...
89  */
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 */
94
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...
98  */
99         fstp    st(1)                   /* ...saving just 'r' for return */
100
101 #if defined _%name%l_source
102 /* For the %name%l() function, there is no more to do...
103  */
104         ret                             /* ...but return the REAL10 result... */
105
106 #elif defined _%name%f_source
107 /* ...whereas for %name%f(), we must...
108  */
109         jmp     ___x87cvtf              /* ...convert to REAL4... */
110
111 #else /* _%name%_source */
112 /* ...while for %name%(), we must...
113  */
114         jmp     ___x87cvt               /* ...convert to REAL8 */
115
116 #endif
117
118 /* vim: set autoindent filetype=asm formatoptions=croqlj: */
119 /* $RCSfile$: end of file */