xref: /inferno-os/utils/8c/mul.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1*74a4d8c2SCharles.Forsyth #include "gc.h"
2*74a4d8c2SCharles.Forsyth 
3*74a4d8c2SCharles.Forsyth typedef struct	Malg	Malg;
4*74a4d8c2SCharles.Forsyth typedef struct	Mparam	Mparam;
5*74a4d8c2SCharles.Forsyth 
6*74a4d8c2SCharles.Forsyth struct	Malg
7*74a4d8c2SCharles.Forsyth {
8*74a4d8c2SCharles.Forsyth 	char	vals[10];
9*74a4d8c2SCharles.Forsyth };
10*74a4d8c2SCharles.Forsyth 
11*74a4d8c2SCharles.Forsyth struct	Mparam
12*74a4d8c2SCharles.Forsyth {
13*74a4d8c2SCharles.Forsyth 	ulong	value;
14*74a4d8c2SCharles.Forsyth 	char	alg;
15*74a4d8c2SCharles.Forsyth 	char	neg;
16*74a4d8c2SCharles.Forsyth 	char	shift;
17*74a4d8c2SCharles.Forsyth 	char	arg;
18*74a4d8c2SCharles.Forsyth 	char	off;
19*74a4d8c2SCharles.Forsyth };
20*74a4d8c2SCharles.Forsyth 
21*74a4d8c2SCharles.Forsyth static	Mparam	multab[32];
22*74a4d8c2SCharles.Forsyth static	int	mulptr;
23*74a4d8c2SCharles.Forsyth 
24*74a4d8c2SCharles.Forsyth static	Malg	malgs[]	=
25*74a4d8c2SCharles.Forsyth {
26*74a4d8c2SCharles.Forsyth 	{0, 100},
27*74a4d8c2SCharles.Forsyth 	{-1, 1, 100},
28*74a4d8c2SCharles.Forsyth 	{-9, -5, -3, 3, 5, 9, 100},
29*74a4d8c2SCharles.Forsyth 	{6, 10, 12, 18, 20, 24, 36, 40, 72, 100},
30*74a4d8c2SCharles.Forsyth 	{-8, -4, -2, 2, 4, 8, 100},
31*74a4d8c2SCharles.Forsyth };
32*74a4d8c2SCharles.Forsyth 
33*74a4d8c2SCharles.Forsyth /*
34*74a4d8c2SCharles.Forsyth  * return position of lowest 1
35*74a4d8c2SCharles.Forsyth  */
36*74a4d8c2SCharles.Forsyth int
lowbit(ulong v)37*74a4d8c2SCharles.Forsyth lowbit(ulong v)
38*74a4d8c2SCharles.Forsyth {
39*74a4d8c2SCharles.Forsyth 	int s, i;
40*74a4d8c2SCharles.Forsyth 	ulong m;
41*74a4d8c2SCharles.Forsyth 
42*74a4d8c2SCharles.Forsyth 	s = 0;
43*74a4d8c2SCharles.Forsyth 	m = 0xFFFFFFFFUL;
44*74a4d8c2SCharles.Forsyth 	for(i = 16; i > 0; i >>= 1) {
45*74a4d8c2SCharles.Forsyth 		m >>= i;
46*74a4d8c2SCharles.Forsyth 		if((v & m) == 0) {
47*74a4d8c2SCharles.Forsyth 			v >>= i;
48*74a4d8c2SCharles.Forsyth 			s += i;
49*74a4d8c2SCharles.Forsyth 		}
50*74a4d8c2SCharles.Forsyth 	}
51*74a4d8c2SCharles.Forsyth 	return s;
52*74a4d8c2SCharles.Forsyth }
53*74a4d8c2SCharles.Forsyth 
54*74a4d8c2SCharles.Forsyth void
genmuladd(Node * d,Node * s,int m,Node * a)55*74a4d8c2SCharles.Forsyth genmuladd(Node *d, Node *s, int m, Node *a)
56*74a4d8c2SCharles.Forsyth {
57*74a4d8c2SCharles.Forsyth 	Node nod;
58*74a4d8c2SCharles.Forsyth 
59*74a4d8c2SCharles.Forsyth 	nod.op = OINDEX;
60*74a4d8c2SCharles.Forsyth 	nod.left = a;
61*74a4d8c2SCharles.Forsyth 	nod.right = s;
62*74a4d8c2SCharles.Forsyth 	nod.scale = m;
63*74a4d8c2SCharles.Forsyth 	nod.type = types[TIND];
64*74a4d8c2SCharles.Forsyth 	nod.xoffset = 0;
65*74a4d8c2SCharles.Forsyth 	xcom(&nod);
66*74a4d8c2SCharles.Forsyth 	gopcode(OADDR, d->type, &nod, d);
67*74a4d8c2SCharles.Forsyth }
68*74a4d8c2SCharles.Forsyth 
69*74a4d8c2SCharles.Forsyth void
mulparam(ulong m,Mparam * mp)70*74a4d8c2SCharles.Forsyth mulparam(ulong m, Mparam *mp)
71*74a4d8c2SCharles.Forsyth {
72*74a4d8c2SCharles.Forsyth 	int c, i, j, n, o, q, s;
73*74a4d8c2SCharles.Forsyth 	int bc, bi, bn, bo, bq, bs, bt;
74*74a4d8c2SCharles.Forsyth 	char *p;
75*74a4d8c2SCharles.Forsyth 	long u;
76*74a4d8c2SCharles.Forsyth 	ulong t;
77*74a4d8c2SCharles.Forsyth 
78*74a4d8c2SCharles.Forsyth 	bc = bq = 10;
79*74a4d8c2SCharles.Forsyth 	bi = bn = bo = bs = bt = 0;
80*74a4d8c2SCharles.Forsyth 	for(i = 0; i < nelem(malgs); i++) {
81*74a4d8c2SCharles.Forsyth 		for(p = malgs[i].vals, j = 0; (o = p[j]) < 100; j++)
82*74a4d8c2SCharles.Forsyth 		for(s = 0; s < 2; s++) {
83*74a4d8c2SCharles.Forsyth 			c = 10;
84*74a4d8c2SCharles.Forsyth 			q = 10;
85*74a4d8c2SCharles.Forsyth 			u = m - o;
86*74a4d8c2SCharles.Forsyth 			if(u == 0)
87*74a4d8c2SCharles.Forsyth 				continue;
88*74a4d8c2SCharles.Forsyth 			if(s) {
89*74a4d8c2SCharles.Forsyth 				o = -o;
90*74a4d8c2SCharles.Forsyth 				if(o > 0)
91*74a4d8c2SCharles.Forsyth 					continue;
92*74a4d8c2SCharles.Forsyth 				u = -u;
93*74a4d8c2SCharles.Forsyth 			}
94*74a4d8c2SCharles.Forsyth 			n = lowbit(u);
95*74a4d8c2SCharles.Forsyth 			t = (ulong)u >> n;
96*74a4d8c2SCharles.Forsyth 			switch(i) {
97*74a4d8c2SCharles.Forsyth 			case 0:
98*74a4d8c2SCharles.Forsyth 				if(t == 1) {
99*74a4d8c2SCharles.Forsyth 					c = s + 1;
100*74a4d8c2SCharles.Forsyth 					q = 0;
101*74a4d8c2SCharles.Forsyth 					break;
102*74a4d8c2SCharles.Forsyth 				}
103*74a4d8c2SCharles.Forsyth 				switch(t) {
104*74a4d8c2SCharles.Forsyth 				case 3:
105*74a4d8c2SCharles.Forsyth 				case 5:
106*74a4d8c2SCharles.Forsyth 				case 9:
107*74a4d8c2SCharles.Forsyth 					c = s + 1;
108*74a4d8c2SCharles.Forsyth 					if(n)
109*74a4d8c2SCharles.Forsyth 						c++;
110*74a4d8c2SCharles.Forsyth 					q = 0;
111*74a4d8c2SCharles.Forsyth 					break;
112*74a4d8c2SCharles.Forsyth 				}
113*74a4d8c2SCharles.Forsyth 				if(s)
114*74a4d8c2SCharles.Forsyth 					break;
115*74a4d8c2SCharles.Forsyth 				switch(t) {
116*74a4d8c2SCharles.Forsyth 				case 15:
117*74a4d8c2SCharles.Forsyth 				case 25:
118*74a4d8c2SCharles.Forsyth 				case 27:
119*74a4d8c2SCharles.Forsyth 				case 45:
120*74a4d8c2SCharles.Forsyth 				case 81:
121*74a4d8c2SCharles.Forsyth 					c = 2;
122*74a4d8c2SCharles.Forsyth 					if(n)
123*74a4d8c2SCharles.Forsyth 						c++;
124*74a4d8c2SCharles.Forsyth 					q = 1;
125*74a4d8c2SCharles.Forsyth 					break;
126*74a4d8c2SCharles.Forsyth 				}
127*74a4d8c2SCharles.Forsyth 				break;
128*74a4d8c2SCharles.Forsyth 			case 1:
129*74a4d8c2SCharles.Forsyth 				if(t == 1) {
130*74a4d8c2SCharles.Forsyth 					c = 3;
131*74a4d8c2SCharles.Forsyth 					q = 3;
132*74a4d8c2SCharles.Forsyth 					break;
133*74a4d8c2SCharles.Forsyth 				}
134*74a4d8c2SCharles.Forsyth 				switch(t) {
135*74a4d8c2SCharles.Forsyth 				case 3:
136*74a4d8c2SCharles.Forsyth 				case 5:
137*74a4d8c2SCharles.Forsyth 				case 9:
138*74a4d8c2SCharles.Forsyth 					c = 3;
139*74a4d8c2SCharles.Forsyth 					q = 2;
140*74a4d8c2SCharles.Forsyth 					break;
141*74a4d8c2SCharles.Forsyth 				}
142*74a4d8c2SCharles.Forsyth 				break;
143*74a4d8c2SCharles.Forsyth 			case 2:
144*74a4d8c2SCharles.Forsyth 				if(t == 1) {
145*74a4d8c2SCharles.Forsyth 					c = 3;
146*74a4d8c2SCharles.Forsyth 					q = 2;
147*74a4d8c2SCharles.Forsyth 					break;
148*74a4d8c2SCharles.Forsyth 				}
149*74a4d8c2SCharles.Forsyth 				break;
150*74a4d8c2SCharles.Forsyth 			case 3:
151*74a4d8c2SCharles.Forsyth 				if(s)
152*74a4d8c2SCharles.Forsyth 					break;
153*74a4d8c2SCharles.Forsyth 				if(t == 1) {
154*74a4d8c2SCharles.Forsyth 					c = 3;
155*74a4d8c2SCharles.Forsyth 					q = 1;
156*74a4d8c2SCharles.Forsyth 					break;
157*74a4d8c2SCharles.Forsyth 				}
158*74a4d8c2SCharles.Forsyth 				break;
159*74a4d8c2SCharles.Forsyth 			case 4:
160*74a4d8c2SCharles.Forsyth 				if(t == 1) {
161*74a4d8c2SCharles.Forsyth 					c = 3;
162*74a4d8c2SCharles.Forsyth 					q = 0;
163*74a4d8c2SCharles.Forsyth 					break;
164*74a4d8c2SCharles.Forsyth 				}
165*74a4d8c2SCharles.Forsyth 				break;
166*74a4d8c2SCharles.Forsyth 			}
167*74a4d8c2SCharles.Forsyth 			if(c < bc || (c == bc && q > bq)) {
168*74a4d8c2SCharles.Forsyth 				bc = c;
169*74a4d8c2SCharles.Forsyth 				bi = i;
170*74a4d8c2SCharles.Forsyth 				bn = n;
171*74a4d8c2SCharles.Forsyth 				bo = o;
172*74a4d8c2SCharles.Forsyth 				bq = q;
173*74a4d8c2SCharles.Forsyth 				bs = s;
174*74a4d8c2SCharles.Forsyth 				bt = t;
175*74a4d8c2SCharles.Forsyth 			}
176*74a4d8c2SCharles.Forsyth 		}
177*74a4d8c2SCharles.Forsyth 	}
178*74a4d8c2SCharles.Forsyth 	mp->value = m;
179*74a4d8c2SCharles.Forsyth 	if(bc <= 3) {
180*74a4d8c2SCharles.Forsyth 		mp->alg = bi;
181*74a4d8c2SCharles.Forsyth 		mp->shift = bn;
182*74a4d8c2SCharles.Forsyth 		mp->off = bo;
183*74a4d8c2SCharles.Forsyth 		mp->neg = bs;
184*74a4d8c2SCharles.Forsyth 		mp->arg = bt;
185*74a4d8c2SCharles.Forsyth 	}
186*74a4d8c2SCharles.Forsyth 	else
187*74a4d8c2SCharles.Forsyth 		mp->alg = -1;
188*74a4d8c2SCharles.Forsyth }
189*74a4d8c2SCharles.Forsyth 
190*74a4d8c2SCharles.Forsyth int
m0(int a)191*74a4d8c2SCharles.Forsyth m0(int a)
192*74a4d8c2SCharles.Forsyth {
193*74a4d8c2SCharles.Forsyth 	switch(a) {
194*74a4d8c2SCharles.Forsyth 	case -2:
195*74a4d8c2SCharles.Forsyth 	case 2:
196*74a4d8c2SCharles.Forsyth 		return 2;
197*74a4d8c2SCharles.Forsyth 	case -3:
198*74a4d8c2SCharles.Forsyth 	case 3:
199*74a4d8c2SCharles.Forsyth 		return 2;
200*74a4d8c2SCharles.Forsyth 	case -4:
201*74a4d8c2SCharles.Forsyth 	case 4:
202*74a4d8c2SCharles.Forsyth 		return 4;
203*74a4d8c2SCharles.Forsyth 	case -5:
204*74a4d8c2SCharles.Forsyth 	case 5:
205*74a4d8c2SCharles.Forsyth 		return 4;
206*74a4d8c2SCharles.Forsyth 	case 6:
207*74a4d8c2SCharles.Forsyth 		return 2;
208*74a4d8c2SCharles.Forsyth 	case -8:
209*74a4d8c2SCharles.Forsyth 	case 8:
210*74a4d8c2SCharles.Forsyth 		return 8;
211*74a4d8c2SCharles.Forsyth 	case -9:
212*74a4d8c2SCharles.Forsyth 	case 9:
213*74a4d8c2SCharles.Forsyth 		return 8;
214*74a4d8c2SCharles.Forsyth 	case 10:
215*74a4d8c2SCharles.Forsyth 		return 4;
216*74a4d8c2SCharles.Forsyth 	case 12:
217*74a4d8c2SCharles.Forsyth 		return 2;
218*74a4d8c2SCharles.Forsyth 	case 15:
219*74a4d8c2SCharles.Forsyth 		return 2;
220*74a4d8c2SCharles.Forsyth 	case 18:
221*74a4d8c2SCharles.Forsyth 		return 8;
222*74a4d8c2SCharles.Forsyth 	case 20:
223*74a4d8c2SCharles.Forsyth 		return 4;
224*74a4d8c2SCharles.Forsyth 	case 24:
225*74a4d8c2SCharles.Forsyth 		return 2;
226*74a4d8c2SCharles.Forsyth 	case 25:
227*74a4d8c2SCharles.Forsyth 		return 4;
228*74a4d8c2SCharles.Forsyth 	case 27:
229*74a4d8c2SCharles.Forsyth 		return 2;
230*74a4d8c2SCharles.Forsyth 	case 36:
231*74a4d8c2SCharles.Forsyth 		return 8;
232*74a4d8c2SCharles.Forsyth 	case 40:
233*74a4d8c2SCharles.Forsyth 		return 4;
234*74a4d8c2SCharles.Forsyth 	case 45:
235*74a4d8c2SCharles.Forsyth 		return 4;
236*74a4d8c2SCharles.Forsyth 	case 72:
237*74a4d8c2SCharles.Forsyth 		return 8;
238*74a4d8c2SCharles.Forsyth 	case 81:
239*74a4d8c2SCharles.Forsyth 		return 8;
240*74a4d8c2SCharles.Forsyth 	}
241*74a4d8c2SCharles.Forsyth 	diag(Z, "bad m0");
242*74a4d8c2SCharles.Forsyth 	return 0;
243*74a4d8c2SCharles.Forsyth }
244*74a4d8c2SCharles.Forsyth 
245*74a4d8c2SCharles.Forsyth int
m1(int a)246*74a4d8c2SCharles.Forsyth m1(int a)
247*74a4d8c2SCharles.Forsyth {
248*74a4d8c2SCharles.Forsyth 	switch(a) {
249*74a4d8c2SCharles.Forsyth 	case 15:
250*74a4d8c2SCharles.Forsyth 		return 4;
251*74a4d8c2SCharles.Forsyth 	case 25:
252*74a4d8c2SCharles.Forsyth 		return 4;
253*74a4d8c2SCharles.Forsyth 	case 27:
254*74a4d8c2SCharles.Forsyth 		return 8;
255*74a4d8c2SCharles.Forsyth 	case 45:
256*74a4d8c2SCharles.Forsyth 		return 8;
257*74a4d8c2SCharles.Forsyth 	case 81:
258*74a4d8c2SCharles.Forsyth 		return 8;
259*74a4d8c2SCharles.Forsyth 	}
260*74a4d8c2SCharles.Forsyth 	diag(Z, "bad m1");
261*74a4d8c2SCharles.Forsyth 	return 0;
262*74a4d8c2SCharles.Forsyth }
263*74a4d8c2SCharles.Forsyth 
264*74a4d8c2SCharles.Forsyth int
m2(int a)265*74a4d8c2SCharles.Forsyth m2(int a)
266*74a4d8c2SCharles.Forsyth {
267*74a4d8c2SCharles.Forsyth 	switch(a) {
268*74a4d8c2SCharles.Forsyth 	case 6:
269*74a4d8c2SCharles.Forsyth 		return 2;
270*74a4d8c2SCharles.Forsyth 	case 10:
271*74a4d8c2SCharles.Forsyth 		return 2;
272*74a4d8c2SCharles.Forsyth 	case 12:
273*74a4d8c2SCharles.Forsyth 		return 4;
274*74a4d8c2SCharles.Forsyth 	case 18:
275*74a4d8c2SCharles.Forsyth 		return 2;
276*74a4d8c2SCharles.Forsyth 	case 20:
277*74a4d8c2SCharles.Forsyth 		return 4;
278*74a4d8c2SCharles.Forsyth 	case 24:
279*74a4d8c2SCharles.Forsyth 		return 8;
280*74a4d8c2SCharles.Forsyth 	case 36:
281*74a4d8c2SCharles.Forsyth 		return 4;
282*74a4d8c2SCharles.Forsyth 	case 40:
283*74a4d8c2SCharles.Forsyth 		return 8;
284*74a4d8c2SCharles.Forsyth 	case 72:
285*74a4d8c2SCharles.Forsyth 		return 8;
286*74a4d8c2SCharles.Forsyth 	}
287*74a4d8c2SCharles.Forsyth 	diag(Z, "bad m2");
288*74a4d8c2SCharles.Forsyth 	return 0;
289*74a4d8c2SCharles.Forsyth }
290*74a4d8c2SCharles.Forsyth 
291*74a4d8c2SCharles.Forsyth void
shiftit(Type * t,Node * s,Node * d)292*74a4d8c2SCharles.Forsyth shiftit(Type *t, Node *s, Node *d)
293*74a4d8c2SCharles.Forsyth {
294*74a4d8c2SCharles.Forsyth 	long c;
295*74a4d8c2SCharles.Forsyth 
296*74a4d8c2SCharles.Forsyth 	c = (long)s->vconst & 31;
297*74a4d8c2SCharles.Forsyth 	switch(c) {
298*74a4d8c2SCharles.Forsyth 	case 0:
299*74a4d8c2SCharles.Forsyth 		break;
300*74a4d8c2SCharles.Forsyth 	case 1:
301*74a4d8c2SCharles.Forsyth 		gopcode(OADD, t, d, d);
302*74a4d8c2SCharles.Forsyth 		break;
303*74a4d8c2SCharles.Forsyth 	default:
304*74a4d8c2SCharles.Forsyth 		gopcode(OASHL, t, s, d);
305*74a4d8c2SCharles.Forsyth 	}
306*74a4d8c2SCharles.Forsyth }
307*74a4d8c2SCharles.Forsyth 
308*74a4d8c2SCharles.Forsyth static int
mulgen1(ulong v,Node * n)309*74a4d8c2SCharles.Forsyth mulgen1(ulong v, Node *n)
310*74a4d8c2SCharles.Forsyth {
311*74a4d8c2SCharles.Forsyth 	int i, o;
312*74a4d8c2SCharles.Forsyth 	Mparam *p;
313*74a4d8c2SCharles.Forsyth 	Node nod, nods;
314*74a4d8c2SCharles.Forsyth 
315*74a4d8c2SCharles.Forsyth 	for(i = 0; i < nelem(multab); i++) {
316*74a4d8c2SCharles.Forsyth 		p = &multab[i];
317*74a4d8c2SCharles.Forsyth 		if(p->value == v)
318*74a4d8c2SCharles.Forsyth 			goto found;
319*74a4d8c2SCharles.Forsyth 	}
320*74a4d8c2SCharles.Forsyth 
321*74a4d8c2SCharles.Forsyth 	p = &multab[mulptr];
322*74a4d8c2SCharles.Forsyth 	if(++mulptr == nelem(multab))
323*74a4d8c2SCharles.Forsyth 		mulptr = 0;
324*74a4d8c2SCharles.Forsyth 
325*74a4d8c2SCharles.Forsyth 	mulparam(v, p);
326*74a4d8c2SCharles.Forsyth 
327*74a4d8c2SCharles.Forsyth found:
328*74a4d8c2SCharles.Forsyth //	print("v=%.lx a=%d n=%d s=%d g=%d o=%d \n", p->value, p->alg, p->neg, p->shift, p->arg, p->off);
329*74a4d8c2SCharles.Forsyth 	if(p->alg < 0)
330*74a4d8c2SCharles.Forsyth 		return 0;
331*74a4d8c2SCharles.Forsyth 
332*74a4d8c2SCharles.Forsyth 	nods = *nodconst(p->shift);
333*74a4d8c2SCharles.Forsyth 
334*74a4d8c2SCharles.Forsyth 	o = OADD;
335*74a4d8c2SCharles.Forsyth 	if(p->alg > 0) {
336*74a4d8c2SCharles.Forsyth 		regalloc(&nod, n, Z);
337*74a4d8c2SCharles.Forsyth 		if(p->off < 0)
338*74a4d8c2SCharles.Forsyth 			o = OSUB;
339*74a4d8c2SCharles.Forsyth 	}
340*74a4d8c2SCharles.Forsyth 
341*74a4d8c2SCharles.Forsyth 	switch(p->alg) {
342*74a4d8c2SCharles.Forsyth 	case 0:
343*74a4d8c2SCharles.Forsyth 		switch(p->arg) {
344*74a4d8c2SCharles.Forsyth 		case 1:
345*74a4d8c2SCharles.Forsyth 			shiftit(n->type, &nods, n);
346*74a4d8c2SCharles.Forsyth 			break;
347*74a4d8c2SCharles.Forsyth 		case 15:
348*74a4d8c2SCharles.Forsyth 		case 25:
349*74a4d8c2SCharles.Forsyth 		case 27:
350*74a4d8c2SCharles.Forsyth 		case 45:
351*74a4d8c2SCharles.Forsyth 		case 81:
352*74a4d8c2SCharles.Forsyth 			genmuladd(n, n, m1(p->arg), n);
353*74a4d8c2SCharles.Forsyth 			/* fall thru */
354*74a4d8c2SCharles.Forsyth 		case 3:
355*74a4d8c2SCharles.Forsyth 		case 5:
356*74a4d8c2SCharles.Forsyth 		case 9:
357*74a4d8c2SCharles.Forsyth 			genmuladd(n, n, m0(p->arg), n);
358*74a4d8c2SCharles.Forsyth 			shiftit(n->type, &nods, n);
359*74a4d8c2SCharles.Forsyth 			break;
360*74a4d8c2SCharles.Forsyth 		default:
361*74a4d8c2SCharles.Forsyth 			goto bad;
362*74a4d8c2SCharles.Forsyth 		}
363*74a4d8c2SCharles.Forsyth 		if(p->neg == 1)
364*74a4d8c2SCharles.Forsyth 			gins(ANEGL, Z, n);
365*74a4d8c2SCharles.Forsyth 		break;
366*74a4d8c2SCharles.Forsyth 	case 1:
367*74a4d8c2SCharles.Forsyth 		switch(p->arg) {
368*74a4d8c2SCharles.Forsyth 		case 1:
369*74a4d8c2SCharles.Forsyth 			gmove(n, &nod);
370*74a4d8c2SCharles.Forsyth 			shiftit(n->type, &nods, &nod);
371*74a4d8c2SCharles.Forsyth 			break;
372*74a4d8c2SCharles.Forsyth 		case 3:
373*74a4d8c2SCharles.Forsyth 		case 5:
374*74a4d8c2SCharles.Forsyth 		case 9:
375*74a4d8c2SCharles.Forsyth 			genmuladd(&nod, n, m0(p->arg), n);
376*74a4d8c2SCharles.Forsyth 			shiftit(n->type, &nods, &nod);
377*74a4d8c2SCharles.Forsyth 			break;
378*74a4d8c2SCharles.Forsyth 		default:
379*74a4d8c2SCharles.Forsyth 			goto bad;
380*74a4d8c2SCharles.Forsyth 		}
381*74a4d8c2SCharles.Forsyth 		if(p->neg)
382*74a4d8c2SCharles.Forsyth 			gopcode(o, n->type, &nod, n);
383*74a4d8c2SCharles.Forsyth 		else {
384*74a4d8c2SCharles.Forsyth 			gopcode(o, n->type, n, &nod);
385*74a4d8c2SCharles.Forsyth 			gmove(&nod, n);
386*74a4d8c2SCharles.Forsyth 		}
387*74a4d8c2SCharles.Forsyth 		break;
388*74a4d8c2SCharles.Forsyth 	case 2:
389*74a4d8c2SCharles.Forsyth 		genmuladd(&nod, n, m0(p->off), n);
390*74a4d8c2SCharles.Forsyth 		shiftit(n->type, &nods, n);
391*74a4d8c2SCharles.Forsyth 		goto comop;
392*74a4d8c2SCharles.Forsyth 	case 3:
393*74a4d8c2SCharles.Forsyth 		genmuladd(&nod, n, m0(p->off), n);
394*74a4d8c2SCharles.Forsyth 		shiftit(n->type, &nods, n);
395*74a4d8c2SCharles.Forsyth 		genmuladd(n, &nod, m2(p->off), n);
396*74a4d8c2SCharles.Forsyth 		break;
397*74a4d8c2SCharles.Forsyth 	case 4:
398*74a4d8c2SCharles.Forsyth 		genmuladd(&nod, n, m0(p->off), nodconst(0));
399*74a4d8c2SCharles.Forsyth 		shiftit(n->type, &nods, n);
400*74a4d8c2SCharles.Forsyth 		goto comop;
401*74a4d8c2SCharles.Forsyth 	default:
402*74a4d8c2SCharles.Forsyth 		diag(Z, "bad mul alg");
403*74a4d8c2SCharles.Forsyth 		break;
404*74a4d8c2SCharles.Forsyth 	comop:
405*74a4d8c2SCharles.Forsyth 		if(p->neg) {
406*74a4d8c2SCharles.Forsyth 			gopcode(o, n->type, n, &nod);
407*74a4d8c2SCharles.Forsyth 			gmove(&nod, n);
408*74a4d8c2SCharles.Forsyth 		}
409*74a4d8c2SCharles.Forsyth 		else
410*74a4d8c2SCharles.Forsyth 			gopcode(o, n->type, &nod, n);
411*74a4d8c2SCharles.Forsyth 	}
412*74a4d8c2SCharles.Forsyth 
413*74a4d8c2SCharles.Forsyth 	if(p->alg > 0)
414*74a4d8c2SCharles.Forsyth 		regfree(&nod);
415*74a4d8c2SCharles.Forsyth 
416*74a4d8c2SCharles.Forsyth 	return 1;
417*74a4d8c2SCharles.Forsyth 
418*74a4d8c2SCharles.Forsyth bad:
419*74a4d8c2SCharles.Forsyth 	diag(Z, "mulgen botch");
420*74a4d8c2SCharles.Forsyth 	return 1;
421*74a4d8c2SCharles.Forsyth }
422*74a4d8c2SCharles.Forsyth 
423*74a4d8c2SCharles.Forsyth void
mulgen(Type * t,Node * r,Node * n)424*74a4d8c2SCharles.Forsyth mulgen(Type *t, Node *r, Node *n)
425*74a4d8c2SCharles.Forsyth {
426*74a4d8c2SCharles.Forsyth 	if(!mulgen1(r->vconst, n))
427*74a4d8c2SCharles.Forsyth 		gopcode(OMUL, t, r, n);
428*74a4d8c2SCharles.Forsyth }
429