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 y0 (__divulong_PARM_2)
84 #define y1 (__divulong_PARM_2 + 1)
85 #define y2 (__divulong_PARM_2 + 2)
86 #define y3 (__divulong_PARM_2 + 3)
92 #endif // !SDCC_PARMS_IN_BANK1
93 ; parameter x comes in a, b, dph, dpl
94 mov x3,a ; save parameter x3
103 ; optimization loop in lp0 until the first bit is shifted into rest
105 lp0: mov a,x0 ; x <<= 1
123 loop: mov a,x0 ; x <<= 1
136 in_lp: mov a,reste0 ; reste <<= 1
137 rlc a ; feed in carry
149 mov a,reste0 ; reste - y
150 subb a,y0 ; carry is always clear here, because
151 ; reste <<= 1 never overflows
159 jc minus ; reste >= y?
161 ; -> yes; reste -= y;
163 subb a,y0 ; carry is always clear here (jc)
177 minus: djnz count,loop ; -> no
179 exit: mov a,x3 ; prepare the return value
185 #elif defined _DIVULONG_ASM_SMALL_AUTO
188 _divlong_dummy (void) __naked
208 .globl __divlong ; entry point for __divslong
212 ; parameter x comes in a, b, dph, dpl
213 mov x3,a ; save parameter x3
216 add a,#-2-3 ; 2 bytes return address, 3 bytes param y
217 mov r0,a ; r0 points to y0
219 __divlong: ; entry point for __divslong
223 inc r0 ; r0 points to y1
232 ; optimization loop in lp0 until the first bit is shifted into rest
234 lp0: mov a,x0 ; x <<= 1
252 loop: mov a,x0 ; x <<= 1
265 in_lp: mov a,reste0 ; reste <<= 1
266 rlc a ; feed in carry
278 mov a,reste0 ; reste - y
279 subb a,y0 ; carry is always clear here, because
280 ; reste <<= 1 never overflows
292 jc minus ; reste >= y?
294 ; -> yes; reste -= y;
296 subb a,y0 ; carry is always clear here (jc)
314 minus: djnz count,loop ; -> no
316 exit: mov a,x3 ; prepare the return value
322 #else // _DIVULONG_ASM
324 #define MSB_SET(x) ((x >> (8*sizeof(x)-1)) & 1)
327 _divulong (unsigned long x, unsigned long y)
329 unsigned long reste = 0L;
330 unsigned char count = 32;
353 #endif // _DIVULONG_ASM