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
32 #if !defined(SDCC_USE_XSTACK) && !defined(_SDCC_NO_ASM_LIB_FUNCS)
33 # if defined(SDCC_mcs51)
34 # if defined(SDCC_MODEL_SMALL)
35 # if defined(SDCC_STACK_AUTO) && !defined(SDCC_PARMS_IN_BANK1)
36 # define _DIVULONG_ASM_SMALL_AUTO
38 # define _DIVULONG_ASM_SMALL
44 #if defined _DIVULONG_ASM_SMALL
47 _divlong_dummy (void) _naked
66 #if !defined(SDCC_PARMS_IN_BANK1)
68 #if defined(SDCC_NOOVERLAY)
74 .globl __divulong_PARM_2
75 .globl __divslong_PARM_2
83 #define b0 (__divulong_PARM_2)
84 #define b1 (__divulong_PARM_2 + 1)
85 #define b2 (__divulong_PARM_2 + 2)
86 #define b3 (__divulong_PARM_2 + 3)
92 #endif // !SDCC_PARMS_IN_BANK1
93 ; parameter a comes in a, b, dph, dpl
94 mov a3,a ; save parameter a3
103 ; optimization loop in lp0 until the first bit is shifted into rest
105 lp0: mov a,a0 ; a <<= 1
123 loop: mov a,a0 ; a <<= 1
136 in_lp: mov a,reste0 ; reste <<= 1
137 rlc a ; feed in carry
149 mov a,reste0 ; reste - b
150 subb a,b0 ; carry is always clear here, because
151 ; reste <<= 1 never overflows
159 jc minus ; reste >= b?
161 ; -> yes; reste -= b;
163 subb a,b0 ; carry is always clear here (jc)
177 minus: djnz count,loop ; -> no
179 exit: mov a,a3 ; prepare the return value
185 #elif defined _DIVULONG_ASM_SMALL_AUTO
188 _divlong_dummy (void) _naked
208 .globl __divlong ; entry point for __divslong
212 ar0 = 0 ; BUG register set is not considered
215 ; parameter a comes in a, b, dph, dpl
216 mov a3,a ; save parameter a3
219 add a,#-2-3 ; 2 bytes return address, 3 bytes param b
220 mov r0,a ; r0 points to b0
222 __divlong: ; entry point for __divslong
224 mov ar1,@r0 ; load b0
225 inc r0 ; r0 points to b1
234 ; optimization loop in lp0 until the first bit is shifted into rest
236 lp0: mov a,a0 ; a <<= 1
254 loop: mov a,a0 ; a <<= 1
267 in_lp: mov a,reste0 ; reste <<= 1
268 rlc a ; feed in carry
280 mov a,reste0 ; reste - b
281 subb a,b0 ; carry is always clear here, because
282 ; reste <<= 1 never overflows
294 jc minus ; reste >= b?
296 ; -> yes; reste -= b;
298 subb a,b0 ; carry is always clear here (jc)
316 minus: djnz count,loop ; -> no
318 exit: mov a,a3 ; prepare the return value
324 #else // _DIVULONG_ASM
326 #define MSB_SET(x) ((x >> (8*sizeof(x)-1)) & 1)
329 _divulong (unsigned long a, unsigned long b)
331 unsigned long reste = 0L;
332 unsigned char count = 32;
355 #endif // _DIVULONG_ASM