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