1 /*-------------------------------------------------------------------------
2 _mulint.c :- routine for (unsigned) int (16 bit) multiplication
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1999)
6 This library is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Library General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
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 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
25 /* Signed and unsigned multiplication are the same - as long as the output
26 has the same precision as the input.
28 Assembler-functions are provided for:
31 mcs51 small stack-auto
35 #if !defined(SDCC_USE_XSTACK) && !defined(_SDCC_NO_ASM_LIB_FUNCS)
36 # if defined(SDCC_ds390)
37 # if !defined(SDCC_STACK_AUTO)
38 # define _MULINT_ASM_LARGE
40 # elif defined(SDCC_mcs51)
41 # if defined(SDCC_MODEL_SMALL)
42 # if defined(SDCC_STACK_AUTO) && !defined(SDCC_PARMS_IN_BANK1)
43 # define _MULINT_ASM_SMALL_AUTO
45 # define _MULINT_ASM_SMALL
47 # else // must be SDCC_MODEL_LARGE
48 # if !defined(SDCC_STACK_AUTO)
49 # define _MULINT_ASM_LARGE
55 #if defined(_MULINT_ASM_LARGE)
60 _mulint (int a, int b)
62 a*b; // hush the compiler
66 (char)(msb_a*lsb_b)<<8 +
67 (char)(lsb_a*msb_b)<<8
75 #if defined(SDCC_PARMS_IN_BANK1)
78 mov dptr,#__mulint_PARM_2
86 #if defined(SDCC_PARMS_IN_BANK1)
96 #if defined(SDCC_PARMS_IN_BANK1)
112 #elif defined(_MULINT_ASM_SMALL) || defined(_MULINT_ASM_SMALL_AUTO)
115 #pragma less_pedantic
117 _mulint_dummy (void) _naked
125 #if !defined(SDCC_STACK_AUTO) || defined(SDCC_PARMS_IN_BANK1)
127 #if defined(SDCC_NOOVERLAY)
130 .area OSEG (OVR,DATA)
132 #if defined(SDCC_PARMS_IN_BANK1)
136 #define bl (__mulint_PARM_2)
137 #define bh (__mulint_PARM_2 + 1)
140 .globl __mulint_PARM_2
147 ; globbered registers none
152 xch a,dpl ; 1 store low-byte of return value, fetch al
159 xch a,dph ; 1 ah -> acc
168 #else // SDCC_STACK_AUTO
170 ; globbered registers r0
172 mov a,#-2 ; 1 return address 2 bytes
174 mov r0,a ; 1 r0 points to bh
186 mov dpl,a ; 1 low-byte of return-value
190 xch a,dph ; 1 ah -> acc
199 #endif // SDCC_STACK_AUTO
208 struct { unsigned char lo,hi ;} s;
213 _mulint (int a, int b)
215 #if !defined(SDCC_STACK_AUTO) && (defined(SDCC_MODEL_LARGE) || defined(SDCC_ds390)) // still needed for large
219 x = (union uu xdata *)&a;
220 y = (union uu xdata *)&b;
222 register union uu *x;
223 register union uu *y;
229 t.t = x->s.lo * y->s.lo;
230 t.s.hi += (x->s.lo * y->s.hi) + (x->s.hi * y->s.lo);