]> git.gag.com Git - fw/sdcc/blob - device/lib/_muluint.c
short (8 bit) replaced by char
[fw/sdcc] / device / lib / _muluint.c
1 /*-------------------------------------------------------------------------
2
3   _muluint.c :- routine for unsigned int (16 bit) multiplication               
4
5              Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1999)
6
7    This library is free software; you can redistribute it and/or modify it
8    under the terms of the GNU Library General Public License as published by the
9    Free Software Foundation; either version 2, or (at your option) any
10    later version.
11    
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 Library General Public License for more details.
16    
17    You should have received a copy of the GNU Library 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.
20    
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 -------------------------------------------------------------------------*/
25
26 #if defined(__ds390) || defined (__mcs51)
27
28 // we can do this faster and more efficient in assembler
29
30 unsigned int _muluint (unsigned int a, unsigned int b) 
31 {
32   a*b; // hush the compiler
33
34   /* muluint=
35       (int)(lsb_a*lsb_b) +
36       (char)(msb_a*lsb_b)<<8 +
37       (char)(lsb_a*msb_b)<<8
38   */
39
40   _asm 
41     mov r2,dph ; msb_a
42     mov r3,dpl ; lsb_a
43
44     mov b,r3 ; lsb_a
45 #if defined(SDCC_ds390) || defined(SDCC_MODEL_LARGE)
46     mov dptr,#__muluint_PARM_2
47     movx a,@dptr ; lsb_b
48 #else // must be SDCC_MODEL_SMALL
49     mov a,__muluint_PARM_2 ; lsb_b
50 #endif
51     mul ab ; lsb_a*lsb_b
52     mov r0,a
53     mov r1,b
54
55     mov b,r2 ; msb_a
56     movx a,@dptr ; lsb_b
57     mul ab ; msb_a*lsb_b
58     add a,r1
59     mov r1,a
60
61     mov b,r3 ; lsb_a
62 #if defined(SDCC_ds390) || defined(SDCC_MODEL_LARGE)
63     inc dptr
64     movx a,@dptr ; msb_b
65 #else // must be SDCC_MODEL_SMALL
66     mov a,1+__muluint_PARM_2 ; msb_b
67 #endif
68     mul ab ; lsb_a*msb_b
69     add a,r1
70
71     mov dph,a
72     mov dpl,r0
73     ret
74   _endasm;
75 }
76
77 #else
78
79 // we have to do it the hard way
80
81 union uu {
82   struct { unsigned char lo,hi ;} s;
83   unsigned int t;
84 };
85
86 unsigned int _muluint (unsigned int a, unsigned int b) 
87 {
88   union uu *x;
89   union uu *y; 
90   union uu t;
91   x = (union uu *)&a;
92   y = (union uu *)&b;
93
94   t.t = x->s.lo * y->s.lo;
95   t.s.hi += (x->s.lo * y->s.hi) + (x->s.hi * y->s.lo);
96   
97   return t.t;
98
99
100 #endif