1e887ea33SDavid du Colombier #include "gc.h"
2e887ea33SDavid du Colombier
3e887ea33SDavid du Colombier /* ,x/^(print|prtree)\(/i/\/\/ */
4e887ea33SDavid du Colombier int castup(Type*, Type*);
5*1936bb65SDavid du Colombier void checkmask(Node*, Node*);
6e887ea33SDavid du Colombier
7e887ea33SDavid du Colombier void
cgen(Node * n,Node * nn)8e887ea33SDavid du Colombier cgen(Node *n, Node *nn)
9e887ea33SDavid du Colombier {
10e887ea33SDavid du Colombier Node *l, *r, *t;
11e887ea33SDavid du Colombier Prog *p1;
12e887ea33SDavid du Colombier Node nod, nod1, nod2, nod3, nod4;
13e887ea33SDavid du Colombier int o, hardleft;
14e887ea33SDavid du Colombier long v, curs;
15e887ea33SDavid du Colombier vlong c;
16e887ea33SDavid du Colombier
17e887ea33SDavid du Colombier if(debug['g']) {
18e887ea33SDavid du Colombier prtree(nn, "cgen lhs");
19e887ea33SDavid du Colombier prtree(n, "cgen");
20e887ea33SDavid du Colombier }
21e887ea33SDavid du Colombier if(n == Z || n->type == T)
22e887ea33SDavid du Colombier return;
23e887ea33SDavid du Colombier if(typesu[n->type->etype]) {
24e887ea33SDavid du Colombier sugen(n, nn, n->type->width);
25e887ea33SDavid du Colombier return;
26e887ea33SDavid du Colombier }
27e887ea33SDavid du Colombier l = n->left;
28e887ea33SDavid du Colombier r = n->right;
29e887ea33SDavid du Colombier o = n->op;
30e887ea33SDavid du Colombier if(n->addable >= INDEXED) {
31e887ea33SDavid du Colombier if(nn == Z) {
32e887ea33SDavid du Colombier switch(o) {
33e887ea33SDavid du Colombier default:
34e887ea33SDavid du Colombier nullwarn(Z, Z);
35e887ea33SDavid du Colombier break;
36e887ea33SDavid du Colombier case OINDEX:
37e887ea33SDavid du Colombier nullwarn(l, r);
38e887ea33SDavid du Colombier break;
39e887ea33SDavid du Colombier }
40e887ea33SDavid du Colombier return;
41e887ea33SDavid du Colombier }
42e887ea33SDavid du Colombier gmove(n, nn);
43e887ea33SDavid du Colombier return;
44e887ea33SDavid du Colombier }
45e887ea33SDavid du Colombier curs = cursafe;
46e887ea33SDavid du Colombier
47e887ea33SDavid du Colombier if(l->complex >= FNX)
48e887ea33SDavid du Colombier if(r != Z && r->complex >= FNX)
49e887ea33SDavid du Colombier switch(o) {
50e887ea33SDavid du Colombier default:
51e887ea33SDavid du Colombier if(cond(o) && typesu[l->type->etype])
52e887ea33SDavid du Colombier break;
53e887ea33SDavid du Colombier
54e887ea33SDavid du Colombier regret(&nod, r);
55e887ea33SDavid du Colombier cgen(r, &nod);
56e887ea33SDavid du Colombier
57e887ea33SDavid du Colombier regsalloc(&nod1, r);
58e887ea33SDavid du Colombier gmove(&nod, &nod1);
59e887ea33SDavid du Colombier
60e887ea33SDavid du Colombier regfree(&nod);
61e887ea33SDavid du Colombier nod = *n;
62e887ea33SDavid du Colombier nod.right = &nod1;
63e887ea33SDavid du Colombier
64e887ea33SDavid du Colombier cgen(&nod, nn);
65e887ea33SDavid du Colombier return;
66e887ea33SDavid du Colombier
67e887ea33SDavid du Colombier case OFUNC:
68e887ea33SDavid du Colombier case OCOMMA:
69e887ea33SDavid du Colombier case OANDAND:
70e887ea33SDavid du Colombier case OOROR:
71e887ea33SDavid du Colombier case OCOND:
72e887ea33SDavid du Colombier case ODOT:
73e887ea33SDavid du Colombier break;
74e887ea33SDavid du Colombier }
75e887ea33SDavid du Colombier
76e887ea33SDavid du Colombier hardleft = l->addable < INDEXED || l->complex >= FNX;
77e887ea33SDavid du Colombier switch(o) {
78e887ea33SDavid du Colombier default:
79e887ea33SDavid du Colombier diag(n, "unknown op in cgen: %O", o);
80e887ea33SDavid du Colombier break;
81e887ea33SDavid du Colombier
82e887ea33SDavid du Colombier case ONEG:
83e887ea33SDavid du Colombier case OCOM:
84e887ea33SDavid du Colombier if(nn == Z) {
85e887ea33SDavid du Colombier nullwarn(l, Z);
86e887ea33SDavid du Colombier break;
87e887ea33SDavid du Colombier }
88e887ea33SDavid du Colombier regalloc(&nod, l, nn);
89e887ea33SDavid du Colombier cgen(l, &nod);
90e887ea33SDavid du Colombier gopcode(o, n->type, Z, &nod);
91e887ea33SDavid du Colombier gmove(&nod, nn);
92e887ea33SDavid du Colombier regfree(&nod);
93e887ea33SDavid du Colombier break;
94e887ea33SDavid du Colombier
95e887ea33SDavid du Colombier case OAS:
96e887ea33SDavid du Colombier if(l->op == OBIT)
97e887ea33SDavid du Colombier goto bitas;
98e887ea33SDavid du Colombier if(!hardleft) {
99e887ea33SDavid du Colombier if(nn != Z || r->addable < INDEXED || hardconst(r)) {
100e887ea33SDavid du Colombier if(r->complex >= FNX && nn == Z)
101e887ea33SDavid du Colombier regret(&nod, r);
102e887ea33SDavid du Colombier else
103e887ea33SDavid du Colombier regalloc(&nod, r, nn);
104e887ea33SDavid du Colombier cgen(r, &nod);
105e887ea33SDavid du Colombier gmove(&nod, l);
106e887ea33SDavid du Colombier if(nn != Z)
107e887ea33SDavid du Colombier gmove(&nod, nn);
108e887ea33SDavid du Colombier regfree(&nod);
109e887ea33SDavid du Colombier } else
110e887ea33SDavid du Colombier gmove(r, l);
111e887ea33SDavid du Colombier break;
112e887ea33SDavid du Colombier }
113e887ea33SDavid du Colombier if(l->complex >= r->complex) {
114e887ea33SDavid du Colombier if(l->op == OINDEX && immconst(r)) {
115e887ea33SDavid du Colombier gmove(r, l);
116e887ea33SDavid du Colombier break;
117e887ea33SDavid du Colombier }
118e887ea33SDavid du Colombier reglcgen(&nod1, l, Z);
119e887ea33SDavid du Colombier if(r->addable >= INDEXED && !hardconst(r)) {
120e887ea33SDavid du Colombier gmove(r, &nod1);
121e887ea33SDavid du Colombier if(nn != Z)
122e887ea33SDavid du Colombier gmove(r, nn);
123e887ea33SDavid du Colombier regfree(&nod1);
124e887ea33SDavid du Colombier break;
125e887ea33SDavid du Colombier }
126e887ea33SDavid du Colombier regalloc(&nod, r, nn);
127e887ea33SDavid du Colombier cgen(r, &nod);
128e887ea33SDavid du Colombier } else {
129e887ea33SDavid du Colombier regalloc(&nod, r, nn);
130e887ea33SDavid du Colombier cgen(r, &nod);
131e887ea33SDavid du Colombier reglcgen(&nod1, l, Z);
132e887ea33SDavid du Colombier }
133e887ea33SDavid du Colombier gmove(&nod, &nod1);
134e887ea33SDavid du Colombier regfree(&nod);
135e887ea33SDavid du Colombier regfree(&nod1);
136e887ea33SDavid du Colombier break;
137e887ea33SDavid du Colombier
138e887ea33SDavid du Colombier bitas:
139e887ea33SDavid du Colombier n = l->left;
140e887ea33SDavid du Colombier regalloc(&nod, r, nn);
141e887ea33SDavid du Colombier if(l->complex >= r->complex) {
142e887ea33SDavid du Colombier reglcgen(&nod1, n, Z);
143e887ea33SDavid du Colombier cgen(r, &nod);
144e887ea33SDavid du Colombier } else {
145e887ea33SDavid du Colombier cgen(r, &nod);
146e887ea33SDavid du Colombier reglcgen(&nod1, n, Z);
147e887ea33SDavid du Colombier }
148e887ea33SDavid du Colombier regalloc(&nod2, n, Z);
149e887ea33SDavid du Colombier gmove(&nod1, &nod2);
150e887ea33SDavid du Colombier bitstore(l, &nod, &nod1, &nod2, nn);
151e887ea33SDavid du Colombier break;
152e887ea33SDavid du Colombier
153e887ea33SDavid du Colombier case OBIT:
154e887ea33SDavid du Colombier if(nn == Z) {
155e887ea33SDavid du Colombier nullwarn(l, Z);
156e887ea33SDavid du Colombier break;
157e887ea33SDavid du Colombier }
158e887ea33SDavid du Colombier bitload(n, &nod, Z, Z, nn);
159e887ea33SDavid du Colombier gmove(&nod, nn);
160e887ea33SDavid du Colombier regfree(&nod);
161e887ea33SDavid du Colombier break;
162e887ea33SDavid du Colombier
163e887ea33SDavid du Colombier case OLSHR:
164e887ea33SDavid du Colombier case OASHL:
165e887ea33SDavid du Colombier case OASHR:
166e887ea33SDavid du Colombier if(nn == Z) {
167e887ea33SDavid du Colombier nullwarn(l, r);
168e887ea33SDavid du Colombier break;
169e887ea33SDavid du Colombier }
170e887ea33SDavid du Colombier if(r->op == OCONST) {
171e887ea33SDavid du Colombier if(r->vconst == 0) {
172e887ea33SDavid du Colombier cgen(l, nn);
173e887ea33SDavid du Colombier break;
174e887ea33SDavid du Colombier }
175e887ea33SDavid du Colombier regalloc(&nod, l, nn);
176e887ea33SDavid du Colombier cgen(l, &nod);
177e887ea33SDavid du Colombier if(o == OASHL && r->vconst == 1)
178e887ea33SDavid du Colombier gopcode(OADD, n->type, &nod, &nod);
179e887ea33SDavid du Colombier else
180e887ea33SDavid du Colombier gopcode(o, n->type, r, &nod);
181e887ea33SDavid du Colombier gmove(&nod, nn);
182e887ea33SDavid du Colombier regfree(&nod);
183e887ea33SDavid du Colombier break;
184e887ea33SDavid du Colombier }
185e887ea33SDavid du Colombier
186e887ea33SDavid du Colombier /*
187e887ea33SDavid du Colombier * get nod to be D_CX
188e887ea33SDavid du Colombier */
189e887ea33SDavid du Colombier if(nodreg(&nod, nn, D_CX)) {
190e887ea33SDavid du Colombier regsalloc(&nod1, n);
191e887ea33SDavid du Colombier gmove(&nod, &nod1);
192e887ea33SDavid du Colombier cgen(n, &nod); /* probably a bug */
193e887ea33SDavid du Colombier gmove(&nod, nn);
194e887ea33SDavid du Colombier gmove(&nod1, &nod);
195e887ea33SDavid du Colombier break;
196e887ea33SDavid du Colombier }
197e887ea33SDavid du Colombier reg[D_CX]++;
198e887ea33SDavid du Colombier if(nn->op == OREGISTER && nn->reg == D_CX)
199e887ea33SDavid du Colombier regalloc(&nod1, l, Z);
200e887ea33SDavid du Colombier else
201e887ea33SDavid du Colombier regalloc(&nod1, l, nn);
202e887ea33SDavid du Colombier if(r->complex >= l->complex) {
203e887ea33SDavid du Colombier cgen(r, &nod);
204e887ea33SDavid du Colombier cgen(l, &nod1);
205e887ea33SDavid du Colombier } else {
206e887ea33SDavid du Colombier cgen(l, &nod1);
207e887ea33SDavid du Colombier cgen(r, &nod);
208e887ea33SDavid du Colombier }
209e887ea33SDavid du Colombier gopcode(o, n->type, &nod, &nod1);
210e887ea33SDavid du Colombier gmove(&nod1, nn);
211e887ea33SDavid du Colombier regfree(&nod);
212e887ea33SDavid du Colombier regfree(&nod1);
213e887ea33SDavid du Colombier break;
214e887ea33SDavid du Colombier
215e887ea33SDavid du Colombier case OADD:
216e887ea33SDavid du Colombier case OSUB:
217e887ea33SDavid du Colombier case OOR:
218e887ea33SDavid du Colombier case OXOR:
219e887ea33SDavid du Colombier case OAND:
220e887ea33SDavid du Colombier if(nn == Z) {
221e887ea33SDavid du Colombier nullwarn(l, r);
222e887ea33SDavid du Colombier break;
223e887ea33SDavid du Colombier }
224e887ea33SDavid du Colombier if(typefd[n->type->etype])
225e887ea33SDavid du Colombier goto fop;
226e887ea33SDavid du Colombier if(r->op == OCONST) {
227e887ea33SDavid du Colombier if(r->vconst == 0 && o != OAND) {
228e887ea33SDavid du Colombier cgen(l, nn);
229e887ea33SDavid du Colombier break;
230e887ea33SDavid du Colombier }
231e887ea33SDavid du Colombier }
232e887ea33SDavid du Colombier if(n->op == OADD && l->op == OASHL && l->right->op == OCONST
233e887ea33SDavid du Colombier && (r->op != OCONST || r->vconst < -128 || r->vconst > 127)) {
234e887ea33SDavid du Colombier c = l->right->vconst;
235e887ea33SDavid du Colombier if(c > 0 && c <= 3) {
236e887ea33SDavid du Colombier if(l->left->complex >= r->complex) {
237e887ea33SDavid du Colombier regalloc(&nod, l->left, nn);
238e887ea33SDavid du Colombier cgen(l->left, &nod);
239e887ea33SDavid du Colombier if(r->addable < INDEXED) {
240e887ea33SDavid du Colombier regalloc(&nod1, r, Z);
241e887ea33SDavid du Colombier cgen(r, &nod1);
242e887ea33SDavid du Colombier genmuladd(&nod, &nod, 1 << c, &nod1);
243e887ea33SDavid du Colombier regfree(&nod1);
244e887ea33SDavid du Colombier }
245e887ea33SDavid du Colombier else
246e887ea33SDavid du Colombier genmuladd(&nod, &nod, 1 << c, r);
247e887ea33SDavid du Colombier }
248e887ea33SDavid du Colombier else {
249e887ea33SDavid du Colombier regalloc(&nod, r, nn);
250e887ea33SDavid du Colombier cgen(r, &nod);
251e887ea33SDavid du Colombier regalloc(&nod1, l->left, Z);
252e887ea33SDavid du Colombier cgen(l->left, &nod1);
253e887ea33SDavid du Colombier genmuladd(&nod, &nod1, 1 << c, &nod);
254e887ea33SDavid du Colombier regfree(&nod1);
255e887ea33SDavid du Colombier }
256e887ea33SDavid du Colombier gmove(&nod, nn);
257e887ea33SDavid du Colombier regfree(&nod);
258e887ea33SDavid du Colombier break;
259e887ea33SDavid du Colombier }
260e887ea33SDavid du Colombier }
261*1936bb65SDavid du Colombier if(n->op == OAND)
262*1936bb65SDavid du Colombier checkmask(n, r);
263e887ea33SDavid du Colombier if(r->addable >= INDEXED && !hardconst(r)) {
264e887ea33SDavid du Colombier regalloc(&nod, l, nn);
265e887ea33SDavid du Colombier cgen(l, &nod);
266e887ea33SDavid du Colombier gopcode(o, n->type, r, &nod);
267e887ea33SDavid du Colombier gmove(&nod, nn);
268e887ea33SDavid du Colombier regfree(&nod);
269e887ea33SDavid du Colombier break;
270e887ea33SDavid du Colombier }
271e887ea33SDavid du Colombier if(l->complex >= r->complex) {
272e887ea33SDavid du Colombier regalloc(&nod, l, nn);
273e887ea33SDavid du Colombier cgen(l, &nod);
274e887ea33SDavid du Colombier regalloc(&nod1, r, Z);
275e887ea33SDavid du Colombier cgen(r, &nod1);
276e887ea33SDavid du Colombier gopcode(o, n->type, &nod1, &nod);
277e887ea33SDavid du Colombier } else {
278e887ea33SDavid du Colombier regalloc(&nod1, r, nn);
279e887ea33SDavid du Colombier cgen(r, &nod1);
280e887ea33SDavid du Colombier regalloc(&nod, l, Z);
281e887ea33SDavid du Colombier cgen(l, &nod);
282e887ea33SDavid du Colombier gopcode(o, n->type, &nod1, &nod);
283e887ea33SDavid du Colombier }
284e887ea33SDavid du Colombier gmove(&nod, nn);
285e887ea33SDavid du Colombier regfree(&nod);
286e887ea33SDavid du Colombier regfree(&nod1);
287e887ea33SDavid du Colombier break;
288e887ea33SDavid du Colombier
289e887ea33SDavid du Colombier case OLMOD:
290e887ea33SDavid du Colombier case OMOD:
291e887ea33SDavid du Colombier case OLMUL:
292e887ea33SDavid du Colombier case OLDIV:
293e887ea33SDavid du Colombier case OMUL:
294e887ea33SDavid du Colombier case ODIV:
295e887ea33SDavid du Colombier if(nn == Z) {
296e887ea33SDavid du Colombier nullwarn(l, r);
297e887ea33SDavid du Colombier break;
298e887ea33SDavid du Colombier }
299e887ea33SDavid du Colombier if(typefd[n->type->etype])
300e887ea33SDavid du Colombier goto fop;
301e887ea33SDavid du Colombier if(r->op == OCONST && typechl[n->type->etype]) { /* TO DO */
302e887ea33SDavid du Colombier SET(v);
303e887ea33SDavid du Colombier switch(o) {
304e887ea33SDavid du Colombier case ODIV:
305e887ea33SDavid du Colombier case OMOD:
306e887ea33SDavid du Colombier c = r->vconst;
307e887ea33SDavid du Colombier if(c < 0)
308e887ea33SDavid du Colombier c = -c;
309e887ea33SDavid du Colombier v = log2(c);
310e887ea33SDavid du Colombier if(v < 0)
311e887ea33SDavid du Colombier break;
312e887ea33SDavid du Colombier /* fall thru */
313e887ea33SDavid du Colombier case OMUL:
314e887ea33SDavid du Colombier case OLMUL:
315e887ea33SDavid du Colombier regalloc(&nod, l, nn);
316e887ea33SDavid du Colombier cgen(l, &nod);
317e887ea33SDavid du Colombier switch(o) {
318e887ea33SDavid du Colombier case OMUL:
319e887ea33SDavid du Colombier case OLMUL:
320e887ea33SDavid du Colombier mulgen(n->type, r, &nod);
321e887ea33SDavid du Colombier break;
322e887ea33SDavid du Colombier case ODIV:
323e887ea33SDavid du Colombier sdiv2(r->vconst, v, l, &nod);
324e887ea33SDavid du Colombier break;
325e887ea33SDavid du Colombier case OMOD:
326e887ea33SDavid du Colombier smod2(r->vconst, v, l, &nod);
327e887ea33SDavid du Colombier break;
328e887ea33SDavid du Colombier }
329e887ea33SDavid du Colombier gmove(&nod, nn);
330e887ea33SDavid du Colombier regfree(&nod);
331e887ea33SDavid du Colombier goto done;
332e887ea33SDavid du Colombier case OLDIV:
333e887ea33SDavid du Colombier c = r->vconst;
334e887ea33SDavid du Colombier if((c & 0x80000000) == 0)
335e887ea33SDavid du Colombier break;
336e887ea33SDavid du Colombier regalloc(&nod1, l, Z);
337e887ea33SDavid du Colombier cgen(l, &nod1);
338e887ea33SDavid du Colombier regalloc(&nod, l, nn);
339e887ea33SDavid du Colombier zeroregm(&nod);
340e887ea33SDavid du Colombier gins(ACMPL, &nod1, nodconst(c));
341e887ea33SDavid du Colombier gins(ASBBL, nodconst(-1), &nod);
342e887ea33SDavid du Colombier regfree(&nod1);
343e887ea33SDavid du Colombier gmove(&nod, nn);
344e887ea33SDavid du Colombier regfree(&nod);
345e887ea33SDavid du Colombier goto done;
346e887ea33SDavid du Colombier }
347e887ea33SDavid du Colombier }
348e887ea33SDavid du Colombier
349e887ea33SDavid du Colombier if(o == OMUL) {
350e887ea33SDavid du Colombier if(l->addable >= INDEXED) {
351e887ea33SDavid du Colombier t = l;
352e887ea33SDavid du Colombier l = r;
353e887ea33SDavid du Colombier r = t;
354e887ea33SDavid du Colombier }
355e887ea33SDavid du Colombier /* should favour AX */
356e887ea33SDavid du Colombier regalloc(&nod, l, nn);
357e887ea33SDavid du Colombier cgen(l, &nod);
358e887ea33SDavid du Colombier if(r->addable < INDEXED || hardconst(r)) {
359e887ea33SDavid du Colombier regalloc(&nod1, r, Z);
360e887ea33SDavid du Colombier cgen(r, &nod1);
361e887ea33SDavid du Colombier gopcode(OMUL, n->type, &nod1, &nod);
362e887ea33SDavid du Colombier regfree(&nod1);
363e887ea33SDavid du Colombier }else
364e887ea33SDavid du Colombier gopcode(OMUL, n->type, r, &nod); /* addressible */
365e887ea33SDavid du Colombier gmove(&nod, nn);
366e887ea33SDavid du Colombier regfree(&nod);
367e887ea33SDavid du Colombier break;
368e887ea33SDavid du Colombier }
369e887ea33SDavid du Colombier
370e887ea33SDavid du Colombier /*
371e887ea33SDavid du Colombier * get nod to be D_AX
372e887ea33SDavid du Colombier * get nod1 to be D_DX
373e887ea33SDavid du Colombier */
374e887ea33SDavid du Colombier if(nodreg(&nod, nn, D_AX)) {
375e887ea33SDavid du Colombier regsalloc(&nod2, n);
376e887ea33SDavid du Colombier gmove(&nod, &nod2);
377e887ea33SDavid du Colombier v = reg[D_AX];
378e887ea33SDavid du Colombier reg[D_AX] = 0;
379e887ea33SDavid du Colombier
380e887ea33SDavid du Colombier if(isreg(l, D_AX)) {
381e887ea33SDavid du Colombier nod3 = *n;
382e887ea33SDavid du Colombier nod3.left = &nod2;
383e887ea33SDavid du Colombier cgen(&nod3, nn);
384e887ea33SDavid du Colombier } else
385e887ea33SDavid du Colombier if(isreg(r, D_AX)) {
386e887ea33SDavid du Colombier nod3 = *n;
387e887ea33SDavid du Colombier nod3.right = &nod2;
388e887ea33SDavid du Colombier cgen(&nod3, nn);
389e887ea33SDavid du Colombier } else
390e887ea33SDavid du Colombier cgen(n, nn);
391e887ea33SDavid du Colombier
392e887ea33SDavid du Colombier gmove(&nod2, &nod);
393e887ea33SDavid du Colombier reg[D_AX] = v;
394e887ea33SDavid du Colombier break;
395e887ea33SDavid du Colombier }
396e887ea33SDavid du Colombier if(nodreg(&nod1, nn, D_DX)) {
397e887ea33SDavid du Colombier regsalloc(&nod2, n);
398e887ea33SDavid du Colombier gmove(&nod1, &nod2);
399e887ea33SDavid du Colombier v = reg[D_DX];
400e887ea33SDavid du Colombier reg[D_DX] = 0;
401e887ea33SDavid du Colombier
402e887ea33SDavid du Colombier if(isreg(l, D_DX)) {
403e887ea33SDavid du Colombier nod3 = *n;
404e887ea33SDavid du Colombier nod3.left = &nod2;
405e887ea33SDavid du Colombier cgen(&nod3, nn);
406e887ea33SDavid du Colombier } else
407e887ea33SDavid du Colombier if(isreg(r, D_DX)) {
408e887ea33SDavid du Colombier nod3 = *n;
409e887ea33SDavid du Colombier nod3.right = &nod2;
410e887ea33SDavid du Colombier cgen(&nod3, nn);
411e887ea33SDavid du Colombier } else
412e887ea33SDavid du Colombier cgen(n, nn);
413e887ea33SDavid du Colombier
414e887ea33SDavid du Colombier gmove(&nod2, &nod1);
415e887ea33SDavid du Colombier reg[D_DX] = v;
416e887ea33SDavid du Colombier break;
417e887ea33SDavid du Colombier }
418e887ea33SDavid du Colombier reg[D_AX]++;
419e887ea33SDavid du Colombier
420e887ea33SDavid du Colombier if(r->op == OCONST && (o == ODIV || o == OLDIV) && immconst(r) && typechl[r->type->etype]) {
421e887ea33SDavid du Colombier reg[D_DX]++;
422e887ea33SDavid du Colombier if(l->addable < INDEXED) {
423e887ea33SDavid du Colombier regalloc(&nod2, l, Z);
424e887ea33SDavid du Colombier cgen(l, &nod2);
425e887ea33SDavid du Colombier l = &nod2;
426e887ea33SDavid du Colombier }
427e887ea33SDavid du Colombier if(o == ODIV)
428e887ea33SDavid du Colombier sdivgen(l, r, &nod, &nod1);
429e887ea33SDavid du Colombier else
430e887ea33SDavid du Colombier udivgen(l, r, &nod, &nod1);
431e887ea33SDavid du Colombier gmove(&nod1, nn);
432e887ea33SDavid du Colombier if(l == &nod2)
433e887ea33SDavid du Colombier regfree(l);
434e887ea33SDavid du Colombier goto freeaxdx;
435e887ea33SDavid du Colombier }
436e887ea33SDavid du Colombier
437e887ea33SDavid du Colombier if(l->complex >= r->complex) {
438e887ea33SDavid du Colombier cgen(l, &nod);
439e887ea33SDavid du Colombier reg[D_DX]++;
440e887ea33SDavid du Colombier if(o == ODIV || o == OMOD)
441e887ea33SDavid du Colombier gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);
442e887ea33SDavid du Colombier if(o == OLDIV || o == OLMOD)
443e887ea33SDavid du Colombier zeroregm(&nod1);
444e887ea33SDavid du Colombier if(r->addable < INDEXED || r->op == OCONST) {
445e887ea33SDavid du Colombier regalloc(&nod3, r, Z);
446e887ea33SDavid du Colombier cgen(r, &nod3);
447e887ea33SDavid du Colombier gopcode(o, n->type, &nod3, Z);
448e887ea33SDavid du Colombier regfree(&nod3);
449e887ea33SDavid du Colombier } else
450e887ea33SDavid du Colombier gopcode(o, n->type, r, Z);
451e887ea33SDavid du Colombier } else {
452e887ea33SDavid du Colombier regsalloc(&nod3, r);
453e887ea33SDavid du Colombier cgen(r, &nod3);
454e887ea33SDavid du Colombier cgen(l, &nod);
455e887ea33SDavid du Colombier reg[D_DX]++;
456e887ea33SDavid du Colombier if(o == ODIV || o == OMOD)
457e887ea33SDavid du Colombier gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);
458e887ea33SDavid du Colombier if(o == OLDIV || o == OLMOD)
459e887ea33SDavid du Colombier zeroregm(&nod1);
460e887ea33SDavid du Colombier gopcode(o, n->type, &nod3, Z);
461e887ea33SDavid du Colombier }
462e887ea33SDavid du Colombier if(o == OMOD || o == OLMOD)
463e887ea33SDavid du Colombier gmove(&nod1, nn);
464e887ea33SDavid du Colombier else
465e887ea33SDavid du Colombier gmove(&nod, nn);
466e887ea33SDavid du Colombier freeaxdx:
467e887ea33SDavid du Colombier regfree(&nod);
468e887ea33SDavid du Colombier regfree(&nod1);
469e887ea33SDavid du Colombier break;
470e887ea33SDavid du Colombier
471e887ea33SDavid du Colombier case OASLSHR:
472e887ea33SDavid du Colombier case OASASHL:
473e887ea33SDavid du Colombier case OASASHR:
474e887ea33SDavid du Colombier if(r->op == OCONST)
475e887ea33SDavid du Colombier goto asand;
476e887ea33SDavid du Colombier if(l->op == OBIT)
477e887ea33SDavid du Colombier goto asbitop;
478e887ea33SDavid du Colombier if(typefd[n->type->etype])
479e887ea33SDavid du Colombier goto asand; /* can this happen? */
480e887ea33SDavid du Colombier
481e887ea33SDavid du Colombier /*
482e887ea33SDavid du Colombier * get nod to be D_CX
483e887ea33SDavid du Colombier */
484e887ea33SDavid du Colombier if(nodreg(&nod, nn, D_CX)) {
485e887ea33SDavid du Colombier regsalloc(&nod1, n);
486e887ea33SDavid du Colombier gmove(&nod, &nod1);
487e887ea33SDavid du Colombier cgen(n, &nod);
488e887ea33SDavid du Colombier if(nn != Z)
489e887ea33SDavid du Colombier gmove(&nod, nn);
490e887ea33SDavid du Colombier gmove(&nod1, &nod);
491e887ea33SDavid du Colombier break;
492e887ea33SDavid du Colombier }
493e887ea33SDavid du Colombier reg[D_CX]++;
494e887ea33SDavid du Colombier
495e887ea33SDavid du Colombier if(r->complex >= l->complex) {
496e887ea33SDavid du Colombier cgen(r, &nod);
497e887ea33SDavid du Colombier if(hardleft)
498e887ea33SDavid du Colombier reglcgen(&nod1, l, Z);
499e887ea33SDavid du Colombier else
500e887ea33SDavid du Colombier nod1 = *l;
501e887ea33SDavid du Colombier } else {
502e887ea33SDavid du Colombier if(hardleft)
503e887ea33SDavid du Colombier reglcgen(&nod1, l, Z);
504e887ea33SDavid du Colombier else
505e887ea33SDavid du Colombier nod1 = *l;
506e887ea33SDavid du Colombier cgen(r, &nod);
507e887ea33SDavid du Colombier }
508e887ea33SDavid du Colombier
509e887ea33SDavid du Colombier gopcode(o, l->type, &nod, &nod1);
510e887ea33SDavid du Colombier regfree(&nod);
511e887ea33SDavid du Colombier if(nn != Z)
512e887ea33SDavid du Colombier gmove(&nod1, nn);
513e887ea33SDavid du Colombier if(hardleft)
514e887ea33SDavid du Colombier regfree(&nod1);
515e887ea33SDavid du Colombier break;
516e887ea33SDavid du Colombier
517e887ea33SDavid du Colombier case OASAND:
518e887ea33SDavid du Colombier case OASADD:
519e887ea33SDavid du Colombier case OASSUB:
520e887ea33SDavid du Colombier case OASXOR:
521e887ea33SDavid du Colombier case OASOR:
522e887ea33SDavid du Colombier asand:
523e887ea33SDavid du Colombier if(l->op == OBIT)
524e887ea33SDavid du Colombier goto asbitop;
525e887ea33SDavid du Colombier if(typefd[l->type->etype] || typefd[r->type->etype])
526e887ea33SDavid du Colombier goto asfop;
527*1936bb65SDavid du Colombier if(o == OASAND)
528*1936bb65SDavid du Colombier checkmask(n, r);
529e887ea33SDavid du Colombier if(l->complex >= r->complex) {
530e887ea33SDavid du Colombier if(hardleft)
531e887ea33SDavid du Colombier reglcgen(&nod, l, Z);
532e887ea33SDavid du Colombier else
533e887ea33SDavid du Colombier nod = *l;
534e887ea33SDavid du Colombier if(!immconst(r)) {
535e887ea33SDavid du Colombier regalloc(&nod1, r, nn);
536e887ea33SDavid du Colombier cgen(r, &nod1);
537e887ea33SDavid du Colombier gopcode(o, l->type, &nod1, &nod);
538e887ea33SDavid du Colombier regfree(&nod1);
539e887ea33SDavid du Colombier } else
540e887ea33SDavid du Colombier gopcode(o, l->type, r, &nod);
541e887ea33SDavid du Colombier } else {
542e887ea33SDavid du Colombier regalloc(&nod1, r, nn);
543e887ea33SDavid du Colombier cgen(r, &nod1);
544e887ea33SDavid du Colombier if(hardleft)
545e887ea33SDavid du Colombier reglcgen(&nod, l, Z);
546e887ea33SDavid du Colombier else
547e887ea33SDavid du Colombier nod = *l;
548e887ea33SDavid du Colombier gopcode(o, l->type, &nod1, &nod);
549e887ea33SDavid du Colombier regfree(&nod1);
550e887ea33SDavid du Colombier }
551e887ea33SDavid du Colombier if(nn != Z)
552e887ea33SDavid du Colombier gmove(&nod, nn);
553e887ea33SDavid du Colombier if(hardleft)
554e887ea33SDavid du Colombier regfree(&nod);
555e887ea33SDavid du Colombier break;
556e887ea33SDavid du Colombier
557e887ea33SDavid du Colombier asfop:
558e887ea33SDavid du Colombier if(l->complex >= r->complex) {
559e887ea33SDavid du Colombier if(hardleft)
560e887ea33SDavid du Colombier reglcgen(&nod, l, Z);
561e887ea33SDavid du Colombier else
562e887ea33SDavid du Colombier nod = *l;
563e887ea33SDavid du Colombier if(r->addable < INDEXED){
564e887ea33SDavid du Colombier regalloc(&nod1, r, nn);
565e887ea33SDavid du Colombier cgen(r, &nod1);
566e887ea33SDavid du Colombier }else
567e887ea33SDavid du Colombier nod1 = *r;
568e887ea33SDavid du Colombier regalloc(&nod2, r, Z);
569e887ea33SDavid du Colombier gmove(&nod, &nod2);
570e887ea33SDavid du Colombier gopcode(o, r->type, &nod1, &nod2);
571e887ea33SDavid du Colombier gmove(&nod2, &nod);
572e887ea33SDavid du Colombier regfree(&nod2);
573e887ea33SDavid du Colombier if(r->addable < INDEXED)
574e887ea33SDavid du Colombier regfree(&nod1);
575e887ea33SDavid du Colombier } else {
576e887ea33SDavid du Colombier regalloc(&nod1, r, nn);
577e887ea33SDavid du Colombier cgen(r, &nod1);
578e887ea33SDavid du Colombier if(hardleft)
579e887ea33SDavid du Colombier reglcgen(&nod, l, Z);
580e887ea33SDavid du Colombier else
581e887ea33SDavid du Colombier nod = *l;
5822e8f027cSDavid du Colombier if(o != OASMUL && o != OASADD || !typefd[l->type->etype]) {
583e887ea33SDavid du Colombier regalloc(&nod2, r, Z);
584e887ea33SDavid du Colombier gmove(&nod, &nod2);
585e887ea33SDavid du Colombier gopcode(o, r->type, &nod1, &nod2);
586e887ea33SDavid du Colombier regfree(&nod1);
587e887ea33SDavid du Colombier gmove(&nod2, &nod);
588e887ea33SDavid du Colombier regfree(&nod2);
589e887ea33SDavid du Colombier } else {
590e887ea33SDavid du Colombier gopcode(o, r->type, &nod, &nod1);
591e887ea33SDavid du Colombier gmove(&nod1, &nod);
592e887ea33SDavid du Colombier regfree(&nod1);
593e887ea33SDavid du Colombier }
594e887ea33SDavid du Colombier }
595e887ea33SDavid du Colombier if(nn != Z)
596e887ea33SDavid du Colombier gmove(&nod, nn);
597e887ea33SDavid du Colombier if(hardleft)
598e887ea33SDavid du Colombier regfree(&nod);
599e887ea33SDavid du Colombier break;
600e887ea33SDavid du Colombier
601e887ea33SDavid du Colombier case OASLMUL:
602e887ea33SDavid du Colombier case OASLDIV:
603e887ea33SDavid du Colombier case OASLMOD:
604e887ea33SDavid du Colombier case OASMUL:
605e887ea33SDavid du Colombier case OASDIV:
606e887ea33SDavid du Colombier case OASMOD:
607e887ea33SDavid du Colombier if(l->op == OBIT)
608e887ea33SDavid du Colombier goto asbitop;
609e887ea33SDavid du Colombier if(typefd[n->type->etype] || typefd[r->type->etype])
610e887ea33SDavid du Colombier goto asfop;
611e887ea33SDavid du Colombier if(r->op == OCONST && typechl[n->type->etype]) {
612e887ea33SDavid du Colombier SET(v);
613e887ea33SDavid du Colombier switch(o) {
614e887ea33SDavid du Colombier case OASDIV:
615e887ea33SDavid du Colombier case OASMOD:
616e887ea33SDavid du Colombier c = r->vconst;
617e887ea33SDavid du Colombier if(c < 0)
618e887ea33SDavid du Colombier c = -c;
619e887ea33SDavid du Colombier v = log2(c);
620e887ea33SDavid du Colombier if(v < 0)
621e887ea33SDavid du Colombier break;
622e887ea33SDavid du Colombier /* fall thru */
623e887ea33SDavid du Colombier case OASMUL:
624e887ea33SDavid du Colombier case OASLMUL:
625e887ea33SDavid du Colombier if(hardleft)
626e887ea33SDavid du Colombier reglcgen(&nod2, l, Z);
627e887ea33SDavid du Colombier else
628e887ea33SDavid du Colombier nod2 = *l;
629e887ea33SDavid du Colombier regalloc(&nod, l, nn);
630e887ea33SDavid du Colombier cgen(&nod2, &nod);
631e887ea33SDavid du Colombier switch(o) {
632e887ea33SDavid du Colombier case OASMUL:
633e887ea33SDavid du Colombier case OASLMUL:
634e887ea33SDavid du Colombier mulgen(n->type, r, &nod);
635e887ea33SDavid du Colombier break;
636e887ea33SDavid du Colombier case OASDIV:
637e887ea33SDavid du Colombier sdiv2(r->vconst, v, l, &nod);
638e887ea33SDavid du Colombier break;
639e887ea33SDavid du Colombier case OASMOD:
640e887ea33SDavid du Colombier smod2(r->vconst, v, l, &nod);
641e887ea33SDavid du Colombier break;
642e887ea33SDavid du Colombier }
643e887ea33SDavid du Colombier havev:
644e887ea33SDavid du Colombier gmove(&nod, &nod2);
645e887ea33SDavid du Colombier if(nn != Z)
646e887ea33SDavid du Colombier gmove(&nod, nn);
647e887ea33SDavid du Colombier if(hardleft)
648e887ea33SDavid du Colombier regfree(&nod2);
649e887ea33SDavid du Colombier regfree(&nod);
650e887ea33SDavid du Colombier goto done;
651e887ea33SDavid du Colombier case OASLDIV:
652e887ea33SDavid du Colombier c = r->vconst;
653e887ea33SDavid du Colombier if((c & 0x80000000) == 0)
654e887ea33SDavid du Colombier break;
655e887ea33SDavid du Colombier if(hardleft)
656e887ea33SDavid du Colombier reglcgen(&nod2, l, Z);
657e887ea33SDavid du Colombier else
658e887ea33SDavid du Colombier nod2 = *l;
659e887ea33SDavid du Colombier regalloc(&nod1, l, nn);
660e887ea33SDavid du Colombier cgen(&nod2, &nod1);
661e887ea33SDavid du Colombier regalloc(&nod, l, nn);
662e887ea33SDavid du Colombier zeroregm(&nod);
663e887ea33SDavid du Colombier gins(ACMPL, &nod1, nodconst(c));
664e887ea33SDavid du Colombier gins(ASBBL, nodconst(-1), &nod);
665e887ea33SDavid du Colombier regfree(&nod1);
666e887ea33SDavid du Colombier goto havev;
667e887ea33SDavid du Colombier }
668e887ea33SDavid du Colombier }
669e887ea33SDavid du Colombier
670e887ea33SDavid du Colombier if(o == OASMUL) {
671e887ea33SDavid du Colombier /* should favour AX */
672e887ea33SDavid du Colombier regalloc(&nod, l, nn);
673e887ea33SDavid du Colombier if(r->complex >= FNX) {
674e887ea33SDavid du Colombier regalloc(&nod1, r, Z);
675e887ea33SDavid du Colombier cgen(r, &nod1);
676e887ea33SDavid du Colombier r = &nod1;
677e887ea33SDavid du Colombier }
678e887ea33SDavid du Colombier if(hardleft)
679e887ea33SDavid du Colombier reglcgen(&nod2, l, Z);
680e887ea33SDavid du Colombier else
681e887ea33SDavid du Colombier nod2 = *l;
682e887ea33SDavid du Colombier cgen(&nod2, &nod);
683e887ea33SDavid du Colombier if(r->addable < INDEXED || hardconst(r)) {
684e887ea33SDavid du Colombier if(r->complex < FNX) {
685e887ea33SDavid du Colombier regalloc(&nod1, r, Z);
686e887ea33SDavid du Colombier cgen(r, &nod1);
687e887ea33SDavid du Colombier }
688e887ea33SDavid du Colombier gopcode(OASMUL, n->type, &nod1, &nod);
689e887ea33SDavid du Colombier regfree(&nod1);
690e887ea33SDavid du Colombier }
691e887ea33SDavid du Colombier else
692e887ea33SDavid du Colombier gopcode(OASMUL, n->type, r, &nod);
693e887ea33SDavid du Colombier if(r == &nod1)
694e887ea33SDavid du Colombier regfree(r);
695e887ea33SDavid du Colombier gmove(&nod, &nod2);
696e887ea33SDavid du Colombier if(nn != Z)
697e887ea33SDavid du Colombier gmove(&nod, nn);
698e887ea33SDavid du Colombier regfree(&nod);
699e887ea33SDavid du Colombier if(hardleft)
700e887ea33SDavid du Colombier regfree(&nod2);
701e887ea33SDavid du Colombier break;
702e887ea33SDavid du Colombier }
703e887ea33SDavid du Colombier
704e887ea33SDavid du Colombier /*
705e887ea33SDavid du Colombier * get nod to be D_AX
706e887ea33SDavid du Colombier * get nod1 to be D_DX
707e887ea33SDavid du Colombier */
708e887ea33SDavid du Colombier if(nodreg(&nod, nn, D_AX)) {
709e887ea33SDavid du Colombier regsalloc(&nod2, n);
710e887ea33SDavid du Colombier gmove(&nod, &nod2);
711e887ea33SDavid du Colombier v = reg[D_AX];
712e887ea33SDavid du Colombier reg[D_AX] = 0;
713e887ea33SDavid du Colombier
714e887ea33SDavid du Colombier if(isreg(l, D_AX)) {
715e887ea33SDavid du Colombier nod3 = *n;
716e887ea33SDavid du Colombier nod3.left = &nod2;
717e887ea33SDavid du Colombier cgen(&nod3, nn);
718e887ea33SDavid du Colombier } else
719e887ea33SDavid du Colombier if(isreg(r, D_AX)) {
720e887ea33SDavid du Colombier nod3 = *n;
721e887ea33SDavid du Colombier nod3.right = &nod2;
722e887ea33SDavid du Colombier cgen(&nod3, nn);
723e887ea33SDavid du Colombier } else
724e887ea33SDavid du Colombier cgen(n, nn);
725e887ea33SDavid du Colombier
726e887ea33SDavid du Colombier gmove(&nod2, &nod);
727e887ea33SDavid du Colombier reg[D_AX] = v;
728e887ea33SDavid du Colombier break;
729e887ea33SDavid du Colombier }
730e887ea33SDavid du Colombier if(nodreg(&nod1, nn, D_DX)) {
731e887ea33SDavid du Colombier regsalloc(&nod2, n);
732e887ea33SDavid du Colombier gmove(&nod1, &nod2);
733e887ea33SDavid du Colombier v = reg[D_DX];
734e887ea33SDavid du Colombier reg[D_DX] = 0;
735e887ea33SDavid du Colombier
736e887ea33SDavid du Colombier if(isreg(l, D_DX)) {
737e887ea33SDavid du Colombier nod3 = *n;
738e887ea33SDavid du Colombier nod3.left = &nod2;
739e887ea33SDavid du Colombier cgen(&nod3, nn);
740e887ea33SDavid du Colombier } else
741e887ea33SDavid du Colombier if(isreg(r, D_DX)) {
742e887ea33SDavid du Colombier nod3 = *n;
743e887ea33SDavid du Colombier nod3.right = &nod2;
744e887ea33SDavid du Colombier cgen(&nod3, nn);
745e887ea33SDavid du Colombier } else
746e887ea33SDavid du Colombier cgen(n, nn);
747e887ea33SDavid du Colombier
748e887ea33SDavid du Colombier gmove(&nod2, &nod1);
749e887ea33SDavid du Colombier reg[D_DX] = v;
750e887ea33SDavid du Colombier break;
751e887ea33SDavid du Colombier }
752e887ea33SDavid du Colombier reg[D_AX]++;
753e887ea33SDavid du Colombier reg[D_DX]++;
754e887ea33SDavid du Colombier
755e887ea33SDavid du Colombier if(l->complex >= r->complex) {
756e887ea33SDavid du Colombier if(hardleft)
757e887ea33SDavid du Colombier reglcgen(&nod2, l, Z);
758e887ea33SDavid du Colombier else
759e887ea33SDavid du Colombier nod2 = *l;
760e887ea33SDavid du Colombier cgen(&nod2, &nod);
761e887ea33SDavid du Colombier if(r->op == OCONST && typechl[r->type->etype]) {
762e887ea33SDavid du Colombier switch(o) {
763e887ea33SDavid du Colombier case OASDIV:
764e887ea33SDavid du Colombier sdivgen(&nod2, r, &nod, &nod1);
765e887ea33SDavid du Colombier goto divdone;
766e887ea33SDavid du Colombier case OASLDIV:
767e887ea33SDavid du Colombier udivgen(&nod2, r, &nod, &nod1);
768e887ea33SDavid du Colombier divdone:
769e887ea33SDavid du Colombier gmove(&nod1, &nod2);
770e887ea33SDavid du Colombier if(nn != Z)
771e887ea33SDavid du Colombier gmove(&nod1, nn);
772e887ea33SDavid du Colombier goto freelxaxdx;
773e887ea33SDavid du Colombier }
774e887ea33SDavid du Colombier }
775e887ea33SDavid du Colombier if(o == OASDIV || o == OASMOD)
776e887ea33SDavid du Colombier gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);
777e887ea33SDavid du Colombier if(o == OASLDIV || o == OASLMOD)
778e887ea33SDavid du Colombier zeroregm(&nod1);
779e887ea33SDavid du Colombier if(r->addable < INDEXED || r->op == OCONST ||
780e887ea33SDavid du Colombier !typeil[r->type->etype]) {
781e887ea33SDavid du Colombier regalloc(&nod3, r, Z);
782e887ea33SDavid du Colombier cgen(r, &nod3);
783e887ea33SDavid du Colombier gopcode(o, l->type, &nod3, Z);
784e887ea33SDavid du Colombier regfree(&nod3);
785e887ea33SDavid du Colombier } else
786e887ea33SDavid du Colombier gopcode(o, n->type, r, Z);
787e887ea33SDavid du Colombier } else {
788e887ea33SDavid du Colombier regalloc(&nod3, r, Z);
789e887ea33SDavid du Colombier cgen(r, &nod3);
790e887ea33SDavid du Colombier if(hardleft)
791e887ea33SDavid du Colombier reglcgen(&nod2, l, Z);
792e887ea33SDavid du Colombier else
793e887ea33SDavid du Colombier nod2 = *l;
794e887ea33SDavid du Colombier cgen(&nod2, &nod);
795e887ea33SDavid du Colombier if(o == OASDIV || o == OASMOD)
796e887ea33SDavid du Colombier gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);
797e887ea33SDavid du Colombier if(o == OASLDIV || o == OASLMOD)
798e887ea33SDavid du Colombier zeroregm(&nod1);
799e887ea33SDavid du Colombier gopcode(o, l->type, &nod3, Z);
800e887ea33SDavid du Colombier regfree(&nod3);
801e887ea33SDavid du Colombier }
802e887ea33SDavid du Colombier if(o == OASMOD || o == OASLMOD) {
803e887ea33SDavid du Colombier gmove(&nod1, &nod2);
804e887ea33SDavid du Colombier if(nn != Z)
805e887ea33SDavid du Colombier gmove(&nod1, nn);
806e887ea33SDavid du Colombier } else {
807e887ea33SDavid du Colombier gmove(&nod, &nod2);
808e887ea33SDavid du Colombier if(nn != Z)
809e887ea33SDavid du Colombier gmove(&nod, nn);
810e887ea33SDavid du Colombier }
811e887ea33SDavid du Colombier freelxaxdx:
812e887ea33SDavid du Colombier if(hardleft)
813e887ea33SDavid du Colombier regfree(&nod2);
814e887ea33SDavid du Colombier regfree(&nod);
815e887ea33SDavid du Colombier regfree(&nod1);
816e887ea33SDavid du Colombier break;
817e887ea33SDavid du Colombier
818e887ea33SDavid du Colombier fop:
819e887ea33SDavid du Colombier if(l->complex >= r->complex) {
820e887ea33SDavid du Colombier regalloc(&nod, l, nn);
821e887ea33SDavid du Colombier cgen(l, &nod);
822e887ea33SDavid du Colombier if(r->addable < INDEXED) {
823e887ea33SDavid du Colombier regalloc(&nod1, r, Z);
824e887ea33SDavid du Colombier cgen(r, &nod1);
825e887ea33SDavid du Colombier gopcode(o, n->type, &nod1, &nod);
826e887ea33SDavid du Colombier regfree(&nod1);
827e887ea33SDavid du Colombier } else
828e887ea33SDavid du Colombier gopcode(o, n->type, r, &nod);
829e887ea33SDavid du Colombier } else {
830e887ea33SDavid du Colombier /* TO DO: could do better with r->addable >= INDEXED */
831e887ea33SDavid du Colombier regalloc(&nod1, r, Z);
832e887ea33SDavid du Colombier cgen(r, &nod1);
833e887ea33SDavid du Colombier regalloc(&nod, l, nn);
834e887ea33SDavid du Colombier cgen(l, &nod);
835e887ea33SDavid du Colombier gopcode(o, n->type, &nod1, &nod);
836e887ea33SDavid du Colombier regfree(&nod1);
837e887ea33SDavid du Colombier }
838e887ea33SDavid du Colombier gmove(&nod, nn);
839e887ea33SDavid du Colombier regfree(&nod);
840e887ea33SDavid du Colombier break;
841e887ea33SDavid du Colombier
842e887ea33SDavid du Colombier asbitop:
843e887ea33SDavid du Colombier regalloc(&nod4, n, nn);
844e887ea33SDavid du Colombier if(l->complex >= r->complex) {
845e887ea33SDavid du Colombier bitload(l, &nod, &nod1, &nod2, &nod4);
846e887ea33SDavid du Colombier regalloc(&nod3, r, Z);
847e887ea33SDavid du Colombier cgen(r, &nod3);
848e887ea33SDavid du Colombier } else {
849e887ea33SDavid du Colombier regalloc(&nod3, r, Z);
850e887ea33SDavid du Colombier cgen(r, &nod3);
851e887ea33SDavid du Colombier bitload(l, &nod, &nod1, &nod2, &nod4);
852e887ea33SDavid du Colombier }
853e887ea33SDavid du Colombier gmove(&nod, &nod4);
854e887ea33SDavid du Colombier
855e887ea33SDavid du Colombier { /* TO DO: check floating point source */
856e887ea33SDavid du Colombier Node onod;
857e887ea33SDavid du Colombier
858e887ea33SDavid du Colombier /* incredible grot ... */
859e887ea33SDavid du Colombier onod = nod3;
860e887ea33SDavid du Colombier onod.op = o;
861e887ea33SDavid du Colombier onod.complex = 2;
862e887ea33SDavid du Colombier onod.addable = 0;
863e887ea33SDavid du Colombier onod.type = tfield;
864e887ea33SDavid du Colombier onod.left = &nod4;
865e887ea33SDavid du Colombier onod.right = &nod3;
866e887ea33SDavid du Colombier cgen(&onod, Z);
867e887ea33SDavid du Colombier }
868e887ea33SDavid du Colombier regfree(&nod3);
869e887ea33SDavid du Colombier gmove(&nod4, &nod);
870e887ea33SDavid du Colombier regfree(&nod4);
871e887ea33SDavid du Colombier bitstore(l, &nod, &nod1, &nod2, nn);
872e887ea33SDavid du Colombier break;
873e887ea33SDavid du Colombier
874e887ea33SDavid du Colombier case OADDR:
875e887ea33SDavid du Colombier if(nn == Z) {
876e887ea33SDavid du Colombier nullwarn(l, Z);
877e887ea33SDavid du Colombier break;
878e887ea33SDavid du Colombier }
879e887ea33SDavid du Colombier lcgen(l, nn);
880e887ea33SDavid du Colombier break;
881e887ea33SDavid du Colombier
882e887ea33SDavid du Colombier case OFUNC:
883e887ea33SDavid du Colombier if(l->complex >= FNX) {
884e887ea33SDavid du Colombier if(l->op != OIND)
885e887ea33SDavid du Colombier diag(n, "bad function call");
886e887ea33SDavid du Colombier
887e887ea33SDavid du Colombier regret(&nod, l->left);
888e887ea33SDavid du Colombier cgen(l->left, &nod);
889e887ea33SDavid du Colombier regsalloc(&nod1, l->left);
890e887ea33SDavid du Colombier gmove(&nod, &nod1);
891e887ea33SDavid du Colombier regfree(&nod);
892e887ea33SDavid du Colombier
893e887ea33SDavid du Colombier nod = *n;
894e887ea33SDavid du Colombier nod.left = &nod2;
895e887ea33SDavid du Colombier nod2 = *l;
896e887ea33SDavid du Colombier nod2.left = &nod1;
897e887ea33SDavid du Colombier nod2.complex = 1;
898e887ea33SDavid du Colombier cgen(&nod, nn);
899e887ea33SDavid du Colombier
900e887ea33SDavid du Colombier return;
901e887ea33SDavid du Colombier }
902e887ea33SDavid du Colombier o = reg[REGARG];
903e887ea33SDavid du Colombier gargs(r, &nod, &nod1);
904e887ea33SDavid du Colombier if(l->addable < INDEXED) {
905e887ea33SDavid du Colombier reglcgen(&nod, l, nn);
906e887ea33SDavid du Colombier nod.op = OREGISTER;
907e887ea33SDavid du Colombier gopcode(OFUNC, n->type, Z, &nod);
908e887ea33SDavid du Colombier regfree(&nod);
909e887ea33SDavid du Colombier } else
910e887ea33SDavid du Colombier gopcode(OFUNC, n->type, Z, l);
911e887ea33SDavid du Colombier if(REGARG)
912e887ea33SDavid du Colombier if(o != reg[REGARG])
913e887ea33SDavid du Colombier reg[REGARG]--;
914e887ea33SDavid du Colombier if(nn != Z) {
915e887ea33SDavid du Colombier regret(&nod, n);
916e887ea33SDavid du Colombier gmove(&nod, nn);
917e887ea33SDavid du Colombier regfree(&nod);
918e887ea33SDavid du Colombier }
919e887ea33SDavid du Colombier break;
920e887ea33SDavid du Colombier
921e887ea33SDavid du Colombier case OIND:
922e887ea33SDavid du Colombier if(nn == Z) {
923e887ea33SDavid du Colombier nullwarn(l, Z);
924e887ea33SDavid du Colombier break;
925e887ea33SDavid du Colombier }
926e887ea33SDavid du Colombier regialloc(&nod, n, nn);
927e887ea33SDavid du Colombier r = l;
928e887ea33SDavid du Colombier while(r->op == OADD)
929e887ea33SDavid du Colombier r = r->right;
930e887ea33SDavid du Colombier if(sconst(r)) {
931e887ea33SDavid du Colombier v = r->vconst;
932e887ea33SDavid du Colombier r->vconst = 0;
933e887ea33SDavid du Colombier cgen(l, &nod);
934e887ea33SDavid du Colombier nod.xoffset += v;
935e887ea33SDavid du Colombier r->vconst = v;
936e887ea33SDavid du Colombier } else
937e887ea33SDavid du Colombier cgen(l, &nod);
938e887ea33SDavid du Colombier regind(&nod, n);
939e887ea33SDavid du Colombier gmove(&nod, nn);
940e887ea33SDavid du Colombier regfree(&nod);
941e887ea33SDavid du Colombier break;
942e887ea33SDavid du Colombier
943e887ea33SDavid du Colombier case OEQ:
944e887ea33SDavid du Colombier case ONE:
945e887ea33SDavid du Colombier case OLE:
946e887ea33SDavid du Colombier case OLT:
947e887ea33SDavid du Colombier case OGE:
948e887ea33SDavid du Colombier case OGT:
949e887ea33SDavid du Colombier case OLO:
950e887ea33SDavid du Colombier case OLS:
951e887ea33SDavid du Colombier case OHI:
952e887ea33SDavid du Colombier case OHS:
953e887ea33SDavid du Colombier if(nn == Z) {
954e887ea33SDavid du Colombier nullwarn(l, r);
955e887ea33SDavid du Colombier break;
956e887ea33SDavid du Colombier }
957e887ea33SDavid du Colombier boolgen(n, 1, nn);
958e887ea33SDavid du Colombier break;
959e887ea33SDavid du Colombier
960e887ea33SDavid du Colombier case OANDAND:
961e887ea33SDavid du Colombier case OOROR:
962e887ea33SDavid du Colombier boolgen(n, 1, nn);
963e887ea33SDavid du Colombier if(nn == Z)
964e887ea33SDavid du Colombier patch(p, pc);
965e887ea33SDavid du Colombier break;
966e887ea33SDavid du Colombier
967e887ea33SDavid du Colombier case ONOT:
968e887ea33SDavid du Colombier if(nn == Z) {
969e887ea33SDavid du Colombier nullwarn(l, Z);
970e887ea33SDavid du Colombier break;
971e887ea33SDavid du Colombier }
972e887ea33SDavid du Colombier boolgen(n, 1, nn);
973e887ea33SDavid du Colombier break;
974e887ea33SDavid du Colombier
975e887ea33SDavid du Colombier case OCOMMA:
976e887ea33SDavid du Colombier cgen(l, Z);
977e887ea33SDavid du Colombier cgen(r, nn);
978e887ea33SDavid du Colombier break;
979e887ea33SDavid du Colombier
980e887ea33SDavid du Colombier case OCAST:
981e887ea33SDavid du Colombier if(nn == Z) {
982e887ea33SDavid du Colombier nullwarn(l, Z);
983e887ea33SDavid du Colombier break;
984e887ea33SDavid du Colombier }
985e887ea33SDavid du Colombier /*
986e887ea33SDavid du Colombier * convert from types l->n->nn
987e887ea33SDavid du Colombier */
988e887ea33SDavid du Colombier if(nocast(l->type, n->type) && nocast(n->type, nn->type)) {
989e887ea33SDavid du Colombier /* both null, gen l->nn */
990e887ea33SDavid du Colombier cgen(l, nn);
991e887ea33SDavid du Colombier break;
992e887ea33SDavid du Colombier }
993e887ea33SDavid du Colombier if(ewidth[n->type->etype] < ewidth[l->type->etype]){
994e887ea33SDavid du Colombier if(l->type->etype == TIND && typechlp[n->type->etype])
995e887ea33SDavid du Colombier warn(n, "conversion of pointer to shorter integer");
996e887ea33SDavid du Colombier }else if(0){
997e887ea33SDavid du Colombier if(nocast(n->type, nn->type) || castup(n->type, nn->type)){
998e887ea33SDavid du Colombier if(typefd[l->type->etype] != typefd[nn->type->etype])
999e887ea33SDavid du Colombier regalloc(&nod, l, nn);
1000e887ea33SDavid du Colombier else
1001e887ea33SDavid du Colombier regalloc(&nod, nn, nn);
1002e887ea33SDavid du Colombier cgen(l, &nod);
1003e887ea33SDavid du Colombier gmove(&nod, nn);
1004e887ea33SDavid du Colombier regfree(&nod);
1005e887ea33SDavid du Colombier break;
1006e887ea33SDavid du Colombier }
1007e887ea33SDavid du Colombier }
1008e887ea33SDavid du Colombier regalloc(&nod, l, nn);
1009e887ea33SDavid du Colombier cgen(l, &nod);
1010e887ea33SDavid du Colombier regalloc(&nod1, n, &nod);
1011e887ea33SDavid du Colombier gmove(&nod, &nod1);
1012e887ea33SDavid du Colombier gmove(&nod1, nn);
1013e887ea33SDavid du Colombier regfree(&nod1);
1014e887ea33SDavid du Colombier regfree(&nod);
1015e887ea33SDavid du Colombier break;
1016e887ea33SDavid du Colombier
1017e887ea33SDavid du Colombier case ODOT:
1018e887ea33SDavid du Colombier sugen(l, nodrat, l->type->width);
1019e887ea33SDavid du Colombier if(nn == Z)
1020e887ea33SDavid du Colombier break;
1021e887ea33SDavid du Colombier warn(n, "non-interruptable temporary");
1022e887ea33SDavid du Colombier nod = *nodrat;
1023e887ea33SDavid du Colombier if(!r || r->op != OCONST) {
1024e887ea33SDavid du Colombier diag(n, "DOT and no offset");
1025e887ea33SDavid du Colombier break;
1026e887ea33SDavid du Colombier }
1027e887ea33SDavid du Colombier nod.xoffset += (long)r->vconst;
1028e887ea33SDavid du Colombier nod.type = n->type;
1029e887ea33SDavid du Colombier cgen(&nod, nn);
1030e887ea33SDavid du Colombier break;
1031e887ea33SDavid du Colombier
1032e887ea33SDavid du Colombier case OCOND:
1033e887ea33SDavid du Colombier bcgen(l, 1);
1034e887ea33SDavid du Colombier p1 = p;
1035e887ea33SDavid du Colombier cgen(r->left, nn);
1036e887ea33SDavid du Colombier gbranch(OGOTO);
1037e887ea33SDavid du Colombier patch(p1, pc);
1038e887ea33SDavid du Colombier p1 = p;
1039e887ea33SDavid du Colombier cgen(r->right, nn);
1040e887ea33SDavid du Colombier patch(p1, pc);
1041e887ea33SDavid du Colombier break;
1042e887ea33SDavid du Colombier
1043e887ea33SDavid du Colombier case OPOSTINC:
1044e887ea33SDavid du Colombier case OPOSTDEC:
1045e887ea33SDavid du Colombier v = 1;
1046e887ea33SDavid du Colombier if(l->type->etype == TIND)
1047e887ea33SDavid du Colombier v = l->type->link->width;
1048e887ea33SDavid du Colombier if(o == OPOSTDEC)
1049e887ea33SDavid du Colombier v = -v;
1050e887ea33SDavid du Colombier if(l->op == OBIT)
1051e887ea33SDavid du Colombier goto bitinc;
1052e887ea33SDavid du Colombier if(nn == Z)
1053e887ea33SDavid du Colombier goto pre;
1054e887ea33SDavid du Colombier
1055e887ea33SDavid du Colombier if(hardleft)
1056e887ea33SDavid du Colombier reglcgen(&nod, l, Z);
1057e887ea33SDavid du Colombier else
1058e887ea33SDavid du Colombier nod = *l;
1059e887ea33SDavid du Colombier
1060e887ea33SDavid du Colombier gmove(&nod, nn);
1061e887ea33SDavid du Colombier if(typefd[n->type->etype]) {
1062e887ea33SDavid du Colombier regalloc(&nod1, l, Z);
1063e887ea33SDavid du Colombier gmove(&nod, &nod1);
1064e887ea33SDavid du Colombier if(v < 0)
1065e887ea33SDavid du Colombier gopcode(OSUB, n->type, nodfconst(-v), &nod1);
1066e887ea33SDavid du Colombier else
1067e887ea33SDavid du Colombier gopcode(OADD, n->type, nodfconst(v), &nod1);
1068e887ea33SDavid du Colombier gmove(&nod1, &nod);
1069e887ea33SDavid du Colombier regfree(&nod1);
1070e887ea33SDavid du Colombier } else
1071e887ea33SDavid du Colombier gopcode(OADD, n->type, nodconst(v), &nod);
1072e887ea33SDavid du Colombier if(hardleft)
1073e887ea33SDavid du Colombier regfree(&nod);
1074e887ea33SDavid du Colombier break;
1075e887ea33SDavid du Colombier
1076e887ea33SDavid du Colombier case OPREINC:
1077e887ea33SDavid du Colombier case OPREDEC:
1078e887ea33SDavid du Colombier v = 1;
1079e887ea33SDavid du Colombier if(l->type->etype == TIND)
1080e887ea33SDavid du Colombier v = l->type->link->width;
1081e887ea33SDavid du Colombier if(o == OPREDEC)
1082e887ea33SDavid du Colombier v = -v;
1083e887ea33SDavid du Colombier if(l->op == OBIT)
1084e887ea33SDavid du Colombier goto bitinc;
1085e887ea33SDavid du Colombier
1086e887ea33SDavid du Colombier pre:
1087e887ea33SDavid du Colombier if(hardleft)
1088e887ea33SDavid du Colombier reglcgen(&nod, l, Z);
1089e887ea33SDavid du Colombier else
1090e887ea33SDavid du Colombier nod = *l;
1091e887ea33SDavid du Colombier if(typefd[n->type->etype]) {
1092e887ea33SDavid du Colombier regalloc(&nod1, l, Z);
1093e887ea33SDavid du Colombier gmove(&nod, &nod1);
1094e887ea33SDavid du Colombier if(v < 0)
1095e887ea33SDavid du Colombier gopcode(OSUB, n->type, nodfconst(-v), &nod1);
1096e887ea33SDavid du Colombier else
1097e887ea33SDavid du Colombier gopcode(OADD, n->type, nodfconst(v), &nod1);
1098e887ea33SDavid du Colombier gmove(&nod1, &nod);
1099e887ea33SDavid du Colombier regfree(&nod1);
1100e887ea33SDavid du Colombier } else
1101e887ea33SDavid du Colombier gopcode(OADD, n->type, nodconst(v), &nod);
1102e887ea33SDavid du Colombier if(nn != Z)
1103e887ea33SDavid du Colombier gmove(&nod, nn);
1104e887ea33SDavid du Colombier if(hardleft)
1105e887ea33SDavid du Colombier regfree(&nod);
1106e887ea33SDavid du Colombier break;
1107e887ea33SDavid du Colombier
1108e887ea33SDavid du Colombier bitinc:
1109e887ea33SDavid du Colombier if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
1110e887ea33SDavid du Colombier bitload(l, &nod, &nod1, &nod2, Z);
1111e887ea33SDavid du Colombier gmove(&nod, nn);
1112e887ea33SDavid du Colombier gopcode(OADD, tfield, nodconst(v), &nod);
1113e887ea33SDavid du Colombier bitstore(l, &nod, &nod1, &nod2, Z);
1114e887ea33SDavid du Colombier break;
1115e887ea33SDavid du Colombier }
1116e887ea33SDavid du Colombier bitload(l, &nod, &nod1, &nod2, nn);
1117e887ea33SDavid du Colombier gopcode(OADD, tfield, nodconst(v), &nod);
1118e887ea33SDavid du Colombier bitstore(l, &nod, &nod1, &nod2, nn);
1119e887ea33SDavid du Colombier break;
1120e887ea33SDavid du Colombier }
1121e887ea33SDavid du Colombier done:
1122e887ea33SDavid du Colombier cursafe = curs;
1123e887ea33SDavid du Colombier }
1124e887ea33SDavid du Colombier
1125e887ea33SDavid du Colombier void
reglcgen(Node * t,Node * n,Node * nn)1126e887ea33SDavid du Colombier reglcgen(Node *t, Node *n, Node *nn)
1127e887ea33SDavid du Colombier {
1128e887ea33SDavid du Colombier Node *r;
1129e887ea33SDavid du Colombier long v;
1130e887ea33SDavid du Colombier
1131e887ea33SDavid du Colombier regialloc(t, n, nn);
1132e887ea33SDavid du Colombier if(n->op == OIND) {
1133e887ea33SDavid du Colombier r = n->left;
1134e887ea33SDavid du Colombier while(r->op == OADD)
1135e887ea33SDavid du Colombier r = r->right;
1136e887ea33SDavid du Colombier if(sconst(r)) {
1137e887ea33SDavid du Colombier v = r->vconst;
1138e887ea33SDavid du Colombier r->vconst = 0;
1139e887ea33SDavid du Colombier lcgen(n, t);
1140e887ea33SDavid du Colombier t->xoffset += v;
1141e887ea33SDavid du Colombier r->vconst = v;
1142e887ea33SDavid du Colombier regind(t, n);
1143e887ea33SDavid du Colombier return;
1144e887ea33SDavid du Colombier }
1145e887ea33SDavid du Colombier }
1146e887ea33SDavid du Colombier lcgen(n, t);
1147e887ea33SDavid du Colombier regind(t, n);
1148e887ea33SDavid du Colombier }
1149e887ea33SDavid du Colombier
1150e887ea33SDavid du Colombier void
lcgen(Node * n,Node * nn)1151e887ea33SDavid du Colombier lcgen(Node *n, Node *nn)
1152e887ea33SDavid du Colombier {
1153e887ea33SDavid du Colombier Prog *p1;
1154e887ea33SDavid du Colombier Node nod;
1155e887ea33SDavid du Colombier
1156e887ea33SDavid du Colombier if(debug['g']) {
1157e887ea33SDavid du Colombier prtree(nn, "lcgen lhs");
1158e887ea33SDavid du Colombier prtree(n, "lcgen");
1159e887ea33SDavid du Colombier }
1160e887ea33SDavid du Colombier if(n == Z || n->type == T)
1161e887ea33SDavid du Colombier return;
1162e887ea33SDavid du Colombier if(nn == Z) {
1163e887ea33SDavid du Colombier nn = &nod;
1164e887ea33SDavid du Colombier regalloc(&nod, n, Z);
1165e887ea33SDavid du Colombier }
1166e887ea33SDavid du Colombier switch(n->op) {
1167e887ea33SDavid du Colombier default:
1168e887ea33SDavid du Colombier if(n->addable < INDEXED) {
1169e887ea33SDavid du Colombier diag(n, "unknown op in lcgen: %O", n->op);
1170e887ea33SDavid du Colombier break;
1171e887ea33SDavid du Colombier }
1172e887ea33SDavid du Colombier gopcode(OADDR, n->type, n, nn);
1173e887ea33SDavid du Colombier break;
1174e887ea33SDavid du Colombier
1175e887ea33SDavid du Colombier case OCOMMA:
1176e887ea33SDavid du Colombier cgen(n->left, n->left);
1177e887ea33SDavid du Colombier lcgen(n->right, nn);
1178e887ea33SDavid du Colombier break;
1179e887ea33SDavid du Colombier
1180e887ea33SDavid du Colombier case OIND:
1181e887ea33SDavid du Colombier cgen(n->left, nn);
1182e887ea33SDavid du Colombier break;
1183e887ea33SDavid du Colombier
1184e887ea33SDavid du Colombier case OCOND:
1185e887ea33SDavid du Colombier bcgen(n->left, 1);
1186e887ea33SDavid du Colombier p1 = p;
1187e887ea33SDavid du Colombier lcgen(n->right->left, nn);
1188e887ea33SDavid du Colombier gbranch(OGOTO);
1189e887ea33SDavid du Colombier patch(p1, pc);
1190e887ea33SDavid du Colombier p1 = p;
1191e887ea33SDavid du Colombier lcgen(n->right->right, nn);
1192e887ea33SDavid du Colombier patch(p1, pc);
1193e887ea33SDavid du Colombier break;
1194e887ea33SDavid du Colombier }
1195e887ea33SDavid du Colombier }
1196e887ea33SDavid du Colombier
1197e887ea33SDavid du Colombier void
bcgen(Node * n,int true)1198e887ea33SDavid du Colombier bcgen(Node *n, int true)
1199e887ea33SDavid du Colombier {
1200e887ea33SDavid du Colombier
1201e887ea33SDavid du Colombier if(n->type == T)
1202e887ea33SDavid du Colombier gbranch(OGOTO);
1203e887ea33SDavid du Colombier else
1204e887ea33SDavid du Colombier boolgen(n, true, Z);
1205e887ea33SDavid du Colombier }
1206e887ea33SDavid du Colombier
1207e887ea33SDavid du Colombier void
boolgen(Node * n,int true,Node * nn)1208e887ea33SDavid du Colombier boolgen(Node *n, int true, Node *nn)
1209e887ea33SDavid du Colombier {
1210e887ea33SDavid du Colombier int o;
1211e887ea33SDavid du Colombier Prog *p1, *p2;
1212e887ea33SDavid du Colombier Node *l, *r, nod, nod1;
1213e887ea33SDavid du Colombier long curs;
1214e887ea33SDavid du Colombier
1215e887ea33SDavid du Colombier if(debug['g']) {
1216e887ea33SDavid du Colombier prtree(nn, "boolgen lhs");
1217e887ea33SDavid du Colombier prtree(n, "boolgen");
1218e887ea33SDavid du Colombier }
1219e887ea33SDavid du Colombier curs = cursafe;
1220e887ea33SDavid du Colombier l = n->left;
1221e887ea33SDavid du Colombier r = n->right;
1222e887ea33SDavid du Colombier switch(n->op) {
1223e887ea33SDavid du Colombier
1224e887ea33SDavid du Colombier default:
1225e887ea33SDavid du Colombier o = ONE;
1226e887ea33SDavid du Colombier if(true)
1227e887ea33SDavid du Colombier o = OEQ;
1228e887ea33SDavid du Colombier /* bad, 13 is address of external that becomes constant */
1229e887ea33SDavid du Colombier if(n->addable >= INDEXED && n->addable != 13) {
1230e887ea33SDavid du Colombier if(typefd[n->type->etype]) {
1231e887ea33SDavid du Colombier regalloc(&nod1, n, Z);
1232e887ea33SDavid du Colombier gmove(nodfconst(0.0), &nod1); /* TO DO: FREGZERO */
1233e887ea33SDavid du Colombier gopcode(o, n->type, n, &nod1);
1234e887ea33SDavid du Colombier regfree(&nod1);
1235e887ea33SDavid du Colombier } else
1236e887ea33SDavid du Colombier gopcode(o, n->type, n, nodconst(0));
1237e887ea33SDavid du Colombier goto com;
1238e887ea33SDavid du Colombier }
1239e887ea33SDavid du Colombier regalloc(&nod, n, nn);
1240e887ea33SDavid du Colombier cgen(n, &nod);
1241e887ea33SDavid du Colombier if(typefd[n->type->etype]) {
1242e887ea33SDavid du Colombier regalloc(&nod1, n, Z);
1243e887ea33SDavid du Colombier gmove(nodfconst(0.0), &nod1); /* TO DO: FREGZERO */
1244e887ea33SDavid du Colombier gopcode(o, n->type, &nod, &nod1);
1245e887ea33SDavid du Colombier regfree(&nod1);
1246e887ea33SDavid du Colombier } else
1247e887ea33SDavid du Colombier gopcode(o, n->type, &nod, nodconst(0));
1248e887ea33SDavid du Colombier regfree(&nod);
1249e887ea33SDavid du Colombier goto com;
1250e887ea33SDavid du Colombier
1251e887ea33SDavid du Colombier case OCONST:
1252e887ea33SDavid du Colombier o = vconst(n);
1253e887ea33SDavid du Colombier if(!true)
1254e887ea33SDavid du Colombier o = !o;
1255e887ea33SDavid du Colombier gbranch(OGOTO);
1256e887ea33SDavid du Colombier if(o) {
1257e887ea33SDavid du Colombier p1 = p;
1258e887ea33SDavid du Colombier gbranch(OGOTO);
1259e887ea33SDavid du Colombier patch(p1, pc);
1260e887ea33SDavid du Colombier }
1261e887ea33SDavid du Colombier goto com;
1262e887ea33SDavid du Colombier
1263e887ea33SDavid du Colombier case OCOMMA:
1264e887ea33SDavid du Colombier cgen(l, Z);
1265e887ea33SDavid du Colombier boolgen(r, true, nn);
1266e887ea33SDavid du Colombier break;
1267e887ea33SDavid du Colombier
1268e887ea33SDavid du Colombier case ONOT:
1269e887ea33SDavid du Colombier boolgen(l, !true, nn);
1270e887ea33SDavid du Colombier break;
1271e887ea33SDavid du Colombier
1272e887ea33SDavid du Colombier case OCOND:
1273e887ea33SDavid du Colombier bcgen(l, 1);
1274e887ea33SDavid du Colombier p1 = p;
1275e887ea33SDavid du Colombier bcgen(r->left, true);
1276e887ea33SDavid du Colombier p2 = p;
1277e887ea33SDavid du Colombier gbranch(OGOTO);
1278e887ea33SDavid du Colombier patch(p1, pc);
1279e887ea33SDavid du Colombier p1 = p;
1280e887ea33SDavid du Colombier bcgen(r->right, !true);
1281e887ea33SDavid du Colombier patch(p2, pc);
1282e887ea33SDavid du Colombier p2 = p;
1283e887ea33SDavid du Colombier gbranch(OGOTO);
1284e887ea33SDavid du Colombier patch(p1, pc);
1285e887ea33SDavid du Colombier patch(p2, pc);
1286e887ea33SDavid du Colombier goto com;
1287e887ea33SDavid du Colombier
1288e887ea33SDavid du Colombier case OANDAND:
1289e887ea33SDavid du Colombier if(!true)
1290e887ea33SDavid du Colombier goto caseor;
1291e887ea33SDavid du Colombier
1292e887ea33SDavid du Colombier caseand:
1293e887ea33SDavid du Colombier bcgen(l, true);
1294e887ea33SDavid du Colombier p1 = p;
1295e887ea33SDavid du Colombier bcgen(r, !true);
1296e887ea33SDavid du Colombier p2 = p;
1297e887ea33SDavid du Colombier patch(p1, pc);
1298e887ea33SDavid du Colombier gbranch(OGOTO);
1299e887ea33SDavid du Colombier patch(p2, pc);
1300e887ea33SDavid du Colombier goto com;
1301e887ea33SDavid du Colombier
1302e887ea33SDavid du Colombier case OOROR:
1303e887ea33SDavid du Colombier if(!true)
1304e887ea33SDavid du Colombier goto caseand;
1305e887ea33SDavid du Colombier
1306e887ea33SDavid du Colombier caseor:
1307e887ea33SDavid du Colombier bcgen(l, !true);
1308e887ea33SDavid du Colombier p1 = p;
1309e887ea33SDavid du Colombier bcgen(r, !true);
1310e887ea33SDavid du Colombier p2 = p;
1311e887ea33SDavid du Colombier gbranch(OGOTO);
1312e887ea33SDavid du Colombier patch(p1, pc);
1313e887ea33SDavid du Colombier patch(p2, pc);
1314e887ea33SDavid du Colombier goto com;
1315e887ea33SDavid du Colombier
1316e887ea33SDavid du Colombier case OEQ:
1317e887ea33SDavid du Colombier case ONE:
1318e887ea33SDavid du Colombier case OLE:
1319e887ea33SDavid du Colombier case OLT:
1320e887ea33SDavid du Colombier case OGE:
1321e887ea33SDavid du Colombier case OGT:
1322e887ea33SDavid du Colombier case OHI:
1323e887ea33SDavid du Colombier case OHS:
1324e887ea33SDavid du Colombier case OLO:
1325e887ea33SDavid du Colombier case OLS:
1326e887ea33SDavid du Colombier o = n->op;
1327e887ea33SDavid du Colombier if(true)
1328e887ea33SDavid du Colombier o = comrel[relindex(o)];
1329e887ea33SDavid du Colombier if(l->complex >= FNX && r->complex >= FNX) {
1330e887ea33SDavid du Colombier regret(&nod, r);
1331e887ea33SDavid du Colombier cgen(r, &nod);
1332e887ea33SDavid du Colombier regsalloc(&nod1, r);
1333e887ea33SDavid du Colombier gmove(&nod, &nod1);
1334e887ea33SDavid du Colombier regfree(&nod);
1335e887ea33SDavid du Colombier nod = *n;
1336e887ea33SDavid du Colombier nod.right = &nod1;
1337e887ea33SDavid du Colombier boolgen(&nod, true, nn);
1338e887ea33SDavid du Colombier break;
1339e887ea33SDavid du Colombier }
1340e887ea33SDavid du Colombier if(immconst(l)) {
1341e887ea33SDavid du Colombier o = invrel[relindex(o)];
1342e887ea33SDavid du Colombier /* bad, 13 is address of external that becomes constant */
1343e887ea33SDavid du Colombier if(r->addable < INDEXED || r->addable == 13) {
1344e887ea33SDavid du Colombier regalloc(&nod, r, nn);
1345e887ea33SDavid du Colombier cgen(r, &nod);
1346e887ea33SDavid du Colombier gopcode(o, l->type, &nod, l);
1347e887ea33SDavid du Colombier regfree(&nod);
1348e887ea33SDavid du Colombier } else
1349e887ea33SDavid du Colombier gopcode(o, l->type, r, l);
1350e887ea33SDavid du Colombier goto com;
1351e887ea33SDavid du Colombier }
1352e887ea33SDavid du Colombier if(typefd[l->type->etype])
1353e887ea33SDavid du Colombier o = invrel[relindex(logrel[relindex(o)])];
1354e887ea33SDavid du Colombier if(l->complex >= r->complex) {
1355e887ea33SDavid du Colombier regalloc(&nod, l, nn);
1356e887ea33SDavid du Colombier cgen(l, &nod);
1357e887ea33SDavid du Colombier if(r->addable < INDEXED || hardconst(r) || typefd[l->type->etype]) {
1358e887ea33SDavid du Colombier regalloc(&nod1, r, Z);
1359e887ea33SDavid du Colombier cgen(r, &nod1);
1360e887ea33SDavid du Colombier gopcode(o, l->type, &nod, &nod1);
1361e887ea33SDavid du Colombier regfree(&nod1);
1362e887ea33SDavid du Colombier } else
1363e887ea33SDavid du Colombier gopcode(o, l->type, &nod, r);
1364e887ea33SDavid du Colombier regfree(&nod);
1365e887ea33SDavid du Colombier goto com;
1366e887ea33SDavid du Colombier }
1367e887ea33SDavid du Colombier regalloc(&nod, r, nn);
1368e887ea33SDavid du Colombier cgen(r, &nod);
1369e887ea33SDavid du Colombier if(l->addable < INDEXED || l->addable == 13 || hardconst(l)) {
1370e887ea33SDavid du Colombier regalloc(&nod1, l, Z);
1371e887ea33SDavid du Colombier cgen(l, &nod1);
1372e887ea33SDavid du Colombier if(typechl[l->type->etype] && ewidth[l->type->etype] <= ewidth[TINT])
1373e887ea33SDavid du Colombier gopcode(o, types[TINT], &nod1, &nod);
1374e887ea33SDavid du Colombier else
1375e887ea33SDavid du Colombier gopcode(o, l->type, &nod1, &nod);
1376e887ea33SDavid du Colombier regfree(&nod1);
1377e887ea33SDavid du Colombier } else
1378e887ea33SDavid du Colombier gopcode(o, l->type, l, &nod);
1379e887ea33SDavid du Colombier regfree(&nod);
1380e887ea33SDavid du Colombier
1381e887ea33SDavid du Colombier com:
1382e887ea33SDavid du Colombier if(nn != Z) {
1383e887ea33SDavid du Colombier p1 = p;
1384e887ea33SDavid du Colombier gmove(nodconst(1L), nn);
1385e887ea33SDavid du Colombier gbranch(OGOTO);
1386e887ea33SDavid du Colombier p2 = p;
1387e887ea33SDavid du Colombier patch(p1, pc);
1388e887ea33SDavid du Colombier gmove(nodconst(0L), nn);
1389e887ea33SDavid du Colombier patch(p2, pc);
1390e887ea33SDavid du Colombier }
1391e887ea33SDavid du Colombier break;
1392e887ea33SDavid du Colombier }
1393e887ea33SDavid du Colombier cursafe = curs;
1394e887ea33SDavid du Colombier }
1395e887ea33SDavid du Colombier
1396e887ea33SDavid du Colombier void
sugen(Node * n,Node * nn,long w)1397e887ea33SDavid du Colombier sugen(Node *n, Node *nn, long w)
1398e887ea33SDavid du Colombier {
1399e887ea33SDavid du Colombier Prog *p1;
1400e887ea33SDavid du Colombier Node nod0, nod1, nod2, nod3, nod4, *l, *r;
1401e887ea33SDavid du Colombier Type *t;
1402e887ea33SDavid du Colombier int c, mt, mo;
1403e887ea33SDavid du Colombier vlong o0, o1;
1404e887ea33SDavid du Colombier
1405e887ea33SDavid du Colombier if(n == Z || n->type == T)
1406e887ea33SDavid du Colombier return;
1407e887ea33SDavid du Colombier if(debug['g']) {
1408e887ea33SDavid du Colombier prtree(nn, "sugen lhs");
1409e887ea33SDavid du Colombier prtree(n, "sugen");
1410e887ea33SDavid du Colombier }
1411e887ea33SDavid du Colombier if(nn == nodrat)
1412e887ea33SDavid du Colombier if(w > nrathole)
1413e887ea33SDavid du Colombier nrathole = w;
1414e887ea33SDavid du Colombier switch(n->op) {
1415e887ea33SDavid du Colombier case OIND:
1416e887ea33SDavid du Colombier if(nn == Z) {
1417e887ea33SDavid du Colombier nullwarn(n->left, Z);
1418e887ea33SDavid du Colombier break;
1419e887ea33SDavid du Colombier }
1420e887ea33SDavid du Colombier
1421e887ea33SDavid du Colombier default:
1422e887ea33SDavid du Colombier goto copy;
1423e887ea33SDavid du Colombier
1424e887ea33SDavid du Colombier case OCONST:
1425e887ea33SDavid du Colombier goto copy;
1426e887ea33SDavid du Colombier
1427e887ea33SDavid du Colombier case ODOT:
1428e887ea33SDavid du Colombier l = n->left;
1429e887ea33SDavid du Colombier sugen(l, nodrat, l->type->width);
1430e887ea33SDavid du Colombier if(nn == Z)
1431e887ea33SDavid du Colombier break;
1432e887ea33SDavid du Colombier warn(n, "non-interruptable temporary");
1433e887ea33SDavid du Colombier nod1 = *nodrat;
1434e887ea33SDavid du Colombier r = n->right;
1435e887ea33SDavid du Colombier if(!r || r->op != OCONST) {
1436e887ea33SDavid du Colombier diag(n, "DOT and no offset");
1437e887ea33SDavid du Colombier break;
1438e887ea33SDavid du Colombier }
1439e887ea33SDavid du Colombier nod1.xoffset += (long)r->vconst;
1440e887ea33SDavid du Colombier nod1.type = n->type;
1441e887ea33SDavid du Colombier sugen(&nod1, nn, w);
1442e887ea33SDavid du Colombier break;
1443e887ea33SDavid du Colombier
1444e887ea33SDavid du Colombier case OSTRUCT:
1445e887ea33SDavid du Colombier /*
1446e887ea33SDavid du Colombier * rewrite so lhs has no fn call
1447e887ea33SDavid du Colombier */
1448e887ea33SDavid du Colombier if(nn != Z && side(nn)) {
1449e887ea33SDavid du Colombier nod1 = *n;
1450e887ea33SDavid du Colombier nod1.type = typ(TIND, n->type);
1451e887ea33SDavid du Colombier regret(&nod2, &nod1);
1452e887ea33SDavid du Colombier lcgen(nn, &nod2);
1453e887ea33SDavid du Colombier regsalloc(&nod0, &nod1);
1454e887ea33SDavid du Colombier cgen(&nod2, &nod0);
1455e887ea33SDavid du Colombier regfree(&nod2);
1456e887ea33SDavid du Colombier
1457e887ea33SDavid du Colombier nod1 = *n;
1458e887ea33SDavid du Colombier nod1.op = OIND;
1459e887ea33SDavid du Colombier nod1.left = &nod0;
1460e887ea33SDavid du Colombier nod1.right = Z;
1461e887ea33SDavid du Colombier nod1.complex = 1;
1462e887ea33SDavid du Colombier
1463e887ea33SDavid du Colombier sugen(n, &nod1, w);
1464e887ea33SDavid du Colombier return;
1465e887ea33SDavid du Colombier }
1466e887ea33SDavid du Colombier
1467e887ea33SDavid du Colombier r = n->left;
1468e887ea33SDavid du Colombier for(t = n->type->link; t != T; t = t->down) {
1469e887ea33SDavid du Colombier l = r;
1470e887ea33SDavid du Colombier if(r->op == OLIST) {
1471e887ea33SDavid du Colombier l = r->left;
1472e887ea33SDavid du Colombier r = r->right;
1473e887ea33SDavid du Colombier }
1474e887ea33SDavid du Colombier if(nn == Z) {
1475e887ea33SDavid du Colombier cgen(l, nn);
1476e887ea33SDavid du Colombier continue;
1477e887ea33SDavid du Colombier }
1478e887ea33SDavid du Colombier /*
1479e887ea33SDavid du Colombier * hand craft *(&nn + o) = l
1480e887ea33SDavid du Colombier */
1481e887ea33SDavid du Colombier nod0 = znode;
1482e887ea33SDavid du Colombier nod0.op = OAS;
1483e887ea33SDavid du Colombier nod0.type = t;
1484e887ea33SDavid du Colombier nod0.left = &nod1;
1485e887ea33SDavid du Colombier nod0.right = nil;
1486e887ea33SDavid du Colombier
1487e887ea33SDavid du Colombier nod1 = znode;
1488e887ea33SDavid du Colombier nod1.op = OIND;
1489e887ea33SDavid du Colombier nod1.type = t;
1490e887ea33SDavid du Colombier nod1.left = &nod2;
1491e887ea33SDavid du Colombier
1492e887ea33SDavid du Colombier nod2 = znode;
1493e887ea33SDavid du Colombier nod2.op = OADD;
1494e887ea33SDavid du Colombier nod2.type = typ(TIND, t);
1495e887ea33SDavid du Colombier nod2.left = &nod3;
1496e887ea33SDavid du Colombier nod2.right = &nod4;
1497e887ea33SDavid du Colombier
1498e887ea33SDavid du Colombier nod3 = znode;
1499e887ea33SDavid du Colombier nod3.op = OADDR;
1500e887ea33SDavid du Colombier nod3.type = nod2.type;
1501e887ea33SDavid du Colombier nod3.left = nn;
1502e887ea33SDavid du Colombier
1503e887ea33SDavid du Colombier nod4 = znode;
1504e887ea33SDavid du Colombier nod4.op = OCONST;
1505e887ea33SDavid du Colombier nod4.type = nod2.type;
1506e887ea33SDavid du Colombier nod4.vconst = t->offset;
1507e887ea33SDavid du Colombier
1508e887ea33SDavid du Colombier ccom(&nod0);
1509e887ea33SDavid du Colombier acom(&nod0);
1510e887ea33SDavid du Colombier xcom(&nod0);
1511e887ea33SDavid du Colombier nod0.addable = 0;
1512e887ea33SDavid du Colombier nod0.right = l;
1513e887ea33SDavid du Colombier
1514e887ea33SDavid du Colombier /* prtree(&nod0, "hand craft"); /* */
1515e887ea33SDavid du Colombier cgen(&nod0, Z);
1516e887ea33SDavid du Colombier }
1517e887ea33SDavid du Colombier break;
1518e887ea33SDavid du Colombier
1519e887ea33SDavid du Colombier case OAS:
1520e887ea33SDavid du Colombier if(nn == Z) {
1521e887ea33SDavid du Colombier if(n->addable < INDEXED)
1522e887ea33SDavid du Colombier sugen(n->right, n->left, w);
1523e887ea33SDavid du Colombier break;
1524e887ea33SDavid du Colombier }
1525e887ea33SDavid du Colombier
1526e887ea33SDavid du Colombier sugen(n->right, nodrat, w);
1527e887ea33SDavid du Colombier warn(n, "non-interruptable temporary");
1528e887ea33SDavid du Colombier sugen(nodrat, n->left, w);
1529e887ea33SDavid du Colombier sugen(nodrat, nn, w);
1530e887ea33SDavid du Colombier break;
1531e887ea33SDavid du Colombier
1532e887ea33SDavid du Colombier case OFUNC:
1533e887ea33SDavid du Colombier if(nn == Z) {
1534e887ea33SDavid du Colombier sugen(n, nodrat, w);
1535e887ea33SDavid du Colombier break;
1536e887ea33SDavid du Colombier }
1537e887ea33SDavid du Colombier if(nn->op != OIND) {
1538e887ea33SDavid du Colombier nn = new1(OADDR, nn, Z);
1539e887ea33SDavid du Colombier nn->type = types[TIND];
1540e887ea33SDavid du Colombier nn->addable = 0;
1541e887ea33SDavid du Colombier } else
1542e887ea33SDavid du Colombier nn = nn->left;
1543e887ea33SDavid du Colombier n = new(OFUNC, n->left, new(OLIST, nn, n->right));
1544e887ea33SDavid du Colombier n->type = types[TVOID];
1545e887ea33SDavid du Colombier n->left->type = types[TVOID];
1546e887ea33SDavid du Colombier cgen(n, Z);
1547e887ea33SDavid du Colombier break;
1548e887ea33SDavid du Colombier
1549e887ea33SDavid du Colombier case OCOND:
1550e887ea33SDavid du Colombier bcgen(n->left, 1);
1551e887ea33SDavid du Colombier p1 = p;
1552e887ea33SDavid du Colombier sugen(n->right->left, nn, w);
1553e887ea33SDavid du Colombier gbranch(OGOTO);
1554e887ea33SDavid du Colombier patch(p1, pc);
1555e887ea33SDavid du Colombier p1 = p;
1556e887ea33SDavid du Colombier sugen(n->right->right, nn, w);
1557e887ea33SDavid du Colombier patch(p1, pc);
1558e887ea33SDavid du Colombier break;
1559e887ea33SDavid du Colombier
1560e887ea33SDavid du Colombier case OCOMMA:
1561e887ea33SDavid du Colombier cgen(n->left, Z);
1562e887ea33SDavid du Colombier sugen(n->right, nn, w);
1563e887ea33SDavid du Colombier break;
1564e887ea33SDavid du Colombier }
1565e887ea33SDavid du Colombier return;
1566e887ea33SDavid du Colombier
1567e887ea33SDavid du Colombier copy:
1568e887ea33SDavid du Colombier if(nn == Z) {
1569e887ea33SDavid du Colombier switch(n->op) {
1570e887ea33SDavid du Colombier case OASADD:
1571e887ea33SDavid du Colombier case OASSUB:
1572e887ea33SDavid du Colombier case OASAND:
1573e887ea33SDavid du Colombier case OASOR:
1574e887ea33SDavid du Colombier case OASXOR:
1575e887ea33SDavid du Colombier
1576e887ea33SDavid du Colombier case OASMUL:
1577e887ea33SDavid du Colombier case OASLMUL:
1578e887ea33SDavid du Colombier
1579e887ea33SDavid du Colombier
1580e887ea33SDavid du Colombier case OASASHL:
1581e887ea33SDavid du Colombier case OASASHR:
1582e887ea33SDavid du Colombier case OASLSHR:
1583e887ea33SDavid du Colombier break;
1584e887ea33SDavid du Colombier
1585e887ea33SDavid du Colombier case OPOSTINC:
1586e887ea33SDavid du Colombier case OPOSTDEC:
1587e887ea33SDavid du Colombier case OPREINC:
1588e887ea33SDavid du Colombier case OPREDEC:
1589e887ea33SDavid du Colombier break;
1590e887ea33SDavid du Colombier
1591e887ea33SDavid du Colombier default:
1592e887ea33SDavid du Colombier return;
1593e887ea33SDavid du Colombier }
1594e887ea33SDavid du Colombier }
1595e887ea33SDavid du Colombier
1596e887ea33SDavid du Colombier if(n->complex >= FNX && nn != nil && nn->complex >= FNX) {
1597e887ea33SDavid du Colombier t = nn->type;
1598e887ea33SDavid du Colombier nn->type = types[TLONG];
1599e887ea33SDavid du Colombier regialloc(&nod1, nn, Z);
1600e887ea33SDavid du Colombier lcgen(nn, &nod1);
1601e887ea33SDavid du Colombier regsalloc(&nod2, nn);
1602e887ea33SDavid du Colombier nn->type = t;
1603e887ea33SDavid du Colombier
1604*1936bb65SDavid du Colombier gins(AMOVQ, &nod1, &nod2);
1605e887ea33SDavid du Colombier regfree(&nod1);
1606e887ea33SDavid du Colombier
1607e887ea33SDavid du Colombier nod2.type = typ(TIND, t);
1608e887ea33SDavid du Colombier
1609e887ea33SDavid du Colombier nod1 = nod2;
1610e887ea33SDavid du Colombier nod1.op = OIND;
1611e887ea33SDavid du Colombier nod1.left = &nod2;
1612e887ea33SDavid du Colombier nod1.right = Z;
1613e887ea33SDavid du Colombier nod1.complex = 1;
1614e887ea33SDavid du Colombier nod1.type = t;
1615e887ea33SDavid du Colombier
1616e887ea33SDavid du Colombier sugen(n, &nod1, w);
1617e887ea33SDavid du Colombier return;
1618e887ea33SDavid du Colombier }
1619e887ea33SDavid du Colombier
1620e887ea33SDavid du Colombier if(w <= 32) {
1621e887ea33SDavid du Colombier c = cursafe;
1622e887ea33SDavid du Colombier if(n->left != Z && n->left->complex >= FNX
1623e887ea33SDavid du Colombier && n->right != Z && n->right->complex >= FNX) {
1624e887ea33SDavid du Colombier regsalloc(&nod1, n->right);
1625e887ea33SDavid du Colombier cgen(n->right, &nod1);
1626e887ea33SDavid du Colombier nod2 = *n;
1627e887ea33SDavid du Colombier nod2.right = &nod1;
1628e887ea33SDavid du Colombier cgen(&nod2, nn);
1629e887ea33SDavid du Colombier cursafe = c;
1630e887ea33SDavid du Colombier return;
1631e887ea33SDavid du Colombier }
1632e887ea33SDavid du Colombier if(w & 7) {
1633e887ea33SDavid du Colombier mt = TLONG;
1634e887ea33SDavid du Colombier mo = AMOVL;
1635e887ea33SDavid du Colombier } else {
1636e887ea33SDavid du Colombier mt = TVLONG;
1637e887ea33SDavid du Colombier mo = AMOVQ;
1638e887ea33SDavid du Colombier }
1639e887ea33SDavid du Colombier if(n->complex > nn->complex) {
1640e887ea33SDavid du Colombier t = n->type;
1641e887ea33SDavid du Colombier n->type = types[mt];
1642e887ea33SDavid du Colombier regalloc(&nod0, n, Z);
1643e887ea33SDavid du Colombier if(!vaddr(n, 0)) {
1644e887ea33SDavid du Colombier reglcgen(&nod1, n, Z);
1645e887ea33SDavid du Colombier n->type = t;
1646e887ea33SDavid du Colombier n = &nod1;
1647e887ea33SDavid du Colombier }
1648e887ea33SDavid du Colombier else
1649e887ea33SDavid du Colombier n->type = t;
1650e887ea33SDavid du Colombier
1651e887ea33SDavid du Colombier t = nn->type;
1652e887ea33SDavid du Colombier nn->type = types[mt];
1653e887ea33SDavid du Colombier if(!vaddr(nn, 0)) {
1654e887ea33SDavid du Colombier reglcgen(&nod2, nn, Z);
1655e887ea33SDavid du Colombier nn->type = t;
1656e887ea33SDavid du Colombier nn = &nod2;
1657e887ea33SDavid du Colombier }
1658e887ea33SDavid du Colombier else
1659e887ea33SDavid du Colombier nn->type = t;
1660e887ea33SDavid du Colombier } else {
1661e887ea33SDavid du Colombier t = nn->type;
1662e887ea33SDavid du Colombier nn->type = types[mt];
1663e887ea33SDavid du Colombier regalloc(&nod0, nn, Z);
1664e887ea33SDavid du Colombier if(!vaddr(nn, 0)) {
1665e887ea33SDavid du Colombier reglcgen(&nod2, nn, Z);
1666e887ea33SDavid du Colombier nn->type = t;
1667e887ea33SDavid du Colombier nn = &nod2;
1668e887ea33SDavid du Colombier }
1669e887ea33SDavid du Colombier else
1670e887ea33SDavid du Colombier nn->type = t;
1671e887ea33SDavid du Colombier
1672e887ea33SDavid du Colombier t = n->type;
1673e887ea33SDavid du Colombier n->type = types[mt];
1674e887ea33SDavid du Colombier if(!vaddr(n, 0)) {
1675e887ea33SDavid du Colombier reglcgen(&nod1, n, Z);
1676e887ea33SDavid du Colombier n->type = t;
1677e887ea33SDavid du Colombier n = &nod1;
1678e887ea33SDavid du Colombier }
1679e887ea33SDavid du Colombier else
1680e887ea33SDavid du Colombier n->type = t;
1681e887ea33SDavid du Colombier }
1682e887ea33SDavid du Colombier o0 = n->xoffset;
1683e887ea33SDavid du Colombier o1 = nn->xoffset;
1684e887ea33SDavid du Colombier w /= ewidth[mt];
1685e887ea33SDavid du Colombier while(--w >= 0) {
1686e887ea33SDavid du Colombier gins(mo, n, &nod0);
1687e887ea33SDavid du Colombier gins(mo, &nod0, nn);
1688e887ea33SDavid du Colombier n->xoffset += ewidth[mt];
1689e887ea33SDavid du Colombier nn->xoffset += ewidth[mt];
1690e887ea33SDavid du Colombier }
1691e887ea33SDavid du Colombier n->xoffset = o0;
1692e887ea33SDavid du Colombier nn->xoffset = o1;
1693e887ea33SDavid du Colombier if(nn == &nod2)
1694e887ea33SDavid du Colombier regfree(&nod2);
1695e887ea33SDavid du Colombier if(n == &nod1)
1696e887ea33SDavid du Colombier regfree(&nod1);
1697e887ea33SDavid du Colombier regfree(&nod0);
1698e887ea33SDavid du Colombier return;
1699e887ea33SDavid du Colombier }
1700e887ea33SDavid du Colombier
1701e887ea33SDavid du Colombier /* botch, need to save in .safe */
1702e887ea33SDavid du Colombier c = 0;
1703e887ea33SDavid du Colombier if(n->complex > nn->complex) {
1704e887ea33SDavid du Colombier t = n->type;
1705*1936bb65SDavid du Colombier n->type = types[TIND];
1706e887ea33SDavid du Colombier nodreg(&nod1, n, D_SI);
1707e887ea33SDavid du Colombier if(reg[D_SI]) {
1708e887ea33SDavid du Colombier gins(APUSHQ, &nod1, Z);
1709e887ea33SDavid du Colombier c |= 1;
1710e887ea33SDavid du Colombier reg[D_SI]++;
1711e887ea33SDavid du Colombier }
1712e887ea33SDavid du Colombier lcgen(n, &nod1);
1713e887ea33SDavid du Colombier n->type = t;
1714e887ea33SDavid du Colombier
1715e887ea33SDavid du Colombier t = nn->type;
1716*1936bb65SDavid du Colombier nn->type = types[TIND];
1717e887ea33SDavid du Colombier nodreg(&nod2, nn, D_DI);
1718e887ea33SDavid du Colombier if(reg[D_DI]) {
1719e887ea33SDavid du Colombier warn(Z, "DI botch");
1720e887ea33SDavid du Colombier gins(APUSHQ, &nod2, Z);
1721e887ea33SDavid du Colombier c |= 2;
1722e887ea33SDavid du Colombier reg[D_DI]++;
1723e887ea33SDavid du Colombier }
1724e887ea33SDavid du Colombier lcgen(nn, &nod2);
1725e887ea33SDavid du Colombier nn->type = t;
1726e887ea33SDavid du Colombier } else {
1727e887ea33SDavid du Colombier t = nn->type;
1728*1936bb65SDavid du Colombier nn->type = types[TIND];
1729e887ea33SDavid du Colombier nodreg(&nod2, nn, D_DI);
1730e887ea33SDavid du Colombier if(reg[D_DI]) {
1731e887ea33SDavid du Colombier warn(Z, "DI botch");
1732e887ea33SDavid du Colombier gins(APUSHQ, &nod2, Z);
1733e887ea33SDavid du Colombier c |= 2;
1734e887ea33SDavid du Colombier reg[D_DI]++;
1735e887ea33SDavid du Colombier }
1736e887ea33SDavid du Colombier lcgen(nn, &nod2);
1737e887ea33SDavid du Colombier nn->type = t;
1738e887ea33SDavid du Colombier
1739e887ea33SDavid du Colombier t = n->type;
1740*1936bb65SDavid du Colombier n->type = types[TIND];
1741e887ea33SDavid du Colombier nodreg(&nod1, n, D_SI);
1742e887ea33SDavid du Colombier if(reg[D_SI]) {
1743e887ea33SDavid du Colombier gins(APUSHQ, &nod1, Z);
1744e887ea33SDavid du Colombier c |= 1;
1745e887ea33SDavid du Colombier reg[D_SI]++;
1746e887ea33SDavid du Colombier }
1747e887ea33SDavid du Colombier lcgen(n, &nod1);
1748e887ea33SDavid du Colombier n->type = t;
1749e887ea33SDavid du Colombier }
1750e887ea33SDavid du Colombier nodreg(&nod3, n, D_CX);
1751e887ea33SDavid du Colombier if(reg[D_CX]) {
1752e887ea33SDavid du Colombier gins(APUSHQ, &nod3, Z);
1753e887ea33SDavid du Colombier c |= 4;
1754e887ea33SDavid du Colombier reg[D_CX]++;
1755e887ea33SDavid du Colombier }
1756e887ea33SDavid du Colombier gins(AMOVL, nodconst(w/SZ_INT), &nod3);
1757e887ea33SDavid du Colombier gins(ACLD, Z, Z);
1758e887ea33SDavid du Colombier gins(AREP, Z, Z);
1759e887ea33SDavid du Colombier gins(AMOVSL, Z, Z);
1760e887ea33SDavid du Colombier if(c & 4) {
1761e887ea33SDavid du Colombier gins(APOPQ, Z, &nod3);
1762e887ea33SDavid du Colombier reg[D_CX]--;
1763e887ea33SDavid du Colombier }
1764e887ea33SDavid du Colombier if(c & 2) {
1765e887ea33SDavid du Colombier gins(APOPQ, Z, &nod2);
1766e887ea33SDavid du Colombier reg[nod2.reg]--;
1767e887ea33SDavid du Colombier }
1768e887ea33SDavid du Colombier if(c & 1) {
1769e887ea33SDavid du Colombier gins(APOPQ, Z, &nod1);
1770e887ea33SDavid du Colombier reg[nod1.reg]--;
1771e887ea33SDavid du Colombier }
1772e887ea33SDavid du Colombier }
1773e887ea33SDavid du Colombier
1774e887ea33SDavid du Colombier /*
1775e887ea33SDavid du Colombier * TO DO
1776e887ea33SDavid du Colombier */
1777e887ea33SDavid du Colombier void
layout(Node * f,Node * t,int c,int cv,Node * cn)1778e887ea33SDavid du Colombier layout(Node *f, Node *t, int c, int cv, Node *cn)
1779e887ea33SDavid du Colombier {
1780e887ea33SDavid du Colombier Node t1, t2;
1781e887ea33SDavid du Colombier
1782e887ea33SDavid du Colombier while(c > 3) {
1783e887ea33SDavid du Colombier layout(f, t, 2, 0, Z);
1784e887ea33SDavid du Colombier c -= 2;
1785e887ea33SDavid du Colombier }
1786e887ea33SDavid du Colombier
1787e887ea33SDavid du Colombier regalloc(&t1, &lregnode, Z);
1788e887ea33SDavid du Colombier regalloc(&t2, &lregnode, Z);
1789e887ea33SDavid du Colombier if(c > 0) {
1790e887ea33SDavid du Colombier gmove(f, &t1);
1791e887ea33SDavid du Colombier f->xoffset += SZ_INT;
1792e887ea33SDavid du Colombier }
1793e887ea33SDavid du Colombier if(cn != Z)
1794e887ea33SDavid du Colombier gmove(nodconst(cv), cn);
1795e887ea33SDavid du Colombier if(c > 1) {
1796e887ea33SDavid du Colombier gmove(f, &t2);
1797e887ea33SDavid du Colombier f->xoffset += SZ_INT;
1798e887ea33SDavid du Colombier }
1799e887ea33SDavid du Colombier if(c > 0) {
1800e887ea33SDavid du Colombier gmove(&t1, t);
1801e887ea33SDavid du Colombier t->xoffset += SZ_INT;
1802e887ea33SDavid du Colombier }
1803e887ea33SDavid du Colombier if(c > 2) {
1804e887ea33SDavid du Colombier gmove(f, &t1);
1805e887ea33SDavid du Colombier f->xoffset += SZ_INT;
1806e887ea33SDavid du Colombier }
1807e887ea33SDavid du Colombier if(c > 1) {
1808e887ea33SDavid du Colombier gmove(&t2, t);
1809e887ea33SDavid du Colombier t->xoffset += SZ_INT;
1810e887ea33SDavid du Colombier }
1811e887ea33SDavid du Colombier if(c > 2) {
1812e887ea33SDavid du Colombier gmove(&t1, t);
1813e887ea33SDavid du Colombier t->xoffset += SZ_INT;
1814e887ea33SDavid du Colombier }
1815e887ea33SDavid du Colombier regfree(&t1);
1816e887ea33SDavid du Colombier regfree(&t2);
1817e887ea33SDavid du Colombier }
1818e887ea33SDavid du Colombier
1819e887ea33SDavid du Colombier /*
1820e887ea33SDavid du Colombier * constant is not vlong or fits as 32-bit signed immediate
1821e887ea33SDavid du Colombier */
1822e887ea33SDavid du Colombier int
immconst(Node * n)1823e887ea33SDavid du Colombier immconst(Node *n)
1824e887ea33SDavid du Colombier {
1825e887ea33SDavid du Colombier long v;
1826e887ea33SDavid du Colombier
1827e887ea33SDavid du Colombier if(n->op != OCONST || !typechlpv[n->type->etype])
1828e887ea33SDavid du Colombier return 0;
1829e887ea33SDavid du Colombier if(typechl[n->type->etype])
1830e887ea33SDavid du Colombier return 1;
1831e887ea33SDavid du Colombier v = n->vconst;
1832e887ea33SDavid du Colombier return n->vconst == (vlong)v;
1833e887ea33SDavid du Colombier }
1834e887ea33SDavid du Colombier
1835e887ea33SDavid du Colombier /*
1836e887ea33SDavid du Colombier * if a constant and vlong, doesn't fit as 32-bit signed immediate
1837e887ea33SDavid du Colombier */
1838e887ea33SDavid du Colombier int
hardconst(Node * n)1839e887ea33SDavid du Colombier hardconst(Node *n)
1840e887ea33SDavid du Colombier {
1841e887ea33SDavid du Colombier return n->op == OCONST && !immconst(n);
1842e887ea33SDavid du Colombier }
1843e887ea33SDavid du Colombier
1844e887ea33SDavid du Colombier /*
1845e887ea33SDavid du Colombier * casting up to t2 covers an intermediate cast to t1
1846e887ea33SDavid du Colombier */
1847e887ea33SDavid du Colombier int
castup(Type * t1,Type * t2)1848e887ea33SDavid du Colombier castup(Type *t1, Type *t2)
1849e887ea33SDavid du Colombier {
1850e887ea33SDavid du Colombier int ft;
1851e887ea33SDavid du Colombier
1852e887ea33SDavid du Colombier if(!nilcast(t1, t2))
1853e887ea33SDavid du Colombier return 0;
1854e887ea33SDavid du Colombier /* known to be small to large */
1855e887ea33SDavid du Colombier ft = t1->etype;
1856e887ea33SDavid du Colombier switch(t2->etype){
1857e887ea33SDavid du Colombier case TINT:
1858e887ea33SDavid du Colombier case TLONG:
1859e887ea33SDavid du Colombier return ft == TLONG || ft == TINT || ft == TSHORT || ft == TCHAR;
1860e887ea33SDavid du Colombier case TUINT:
1861e887ea33SDavid du Colombier case TULONG:
1862e887ea33SDavid du Colombier return ft == TULONG || ft == TUINT || ft == TUSHORT || ft == TUCHAR;
1863e887ea33SDavid du Colombier case TVLONG:
1864e887ea33SDavid du Colombier return ft == TLONG || ft == TINT || ft == TSHORT;
1865e887ea33SDavid du Colombier case TUVLONG:
1866e887ea33SDavid du Colombier return ft == TULONG || ft == TUINT || ft == TUSHORT;
1867e887ea33SDavid du Colombier }
1868e887ea33SDavid du Colombier return 0;
1869e887ea33SDavid du Colombier }
1870e887ea33SDavid du Colombier
1871*1936bb65SDavid du Colombier /*
1872*1936bb65SDavid du Colombier * vl &= ~ul or vl & ~ul
1873*1936bb65SDavid du Colombier * create a ul mask with top bits zero, which is usually wrong
1874*1936bb65SDavid du Colombier */
1875*1936bb65SDavid du Colombier void
checkmask(Node * n,Node * r)1876*1936bb65SDavid du Colombier checkmask(Node *n, Node *r)
1877*1936bb65SDavid du Colombier {
1878*1936bb65SDavid du Colombier Node *rl;
1879*1936bb65SDavid du Colombier
1880*1936bb65SDavid du Colombier if((n->op == OAND || n->op == OASAND) &&
1881*1936bb65SDavid du Colombier r->op == OCAST &&
1882*1936bb65SDavid du Colombier (rl = r->left)->op == OCOM &&
1883*1936bb65SDavid du Colombier typesuv[n->type->etype] && typeu[rl->type->etype] && typechl[rl->type->etype])
1884*1936bb65SDavid du Colombier warn(n, "32-bit mask zero-extended to 64 bits");
1885*1936bb65SDavid du Colombier }
1886*1936bb65SDavid du Colombier
1887e887ea33SDavid du Colombier void
zeroregm(Node * n)1888e887ea33SDavid du Colombier zeroregm(Node *n)
1889e887ea33SDavid du Colombier {
1890e887ea33SDavid du Colombier gins(AMOVL, nodconst(0), n);
1891e887ea33SDavid du Colombier }
1892e887ea33SDavid du Colombier
1893e887ea33SDavid du Colombier /* do we need to load the address of a vlong? */
1894e887ea33SDavid du Colombier int
vaddr(Node * n,int a)1895e887ea33SDavid du Colombier vaddr(Node *n, int a)
1896e887ea33SDavid du Colombier {
1897e887ea33SDavid du Colombier switch(n->op) {
1898e887ea33SDavid du Colombier case ONAME:
1899e887ea33SDavid du Colombier if(a)
1900e887ea33SDavid du Colombier return 1;
1901e887ea33SDavid du Colombier return !(n->class == CEXTERN || n->class == CGLOBL || n->class == CSTATIC);
1902e887ea33SDavid du Colombier
1903e887ea33SDavid du Colombier case OCONST:
1904e887ea33SDavid du Colombier case OREGISTER:
1905e887ea33SDavid du Colombier case OINDREG:
1906e887ea33SDavid du Colombier return 1;
1907e887ea33SDavid du Colombier }
1908e887ea33SDavid du Colombier return 0;
1909e887ea33SDavid du Colombier }
1910e887ea33SDavid du Colombier
1911e887ea33SDavid du Colombier long
hi64v(Node * n)1912e887ea33SDavid du Colombier hi64v(Node *n)
1913e887ea33SDavid du Colombier {
1914e887ea33SDavid du Colombier if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
1915e887ea33SDavid du Colombier return (long)(n->vconst) & ~0L;
1916e887ea33SDavid du Colombier else
1917e887ea33SDavid du Colombier return (long)((uvlong)n->vconst>>32) & ~0L;
1918e887ea33SDavid du Colombier }
1919e887ea33SDavid du Colombier
1920e887ea33SDavid du Colombier long
lo64v(Node * n)1921e887ea33SDavid du Colombier lo64v(Node *n)
1922e887ea33SDavid du Colombier {
1923e887ea33SDavid du Colombier if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
1924e887ea33SDavid du Colombier return (long)((uvlong)n->vconst>>32) & ~0L;
1925e887ea33SDavid du Colombier else
1926e887ea33SDavid du Colombier return (long)(n->vconst) & ~0L;
1927e887ea33SDavid du Colombier }
1928e887ea33SDavid du Colombier
1929e887ea33SDavid du Colombier Node *
hi64(Node * n)1930e887ea33SDavid du Colombier hi64(Node *n)
1931e887ea33SDavid du Colombier {
1932e887ea33SDavid du Colombier return nodconst(hi64v(n));
1933e887ea33SDavid du Colombier }
1934e887ea33SDavid du Colombier
1935e887ea33SDavid du Colombier Node *
lo64(Node * n)1936e887ea33SDavid du Colombier lo64(Node *n)
1937e887ea33SDavid du Colombier {
1938e887ea33SDavid du Colombier return nodconst(lo64v(n));
1939e887ea33SDavid du Colombier }
1940e887ea33SDavid du Colombier
1941e887ea33SDavid du Colombier int
cond(int op)1942e887ea33SDavid du Colombier cond(int op)
1943e887ea33SDavid du Colombier {
1944e887ea33SDavid du Colombier switch(op) {
1945e887ea33SDavid du Colombier case OANDAND:
1946e887ea33SDavid du Colombier case OOROR:
1947e887ea33SDavid du Colombier case ONOT:
1948e887ea33SDavid du Colombier return 1;
1949e887ea33SDavid du Colombier
1950e887ea33SDavid du Colombier case OEQ:
1951e887ea33SDavid du Colombier case ONE:
1952e887ea33SDavid du Colombier case OLE:
1953e887ea33SDavid du Colombier case OLT:
1954e887ea33SDavid du Colombier case OGE:
1955e887ea33SDavid du Colombier case OGT:
1956e887ea33SDavid du Colombier case OHI:
1957e887ea33SDavid du Colombier case OHS:
1958e887ea33SDavid du Colombier case OLO:
1959e887ea33SDavid du Colombier case OLS:
1960e887ea33SDavid du Colombier return 1;
1961e887ea33SDavid du Colombier }
1962e887ea33SDavid du Colombier return 0;
1963e887ea33SDavid du Colombier }
1964