Hackfix and re-enable strtoull and wcstoull, see bug #3798.
[sdcc.git] / sdcc / device / lib / _moduint.c
blob73cb08bf026a291ba1a0875a509778ec6c8c0a3f
1 /*-------------------------------------------------------------------------
2 _moduint.c - routine for unsigned int (16 bit) modulus
4 Copyright (C) 1999, Sandeep Dutta . sandeep.dutta@usa.net
5 Bug fixes by Martijn van Balen, aed@iae.nl
7 This library is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
10 later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this library; see the file COPYING. If not, write to the
19 Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
20 MA 02110-1301, USA.
22 As a special exception, if you link this library with other files,
23 some of which are compiled with SDCC, to produce an executable,
24 this library does not by itself cause the resulting executable to
25 be covered by the GNU General Public License. This exception does
26 not however invalidate any other reasons why the executable file
27 might be covered by the GNU General Public License.
28 -------------------------------------------------------------------------*/
30 /* Assembler-functions are provided for:
31 mcs51 small
32 mcs51 small stack-auto
35 #include <sdcc-lib.h>
37 #if !defined(__SDCC_USE_XSTACK) && !defined(_SDCC_NO_ASM_LIB_FUNCS)
38 # if defined(__SDCC_mcs51)
39 # if defined(__SDCC_MODEL_SMALL)
40 # if defined(__SDCC_STACK_AUTO)
41 # define _MODUINT_ASM_SMALL_AUTO
42 # else
43 # define _MODUINT_ASM_SMALL
44 # endif
45 # endif
46 # endif
47 #endif
49 #if defined _MODUINT_ASM_SMALL || defined _MODUINT_ASM_SMALL_AUTO
51 static void
52 _moduint_dummy (void) __naked
54 __asm
56 .globl __moduint
58 __moduint:
60 #define count r2
61 #define al dpl
62 #define ah dph
64 #if defined(__SDCC_STACK_AUTO) && !defined(__SDCC_PARMS_IN_BANK1)
66 ar0 = 0 ; BUG register set is not considered
67 ar1 = 1
69 .globl __modint
71 mov a,sp
72 add a,#-2 ; 2 bytes return address
73 mov r0,a ; r0 points to bh
74 mov ar1,@r0 ; load bh
75 dec r0
76 mov ar0,@r0 ; load bl
78 #define bl r0
79 #define bh r1
81 __modint: ; entry point for __modsint
84 #else // __SDCC_STACK_AUTO
86 #if !defined(__SDCC_PARMS_IN_BANK1)
87 #if defined(__SDCC_NOOVERLAY)
88 .area DSEG (DATA)
89 #else
90 .area OSEG (OVR,DATA)
91 #endif
93 .globl __moduint_PARM_2
94 .globl __modsint_PARM_2
96 __moduint_PARM_2:
97 __modsint_PARM_2:
98 .ds 2
100 .area CSEG (CODE)
102 #define bl (__moduint_PARM_2)
103 #define bh (__moduint_PARM_2 + 1)
104 #else
105 #define bl (b1_0)
106 #define bh (b1_1)
107 #endif
108 #endif // __SDCC_STACK_AUTO
110 mov a,bl ; avoid endless loop
111 orl a,bh
112 jz div_by_0
114 mov count,#1
116 loop1: mov a,bl ; b <<= 1
117 add a,acc
118 mov bl,a
119 mov a,bh
120 rlc a
121 jc msbset
122 mov bh,a
124 mov a,al ; a - b
125 subb a,bl ; here carry is always clear
126 mov a,ah
127 subb a,bh
129 jc start
131 inc count
132 sjmp loop1
134 start: clr c
135 mov a,bh ; b >>= 1;
136 msbset: rrc a
137 mov bh,a
138 mov a,bl
139 rrc a
140 mov bl,a
142 loop2: clr c
143 mov a,al ; a - b
144 subb a,bl
146 mov b,a
147 mov a,ah
148 subb a,bh
150 jc smaller ; a >= b?
152 mov ah,a ; -> yes; a = a - b;
153 mov al,b
154 smaller: ; -> no
155 clr c
156 mov a,bh ; b >>= 1;
157 rrc a
158 mov bh,a
159 mov a,bl
160 rrc a
161 mov bl,a
163 djnz count,loop2
164 div_by_0:
167 __endasm;
170 #else // defined _MODUINT_ASM_SMALL || defined _MODUINT_ASM_SMALL_AUTO
172 #define MSB_SET(x) ((x >> (8*sizeof(x)-1)) & 1)
174 unsigned int
175 _moduint (unsigned int a, unsigned int b) __SDCC_NONBANKED
177 unsigned char count = 0;
179 while (!MSB_SET(b))
181 b <<= 1;
182 if (b > a)
184 b >>=1;
185 break;
187 count++;
191 if (a >= b)
192 a -= b;
193 b >>= 1;
195 while (count--);
196 return a;
199 #endif // defined _MODUINT_ASM_SMALL || defined _MODUINT_ASM_SMALL_AUTO