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