Prepare for SDCC 4.5.0 release.
[sdcc.git] / sdcc / device / lib / _divsint.c
blob1561cca676da56e8fec38e061444b103d3b7049f
1 /*-------------------------------------------------------------------------
2 _divsint.c :- routine for signed int (16 bit) division. just calls
3 routine for unsigned division after sign adjustment
5 Copyright (C) 1999, Sandeep Dutta . sandeep.dutta@usa.net
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 -------------------------------------------------------------------------*/
31 #include <sdcc-lib.h>
33 #if _SDCC_MANGLES_SUPPORT_FUNS
34 unsigned unsigned _divuint (unsigned x, unsigned y);
35 #endif
37 /* Assembler-functions are provided for:
38 mcs51 small
39 mcs51 small stack-auto
42 #if !defined(__SDCC_USE_XSTACK) && !defined(_SDCC_NO_ASM_LIB_FUNCS)
43 # if defined(__SDCC_mcs51)
44 # if defined(__SDCC_MODEL_SMALL)
45 # if defined(__SDCC_STACK_AUTO) && !defined(__SDCC_PARMS_IN_BANK1)
46 # define _DIVSINT_ASM_SMALL_AUTO
47 # else
48 # define _DIVSINT_ASM_SMALL
49 # endif
50 # endif
51 # endif
52 #endif
54 #if defined _DIVSINT_ASM_SMALL
56 static void
57 _divsint_dummy (void) __naked
59 __asm
61 #define xl dpl
62 #define xh dph
64 .globl __divsint
66 // _divsint_PARM_2 shares the same memory with _divuint_PARM_2
67 // and is defined in _divuint.c
68 #if defined(__SDCC_PARMS_IN_BANK1)
69 #define yl (b1_0)
70 #define yh (b1_1)
71 #else
72 #define yl (__divsint_PARM_2)
73 #define yh (__divsint_PARM_2 + 1)
74 #endif
75 __divsint:
76 ; xh in dph
77 ; yh in (__divsint_PARM_2 + 1)
79 clr F0 ; Flag 0 in PSW
80 ; available to user for general purpose
81 mov a,xh
82 jnb acc.7,a_not_negative
84 setb F0
86 clr a
87 clr c
88 subb a,xl
89 mov xl,a
90 clr a
91 subb a,xh
92 mov xh,a
94 a_not_negative:
96 mov a,yh
97 jnb acc.7,b_not_negative
99 cpl F0
101 clr a
102 clr c
103 subb a,yl
104 mov yl,a
105 clr a
106 subb a,yh
107 mov yh,a
109 b_not_negative:
111 lcall __divuint
113 jnb F0,not_negative
115 clr a
116 clr c
117 subb a,xl
118 mov xl,a
119 clr a
120 subb a,xh
121 mov xh,a
123 not_negative:
126 __endasm;
129 #elif defined _DIVSINT_ASM_SMALL_AUTO
131 static void
132 _divsint_dummy (void) __naked
134 __asm
136 #define xl dpl
137 #define xh dph
139 .globl __divsint
141 __divsint:
143 clr F0 ; Flag 0 in PSW
144 ; available to user for general purpose
145 mov a,xh
146 jnb acc.7,a_not_negative
148 setb F0
150 clr a
151 clr c
152 subb a,xl
153 mov xl,a
154 clr a
155 subb a,xh
156 mov xh,a
158 a_not_negative:
160 mov a,sp
161 add a,#-2 ; 2 bytes return address
162 mov r0,a ; r0 points to yh
163 mov a,@r0 ; a = yh
165 jnb acc.7,b_not_negative
167 cpl F0
169 dec r0
171 clr a
172 clr c
173 subb a,@r0 ; yl
174 mov @r0,a
175 clr a
176 inc r0
177 subb a,@r0 ; a = yh
179 b_not_negative:
181 mov r1,a ; yh
182 dec r0
183 mov a,@r0 ; yl
184 mov r0,a
186 lcall __divint
188 jnb F0,not_negative
190 clr a
191 clr c
192 subb a,xl
193 mov xl,a
194 clr a
195 subb a,xh
196 mov xh,a
198 not_negative:
201 __endasm;
204 #else // _DIVSINT_ASM_
207 _divsint (int x, int y) __SDCC_NONBANKED
209 register int r;
211 r = (unsigned int)(x < 0 ? -x : x) / (unsigned int)(y < 0 ? -y : y);
212 if ((x < 0) ^ (y < 0))
213 return -r;
214 else
215 return r;
218 #endif // _DIVSINT_ASM_