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)
34 # define _DIVULONG_ASM_SMALL_AUTO
36 # define _DIVULONG_ASM_SMALL
42 #if defined _DIVULONG_ASM_SMALL
45 _divlong_dummy (void) _naked
65 #if defined(SDCC_NOOVERLAY) // BUG SDCC_NOOVERLAY is not set by -no-overlay
71 .globl __divulong_PARM_2
72 .globl __divslong_PARM_2
80 #define b0 (__divulong_PARM_2)
81 #define b1 (__divulong_PARM_2 + 1)
82 #define b2 (__divulong_PARM_2 + 2)
83 #define b3 (__divulong_PARM_2 + 3)
85 ; parameter a comes in a, b, dph, dpl
86 mov a3,a ; save parameter a3
95 ; optimization loop in lp0 until the first bit is shifted into rest
97 lp0: mov a,a0 ; a <<= 1
115 loop: mov a,a0 ; a <<= 1
128 in_lp: mov a,reste0 ; reste <<= 1
129 rlc a ; feed in carry
141 mov a,reste0 ; reste - b
142 subb a,b0 ; carry is always clear here, because
143 ; reste <<= 1 never overflows
151 jc minus ; reste >= b?
153 ; -> yes; reste -= b;
155 subb a,b0 ; carry is always clear here (jc)
169 minus: djnz count,loop ; -> no
171 exit: mov a,a3 ; prepare the return value
177 #elif defined _DIVULONG_ASM_SMALL_AUTO
180 _divlong_dummy (void) _naked
200 .globl __divlong ; entry point for __divslong
204 ar0 = 0 ; BUG register set is not considered
207 ; parameter a comes in a, b, dph, dpl
208 mov a3,a ; save parameter a3
211 add a,#-2-3 ; 2 bytes return address, 3 bytes param b
212 mov r0,a ; r0 points to b0
214 __divlong: ; entry point for __divslong
216 mov ar1,@r0 ; load b0
217 inc r0 ; r0 points to b1
226 ; optimization loop in lp0 until the first bit is shifted into rest
228 lp0: mov a,a0 ; a <<= 1
246 loop: mov a,a0 ; a <<= 1
259 in_lp: mov a,reste0 ; reste <<= 1
260 rlc a ; feed in carry
272 mov a,reste0 ; reste - b
273 subb a,b0 ; carry is always clear here, because
274 ; reste <<= 1 never overflows
286 jc minus ; reste >= b?
288 ; -> yes; reste -= b;
290 subb a,b0 ; carry is always clear here (jc)
308 minus: djnz count,loop ; -> no
310 exit: mov a,a3 ; prepare the return value
316 #else // _DIVULONG_ASM
318 #define MSB_SET(x) ((x >> (8*sizeof(x)-1)) & 1)
321 _divulong (unsigned long a, unsigned long b)
323 unsigned long reste = 0L;
324 unsigned char count = 32;
325 #if defined(SDCC_STACK_AUTO) || defined(SDCC_z80)
351 #endif // _DIVULONG_ASM