Added bpx Needed for 10bit stack pointer ds390
[fw/sdcc] / device / lib / _moduint.c
1 /*-------------------------------------------------------------------------
2   _moduint.c :- routine for unsigned int (16 bit) modulus
3
4              Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1999)
5
6              Bug fixes by Martijn van Balen, aed@iae.nl
7
8    This library is free software; you can redistribute it and/or modify it
9    under the terms of the GNU Library General Public License as published by the
10    Free Software Foundation; either version 2, or (at your option) any
11    later version.
12
13    This library is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU Library General Public License for more details.
17
18    You should have received a copy of the GNU Library General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22    In other words, you are welcome to use, share and improve this program.
23    You are forbidden to forbid anyone else to use, share and improve
24    what you give them.   Help stamp out software-hoarding!
25 -------------------------------------------------------------------------*/
26
27 /*   Assembler-functions are provided for:
28      mcs51 small
29      mcs51 small stack-auto
30 */
31
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)
36 #        define _MODUINT_ASM_SMALL_AUTO
37 #      else
38 #        define _MODUINT_ASM_SMALL
39 #      endif
40 #    endif
41 #  endif
42 #endif
43
44 #if defined _MODUINT_ASM_SMALL || defined _MODUINT_ASM_SMALL_AUTO
45
46 static void
47 _moduint_dummy (void) _naked
48 {
49         _asm
50
51                 .globl __moduint
52
53         __moduint:
54
55                 #define count   r2
56                 #define al      dpl
57                 #define ah      dph
58
59 #ifdef SDCC_STACK_AUTO
60
61                 ar0 = 0                 ; BUG register set is not considered
62                 ar1 = 1
63
64                 .globl __modint
65
66                 mov     a,sp
67                 add     a,#-2           ; 2 bytes return address
68                 mov     r0,a            ; r0 points to bh
69                 mov     ar1,@r0         ; load bh
70                 dec     r0
71                 mov     ar0,@r0         ; load bl
72
73                 #define bl      r0
74                 #define bh      r1
75
76         __modint:                       ; entry point for __modsint
77
78
79 #else // SDCC_STACK_AUTO
80
81 #if defined(SDCC_NOOVERLAY)
82                 .area DSEG    (DATA)
83 #else
84                 .area OSEG    (OVR,DATA)
85 #endif
86
87                 .globl __moduint_PARM_2
88                 .globl __modsint_PARM_2
89
90         __moduint_PARM_2:
91         __modsint_PARM_2:
92                 .ds     2
93
94                 .area CSEG    (CODE)
95
96                 #define bl      (__moduint_PARM_2)
97                 #define bh      (__moduint_PARM_2 + 1)
98
99 #endif // SDCC_STACK_AUTO
100
101                 mov     a,bl            ; avoid endless loop
102                 orl     a,bh
103                 jz      div_by_0
104
105                 mov     count,#1
106
107         loop1:  mov     a,bl            ; b <<= 1
108                 add     a,acc
109                 mov     bl,a
110                 mov     a,bh
111                 rlc     a
112                 jc      msbset
113                 mov     bh,a
114
115                 mov     a,al            ; a - b
116                 subb    a,bl            ; here carry is always clear
117                 mov     a,ah
118                 subb    a,bh
119
120                 jc      start
121
122                 inc     count
123                 sjmp    loop1
124
125
126         start:  clr     c
127                 mov     a,bh            ; b >>= 1;
128         msbset: rrc     a
129                 mov     bh,a
130                 mov     a,bl
131                 rrc     a
132                 mov     bl,a
133
134
135         loop2:  clr     c
136                 mov     a,al            ; a - b
137                 subb    a,bl
138
139                 mov     b,a
140                 mov     a,ah
141                 subb    a,bh
142
143                 jc      smaller         ; a >= b?
144
145                 mov     ah,a            ; -> yes;  a = a - b;
146                 mov     al,b
147         smaller:                        ; -> no
148                 clr     c
149                 mov     a,bh            ; b >>= 1;
150                 rrc     a
151                 mov     bh,a
152                 mov     a,bl
153                 rrc     a
154                 mov     bl,a
155
156                 djnz    count,loop2
157         div_by_0:
158                 ret
159
160         _endasm ;
161 }
162
163 #else  // defined _MODUINT_ASM_SMALL || defined _MODUINT_ASM_SMALL_AUTO
164
165 #define MSB_SET(x) ((x >> (8*sizeof(x)-1)) & 1) 
166
167 unsigned int
168 _moduint (unsigned int a, unsigned int b)
169 {
170   unsigned char count = 0;
171     
172     
173   while (!MSB_SET(b))
174   {
175     b <<= 1;
176     if (b > a)
177     {
178       b >>=1;
179       break;
180     }
181     count++;
182   }
183   do
184   {
185     if (a >= b)
186       a -= b;
187     b >>= 1;
188   }
189   while (count--);
190   return a;
191 }
192
193 #endif  // defined _MODUINT_ASM_SMALL || defined _MODUINT_ASM_SMALL_AUTO