1 /*-------------------------------------------------------------------------
2 _divulong.c - routine for division of 32 bit unsigned long
4 Ecrit par - Jean-Louis Vern . jlvern@writeme.com (1999)
6 This library is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Library General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
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 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
25 /* Assembler-functions are provided for:
27 mcs51 small stack-auto
30 #if !defined(SDCC_USE_XSTACK) && !defined(_SDCC_NO_ASM_LIB_FUNCS)
31 # if defined(SDCC_mcs51)
32 # if defined(SDCC_MODEL_SMALL)
33 # if defined(SDCC_STACK_AUTO) && !defined(SDCC_PARMS_IN_BANK1)
34 # define _DIVULONG_ASM_SMALL_AUTO
36 # define _DIVULONG_ASM_SMALL
42 #if defined _DIVULONG_ASM_SMALL
45 _divlong_dummy (void) _naked
64 #if !defined(SDCC_PARMS_IN_BANK1)
66 #if defined(SDCC_NOOVERLAY)
72 .globl __divulong_PARM_2
73 .globl __divslong_PARM_2
81 #define b0 (__divulong_PARM_2)
82 #define b1 (__divulong_PARM_2 + 1)
83 #define b2 (__divulong_PARM_2 + 2)
84 #define b3 (__divulong_PARM_2 + 3)
90 #endif // !SDCC_PARMS_IN_BANK1
91 ; parameter a comes in a, b, dph, dpl
92 mov a3,a ; save parameter a3
101 ; optimization loop in lp0 until the first bit is shifted into rest
103 lp0: mov a,a0 ; a <<= 1
121 loop: mov a,a0 ; a <<= 1
134 in_lp: mov a,reste0 ; reste <<= 1
135 rlc a ; feed in carry
147 mov a,reste0 ; reste - b
148 subb a,b0 ; carry is always clear here, because
149 ; reste <<= 1 never overflows
157 jc minus ; reste >= b?
159 ; -> yes; reste -= b;
161 subb a,b0 ; carry is always clear here (jc)
175 minus: djnz count,loop ; -> no
177 exit: mov a,a3 ; prepare the return value
183 #elif defined _DIVULONG_ASM_SMALL_AUTO
186 _divlong_dummy (void) _naked
206 .globl __divlong ; entry point for __divslong
210 ar0 = 0 ; BUG register set is not considered
213 ; parameter a comes in a, b, dph, dpl
214 mov a3,a ; save parameter a3
217 add a,#-2-3 ; 2 bytes return address, 3 bytes param b
218 mov r0,a ; r0 points to b0
220 __divlong: ; entry point for __divslong
222 mov ar1,@r0 ; load b0
223 inc r0 ; r0 points to b1
232 ; optimization loop in lp0 until the first bit is shifted into rest
234 lp0: mov a,a0 ; a <<= 1
252 loop: mov a,a0 ; a <<= 1
265 in_lp: mov a,reste0 ; reste <<= 1
266 rlc a ; feed in carry
278 mov a,reste0 ; reste - b
279 subb a,b0 ; carry is always clear here, because
280 ; reste <<= 1 never overflows
292 jc minus ; reste >= b?
294 ; -> yes; reste -= b;
296 subb a,b0 ; carry is always clear here (jc)
314 minus: djnz count,loop ; -> no
316 exit: mov a,a3 ; prepare the return value
322 #else // _DIVULONG_ASM
324 #define MSB_SET(x) ((x >> (8*sizeof(x)-1)) & 1)
327 _divulong (unsigned long a, unsigned long b)
329 unsigned long reste = 0L;
330 unsigned char count = 32;
353 #endif // _DIVULONG_ASM