1 /*-------------------------------------------------------------------------
2 _divulong.c - routine for division of 32 bit unsigned long
4 Copyright (C) 1999, Jean-Louis Vern <jlvern AT gmail.com>
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
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,
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 -------------------------------------------------------------------------*/
29 /* Assembler-functions are provided for:
31 mcs51 small stack-auto
38 #if !defined(__SDCC_USE_XSTACK) && !defined(_SDCC_NO_ASM_LIB_FUNCS)
39 # if defined(__SDCC_mcs51)
40 # if defined(__SDCC_MODEL_SMALL)
41 # if defined(__SDCC_STACK_AUTO) && !defined(__SDCC_PARMS_IN_BANK1)
42 # define _DIVULONG_ASM_SMALL_AUTO
44 # define _DIVULONG_ASM_SMALL
50 #if defined _DIVULONG_ASM_SMALL
53 _divlong_dummy (void) __naked
72 #if !defined(__SDCC_PARMS_IN_BANK1)
74 #if defined(__SDCC_NOOVERLAY)
80 .globl __divulong_PARM_2
81 .globl __divslong_PARM_2
89 #define y0 (__divulong_PARM_2)
90 #define y1 (__divulong_PARM_2 + 1)
91 #define y2 (__divulong_PARM_2 + 2)
92 #define y3 (__divulong_PARM_2 + 3)
98 #endif // !__SDCC_PARMS_IN_BANK1
99 ; parameter x comes in a
, b
, dph
, dpl
100 mov x3
,a
; save parameter x3
109 ; optimization loop in lp0 until the first bit is shifted into rest
111 lp0
: mov a
,x0
; x
<<= 1
129 loop
: mov a
,x0
; x
<<= 1
142 in_lp
: mov a
,reste0
; reste
<<= 1
143 rlc a
; feed in carry
155 mov a
,reste0
; reste
- y
156 subb a
,y0
; carry is always clear here
, because
157 ; reste
<<= 1 never overflows
165 jc minus
; reste
>= y
?
167 ; -> yes
; reste
-= y
;
169 subb a
,y0
; carry is always clear
here (jc
)
183 minus
: djnz count
,loop
; -> no
185 exit
: mov a
,x3
; prepare the
return value
191 #elif defined _DIVULONG_ASM_SMALL_AUTO
194 _divlong_dummy (void) __naked
214 .globl __divlong
; entry point
for __divslong
218 ; parameter x comes in a
, b
, dph
, dpl
219 mov x3
,a
; save parameter x3
222 add a
,#-2-3 ; 2 bytes return address, 3 bytes param y
223 mov r0
,a
; r0 points to y0
225 __divlong
: ; entry point
for __divslong
229 inc r0
; r0 points to y1
238 ; optimization loop in lp0 until the first bit is shifted into rest
240 lp0
: mov a
,x0
; x
<<= 1
258 loop
: mov a
,x0
; x
<<= 1
271 in_lp
: mov a
,reste0
; reste
<<= 1
272 rlc a
; feed in carry
284 mov a
,reste0
; reste
- y
285 subb a
,y0
; carry is always clear here
, because
286 ; reste
<<= 1 never overflows
298 jc minus
; reste
>= y
?
300 ; -> yes
; reste
-= y
;
302 subb a
,y0
; carry is always clear
here (jc
)
320 minus
: djnz count
,loop
; -> no
322 exit
: mov a
,x3
; prepare the
return value
328 #else // _DIVULONG_ASM
330 #define MSB_SET(x) ((x >> (8*sizeof(x)-1)) & 1)
333 _divulong (unsigned long x
, unsigned long y
) __SDCC_NONBANKED
335 unsigned long reste
= 0L;
336 unsigned char count
= 32;
359 #endif // _DIVULONG_ASM