1 /*-------------------------------------------------------------------------
3 _mulint.c :- routine for (unsigned) int (16 bit) multiplication
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1999)
7 This program 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
12 This program 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 program; if not, write to the Free Software
19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 In other words, you are welcome to use, share and improve this program.
22 You are forbidden to forbid anyone else to use, share and improve
23 what you give them. Help stamp out software-hoarding!
24 -------------------------------------------------------------------------*/
26 /* Signed and unsigned multiplication are the same - as long as the output
27 has the same precision as the input.
29 To do: _muluint and _mulsint should be replaced by _mulint.
31 bernhard@bernhardheld.de
33 Assembler-functions are provided for:
36 mcs51 small stack-auto
40 #if !defined(SDCC_USE_XSTACK) || defined(_SDCC_NO_ASM_LIB_FUNCS)
41 #if defined(SDCC_ds390)
42 #if !defined(SDCC_STACK_AUTO)
43 #define _MULINT_ASM_LARGE
45 #elif defined(SDCC_mcs51)
46 #if defined(SDCC_MODEL_SMALL)
47 #if defined(SDCC_STACK_AUTO)
48 #define _MULINT_ASM_SMALL_AUTO
50 #define _MULINT_ASM_SMALL
52 #else // must be SDCC_MODEL_LARGE
53 #if !defined(SDCC_STACK_AUTO)
54 #define _MULINT_ASM_LARGE
60 #ifdef _MULINT_ASM_LARGE
63 _muluint (unsigned int a, unsigned int b) // in future: _mulint
65 a*b; // hush the compiler
69 (char)(msb_a*lsb_b)<<8 +
70 (char)(lsb_a*msb_b)<<8
78 mov dptr,#__muluint_PARM_2
103 _mulsint (int a, int b) // obsolete
105 return _muluint (a, b);
108 #elif defined _MULINT_ASM_SMALL || defined _MULINT_ASM_SMALL_AUTO
111 _mulint_dummy (void) _naked
116 __muluint: ; obsolete
117 __mulsint: ; obsolete
120 .globl __muluint ; obsolete
121 .globl __mulsint ; obsolete
123 #if !defined(SDCC_STACK_AUTO)
125 #if defined(SDCC_NOOVERLAY) // BUG SDCC_NOOVERLAY is not set by -no-overlay
128 .area OSEG (OVR,DATA)
132 __muluint_PARM_2: ; obsolete
133 __mulsint_PARM_2: ; obsolete
135 .globl __mulint_PARM_2
136 .globl __muluint_PARM_2 ; obsolete
137 .globl __mulsint_PARM_2 ; obsolete
143 ; globbered registers none
146 mov b,__mulint_PARM_2 ; 2 bl
148 xch a,dpl ; 1 store low-byte of return value, fetch al
151 mov b,__mulint_PARM_2 + 1 ; 2 bh
155 xch a,dph ; 1 ah -> acc
157 mov b,__mulint_PARM_2 ; 2 bl
164 #else // SDCC_STACK_AUTO
166 ; globbered registers r0
168 mov a,#-2 ; 1 return address 2 bytes
170 mov r0,a ; 1 r0 points to bh
182 mov dpl,a ; 1 low-byte of return-value
186 xch a,dph ; 1 ah -> acc
195 #endif // SDCC_STACK_AUTO
203 struct { unsigned char lo,hi ;} s;
208 _muluint (unsigned int a, unsigned int b) // in future: _mulint
210 #ifdef SDCC_MODEL_LARGE // still needed for large + stack-auto
214 x = (union uu _xdata *)&a;
215 y = (union uu _xdata *)&b;
217 register union uu *x;
218 register union uu *y;
224 t.t = x->s.lo * y->s.lo;
225 t.s.hi += (x->s.lo * y->s.hi) + (x->s.hi * y->s.lo);
231 _mulsint (int a, int b) // obsolete
233 return _muluint (a, b);