* src/hc08/gen.c (genPlusIncr, genUminus, genMinusDec, genCmp,
[fw/sdcc] / 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 #endif
97 }
98 #pragma restore
99
100 #else
101
102 union uu {
103         struct { unsigned char hi,lo ;} s;
104         unsigned int t;
105 } ;
106
107 int
108 _mulint (int a, int b)
109 {
110 #if !defined(SDCC_STACK_AUTO) && (defined(SDCC_MODEL_LARGE) || defined(SDCC_ds390))     // still needed for large
111         union uu xdata *x;
112         union uu xdata *y;
113         union uu t;
114         x = (union uu xdata *)&a;
115         y = (union uu xdata *)&b;
116 #else
117         register union uu *x;
118         register union uu *y;
119         union uu t;
120         x = (union uu *)&a;
121         y = (union uu *)&b;
122 #endif
123
124         t.t = x->s.lo * y->s.lo;
125         t.s.hi += (x->s.lo * y->s.hi) + (x->s.hi * y->s.lo);
126
127        return t.t;
128 }
129 #endif
130
131
132 #undef _MULINT_ASM