1375daca8SDavid du Colombier #include "cc.h"
2375daca8SDavid du Colombier
3*2cca75a1SDavid du Colombier static Node*
acast(Type * t,Node * n)4*2cca75a1SDavid du Colombier acast(Type *t, Node *n)
5*2cca75a1SDavid du Colombier {
6*2cca75a1SDavid du Colombier if(n->type->etype != t->etype || n->op == OBIT) {
7*2cca75a1SDavid du Colombier n = new1(OCAST, n, Z);
8*2cca75a1SDavid du Colombier if(nocast(n->left->type, t))
9*2cca75a1SDavid du Colombier *n = *n->left;
10*2cca75a1SDavid du Colombier n->type = t;
11*2cca75a1SDavid du Colombier }
12*2cca75a1SDavid du Colombier return n;
13*2cca75a1SDavid du Colombier }
14*2cca75a1SDavid du Colombier
15*2cca75a1SDavid du Colombier
16375daca8SDavid du Colombier void
evconst(Node * n)17375daca8SDavid du Colombier evconst(Node *n)
18375daca8SDavid du Colombier {
19375daca8SDavid du Colombier Node *l, *r;
20375daca8SDavid du Colombier int et, isf;
21375daca8SDavid du Colombier vlong v;
22375daca8SDavid du Colombier double d;
23375daca8SDavid du Colombier
24375daca8SDavid du Colombier if(n == Z || n->type == T)
25375daca8SDavid du Colombier return;
26375daca8SDavid du Colombier
27375daca8SDavid du Colombier et = n->type->etype;
28375daca8SDavid du Colombier isf = typefd[et];
29375daca8SDavid du Colombier
30375daca8SDavid du Colombier l = n->left;
31375daca8SDavid du Colombier r = n->right;
32375daca8SDavid du Colombier
33375daca8SDavid du Colombier d = 0;
34375daca8SDavid du Colombier v = 0;
35375daca8SDavid du Colombier
36375daca8SDavid du Colombier switch(n->op) {
37375daca8SDavid du Colombier default:
38375daca8SDavid du Colombier return;
39375daca8SDavid du Colombier
40375daca8SDavid du Colombier case ONEG:
41375daca8SDavid du Colombier if(isf)
42375daca8SDavid du Colombier d = -l->fconst;
43375daca8SDavid du Colombier else
44375daca8SDavid du Colombier v = -l->vconst;
45375daca8SDavid du Colombier break;
46375daca8SDavid du Colombier
47375daca8SDavid du Colombier case OCOM:
48375daca8SDavid du Colombier v = ~l->vconst;
49375daca8SDavid du Colombier break;
50375daca8SDavid du Colombier
51375daca8SDavid du Colombier case OCAST:
52375daca8SDavid du Colombier if(et == TVOID)
53375daca8SDavid du Colombier return;
54375daca8SDavid du Colombier et = l->type->etype;
55375daca8SDavid du Colombier if(isf) {
56375daca8SDavid du Colombier if(typefd[et])
57375daca8SDavid du Colombier d = l->fconst;
58375daca8SDavid du Colombier else
59375daca8SDavid du Colombier d = l->vconst;
60375daca8SDavid du Colombier } else {
61375daca8SDavid du Colombier if(typefd[et])
62375daca8SDavid du Colombier v = l->fconst;
63375daca8SDavid du Colombier else
64375daca8SDavid du Colombier v = convvtox(l->vconst, n->type->etype);
65375daca8SDavid du Colombier }
66375daca8SDavid du Colombier break;
67375daca8SDavid du Colombier
68375daca8SDavid du Colombier case OCONST:
69375daca8SDavid du Colombier break;
70375daca8SDavid du Colombier
71375daca8SDavid du Colombier case OADD:
72375daca8SDavid du Colombier if(isf)
73375daca8SDavid du Colombier d = l->fconst + r->fconst;
74375daca8SDavid du Colombier else {
75375daca8SDavid du Colombier v = l->vconst + r->vconst;
76375daca8SDavid du Colombier }
77375daca8SDavid du Colombier break;
78375daca8SDavid du Colombier
79375daca8SDavid du Colombier case OSUB:
80375daca8SDavid du Colombier if(isf)
81375daca8SDavid du Colombier d = l->fconst - r->fconst;
82375daca8SDavid du Colombier else
83375daca8SDavid du Colombier v = l->vconst - r->vconst;
84375daca8SDavid du Colombier break;
85375daca8SDavid du Colombier
86375daca8SDavid du Colombier case OMUL:
87375daca8SDavid du Colombier if(isf)
88375daca8SDavid du Colombier d = l->fconst * r->fconst;
89375daca8SDavid du Colombier else {
90375daca8SDavid du Colombier v = l->vconst * r->vconst;
91375daca8SDavid du Colombier }
92375daca8SDavid du Colombier break;
93375daca8SDavid du Colombier
94375daca8SDavid du Colombier case OLMUL:
95375daca8SDavid du Colombier v = (uvlong)l->vconst * (uvlong)r->vconst;
96375daca8SDavid du Colombier break;
97375daca8SDavid du Colombier
98375daca8SDavid du Colombier
99375daca8SDavid du Colombier case ODIV:
100375daca8SDavid du Colombier if(vconst(r) == 0) {
101375daca8SDavid du Colombier warn(n, "divide by zero");
102375daca8SDavid du Colombier return;
103375daca8SDavid du Colombier }
104375daca8SDavid du Colombier if(isf)
105375daca8SDavid du Colombier d = l->fconst / r->fconst;
106375daca8SDavid du Colombier else
107375daca8SDavid du Colombier v = l->vconst / r->vconst;
108375daca8SDavid du Colombier break;
109375daca8SDavid du Colombier
110375daca8SDavid du Colombier case OLDIV:
111375daca8SDavid du Colombier if(vconst(r) == 0) {
112375daca8SDavid du Colombier warn(n, "divide by zero");
113375daca8SDavid du Colombier return;
114375daca8SDavid du Colombier }
115375daca8SDavid du Colombier v = (uvlong)l->vconst / (uvlong)r->vconst;
116375daca8SDavid du Colombier break;
117375daca8SDavid du Colombier
118375daca8SDavid du Colombier case OMOD:
119375daca8SDavid du Colombier if(vconst(r) == 0) {
120375daca8SDavid du Colombier warn(n, "modulo by zero");
121375daca8SDavid du Colombier return;
122375daca8SDavid du Colombier }
123375daca8SDavid du Colombier v = l->vconst % r->vconst;
124375daca8SDavid du Colombier break;
125375daca8SDavid du Colombier
126375daca8SDavid du Colombier case OLMOD:
127375daca8SDavid du Colombier if(vconst(r) == 0) {
128375daca8SDavid du Colombier warn(n, "modulo by zero");
129375daca8SDavid du Colombier return;
130375daca8SDavid du Colombier }
131375daca8SDavid du Colombier v = (uvlong)l->vconst % (uvlong)r->vconst;
132375daca8SDavid du Colombier break;
133375daca8SDavid du Colombier
134375daca8SDavid du Colombier case OAND:
135375daca8SDavid du Colombier v = l->vconst & r->vconst;
136375daca8SDavid du Colombier break;
137375daca8SDavid du Colombier
138375daca8SDavid du Colombier case OOR:
139375daca8SDavid du Colombier v = l->vconst | r->vconst;
140375daca8SDavid du Colombier break;
141375daca8SDavid du Colombier
142375daca8SDavid du Colombier case OXOR:
143375daca8SDavid du Colombier v = l->vconst ^ r->vconst;
144375daca8SDavid du Colombier break;
145375daca8SDavid du Colombier
146375daca8SDavid du Colombier case OLSHR:
147375daca8SDavid du Colombier v = (uvlong)l->vconst >> r->vconst;
148375daca8SDavid du Colombier break;
149375daca8SDavid du Colombier
150375daca8SDavid du Colombier case OASHR:
151375daca8SDavid du Colombier v = l->vconst >> r->vconst;
152375daca8SDavid du Colombier break;
153375daca8SDavid du Colombier
154375daca8SDavid du Colombier case OASHL:
155375daca8SDavid du Colombier v = l->vconst << r->vconst;
156375daca8SDavid du Colombier break;
157375daca8SDavid du Colombier
158375daca8SDavid du Colombier case OLO:
159375daca8SDavid du Colombier v = (uvlong)l->vconst < (uvlong)r->vconst;
160375daca8SDavid du Colombier break;
161375daca8SDavid du Colombier
162375daca8SDavid du Colombier case OLT:
163375daca8SDavid du Colombier if(typefd[l->type->etype])
164375daca8SDavid du Colombier v = l->fconst < r->fconst;
165375daca8SDavid du Colombier else
166375daca8SDavid du Colombier v = l->vconst < r->vconst;
167375daca8SDavid du Colombier break;
168375daca8SDavid du Colombier
169375daca8SDavid du Colombier case OHI:
170375daca8SDavid du Colombier v = (uvlong)l->vconst > (uvlong)r->vconst;
171375daca8SDavid du Colombier break;
172375daca8SDavid du Colombier
173375daca8SDavid du Colombier case OGT:
174375daca8SDavid du Colombier if(typefd[l->type->etype])
175375daca8SDavid du Colombier v = l->fconst > r->fconst;
176375daca8SDavid du Colombier else
177375daca8SDavid du Colombier v = l->vconst > r->vconst;
178375daca8SDavid du Colombier break;
179375daca8SDavid du Colombier
180375daca8SDavid du Colombier case OLS:
181375daca8SDavid du Colombier v = (uvlong)l->vconst <= (uvlong)r->vconst;
182375daca8SDavid du Colombier break;
183375daca8SDavid du Colombier
184375daca8SDavid du Colombier case OLE:
185375daca8SDavid du Colombier if(typefd[l->type->etype])
186375daca8SDavid du Colombier v = l->fconst <= r->fconst;
187375daca8SDavid du Colombier else
188375daca8SDavid du Colombier v = l->vconst <= r->vconst;
189375daca8SDavid du Colombier break;
190375daca8SDavid du Colombier
191375daca8SDavid du Colombier case OHS:
192375daca8SDavid du Colombier v = (uvlong)l->vconst >= (uvlong)r->vconst;
193375daca8SDavid du Colombier break;
194375daca8SDavid du Colombier
195375daca8SDavid du Colombier case OGE:
196375daca8SDavid du Colombier if(typefd[l->type->etype])
197375daca8SDavid du Colombier v = l->fconst >= r->fconst;
198375daca8SDavid du Colombier else
199375daca8SDavid du Colombier v = l->vconst >= r->vconst;
200375daca8SDavid du Colombier break;
201375daca8SDavid du Colombier
202375daca8SDavid du Colombier case OEQ:
203375daca8SDavid du Colombier if(typefd[l->type->etype])
204375daca8SDavid du Colombier v = l->fconst == r->fconst;
205375daca8SDavid du Colombier else
206375daca8SDavid du Colombier v = l->vconst == r->vconst;
207375daca8SDavid du Colombier break;
208375daca8SDavid du Colombier
209375daca8SDavid du Colombier case ONE:
210375daca8SDavid du Colombier if(typefd[l->type->etype])
211375daca8SDavid du Colombier v = l->fconst != r->fconst;
212375daca8SDavid du Colombier else
213375daca8SDavid du Colombier v = l->vconst != r->vconst;
214375daca8SDavid du Colombier break;
215375daca8SDavid du Colombier
216375daca8SDavid du Colombier case ONOT:
217375daca8SDavid du Colombier if(typefd[l->type->etype])
218375daca8SDavid du Colombier v = !l->fconst;
219375daca8SDavid du Colombier else
220375daca8SDavid du Colombier v = !l->vconst;
221375daca8SDavid du Colombier break;
222375daca8SDavid du Colombier
223375daca8SDavid du Colombier case OANDAND:
224375daca8SDavid du Colombier if(typefd[l->type->etype])
225375daca8SDavid du Colombier v = l->fconst && r->fconst;
226375daca8SDavid du Colombier else
227375daca8SDavid du Colombier v = l->vconst && r->vconst;
228375daca8SDavid du Colombier break;
229375daca8SDavid du Colombier
230375daca8SDavid du Colombier case OOROR:
231375daca8SDavid du Colombier if(typefd[l->type->etype])
232375daca8SDavid du Colombier v = l->fconst || r->fconst;
233375daca8SDavid du Colombier else
234375daca8SDavid du Colombier v = l->vconst || r->vconst;
235375daca8SDavid du Colombier break;
236375daca8SDavid du Colombier }
237375daca8SDavid du Colombier if(isf) {
238375daca8SDavid du Colombier n->fconst = d;
239375daca8SDavid du Colombier } else {
240375daca8SDavid du Colombier n->vconst = convvtox(v, n->type->etype);
241375daca8SDavid du Colombier }
24222a127bbSDavid du Colombier n->oldop = n->op;
243375daca8SDavid du Colombier n->op = OCONST;
244375daca8SDavid du Colombier }
245375daca8SDavid du Colombier
246375daca8SDavid du Colombier void
acom(Node * n)247375daca8SDavid du Colombier acom(Node *n)
248375daca8SDavid du Colombier {
249375daca8SDavid du Colombier Type *t;
250375daca8SDavid du Colombier Node *l, *r;
251375daca8SDavid du Colombier int i;
252375daca8SDavid du Colombier
253375daca8SDavid du Colombier switch(n->op)
254375daca8SDavid du Colombier {
255375daca8SDavid du Colombier
256375daca8SDavid du Colombier case ONAME:
257375daca8SDavid du Colombier case OCONST:
258375daca8SDavid du Colombier case OSTRING:
259375daca8SDavid du Colombier case OINDREG:
260375daca8SDavid du Colombier case OREGISTER:
261375daca8SDavid du Colombier return;
262375daca8SDavid du Colombier
263375daca8SDavid du Colombier case ONEG:
264375daca8SDavid du Colombier l = n->left;
265375daca8SDavid du Colombier if(addo(n) && addo(l))
266375daca8SDavid du Colombier break;
267375daca8SDavid du Colombier acom(l);
268375daca8SDavid du Colombier return;
269375daca8SDavid du Colombier
270375daca8SDavid du Colombier case OADD:
271375daca8SDavid du Colombier case OSUB:
272375daca8SDavid du Colombier case OMUL:
273375daca8SDavid du Colombier l = n->left;
274375daca8SDavid du Colombier r = n->right;
275375daca8SDavid du Colombier if(addo(n)) {
276375daca8SDavid du Colombier if(addo(r))
277375daca8SDavid du Colombier break;
278375daca8SDavid du Colombier if(addo(l))
279375daca8SDavid du Colombier break;
280375daca8SDavid du Colombier }
281375daca8SDavid du Colombier acom(l);
282375daca8SDavid du Colombier acom(r);
283375daca8SDavid du Colombier return;
284375daca8SDavid du Colombier
285375daca8SDavid du Colombier default:
286375daca8SDavid du Colombier l = n->left;
287375daca8SDavid du Colombier r = n->right;
288375daca8SDavid du Colombier if(l != Z)
289375daca8SDavid du Colombier acom(l);
290375daca8SDavid du Colombier if(r != Z)
291375daca8SDavid du Colombier acom(r);
292375daca8SDavid du Colombier return;
293375daca8SDavid du Colombier }
294375daca8SDavid du Colombier
295375daca8SDavid du Colombier /* bust terms out */
296375daca8SDavid du Colombier t = n->type;
297375daca8SDavid du Colombier term[0].mult = 0;
298375daca8SDavid du Colombier term[0].node = Z;
299375daca8SDavid du Colombier nterm = 1;
300375daca8SDavid du Colombier acom1(1, n);
301375daca8SDavid du Colombier if(debug['m'])
302375daca8SDavid du Colombier for(i=0; i<nterm; i++) {
303375daca8SDavid du Colombier print("%d %3lld ", i, term[i].mult);
304375daca8SDavid du Colombier prtree1(term[i].node, 1, 0);
305375daca8SDavid du Colombier }
306375daca8SDavid du Colombier if(nterm < NTERM)
307375daca8SDavid du Colombier acom2(n, t);
308375daca8SDavid du Colombier n->type = t;
309375daca8SDavid du Colombier }
310375daca8SDavid du Colombier
311375daca8SDavid du Colombier int
acomcmp1(const void * a1,const void * a2)312375daca8SDavid du Colombier acomcmp1(const void *a1, const void *a2)
313375daca8SDavid du Colombier {
314375daca8SDavid du Colombier vlong c1, c2;
315375daca8SDavid du Colombier Term *t1, *t2;
316375daca8SDavid du Colombier
317375daca8SDavid du Colombier t1 = (Term*)a1;
318375daca8SDavid du Colombier t2 = (Term*)a2;
319375daca8SDavid du Colombier c1 = t1->mult;
320375daca8SDavid du Colombier if(c1 < 0)
321375daca8SDavid du Colombier c1 = -c1;
322375daca8SDavid du Colombier c2 = t2->mult;
323375daca8SDavid du Colombier if(c2 < 0)
324375daca8SDavid du Colombier c2 = -c2;
325375daca8SDavid du Colombier if(c1 > c2)
326375daca8SDavid du Colombier return 1;
327375daca8SDavid du Colombier if(c1 < c2)
328375daca8SDavid du Colombier return -1;
329375daca8SDavid du Colombier c1 = 1;
330375daca8SDavid du Colombier if(t1->mult < 0)
331375daca8SDavid du Colombier c1 = 0;
332375daca8SDavid du Colombier c2 = 1;
333375daca8SDavid du Colombier if(t2->mult < 0)
334375daca8SDavid du Colombier c2 = 0;
335375daca8SDavid du Colombier if(c2 -= c1)
336375daca8SDavid du Colombier return c2;
337375daca8SDavid du Colombier if(t2 > t1)
338375daca8SDavid du Colombier return 1;
339375daca8SDavid du Colombier return -1;
340375daca8SDavid du Colombier }
341375daca8SDavid du Colombier
342375daca8SDavid du Colombier int
acomcmp2(const void * a1,const void * a2)343375daca8SDavid du Colombier acomcmp2(const void *a1, const void *a2)
344375daca8SDavid du Colombier {
345375daca8SDavid du Colombier vlong c1, c2;
346375daca8SDavid du Colombier Term *t1, *t2;
347375daca8SDavid du Colombier
348375daca8SDavid du Colombier t1 = (Term*)a1;
349375daca8SDavid du Colombier t2 = (Term*)a2;
350375daca8SDavid du Colombier c1 = t1->mult;
351375daca8SDavid du Colombier c2 = t2->mult;
352375daca8SDavid du Colombier if(c1 > c2)
353375daca8SDavid du Colombier return 1;
354375daca8SDavid du Colombier if(c1 < c2)
355375daca8SDavid du Colombier return -1;
356375daca8SDavid du Colombier if(t2 > t1)
357375daca8SDavid du Colombier return 1;
358375daca8SDavid du Colombier return -1;
359375daca8SDavid du Colombier }
360375daca8SDavid du Colombier
361375daca8SDavid du Colombier void
acom2(Node * n,Type * t)362375daca8SDavid du Colombier acom2(Node *n, Type *t)
363375daca8SDavid du Colombier {
364375daca8SDavid du Colombier Node *l, *r;
365375daca8SDavid du Colombier Term trm[NTERM];
366375daca8SDavid du Colombier int et, nt, i, j;
367375daca8SDavid du Colombier vlong c1, c2;
368375daca8SDavid du Colombier
369375daca8SDavid du Colombier /*
370375daca8SDavid du Colombier * copy into automatic
371375daca8SDavid du Colombier */
372375daca8SDavid du Colombier c2 = 0;
373375daca8SDavid du Colombier nt = nterm;
374375daca8SDavid du Colombier for(i=0; i<nt; i++)
375375daca8SDavid du Colombier trm[i] = term[i];
376375daca8SDavid du Colombier /*
377375daca8SDavid du Colombier * recur on subtrees
378375daca8SDavid du Colombier */
379375daca8SDavid du Colombier j = 0;
380375daca8SDavid du Colombier for(i=1; i<nt; i++) {
381375daca8SDavid du Colombier c1 = trm[i].mult;
382375daca8SDavid du Colombier if(c1 == 0)
383375daca8SDavid du Colombier continue;
384375daca8SDavid du Colombier l = trm[i].node;
385375daca8SDavid du Colombier if(l != Z) {
386375daca8SDavid du Colombier j = 1;
387375daca8SDavid du Colombier acom(l);
388375daca8SDavid du Colombier }
389375daca8SDavid du Colombier }
390375daca8SDavid du Colombier c1 = trm[0].mult;
391375daca8SDavid du Colombier if(j == 0) {
39222a127bbSDavid du Colombier n->oldop = n->op;
393375daca8SDavid du Colombier n->op = OCONST;
394375daca8SDavid du Colombier n->vconst = c1;
395375daca8SDavid du Colombier return;
396375daca8SDavid du Colombier }
397375daca8SDavid du Colombier et = t->etype;
398375daca8SDavid du Colombier
399375daca8SDavid du Colombier /*
400375daca8SDavid du Colombier * prepare constant term,
401375daca8SDavid du Colombier * combine it with an addressing term
402375daca8SDavid du Colombier */
403375daca8SDavid du Colombier if(c1 != 0) {
404375daca8SDavid du Colombier l = new1(OCONST, Z, Z);
405375daca8SDavid du Colombier l->type = t;
406375daca8SDavid du Colombier l->vconst = c1;
407375daca8SDavid du Colombier trm[0].mult = 1;
408375daca8SDavid du Colombier for(i=1; i<nt; i++) {
409375daca8SDavid du Colombier if(trm[i].mult != 1)
410375daca8SDavid du Colombier continue;
411375daca8SDavid du Colombier r = trm[i].node;
412375daca8SDavid du Colombier if(r->op != OADDR)
413375daca8SDavid du Colombier continue;
414375daca8SDavid du Colombier r->type = t;
415375daca8SDavid du Colombier l = new1(OADD, r, l);
416375daca8SDavid du Colombier l->type = t;
417375daca8SDavid du Colombier trm[i].mult = 0;
418375daca8SDavid du Colombier break;
419375daca8SDavid du Colombier }
420375daca8SDavid du Colombier trm[0].node = l;
421375daca8SDavid du Colombier }
422375daca8SDavid du Colombier /*
423375daca8SDavid du Colombier * look for factorable terms
424375daca8SDavid du Colombier * c1*i + c1*c2*j -> c1*(i + c2*j)
425375daca8SDavid du Colombier */
426375daca8SDavid du Colombier qsort(trm+1, nt-1, sizeof(trm[0]), acomcmp1);
427375daca8SDavid du Colombier for(i=nt-1; i>=0; i--) {
428375daca8SDavid du Colombier c1 = trm[i].mult;
429375daca8SDavid du Colombier if(c1 < 0)
430375daca8SDavid du Colombier c1 = -c1;
431375daca8SDavid du Colombier if(c1 <= 1)
432375daca8SDavid du Colombier continue;
433375daca8SDavid du Colombier for(j=i+1; j<nt; j++) {
434375daca8SDavid du Colombier c2 = trm[j].mult;
435375daca8SDavid du Colombier if(c2 < 0)
436375daca8SDavid du Colombier c2 = -c2;
437375daca8SDavid du Colombier if(c2 <= 1)
438375daca8SDavid du Colombier continue;
439375daca8SDavid du Colombier if(c2 % c1)
440375daca8SDavid du Colombier continue;
441375daca8SDavid du Colombier r = trm[j].node;
442*2cca75a1SDavid du Colombier if(r->type->etype != et)
443*2cca75a1SDavid du Colombier r = acast(t, r);
444375daca8SDavid du Colombier c2 = trm[j].mult/trm[i].mult;
445375daca8SDavid du Colombier if(c2 != 1 && c2 != -1) {
446375daca8SDavid du Colombier r = new1(OMUL, r, new(OCONST, Z, Z));
447375daca8SDavid du Colombier r->type = t;
448375daca8SDavid du Colombier r->right->type = t;
449375daca8SDavid du Colombier r->right->vconst = c2;
450375daca8SDavid du Colombier }
451375daca8SDavid du Colombier l = trm[i].node;
452*2cca75a1SDavid du Colombier if(l->type->etype != et)
453*2cca75a1SDavid du Colombier l = acast(t, l);
454375daca8SDavid du Colombier r = new1(OADD, l, r);
455375daca8SDavid du Colombier r->type = t;
456375daca8SDavid du Colombier if(c2 == -1)
457375daca8SDavid du Colombier r->op = OSUB;
458375daca8SDavid du Colombier trm[i].node = r;
459375daca8SDavid du Colombier trm[j].mult = 0;
460375daca8SDavid du Colombier }
461375daca8SDavid du Colombier }
462375daca8SDavid du Colombier if(debug['m']) {
463375daca8SDavid du Colombier print("\n");
464375daca8SDavid du Colombier for(i=0; i<nt; i++) {
465375daca8SDavid du Colombier print("%d %3lld ", i, trm[i].mult);
466375daca8SDavid du Colombier prtree1(trm[i].node, 1, 0);
467375daca8SDavid du Colombier }
468375daca8SDavid du Colombier }
469375daca8SDavid du Colombier
470375daca8SDavid du Colombier /*
471375daca8SDavid du Colombier * put it all back together
472375daca8SDavid du Colombier */
473375daca8SDavid du Colombier qsort(trm+1, nt-1, sizeof(trm[0]), acomcmp2);
474375daca8SDavid du Colombier l = Z;
475375daca8SDavid du Colombier for(i=nt-1; i>=0; i--) {
476375daca8SDavid du Colombier c1 = trm[i].mult;
477375daca8SDavid du Colombier if(c1 == 0)
478375daca8SDavid du Colombier continue;
479375daca8SDavid du Colombier r = trm[i].node;
480*2cca75a1SDavid du Colombier if(r->type->etype != et || r->op == OBIT)
481*2cca75a1SDavid du Colombier r = acast(t, r);
482375daca8SDavid du Colombier if(c1 != 1 && c1 != -1) {
483375daca8SDavid du Colombier r = new1(OMUL, r, new(OCONST, Z, Z));
484375daca8SDavid du Colombier r->type = t;
485375daca8SDavid du Colombier r->right->type = t;
486375daca8SDavid du Colombier if(c1 < 0) {
487375daca8SDavid du Colombier r->right->vconst = -c1;
488375daca8SDavid du Colombier c1 = -1;
489375daca8SDavid du Colombier } else {
490375daca8SDavid du Colombier r->right->vconst = c1;
491375daca8SDavid du Colombier c1 = 1;
492375daca8SDavid du Colombier }
493375daca8SDavid du Colombier }
494375daca8SDavid du Colombier if(l == Z) {
495375daca8SDavid du Colombier l = r;
496375daca8SDavid du Colombier c2 = c1;
497375daca8SDavid du Colombier continue;
498375daca8SDavid du Colombier }
499375daca8SDavid du Colombier if(c1 < 0)
500375daca8SDavid du Colombier if(c2 < 0)
501375daca8SDavid du Colombier l = new1(OADD, l, r);
502375daca8SDavid du Colombier else
503375daca8SDavid du Colombier l = new1(OSUB, l, r);
504375daca8SDavid du Colombier else
505375daca8SDavid du Colombier if(c2 < 0) {
506375daca8SDavid du Colombier l = new1(OSUB, r, l);
507375daca8SDavid du Colombier c2 = 1;
508375daca8SDavid du Colombier } else
509375daca8SDavid du Colombier l = new1(OADD, l, r);
510375daca8SDavid du Colombier l->type = t;
511375daca8SDavid du Colombier }
512375daca8SDavid du Colombier if(c2 < 0) {
513375daca8SDavid du Colombier r = new1(OCONST, 0, 0);
514375daca8SDavid du Colombier r->vconst = 0;
515375daca8SDavid du Colombier r->type = t;
516375daca8SDavid du Colombier l = new1(OSUB, r, l);
517375daca8SDavid du Colombier l->type = t;
518375daca8SDavid du Colombier }
519375daca8SDavid du Colombier *n = *l;
520375daca8SDavid du Colombier }
521375daca8SDavid du Colombier
522375daca8SDavid du Colombier void
acom1(vlong v,Node * n)523375daca8SDavid du Colombier acom1(vlong v, Node *n)
524375daca8SDavid du Colombier {
525375daca8SDavid du Colombier Node *l, *r;
526375daca8SDavid du Colombier
527375daca8SDavid du Colombier if(v == 0 || nterm >= NTERM)
528375daca8SDavid du Colombier return;
529375daca8SDavid du Colombier if(!addo(n)) {
530375daca8SDavid du Colombier if(n->op == OCONST)
531375daca8SDavid du Colombier if(!typefd[n->type->etype]) {
532375daca8SDavid du Colombier term[0].mult += v*n->vconst;
533375daca8SDavid du Colombier return;
534375daca8SDavid du Colombier }
535375daca8SDavid du Colombier term[nterm].mult = v;
536375daca8SDavid du Colombier term[nterm].node = n;
537375daca8SDavid du Colombier nterm++;
538375daca8SDavid du Colombier return;
539375daca8SDavid du Colombier }
540375daca8SDavid du Colombier switch(n->op) {
541375daca8SDavid du Colombier
542375daca8SDavid du Colombier case OCAST:
543375daca8SDavid du Colombier acom1(v, n->left);
544375daca8SDavid du Colombier break;
545375daca8SDavid du Colombier
546375daca8SDavid du Colombier case ONEG:
547375daca8SDavid du Colombier acom1(-v, n->left);
548375daca8SDavid du Colombier break;
549375daca8SDavid du Colombier
550375daca8SDavid du Colombier case OADD:
551375daca8SDavid du Colombier acom1(v, n->left);
552375daca8SDavid du Colombier acom1(v, n->right);
553375daca8SDavid du Colombier break;
554375daca8SDavid du Colombier
555375daca8SDavid du Colombier case OSUB:
556375daca8SDavid du Colombier acom1(v, n->left);
557375daca8SDavid du Colombier acom1(-v, n->right);
558375daca8SDavid du Colombier break;
559375daca8SDavid du Colombier
560375daca8SDavid du Colombier case OMUL:
561375daca8SDavid du Colombier l = n->left;
562375daca8SDavid du Colombier r = n->right;
563375daca8SDavid du Colombier if(l->op == OCONST)
564375daca8SDavid du Colombier if(!typefd[n->type->etype]) {
565375daca8SDavid du Colombier acom1(v*l->vconst, r);
566375daca8SDavid du Colombier break;
567375daca8SDavid du Colombier }
568375daca8SDavid du Colombier if(r->op == OCONST)
569375daca8SDavid du Colombier if(!typefd[n->type->etype]) {
570375daca8SDavid du Colombier acom1(v*r->vconst, l);
571375daca8SDavid du Colombier break;
572375daca8SDavid du Colombier }
573375daca8SDavid du Colombier break;
574375daca8SDavid du Colombier
575375daca8SDavid du Colombier default:
576375daca8SDavid du Colombier diag(n, "not addo");
577375daca8SDavid du Colombier }
578375daca8SDavid du Colombier }
579375daca8SDavid du Colombier
580375daca8SDavid du Colombier int
addo(Node * n)581375daca8SDavid du Colombier addo(Node *n)
582375daca8SDavid du Colombier {
583375daca8SDavid du Colombier
584375daca8SDavid du Colombier if(n != Z)
585375daca8SDavid du Colombier if(!typefd[n->type->etype])
586*2cca75a1SDavid du Colombier if(!typev[n->type->etype] || ewidth[TVLONG] == ewidth[TIND])
587375daca8SDavid du Colombier switch(n->op) {
588375daca8SDavid du Colombier
589375daca8SDavid du Colombier case OCAST:
590375daca8SDavid du Colombier if(nilcast(n->left->type, n->type))
591375daca8SDavid du Colombier return 1;
592375daca8SDavid du Colombier break;
593375daca8SDavid du Colombier
594375daca8SDavid du Colombier case ONEG:
595375daca8SDavid du Colombier case OADD:
596375daca8SDavid du Colombier case OSUB:
597375daca8SDavid du Colombier return 1;
598375daca8SDavid du Colombier
599375daca8SDavid du Colombier case OMUL:
600375daca8SDavid du Colombier if(n->left->op == OCONST)
601375daca8SDavid du Colombier return 1;
602375daca8SDavid du Colombier if(n->right->op == OCONST)
603375daca8SDavid du Colombier return 1;
604375daca8SDavid du Colombier }
605375daca8SDavid du Colombier return 0;
606375daca8SDavid du Colombier }
607