Imported Upstream version 2.9.0
[debian/cc1111] / device / lib / hc08 / _mulint.c
1 /*-------------------------------------------------------------------------
2   _mulint.c :- routine for (unsigned) int (16 bit) multiplication
3
4              Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1999)
5
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
9    later version.
10
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.
15
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.
19
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 -------------------------------------------------------------------------*/
24
25 /* Signed and unsigned multiplication are the same - as long as the output
26    has the same precision as the input.
27
28    Assembler-functions are provided for:
29      hc08
30      hc08 stack-auto
31 */
32
33
34 #if !defined(_SDCC_NO_ASM_LIB_FUNCS)
35
36 #pragma save
37 #pragma less_pedantic
38 int
39 _mulint (int a, int b)
40 {
41   a,b;  /* reference to make compiler happy */
42
43 #if !defined(SDCC_STACK_AUTO)
44     __asm
45         ais #-2
46         psha
47         pshx
48
49         ldx __mulint_PARM_2+1
50         mul
51         sta 4,s
52         stx 3,s
53
54         lda 1,s
55         ldx __mulint_PARM_2+1
56         mul
57         add 3,s
58         sta 3,s
59
60         lda 2,s
61         ldx __mulint_PARM_2
62         mul
63         add 3,s
64         sta 3,s
65
66         ais #2
67         pulx
68         pula
69     __endasm;
70 #else
71     __asm
72         ais #-2
73         psha
74         pshx
75
76         ldx 8,s
77         mul
78         sta 4,s
79         stx 3,s
80
81         lda 1,s
82         ldx 8,s
83         mul
84         add 3,s
85         sta 3,s
86
87         lda 2,s
88         ldx 7,s
89         mul
90         add 3,s
91         sta 3,s
92
93         ais #2
94         pulx
95         pula
96     __endasm;
97 #endif
98 }
99 #pragma restore
100
101 #else
102
103 union uu {
104         struct { unsigned char hi,lo ;} s;
105         unsigned int t;
106 } ;
107
108 int
109 _mulint (int a, int b)
110 {
111 #if !defined(SDCC_STACK_AUTO) && (defined(SDCC_MODEL_LARGE) || defined(SDCC_ds390))     // still needed for large
112         union uu __xdata *x;
113         union uu __xdata *y;
114         union uu t;
115         x = (union uu __xdata *)&a;
116         y = (union uu __xdata *)&b;
117 #else
118         register union uu *x;
119         register union uu *y;
120         union uu t;
121         x = (union uu *)&a;
122         y = (union uu *)&b;
123 #endif
124
125         t.t = x->s.lo * y->s.lo;
126         t.s.hi += (x->s.lo * y->s.hi) + (x->s.hi * y->s.lo);
127
128        return t.t;
129 }
130 #endif
131
132
133 #undef _MULINT_ASM