Hackfix and re-enable strtoull and wcstoull, see bug #3798.
[sdcc.git] / sdcc / device / lib / _modslong.c
blob4dbfd6571de6456dc16012d71be2ef5a33b746e0
1 /*-------------------------------------------------------------------------
2 _modslong.c - routine for modulus of 32 bit signed long
4 Copyright (C) 1999, Sandeep Dutta . sandeep.dutta@usa.net
6 This library is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this library; see the file COPYING. If not, write to the
18 Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
19 MA 02110-1301, USA.
21 As a special exception, if you link this library with other files,
22 some of which are compiled with SDCC, to produce an executable,
23 this library does not by itself cause the resulting executable to
24 be covered by the GNU General Public License. This exception does
25 not however invalidate any other reasons why the executable file
26 might be covered by the GNU General Public License.
27 -------------------------------------------------------------------------*/
29 #include <sdcc-lib.h>
31 #if _SDCC_MANGLES_SUPPORT_FUNS
32 unsigned long _modulong (unsigned long a, unsigned long b);
33 #endif
35 /* Assembler-functions are provided for:
36 mcs51 small
37 mcs51 small stack-auto
40 #if !defined(__SDCC_USE_XSTACK) && !defined(_SDCC_NO_ASM_LIB_FUNCS)
41 # if defined(__SDCC_mcs51)
42 # if defined(__SDCC_MODEL_SMALL)
43 # if defined(__SDCC_STACK_AUTO) && !defined(__SDCC_PARMS_IN_BANK1)
44 # define _MODSLONG_ASM_SMALL_AUTO
45 # else
46 # define _MODSLONG_ASM_SMALL
47 # endif
48 # endif
49 # endif
50 #endif
52 #if defined _MODSLONG_ASM_SMALL
54 static void
55 _modslong_dummy (void) __naked
57 __asm
59 #define a0 dpl
60 #define a1 dph
61 #define a2 b
62 #define a3 r1
64 .globl __modslong
65 #if defined(__SDCC_PARMS_IN_BANK1)
66 #define b0 (b1_0)
67 #define b1 (b1_1)
68 #define b2 (b1_2)
69 #define b3 (b1_3)
70 #else
71 // _modslong_PARM_2 shares the same memory with _modulong_PARM_2
72 // and is defined in _modulong.c
73 #define b0 (__modslong_PARM_2)
74 #define b1 (__modslong_PARM_2 + 1)
75 #define b2 (__modslong_PARM_2 + 2)
76 #define b3 (__modslong_PARM_2 + 3)
77 #endif
78 __modslong:
79 ; a3 in acc
80 ; b3 in (__modslong_PARM_2 + 3)
81 mov a3,a ; save a3
83 clr F0 ; Flag 0 in PSW
84 ; available to user for general purpose
85 jnb acc.7,a_not_negative
87 setb F0
89 clr a ; a = -a;
90 clr c
91 subb a,a0
92 mov a0,a
93 clr a
94 subb a,a1
95 mov a1,a
96 clr a
97 subb a,a2
98 mov a2,a
99 clr a
100 subb a,a3
101 mov a3,a
103 a_not_negative:
105 mov a,b3
106 jnb acc.7,b_not_negative
108 clr a ; b = -b;
109 clr c
110 subb a,b0
111 mov b0,a
112 clr a
113 subb a,b1
114 mov b1,a
115 clr a
116 subb a,b2
117 mov b2,a
118 clr a
119 subb a,b3
120 mov b3,a
122 b_not_negative:
124 mov a,a3 ; restore a3 in acc
126 lcall __modulong
128 jnb F0,not_negative
130 ; result in (a == r1), b, dph, dpl
131 clr a
132 clr c
133 subb a,a0
134 mov a0,a
135 clr a
136 subb a,a1
137 mov a1,a
138 clr a
139 subb a,a2
140 mov a2,a
141 clr a
142 subb a,a3
143 ; result in a, b, dph, dpl
144 not_negative:
147 __endasm;
150 #elif defined _MODSLONG_ASM_SMALL_AUTO
152 static void
153 _modslong_dummy (void) __naked
155 __asm
157 #define a0 dpl
158 #define a1 dph
159 #define a2 b
160 #define a3 r1
162 #define b0 r2
163 #define b1 r3
164 #define b2 r4
165 #define b3 r5
167 ar2 = 2 ; BUG register set is not considered
168 ar3 = 3
169 ar4 = 4
170 ar5 = 5
172 .globl __modslong
174 __modslong:
176 ; a3 in acc
177 mov a3,a ; save a3
179 clr F0 ; F0 (Flag 0)
180 ; available to user for general purpose
181 jnb acc.7,a_not_negative
183 setb F0
185 clr a ; a = -a;
186 clr c
187 subb a,a0
188 mov a0,a
189 clr a
190 subb a,a1
191 mov a1,a
192 clr a
193 subb a,a2
194 mov a2,a
195 clr a
196 subb a,a3
197 mov a3,a
199 a_not_negative:
201 mov a,sp
202 add a,#-2-3 ; 2 bytes return address, 3 bytes param b
203 mov r0,a ; r1 points to b0
205 mov ar2,@r0 ; load b0
206 inc r0 ; r0 points to b1
207 mov ar3,@r0 ; b1
208 inc r0
209 mov ar4,@r0 ; b2
210 inc r0
211 mov a,@r0 ; b3
212 mov b3,a
214 jnb acc.7,b_not_negative
216 clr a ; b = -b;
217 clr c
218 subb a,b0
219 mov b0,a
220 clr a
221 subb a,b1
222 mov b1,a
223 clr a
224 subb a,b2
225 mov b2,a
226 clr a
227 subb a,b3
228 mov b3,a
230 b_not_negative:
232 lcall __modlong
234 jnb F0,not_negative
236 ; result in (a == r1), b, dph, dpl
237 clr a
238 clr c
239 subb a,a0
240 mov a0,a
241 clr a
242 subb a,a1
243 mov a1,a
244 clr a
245 subb a,a2
246 mov a2,a
247 clr a
248 subb a,a3 ; result in a, b, dph, dpl
250 not_negative:
253 __endasm;
256 #else // _MODSLONG_ASM
258 long
259 _modslong (long a, long b) __SDCC_NONBANKED
261 long r;
263 r = (unsigned long)(a < 0 ? -a : a) % (unsigned long)(b < 0 ? -b : b);
265 if (a < 0)
266 return -r;
267 else
268 return r;
271 #endif // _MODSLONG_ASM