Prepare for SDCC 4.5.0 release.
[sdcc.git] / sdcc / device / lib / _divuint.c
blob63d6e048de5964de3f03870b5851b380215253fd
1 /*-------------------------------------------------------------------------
2 _divuint.c - routine for unsigned int (16 bit) division
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
9 later version.
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,
19 MA 02110-1301, USA.
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:
30 mcs51 small
31 mcs51 small stack-auto
34 #include <stdbool.h>
36 #include <sdcc-lib.h>
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)
42 # define _DIVUINT_ASM_SMALL_AUTO
43 # else
44 # define _DIVUINT_ASM_SMALL
45 # endif
46 # endif
47 # endif
48 #endif
50 #if defined _DIVUINT_ASM_SMALL || defined _DIVUINT_ASM_SMALL_AUTO
52 static void
53 _divuint_dummy (void) __naked
55 __asm
57 .globl __divuint
59 __divuint:
61 #define count r2
62 #define reste_l r3
63 #define reste_h r4
64 #define xl dpl
65 #define xh dph
67 #if defined(__SDCC_PARMS_IN_BANK1)
68 #define yl (b1_0)
69 #define yh (b1_1)
70 #else // __SDCC_PARMS_IN_BANK1
71 #if defined(__SDCC_STACK_AUTO)
73 .globl __divint
75 mov a,sp
76 add a,#-2 ; 2 bytes return address
77 mov r0,a ; r0 points to yh
78 mov a,@r0 ; load yh
79 mov r1,a
80 dec r0
81 mov a,@r0 ; load yl
82 mov r0,a
84 #define yl r0
85 #define yh r1
87 __divint: ; entry point for __divsint
90 #else // __SDCC_STACK_AUTO
92 #if defined(__SDCC_NOOVERLAY)
93 .area DSEG (DATA)
94 #else
95 .area OSEG (OVR,DATA)
96 #endif
98 .globl __divuint_PARM_2
99 .globl __divsint_PARM_2
101 __divuint_PARM_2:
102 __divsint_PARM_2:
103 .ds 2
105 .area CSEG (CODE)
107 #define yl (__divuint_PARM_2)
108 #define yh (__divuint_PARM_2 + 1)
110 #endif // __SDCC_STACK_AUTO
111 #endif // __SDCC_PARMS_IN_BANK1
113 mov count,#16
114 clr a
115 mov reste_l,a
116 mov reste_h,a
118 loop:
119 mov a,xl ; x <<= 1
120 add a,acc
121 mov xl,a
122 mov a,xh
123 rlc a
124 mov xh,a
126 mov a,reste_l ; reste <<= 1
127 rlc a ; feed in carry
128 mov reste_l,a
129 mov a,reste_h
130 rlc a
131 mov reste_h,a
133 mov a,reste_l ; reste - y
134 subb a,yl ; here carry is always clear, because
135 ; reste <<= 1 never overflows
136 mov b,a
137 mov a,reste_h
138 subb a,yh
140 jc smaller ; reste >= y?
142 mov reste_h,a ; -> yes; reste = reste - y;
143 mov reste_l,b
144 orl xl,#1
145 smaller: ; -> no
146 djnz count,loop
149 __endasm;
152 #else // defined _DIVUINT_ASM_SMALL || defined _DIVUINT_ASM_SMALL_AUTO
154 #define MSB_SET(x) ((x >> (8*sizeof(x)-1)) & 1)
156 unsigned int
157 _divuint (unsigned int x, unsigned int y) __SDCC_NONBANKED
159 unsigned int reste = 0;
160 unsigned char count = 16;
161 bool c;
165 // reste: x <- 0;
166 c = MSB_SET(x);
167 x <<= 1;
168 reste <<= 1;
169 if (c)
170 reste |= 1;
172 if (reste >= y)
174 reste -= y;
175 // x <- (result = 1)
176 x |= 1;
179 while (--count);
180 return x;
183 #endif // defined _DIVUINT_ASM_SMALL || defined _DIVUINT_ASM_SMALL_AUTO