Prepare for SDCC 4.5.0 release.
[sdcc.git] / sdcc / device / lib / _divslong.c
blobc3d48f9e68b48e4f868e4912712135b272910874
1 /*-------------------------------------------------------------------------
2 _divslong.c - routine for division of 32 bit 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 -------------------------------------------------------------------------*/
30 #include <sdcc-lib.h>
32 #if _SDCC_MANGLES_SUPPORT_FUNS
33 unsigned long _divulong (unsigned long x, unsigned long y);
34 #endif
36 /* Assembler-functions are provided for:
37 mcs51 small
38 mcs51 small stack-auto
41 #if !defined(__SDCC_USE_XSTACK) && !defined(_SDCC_NO_ASM_LIB_FUNCS)
42 # if defined(__SDCC_mcs51)
43 # if defined(__SDCC_MODEL_SMALL)
44 # if defined(__SDCC_STACK_AUTO) && !defined(__SDCC_PARMS_IN_BANK1)
45 # define _DIVSLONG_ASM_SMALL_AUTO
46 # else
47 # define _DIVSLONG_ASM_SMALL
48 # endif
49 # endif
50 # endif
51 #endif
53 #if defined _DIVSLONG_ASM_SMALL
55 static void
56 _divslong_dummy (void) __naked
58 __asm
60 #define x0 dpl
61 #define x1 dph
62 #define x2 b
63 #define x3 r3
65 .globl __divslong
67 // _divslong_PARM_2 shares the same memory with _divulong_PARM_2
68 // and is defined in _divulong.c
69 #if defined(__SDCC_PARMS_IN_BANK1)
70 #define y0 (b1_0)
71 #define y1 (b1_1)
72 #define y2 (b1_2)
73 #define y3 (b1_3)
74 #else
75 #define y0 (__divslong_PARM_2)
76 #define y1 (__divslong_PARM_2 + 1)
77 #define y2 (__divslong_PARM_2 + 2)
78 #define y3 (__divslong_PARM_2 + 3)
79 #endif
80 __divslong:
81 ; x3 in acc
82 ; y3 in (__divslong_PARM_2 + 3)
83 mov x3,a ; save x3
85 clr F0 ; Flag 0 in PSW
86 ; available to user for general purpose
87 jnb acc.7,a_not_negative
89 setb F0
91 clr a
92 clr c
93 subb a,x0
94 mov x0,a
95 clr a
96 subb a,x1
97 mov x1,a
98 clr a
99 subb a,x2
100 mov x2,a
101 clr a
102 subb a,x3
103 mov x3,a
105 a_not_negative:
107 mov a,y3
108 jnb acc.7,b_not_negative
110 cpl F0
112 clr a
113 clr c
114 subb a,y0
115 mov y0,a
116 clr a
117 subb a,y1
118 mov y1,a
119 clr a
120 subb a,y2
121 mov y2,a
122 clr a
123 subb a,y3
124 mov y3,a
126 b_not_negative:
128 mov a,x3 ; restore x3 in acc
130 lcall __divulong
132 jnb F0,not_negative
134 mov x3,a ; save x3
136 clr a
137 clr c
138 subb a,x0
139 mov x0,a
140 clr a
141 subb a,x1
142 mov x1,a
143 clr a
144 subb a,x2
145 mov x2,a
146 clr a
147 subb a,x3 ; x3 ends in acc
149 not_negative:
152 __endasm;
155 #elif defined _DIVSLONG_ASM_SMALL_AUTO
157 static void
158 _divslong_dummy (void) __naked
160 __asm
162 #define x0 dpl
163 #define x1 dph
164 #define x2 b
165 #define x3 r3
167 .globl __divslong
169 __divslong:
171 ; x3 in acc
172 mov x3,a ; save x3
174 clr F0 ; Flag 0 in PSW
175 ; available to user for general purpose
176 jnb acc.7,a_not_negative
178 setb F0
180 clr a
181 clr c
182 subb a,x0
183 mov x0,a
184 clr a
185 subb a,x1
186 mov x1,a
187 clr a
188 subb a,x2
189 mov x2,a
190 clr a
191 subb a,x3
192 mov x3,a
194 a_not_negative:
196 mov a,sp
197 add a,#-2 ; 2 bytes return address
198 mov r0,a ; r0 points to y3
199 mov a,@r0 ; y3
201 jnb acc.7,b_not_negative
203 cpl F0
205 dec r0
206 dec r0
207 dec r0
209 clr a
210 clr c
211 subb a,@r0 ; y0
212 mov @r0,a
213 clr a
214 inc r0
215 subb a,@r0 ; y1
216 mov @r0,a
217 clr a
218 inc r0
219 subb a,@r0 ; y2
220 mov @r0,a
221 clr a
222 inc r0
223 subb a,@r0 ; y3
224 mov @r0,a
226 b_not_negative:
227 dec r0
228 dec r0
229 dec r0 ; r0 points to y0
231 lcall __divlong
233 jnb F0,not_negative
235 mov x3,a ; save x3
237 clr a
238 clr c
239 subb a,x0
240 mov x0,a
241 clr a
242 subb a,x1
243 mov x1,a
244 clr a
245 subb a,x2
246 mov x2,a
247 clr a
248 subb a,x3 ; x3 ends in acc
250 not_negative:
253 __endasm;
256 #else // _DIVSLONG_ASM
258 long
259 _divslong (long x, long y) __SDCC_NONBANKED
261 long r;
263 r = (unsigned long)(x < 0 ? -x : x) / (unsigned long)(y < 0 ? -y : y);
264 if ((x < 0) ^ (y < 0))
265 return -r;
266 else
267 return r;
270 #endif // _DIVSLONG_ASM