1*fbadb1c4SDavid du Colombier #include "gc.h"
2*fbadb1c4SDavid du Colombier
3*fbadb1c4SDavid du Colombier void
cgen(Node * n,Node * nn)4*fbadb1c4SDavid du Colombier cgen(Node *n, Node *nn)
5*fbadb1c4SDavid du Colombier {
6*fbadb1c4SDavid du Colombier Node *l, *r;
7*fbadb1c4SDavid du Colombier Prog *p1;
8*fbadb1c4SDavid du Colombier Node nod, nod1, nod2, nod3, nod4;
9*fbadb1c4SDavid du Colombier int o;
10*fbadb1c4SDavid du Colombier long v, curs;
11*fbadb1c4SDavid du Colombier
12*fbadb1c4SDavid du Colombier if(debug['g']) {
13*fbadb1c4SDavid du Colombier prtree(nn, "cgen lhs");
14*fbadb1c4SDavid du Colombier prtree(n, "cgen");
15*fbadb1c4SDavid du Colombier }
16*fbadb1c4SDavid du Colombier if(n == Z || n->type == T)
17*fbadb1c4SDavid du Colombier return;
18*fbadb1c4SDavid du Colombier if(typesu[n->type->etype]) {
19*fbadb1c4SDavid du Colombier sugen(n, nn, n->type->width);
20*fbadb1c4SDavid du Colombier return;
21*fbadb1c4SDavid du Colombier }
22*fbadb1c4SDavid du Colombier l = n->left;
23*fbadb1c4SDavid du Colombier r = n->right;
24*fbadb1c4SDavid du Colombier o = n->op;
25*fbadb1c4SDavid du Colombier if(n->addable >= INDEXED) {
26*fbadb1c4SDavid du Colombier if(nn == Z) {
27*fbadb1c4SDavid du Colombier switch(o) {
28*fbadb1c4SDavid du Colombier default:
29*fbadb1c4SDavid du Colombier nullwarn(Z, Z);
30*fbadb1c4SDavid du Colombier break;
31*fbadb1c4SDavid du Colombier case OINDEX:
32*fbadb1c4SDavid du Colombier nullwarn(l, r);
33*fbadb1c4SDavid du Colombier break;
34*fbadb1c4SDavid du Colombier }
35*fbadb1c4SDavid du Colombier return;
36*fbadb1c4SDavid du Colombier }
37*fbadb1c4SDavid du Colombier gmove(n, nn);
38*fbadb1c4SDavid du Colombier return;
39*fbadb1c4SDavid du Colombier }
40*fbadb1c4SDavid du Colombier curs = cursafe;
41*fbadb1c4SDavid du Colombier
42*fbadb1c4SDavid du Colombier if(n->complex >= FNX)
43*fbadb1c4SDavid du Colombier if(l->complex >= FNX)
44*fbadb1c4SDavid du Colombier if(r != Z && r->complex >= FNX)
45*fbadb1c4SDavid du Colombier switch(o) {
46*fbadb1c4SDavid du Colombier default:
47*fbadb1c4SDavid du Colombier regret(&nod, r);
48*fbadb1c4SDavid du Colombier cgen(r, &nod);
49*fbadb1c4SDavid du Colombier
50*fbadb1c4SDavid du Colombier regsalloc(&nod1, r);
51*fbadb1c4SDavid du Colombier gopcode(OAS, &nod, Z, &nod1);
52*fbadb1c4SDavid du Colombier
53*fbadb1c4SDavid du Colombier regfree(&nod);
54*fbadb1c4SDavid du Colombier nod = *n;
55*fbadb1c4SDavid du Colombier nod.right = &nod1;
56*fbadb1c4SDavid du Colombier cgen(&nod, nn);
57*fbadb1c4SDavid du Colombier return;
58*fbadb1c4SDavid du Colombier
59*fbadb1c4SDavid du Colombier case OFUNC:
60*fbadb1c4SDavid du Colombier case OCOMMA:
61*fbadb1c4SDavid du Colombier case OANDAND:
62*fbadb1c4SDavid du Colombier case OOROR:
63*fbadb1c4SDavid du Colombier case OCOND:
64*fbadb1c4SDavid du Colombier case ODOT:
65*fbadb1c4SDavid du Colombier break;
66*fbadb1c4SDavid du Colombier }
67*fbadb1c4SDavid du Colombier
68*fbadb1c4SDavid du Colombier switch(o) {
69*fbadb1c4SDavid du Colombier default:
70*fbadb1c4SDavid du Colombier diag(n, "unknown op in cgen: %O", o);
71*fbadb1c4SDavid du Colombier break;
72*fbadb1c4SDavid du Colombier
73*fbadb1c4SDavid du Colombier case OAS:
74*fbadb1c4SDavid du Colombier if(l->op == OBIT)
75*fbadb1c4SDavid du Colombier goto bitas;
76*fbadb1c4SDavid du Colombier if(l->addable >= INDEXED) {
77*fbadb1c4SDavid du Colombier if(nn != Z || r->addable < INDEXED) {
78*fbadb1c4SDavid du Colombier regalloc(&nod, r, nn);
79*fbadb1c4SDavid du Colombier cgen(r, &nod);
80*fbadb1c4SDavid du Colombier gmove(&nod, l);
81*fbadb1c4SDavid du Colombier regfree(&nod);
82*fbadb1c4SDavid du Colombier } else
83*fbadb1c4SDavid du Colombier gmove(r, l);
84*fbadb1c4SDavid du Colombier break;
85*fbadb1c4SDavid du Colombier }
86*fbadb1c4SDavid du Colombier if(l->complex >= r->complex) {
87*fbadb1c4SDavid du Colombier reglcgen(&nod1, l, Z);
88*fbadb1c4SDavid du Colombier if(r->addable >= INDEXED) {
89*fbadb1c4SDavid du Colombier gmove(r, &nod1);
90*fbadb1c4SDavid du Colombier if(nn != Z)
91*fbadb1c4SDavid du Colombier gmove(r, nn);
92*fbadb1c4SDavid du Colombier regfree(&nod1);
93*fbadb1c4SDavid du Colombier break;
94*fbadb1c4SDavid du Colombier }
95*fbadb1c4SDavid du Colombier regalloc(&nod, r, nn);
96*fbadb1c4SDavid du Colombier cgen(r, &nod);
97*fbadb1c4SDavid du Colombier } else {
98*fbadb1c4SDavid du Colombier regalloc(&nod, r, nn);
99*fbadb1c4SDavid du Colombier cgen(r, &nod);
100*fbadb1c4SDavid du Colombier reglcgen(&nod1, l, Z);
101*fbadb1c4SDavid du Colombier }
102*fbadb1c4SDavid du Colombier gmove(&nod, &nod1);
103*fbadb1c4SDavid du Colombier regfree(&nod);
104*fbadb1c4SDavid du Colombier regfree(&nod1);
105*fbadb1c4SDavid du Colombier break;
106*fbadb1c4SDavid du Colombier
107*fbadb1c4SDavid du Colombier bitas:
108*fbadb1c4SDavid du Colombier n = l->left;
109*fbadb1c4SDavid du Colombier regalloc(&nod, r, nn);
110*fbadb1c4SDavid du Colombier if(l->complex >= r->complex) {
111*fbadb1c4SDavid du Colombier reglcgen(&nod1, n, Z);
112*fbadb1c4SDavid du Colombier cgen(r, &nod);
113*fbadb1c4SDavid du Colombier } else {
114*fbadb1c4SDavid du Colombier cgen(r, &nod);
115*fbadb1c4SDavid du Colombier reglcgen(&nod1, n, Z);
116*fbadb1c4SDavid du Colombier }
117*fbadb1c4SDavid du Colombier regalloc(&nod2, n, Z);
118*fbadb1c4SDavid du Colombier gopcode(OAS, &nod1, Z, &nod2);
119*fbadb1c4SDavid du Colombier bitstore(l, &nod, &nod1, &nod2, nn);
120*fbadb1c4SDavid du Colombier break;
121*fbadb1c4SDavid du Colombier
122*fbadb1c4SDavid du Colombier case OBIT:
123*fbadb1c4SDavid du Colombier if(nn == Z) {
124*fbadb1c4SDavid du Colombier nullwarn(l, Z);
125*fbadb1c4SDavid du Colombier break;
126*fbadb1c4SDavid du Colombier }
127*fbadb1c4SDavid du Colombier bitload(n, &nod, Z, Z, nn);
128*fbadb1c4SDavid du Colombier gopcode(OAS, &nod, Z, nn);
129*fbadb1c4SDavid du Colombier regfree(&nod);
130*fbadb1c4SDavid du Colombier break;
131*fbadb1c4SDavid du Colombier
132*fbadb1c4SDavid du Colombier case OXOR:
133*fbadb1c4SDavid du Colombier if(nn != Z)
134*fbadb1c4SDavid du Colombier if(r->op == OCONST && r->vconst == -1){
135*fbadb1c4SDavid du Colombier cgen(l, nn);
136*fbadb1c4SDavid du Colombier gopcode(OCOM, nn, Z, nn);
137*fbadb1c4SDavid du Colombier break;
138*fbadb1c4SDavid du Colombier }
139*fbadb1c4SDavid du Colombier
140*fbadb1c4SDavid du Colombier case OADD:
141*fbadb1c4SDavid du Colombier case OSUB:
142*fbadb1c4SDavid du Colombier case OAND:
143*fbadb1c4SDavid du Colombier case OOR:
144*fbadb1c4SDavid du Colombier case OLSHR:
145*fbadb1c4SDavid du Colombier case OASHL:
146*fbadb1c4SDavid du Colombier case OASHR:
147*fbadb1c4SDavid du Colombier /*
148*fbadb1c4SDavid du Colombier * immediate operands
149*fbadb1c4SDavid du Colombier */
150*fbadb1c4SDavid du Colombier if(nn != Z &&
151*fbadb1c4SDavid du Colombier r->op == OCONST &&
152*fbadb1c4SDavid du Colombier !typefd[n->type->etype] &&
153*fbadb1c4SDavid du Colombier immconst(r)) {
154*fbadb1c4SDavid du Colombier cgen(l, nn);
155*fbadb1c4SDavid du Colombier if(r->vconst == 0)
156*fbadb1c4SDavid du Colombier if(o != OAND)
157*fbadb1c4SDavid du Colombier break;
158*fbadb1c4SDavid du Colombier if(nn != Z)
159*fbadb1c4SDavid du Colombier gopcode(o, r, Z, nn);
160*fbadb1c4SDavid du Colombier break;
161*fbadb1c4SDavid du Colombier }
162*fbadb1c4SDavid du Colombier
163*fbadb1c4SDavid du Colombier case OMUL:
164*fbadb1c4SDavid du Colombier case OLMUL:
165*fbadb1c4SDavid du Colombier case OLDIV:
166*fbadb1c4SDavid du Colombier case OLMOD:
167*fbadb1c4SDavid du Colombier case ODIV:
168*fbadb1c4SDavid du Colombier case OMOD:
169*fbadb1c4SDavid du Colombier if(nn == Z) {
170*fbadb1c4SDavid du Colombier nullwarn(l, r);
171*fbadb1c4SDavid du Colombier break;
172*fbadb1c4SDavid du Colombier }
173*fbadb1c4SDavid du Colombier if(o == OMUL || o == OLMUL) {
174*fbadb1c4SDavid du Colombier if(mulcon(n, nn))
175*fbadb1c4SDavid du Colombier break;
176*fbadb1c4SDavid du Colombier if(debug['M'])
177*fbadb1c4SDavid du Colombier print("%L multiply\n", n->lineno);
178*fbadb1c4SDavid du Colombier }
179*fbadb1c4SDavid du Colombier if(l->complex >= r->complex) {
180*fbadb1c4SDavid du Colombier regalloc(&nod, l, nn);
181*fbadb1c4SDavid du Colombier cgen(l, &nod);
182*fbadb1c4SDavid du Colombier regalloc(&nod1, l, Z); /* note: l used for type, so shifts work! */
183*fbadb1c4SDavid du Colombier cgen(r, &nod1);
184*fbadb1c4SDavid du Colombier gopcode(o, &nod1, Z, &nod);
185*fbadb1c4SDavid du Colombier } else {
186*fbadb1c4SDavid du Colombier regalloc(&nod, l, nn); /* note: l used for type, so shifts work! */
187*fbadb1c4SDavid du Colombier cgen(r, &nod);
188*fbadb1c4SDavid du Colombier regalloc(&nod1, l, Z);
189*fbadb1c4SDavid du Colombier cgen(l, &nod1);
190*fbadb1c4SDavid du Colombier gopcode(o, &nod, &nod1, &nod);
191*fbadb1c4SDavid du Colombier }
192*fbadb1c4SDavid du Colombier gopcode(OAS, &nod, Z, nn);
193*fbadb1c4SDavid du Colombier regfree(&nod);
194*fbadb1c4SDavid du Colombier regfree(&nod1);
195*fbadb1c4SDavid du Colombier break;
196*fbadb1c4SDavid du Colombier
197*fbadb1c4SDavid du Colombier case OASLSHR:
198*fbadb1c4SDavid du Colombier case OASASHL:
199*fbadb1c4SDavid du Colombier case OASASHR:
200*fbadb1c4SDavid du Colombier case OASAND:
201*fbadb1c4SDavid du Colombier case OASADD:
202*fbadb1c4SDavid du Colombier case OASSUB:
203*fbadb1c4SDavid du Colombier case OASXOR:
204*fbadb1c4SDavid du Colombier case OASOR:
205*fbadb1c4SDavid du Colombier if(l->op == OBIT)
206*fbadb1c4SDavid du Colombier goto asbitop;
207*fbadb1c4SDavid du Colombier if(r->op == OCONST &&
208*fbadb1c4SDavid du Colombier !typefd[n->type->etype] &&
209*fbadb1c4SDavid du Colombier immconst(r)) {
210*fbadb1c4SDavid du Colombier if(l->addable < INDEXED)
211*fbadb1c4SDavid du Colombier reglcgen(&nod2, l, Z);
212*fbadb1c4SDavid du Colombier else
213*fbadb1c4SDavid du Colombier nod2 = *l;
214*fbadb1c4SDavid du Colombier regalloc(&nod, l, nn); /* note: l used for type, so shifts work! */
215*fbadb1c4SDavid du Colombier gopcode(OAS, &nod2, Z, &nod);
216*fbadb1c4SDavid du Colombier gopcode(o, r, Z, &nod);
217*fbadb1c4SDavid du Colombier gopcode(OAS, &nod, Z, &nod2);
218*fbadb1c4SDavid du Colombier
219*fbadb1c4SDavid du Colombier regfree(&nod);
220*fbadb1c4SDavid du Colombier if(l->addable < INDEXED)
221*fbadb1c4SDavid du Colombier regfree(&nod2);
222*fbadb1c4SDavid du Colombier break;
223*fbadb1c4SDavid du Colombier }
224*fbadb1c4SDavid du Colombier
225*fbadb1c4SDavid du Colombier case OASLMUL:
226*fbadb1c4SDavid du Colombier case OASLDIV:
227*fbadb1c4SDavid du Colombier case OASLMOD:
228*fbadb1c4SDavid du Colombier case OASMUL:
229*fbadb1c4SDavid du Colombier case OASDIV:
230*fbadb1c4SDavid du Colombier case OASMOD:
231*fbadb1c4SDavid du Colombier if(l->op == OBIT)
232*fbadb1c4SDavid du Colombier goto asbitop;
233*fbadb1c4SDavid du Colombier if(l->complex >= r->complex) {
234*fbadb1c4SDavid du Colombier if(l->addable < INDEXED)
235*fbadb1c4SDavid du Colombier reglcgen(&nod2, l, Z);
236*fbadb1c4SDavid du Colombier else
237*fbadb1c4SDavid du Colombier nod2 = *l;
238*fbadb1c4SDavid du Colombier regalloc(&nod, n, nn);
239*fbadb1c4SDavid du Colombier cgen(r, &nod);
240*fbadb1c4SDavid du Colombier } else {
241*fbadb1c4SDavid du Colombier regalloc(&nod, n, nn);
242*fbadb1c4SDavid du Colombier cgen(r, &nod);
243*fbadb1c4SDavid du Colombier if(l->addable < INDEXED)
244*fbadb1c4SDavid du Colombier reglcgen(&nod2, l, Z);
245*fbadb1c4SDavid du Colombier else
246*fbadb1c4SDavid du Colombier nod2 = *l;
247*fbadb1c4SDavid du Colombier }
248*fbadb1c4SDavid du Colombier regalloc(&nod1, n, Z);
249*fbadb1c4SDavid du Colombier gopcode(OAS, &nod2, Z, &nod1);
250*fbadb1c4SDavid du Colombier if(nod1.type->etype != nod.type->etype){
251*fbadb1c4SDavid du Colombier regalloc(&nod3, &nod, Z);
252*fbadb1c4SDavid du Colombier gmove(&nod1, &nod3);
253*fbadb1c4SDavid du Colombier regfree(&nod1);
254*fbadb1c4SDavid du Colombier nod1 = nod3;
255*fbadb1c4SDavid du Colombier }
256*fbadb1c4SDavid du Colombier gopcode(o, &nod, &nod1, &nod);
257*fbadb1c4SDavid du Colombier gmove(&nod, &nod2);
258*fbadb1c4SDavid du Colombier if(nn != Z)
259*fbadb1c4SDavid du Colombier gmove(&nod, nn);
260*fbadb1c4SDavid du Colombier regfree(&nod);
261*fbadb1c4SDavid du Colombier regfree(&nod1);
262*fbadb1c4SDavid du Colombier if(l->addable < INDEXED)
263*fbadb1c4SDavid du Colombier regfree(&nod2);
264*fbadb1c4SDavid du Colombier break;
265*fbadb1c4SDavid du Colombier
266*fbadb1c4SDavid du Colombier asbitop:
267*fbadb1c4SDavid du Colombier regalloc(&nod4, n, nn);
268*fbadb1c4SDavid du Colombier regalloc(&nod3, r, Z);
269*fbadb1c4SDavid du Colombier if(l->complex >= r->complex) {
270*fbadb1c4SDavid du Colombier bitload(l, &nod, &nod1, &nod2, &nod4);
271*fbadb1c4SDavid du Colombier cgen(r, &nod3);
272*fbadb1c4SDavid du Colombier } else {
273*fbadb1c4SDavid du Colombier cgen(r, &nod3);
274*fbadb1c4SDavid du Colombier bitload(l, &nod, &nod1, &nod2, &nod4);
275*fbadb1c4SDavid du Colombier }
276*fbadb1c4SDavid du Colombier gmove(&nod, &nod4);
277*fbadb1c4SDavid du Colombier gopcode(n->op, &nod3, Z, &nod4);
278*fbadb1c4SDavid du Colombier regfree(&nod3);
279*fbadb1c4SDavid du Colombier gmove(&nod4, &nod);
280*fbadb1c4SDavid du Colombier regfree(&nod4);
281*fbadb1c4SDavid du Colombier bitstore(l, &nod, &nod1, &nod2, nn);
282*fbadb1c4SDavid du Colombier break;
283*fbadb1c4SDavid du Colombier
284*fbadb1c4SDavid du Colombier case OADDR:
285*fbadb1c4SDavid du Colombier if(nn == Z) {
286*fbadb1c4SDavid du Colombier nullwarn(l, Z);
287*fbadb1c4SDavid du Colombier break;
288*fbadb1c4SDavid du Colombier }
289*fbadb1c4SDavid du Colombier lcgen(l, nn);
290*fbadb1c4SDavid du Colombier break;
291*fbadb1c4SDavid du Colombier
292*fbadb1c4SDavid du Colombier case OFUNC:
293*fbadb1c4SDavid du Colombier if(l->complex >= FNX) {
294*fbadb1c4SDavid du Colombier if(l->op != OIND)
295*fbadb1c4SDavid du Colombier diag(n, "bad function call");
296*fbadb1c4SDavid du Colombier
297*fbadb1c4SDavid du Colombier regret(&nod, l->left);
298*fbadb1c4SDavid du Colombier cgen(l->left, &nod);
299*fbadb1c4SDavid du Colombier regsalloc(&nod1, l->left);
300*fbadb1c4SDavid du Colombier gopcode(OAS, &nod, Z, &nod1);
301*fbadb1c4SDavid du Colombier regfree(&nod);
302*fbadb1c4SDavid du Colombier
303*fbadb1c4SDavid du Colombier nod = *n;
304*fbadb1c4SDavid du Colombier nod.left = &nod2;
305*fbadb1c4SDavid du Colombier nod2 = *l;
306*fbadb1c4SDavid du Colombier nod2.left = &nod1;
307*fbadb1c4SDavid du Colombier nod2.complex = 1;
308*fbadb1c4SDavid du Colombier cgen(&nod, nn);
309*fbadb1c4SDavid du Colombier
310*fbadb1c4SDavid du Colombier return;
311*fbadb1c4SDavid du Colombier }
312*fbadb1c4SDavid du Colombier o = reg[REGARG];
313*fbadb1c4SDavid du Colombier gargs(r, &nod, &nod1);
314*fbadb1c4SDavid du Colombier if(l->addable < INDEXED) {
315*fbadb1c4SDavid du Colombier reglcgen(&nod, l, Z);
316*fbadb1c4SDavid du Colombier gopcode(OFUNC, Z, Z, &nod);
317*fbadb1c4SDavid du Colombier regfree(&nod);
318*fbadb1c4SDavid du Colombier } else
319*fbadb1c4SDavid du Colombier gopcode(OFUNC, Z, Z, l);
320*fbadb1c4SDavid du Colombier if(REGARG>=0)
321*fbadb1c4SDavid du Colombier if(o != reg[REGARG])
322*fbadb1c4SDavid du Colombier reg[REGARG]--;
323*fbadb1c4SDavid du Colombier if(nn != Z) {
324*fbadb1c4SDavid du Colombier regret(&nod, n);
325*fbadb1c4SDavid du Colombier gopcode(OAS, &nod, Z, nn);
326*fbadb1c4SDavid du Colombier regfree(&nod);
327*fbadb1c4SDavid du Colombier }
328*fbadb1c4SDavid du Colombier break;
329*fbadb1c4SDavid du Colombier
330*fbadb1c4SDavid du Colombier case OIND:
331*fbadb1c4SDavid du Colombier if(nn == Z) {
332*fbadb1c4SDavid du Colombier cgen(l, nn);
333*fbadb1c4SDavid du Colombier break;
334*fbadb1c4SDavid du Colombier }
335*fbadb1c4SDavid du Colombier regialloc(&nod, n, nn);
336*fbadb1c4SDavid du Colombier r = l;
337*fbadb1c4SDavid du Colombier while(r->op == OADD)
338*fbadb1c4SDavid du Colombier r = r->right;
339*fbadb1c4SDavid du Colombier if(sconst(r)) {
340*fbadb1c4SDavid du Colombier v = r->vconst;
341*fbadb1c4SDavid du Colombier r->vconst = 0;
342*fbadb1c4SDavid du Colombier cgen(l, &nod);
343*fbadb1c4SDavid du Colombier nod.xoffset += v;
344*fbadb1c4SDavid du Colombier r->vconst = v;
345*fbadb1c4SDavid du Colombier } else
346*fbadb1c4SDavid du Colombier cgen(l, &nod);
347*fbadb1c4SDavid du Colombier regind(&nod, n);
348*fbadb1c4SDavid du Colombier gopcode(OAS, &nod, Z, nn);
349*fbadb1c4SDavid du Colombier regfree(&nod);
350*fbadb1c4SDavid du Colombier break;
351*fbadb1c4SDavid du Colombier
352*fbadb1c4SDavid du Colombier case OEQ:
353*fbadb1c4SDavid du Colombier case ONE:
354*fbadb1c4SDavid du Colombier case OLE:
355*fbadb1c4SDavid du Colombier case OLT:
356*fbadb1c4SDavid du Colombier case OGE:
357*fbadb1c4SDavid du Colombier case OGT:
358*fbadb1c4SDavid du Colombier case OLO:
359*fbadb1c4SDavid du Colombier case OLS:
360*fbadb1c4SDavid du Colombier case OHI:
361*fbadb1c4SDavid du Colombier case OHS:
362*fbadb1c4SDavid du Colombier if(nn == Z) {
363*fbadb1c4SDavid du Colombier nullwarn(l, r);
364*fbadb1c4SDavid du Colombier break;
365*fbadb1c4SDavid du Colombier }
366*fbadb1c4SDavid du Colombier boolgen(n, 1, nn);
367*fbadb1c4SDavid du Colombier break;
368*fbadb1c4SDavid du Colombier
369*fbadb1c4SDavid du Colombier case OANDAND:
370*fbadb1c4SDavid du Colombier case OOROR:
371*fbadb1c4SDavid du Colombier boolgen(n, 1, nn);
372*fbadb1c4SDavid du Colombier if(nn == Z)
373*fbadb1c4SDavid du Colombier patch(p, pc);
374*fbadb1c4SDavid du Colombier break;
375*fbadb1c4SDavid du Colombier
376*fbadb1c4SDavid du Colombier case ONOT:
377*fbadb1c4SDavid du Colombier if(nn == Z) {
378*fbadb1c4SDavid du Colombier nullwarn(l, Z);
379*fbadb1c4SDavid du Colombier break;
380*fbadb1c4SDavid du Colombier }
381*fbadb1c4SDavid du Colombier boolgen(n, 1, nn);
382*fbadb1c4SDavid du Colombier break;
383*fbadb1c4SDavid du Colombier
384*fbadb1c4SDavid du Colombier case OCOMMA:
385*fbadb1c4SDavid du Colombier cgen(l, Z);
386*fbadb1c4SDavid du Colombier cgen(r, nn);
387*fbadb1c4SDavid du Colombier break;
388*fbadb1c4SDavid du Colombier
389*fbadb1c4SDavid du Colombier case OCAST:
390*fbadb1c4SDavid du Colombier if(nn == Z) {
391*fbadb1c4SDavid du Colombier nullwarn(l, Z);
392*fbadb1c4SDavid du Colombier break;
393*fbadb1c4SDavid du Colombier }
394*fbadb1c4SDavid du Colombier /*
395*fbadb1c4SDavid du Colombier * convert from types l->n->nn
396*fbadb1c4SDavid du Colombier */
397*fbadb1c4SDavid du Colombier if(nocast(l->type, n->type) && nocast(n->type, nn->type)) {
398*fbadb1c4SDavid du Colombier /* both null, gen l->nn */
399*fbadb1c4SDavid du Colombier cgen(l, nn);
400*fbadb1c4SDavid du Colombier break;
401*fbadb1c4SDavid du Colombier }
402*fbadb1c4SDavid du Colombier regalloc(&nod, l, nn);
403*fbadb1c4SDavid du Colombier cgen(l, &nod);
404*fbadb1c4SDavid du Colombier regalloc(&nod1, n, &nod);
405*fbadb1c4SDavid du Colombier gopcode(OAS, &nod, Z, &nod1);
406*fbadb1c4SDavid du Colombier gopcode(OAS, &nod1, Z, nn);
407*fbadb1c4SDavid du Colombier regfree(&nod1);
408*fbadb1c4SDavid du Colombier regfree(&nod);
409*fbadb1c4SDavid du Colombier break;
410*fbadb1c4SDavid du Colombier
411*fbadb1c4SDavid du Colombier case ODOT:
412*fbadb1c4SDavid du Colombier sugen(l, nodrat, l->type->width);
413*fbadb1c4SDavid du Colombier if(nn != Z) {
414*fbadb1c4SDavid du Colombier warn(n, "non-interruptable temporary");
415*fbadb1c4SDavid du Colombier nod = *nodrat;
416*fbadb1c4SDavid du Colombier if(!r || r->op != OCONST) {
417*fbadb1c4SDavid du Colombier diag(n, "DOT and no offset");
418*fbadb1c4SDavid du Colombier break;
419*fbadb1c4SDavid du Colombier }
420*fbadb1c4SDavid du Colombier nod.xoffset += (long)r->vconst;
421*fbadb1c4SDavid du Colombier nod.type = n->type;
422*fbadb1c4SDavid du Colombier cgen(&nod, nn);
423*fbadb1c4SDavid du Colombier }
424*fbadb1c4SDavid du Colombier break;
425*fbadb1c4SDavid du Colombier
426*fbadb1c4SDavid du Colombier case OCOND:
427*fbadb1c4SDavid du Colombier bcgen(l, 1);
428*fbadb1c4SDavid du Colombier p1 = p;
429*fbadb1c4SDavid du Colombier cgen(r->left, nn);
430*fbadb1c4SDavid du Colombier gbranch(OGOTO);
431*fbadb1c4SDavid du Colombier patch(p1, pc);
432*fbadb1c4SDavid du Colombier p1 = p;
433*fbadb1c4SDavid du Colombier cgen(r->right, nn);
434*fbadb1c4SDavid du Colombier patch(p1, pc);
435*fbadb1c4SDavid du Colombier break;
436*fbadb1c4SDavid du Colombier
437*fbadb1c4SDavid du Colombier case OPOSTINC:
438*fbadb1c4SDavid du Colombier case OPOSTDEC:
439*fbadb1c4SDavid du Colombier v = 1;
440*fbadb1c4SDavid du Colombier if(l->type->etype == TIND)
441*fbadb1c4SDavid du Colombier v = l->type->link->width;
442*fbadb1c4SDavid du Colombier if(o == OPOSTDEC)
443*fbadb1c4SDavid du Colombier v = -v;
444*fbadb1c4SDavid du Colombier if(l->op == OBIT)
445*fbadb1c4SDavid du Colombier goto bitinc;
446*fbadb1c4SDavid du Colombier if(nn == Z)
447*fbadb1c4SDavid du Colombier goto pre;
448*fbadb1c4SDavid du Colombier
449*fbadb1c4SDavid du Colombier if(l->addable < INDEXED)
450*fbadb1c4SDavid du Colombier reglcgen(&nod2, l, Z);
451*fbadb1c4SDavid du Colombier else
452*fbadb1c4SDavid du Colombier nod2 = *l;
453*fbadb1c4SDavid du Colombier
454*fbadb1c4SDavid du Colombier regalloc(&nod, l, nn);
455*fbadb1c4SDavid du Colombier gopcode(OAS, &nod2, Z, &nod);
456*fbadb1c4SDavid du Colombier regalloc(&nod1, l, Z);
457*fbadb1c4SDavid du Colombier if(typefd[l->type->etype]) {
458*fbadb1c4SDavid du Colombier regalloc(&nod3, l, Z);
459*fbadb1c4SDavid du Colombier if(v < 0) {
460*fbadb1c4SDavid du Colombier gopcode(OAS, nodfconst(-v), Z, &nod3);
461*fbadb1c4SDavid du Colombier gopcode(OSUB, &nod3, &nod, &nod1);
462*fbadb1c4SDavid du Colombier } else {
463*fbadb1c4SDavid du Colombier gopcode(OAS, nodfconst(v), Z, &nod3);
464*fbadb1c4SDavid du Colombier gopcode(OADD, &nod3, &nod, &nod1);
465*fbadb1c4SDavid du Colombier }
466*fbadb1c4SDavid du Colombier regfree(&nod3);
467*fbadb1c4SDavid du Colombier } else
468*fbadb1c4SDavid du Colombier gopcode(OADD, nodconst(v), &nod, &nod1);
469*fbadb1c4SDavid du Colombier gopcode(OAS, &nod1, Z, &nod2);
470*fbadb1c4SDavid du Colombier
471*fbadb1c4SDavid du Colombier regfree(&nod);
472*fbadb1c4SDavid du Colombier regfree(&nod1);
473*fbadb1c4SDavid du Colombier if(l->addable < INDEXED)
474*fbadb1c4SDavid du Colombier regfree(&nod2);
475*fbadb1c4SDavid du Colombier break;
476*fbadb1c4SDavid du Colombier
477*fbadb1c4SDavid du Colombier case OPREINC:
478*fbadb1c4SDavid du Colombier case OPREDEC:
479*fbadb1c4SDavid du Colombier v = 1;
480*fbadb1c4SDavid du Colombier if(l->type->etype == TIND)
481*fbadb1c4SDavid du Colombier v = l->type->link->width;
482*fbadb1c4SDavid du Colombier if(o == OPREDEC)
483*fbadb1c4SDavid du Colombier v = -v;
484*fbadb1c4SDavid du Colombier if(l->op == OBIT)
485*fbadb1c4SDavid du Colombier goto bitinc;
486*fbadb1c4SDavid du Colombier
487*fbadb1c4SDavid du Colombier pre:
488*fbadb1c4SDavid du Colombier if(l->addable < INDEXED)
489*fbadb1c4SDavid du Colombier reglcgen(&nod2, l, Z);
490*fbadb1c4SDavid du Colombier else
491*fbadb1c4SDavid du Colombier nod2 = *l;
492*fbadb1c4SDavid du Colombier
493*fbadb1c4SDavid du Colombier regalloc(&nod, l, nn);
494*fbadb1c4SDavid du Colombier gopcode(OAS, &nod2, Z, &nod);
495*fbadb1c4SDavid du Colombier if(typefd[l->type->etype]) {
496*fbadb1c4SDavid du Colombier regalloc(&nod3, l, Z);
497*fbadb1c4SDavid du Colombier if(v < 0) {
498*fbadb1c4SDavid du Colombier gopcode(OAS, nodfconst(-v), Z, &nod3);
499*fbadb1c4SDavid du Colombier gopcode(OSUB, &nod3, Z, &nod);
500*fbadb1c4SDavid du Colombier } else {
501*fbadb1c4SDavid du Colombier gopcode(OAS, nodfconst(v), Z, &nod3);
502*fbadb1c4SDavid du Colombier gopcode(OADD, &nod3, Z, &nod);
503*fbadb1c4SDavid du Colombier }
504*fbadb1c4SDavid du Colombier regfree(&nod3);
505*fbadb1c4SDavid du Colombier } else
506*fbadb1c4SDavid du Colombier gopcode(OADD, nodconst(v), Z, &nod);
507*fbadb1c4SDavid du Colombier gopcode(OAS, &nod, Z, &nod2);
508*fbadb1c4SDavid du Colombier if(nn && l->op == ONAME) /* in x=++i, emit USED(i) */
509*fbadb1c4SDavid du Colombier gins(ANOP, l, Z);
510*fbadb1c4SDavid du Colombier
511*fbadb1c4SDavid du Colombier regfree(&nod);
512*fbadb1c4SDavid du Colombier if(l->addable < INDEXED)
513*fbadb1c4SDavid du Colombier regfree(&nod2);
514*fbadb1c4SDavid du Colombier break;
515*fbadb1c4SDavid du Colombier
516*fbadb1c4SDavid du Colombier bitinc:
517*fbadb1c4SDavid du Colombier if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
518*fbadb1c4SDavid du Colombier bitload(l, &nod, &nod1, &nod2, Z);
519*fbadb1c4SDavid du Colombier gopcode(OAS, &nod, Z, nn);
520*fbadb1c4SDavid du Colombier gopcode(OADD, nodconst(v), Z, &nod);
521*fbadb1c4SDavid du Colombier bitstore(l, &nod, &nod1, &nod2, Z);
522*fbadb1c4SDavid du Colombier break;
523*fbadb1c4SDavid du Colombier }
524*fbadb1c4SDavid du Colombier bitload(l, &nod, &nod1, &nod2, nn);
525*fbadb1c4SDavid du Colombier gopcode(OADD, nodconst(v), Z, &nod);
526*fbadb1c4SDavid du Colombier bitstore(l, &nod, &nod1, &nod2, nn);
527*fbadb1c4SDavid du Colombier break;
528*fbadb1c4SDavid du Colombier }
529*fbadb1c4SDavid du Colombier cursafe = curs;
530*fbadb1c4SDavid du Colombier }
531*fbadb1c4SDavid du Colombier
532*fbadb1c4SDavid du Colombier void
reglcgen(Node * t,Node * n,Node * nn)533*fbadb1c4SDavid du Colombier reglcgen(Node *t, Node *n, Node *nn)
534*fbadb1c4SDavid du Colombier {
535*fbadb1c4SDavid du Colombier Node *r;
536*fbadb1c4SDavid du Colombier long v;
537*fbadb1c4SDavid du Colombier
538*fbadb1c4SDavid du Colombier regialloc(t, n, nn);
539*fbadb1c4SDavid du Colombier if(n->op == OIND) {
540*fbadb1c4SDavid du Colombier r = n->left;
541*fbadb1c4SDavid du Colombier while(r->op == OADD)
542*fbadb1c4SDavid du Colombier r = r->right;
543*fbadb1c4SDavid du Colombier if(sconst(r)) {
544*fbadb1c4SDavid du Colombier v = r->vconst;
545*fbadb1c4SDavid du Colombier r->vconst = 0;
546*fbadb1c4SDavid du Colombier lcgen(n, t);
547*fbadb1c4SDavid du Colombier t->xoffset += v;
548*fbadb1c4SDavid du Colombier r->vconst = v;
549*fbadb1c4SDavid du Colombier regind(t, n);
550*fbadb1c4SDavid du Colombier return;
551*fbadb1c4SDavid du Colombier }
552*fbadb1c4SDavid du Colombier }
553*fbadb1c4SDavid du Colombier lcgen(n, t);
554*fbadb1c4SDavid du Colombier regind(t, n);
555*fbadb1c4SDavid du Colombier }
556*fbadb1c4SDavid du Colombier
557*fbadb1c4SDavid du Colombier void
lcgen(Node * n,Node * nn)558*fbadb1c4SDavid du Colombier lcgen(Node *n, Node *nn)
559*fbadb1c4SDavid du Colombier {
560*fbadb1c4SDavid du Colombier Prog *p1;
561*fbadb1c4SDavid du Colombier Node nod;
562*fbadb1c4SDavid du Colombier
563*fbadb1c4SDavid du Colombier if(debug['g']) {
564*fbadb1c4SDavid du Colombier prtree(nn, "lcgen lhs");
565*fbadb1c4SDavid du Colombier prtree(n, "lcgen");
566*fbadb1c4SDavid du Colombier }
567*fbadb1c4SDavid du Colombier if(n == Z || n->type == T)
568*fbadb1c4SDavid du Colombier return;
569*fbadb1c4SDavid du Colombier if(nn == Z) {
570*fbadb1c4SDavid du Colombier nn = &nod;
571*fbadb1c4SDavid du Colombier regalloc(&nod, n, Z);
572*fbadb1c4SDavid du Colombier }
573*fbadb1c4SDavid du Colombier switch(n->op) {
574*fbadb1c4SDavid du Colombier default:
575*fbadb1c4SDavid du Colombier if(n->addable < INDEXED) {
576*fbadb1c4SDavid du Colombier diag(n, "unknown op in lcgen: %O", n->op);
577*fbadb1c4SDavid du Colombier break;
578*fbadb1c4SDavid du Colombier }
579*fbadb1c4SDavid du Colombier nod = *n;
580*fbadb1c4SDavid du Colombier nod.op = OADDR;
581*fbadb1c4SDavid du Colombier nod.left = n;
582*fbadb1c4SDavid du Colombier nod.right = Z;
583*fbadb1c4SDavid du Colombier nod.type = types[TIND];
584*fbadb1c4SDavid du Colombier gopcode(OAS, &nod, Z, nn);
585*fbadb1c4SDavid du Colombier break;
586*fbadb1c4SDavid du Colombier
587*fbadb1c4SDavid du Colombier case OCOMMA:
588*fbadb1c4SDavid du Colombier cgen(n->left, n->left);
589*fbadb1c4SDavid du Colombier lcgen(n->right, nn);
590*fbadb1c4SDavid du Colombier break;
591*fbadb1c4SDavid du Colombier
592*fbadb1c4SDavid du Colombier case OIND:
593*fbadb1c4SDavid du Colombier cgen(n->left, nn);
594*fbadb1c4SDavid du Colombier break;
595*fbadb1c4SDavid du Colombier
596*fbadb1c4SDavid du Colombier case OCOND:
597*fbadb1c4SDavid du Colombier bcgen(n->left, 1);
598*fbadb1c4SDavid du Colombier p1 = p;
599*fbadb1c4SDavid du Colombier lcgen(n->right->left, nn);
600*fbadb1c4SDavid du Colombier gbranch(OGOTO);
601*fbadb1c4SDavid du Colombier patch(p1, pc);
602*fbadb1c4SDavid du Colombier p1 = p;
603*fbadb1c4SDavid du Colombier lcgen(n->right->right, nn);
604*fbadb1c4SDavid du Colombier patch(p1, pc);
605*fbadb1c4SDavid du Colombier break;
606*fbadb1c4SDavid du Colombier }
607*fbadb1c4SDavid du Colombier }
608*fbadb1c4SDavid du Colombier
609*fbadb1c4SDavid du Colombier void
bcgen(Node * n,int true)610*fbadb1c4SDavid du Colombier bcgen(Node *n, int true)
611*fbadb1c4SDavid du Colombier {
612*fbadb1c4SDavid du Colombier
613*fbadb1c4SDavid du Colombier if(n->type == T)
614*fbadb1c4SDavid du Colombier gbranch(OGOTO);
615*fbadb1c4SDavid du Colombier else
616*fbadb1c4SDavid du Colombier boolgen(n, true, Z);
617*fbadb1c4SDavid du Colombier }
618*fbadb1c4SDavid du Colombier
619*fbadb1c4SDavid du Colombier void
boolgen(Node * n,int true,Node * nn)620*fbadb1c4SDavid du Colombier boolgen(Node *n, int true, Node *nn)
621*fbadb1c4SDavid du Colombier {
622*fbadb1c4SDavid du Colombier int o;
623*fbadb1c4SDavid du Colombier Prog *p1, *p2;
624*fbadb1c4SDavid du Colombier Node *l, *r, nod, nod1;
625*fbadb1c4SDavid du Colombier long curs;
626*fbadb1c4SDavid du Colombier
627*fbadb1c4SDavid du Colombier if(debug['g']) {
628*fbadb1c4SDavid du Colombier prtree(nn, "boolgen lhs");
629*fbadb1c4SDavid du Colombier prtree(n, "boolgen");
630*fbadb1c4SDavid du Colombier }
631*fbadb1c4SDavid du Colombier curs = cursafe;
632*fbadb1c4SDavid du Colombier l = n->left;
633*fbadb1c4SDavid du Colombier r = n->right;
634*fbadb1c4SDavid du Colombier switch(n->op) {
635*fbadb1c4SDavid du Colombier
636*fbadb1c4SDavid du Colombier default:
637*fbadb1c4SDavid du Colombier if(n->op == OCONST) {
638*fbadb1c4SDavid du Colombier o = vconst(n);
639*fbadb1c4SDavid du Colombier if(!true)
640*fbadb1c4SDavid du Colombier o = !o;
641*fbadb1c4SDavid du Colombier gbranch(OGOTO);
642*fbadb1c4SDavid du Colombier if(o) {
643*fbadb1c4SDavid du Colombier p1 = p;
644*fbadb1c4SDavid du Colombier gbranch(OGOTO);
645*fbadb1c4SDavid du Colombier patch(p1, pc);
646*fbadb1c4SDavid du Colombier }
647*fbadb1c4SDavid du Colombier goto com;
648*fbadb1c4SDavid du Colombier }
649*fbadb1c4SDavid du Colombier regalloc(&nod, n, nn);
650*fbadb1c4SDavid du Colombier cgen(n, &nod);
651*fbadb1c4SDavid du Colombier o = ONE;
652*fbadb1c4SDavid du Colombier if(true)
653*fbadb1c4SDavid du Colombier o = comrel[relindex(o)];
654*fbadb1c4SDavid du Colombier if(typefd[n->type->etype]) {
655*fbadb1c4SDavid du Colombier nodreg(&nod1, n, NREG+FREGZERO);
656*fbadb1c4SDavid du Colombier gopcode(o, &nod, Z, &nod1);
657*fbadb1c4SDavid du Colombier } else
658*fbadb1c4SDavid du Colombier gopcode(o, &nod, Z, nodconst(0));
659*fbadb1c4SDavid du Colombier regfree(&nod);
660*fbadb1c4SDavid du Colombier goto com;
661*fbadb1c4SDavid du Colombier
662*fbadb1c4SDavid du Colombier case OCOMMA:
663*fbadb1c4SDavid du Colombier cgen(l, Z);
664*fbadb1c4SDavid du Colombier boolgen(r, true, nn);
665*fbadb1c4SDavid du Colombier break;
666*fbadb1c4SDavid du Colombier
667*fbadb1c4SDavid du Colombier case ONOT:
668*fbadb1c4SDavid du Colombier boolgen(l, !true, nn);
669*fbadb1c4SDavid du Colombier break;
670*fbadb1c4SDavid du Colombier
671*fbadb1c4SDavid du Colombier case OCOND:
672*fbadb1c4SDavid du Colombier bcgen(l, 1);
673*fbadb1c4SDavid du Colombier p1 = p;
674*fbadb1c4SDavid du Colombier bcgen(r->left, true);
675*fbadb1c4SDavid du Colombier p2 = p;
676*fbadb1c4SDavid du Colombier gbranch(OGOTO);
677*fbadb1c4SDavid du Colombier patch(p1, pc);
678*fbadb1c4SDavid du Colombier p1 = p;
679*fbadb1c4SDavid du Colombier bcgen(r->right, !true);
680*fbadb1c4SDavid du Colombier patch(p2, pc);
681*fbadb1c4SDavid du Colombier p2 = p;
682*fbadb1c4SDavid du Colombier gbranch(OGOTO);
683*fbadb1c4SDavid du Colombier patch(p1, pc);
684*fbadb1c4SDavid du Colombier patch(p2, pc);
685*fbadb1c4SDavid du Colombier goto com;
686*fbadb1c4SDavid du Colombier
687*fbadb1c4SDavid du Colombier case OANDAND:
688*fbadb1c4SDavid du Colombier if(!true)
689*fbadb1c4SDavid du Colombier goto caseor;
690*fbadb1c4SDavid du Colombier
691*fbadb1c4SDavid du Colombier caseand:
692*fbadb1c4SDavid du Colombier bcgen(l, true);
693*fbadb1c4SDavid du Colombier p1 = p;
694*fbadb1c4SDavid du Colombier bcgen(r, !true);
695*fbadb1c4SDavid du Colombier p2 = p;
696*fbadb1c4SDavid du Colombier patch(p1, pc);
697*fbadb1c4SDavid du Colombier gbranch(OGOTO);
698*fbadb1c4SDavid du Colombier patch(p2, pc);
699*fbadb1c4SDavid du Colombier goto com;
700*fbadb1c4SDavid du Colombier
701*fbadb1c4SDavid du Colombier case OOROR:
702*fbadb1c4SDavid du Colombier if(!true)
703*fbadb1c4SDavid du Colombier goto caseand;
704*fbadb1c4SDavid du Colombier
705*fbadb1c4SDavid du Colombier caseor:
706*fbadb1c4SDavid du Colombier bcgen(l, !true);
707*fbadb1c4SDavid du Colombier p1 = p;
708*fbadb1c4SDavid du Colombier bcgen(r, !true);
709*fbadb1c4SDavid du Colombier p2 = p;
710*fbadb1c4SDavid du Colombier gbranch(OGOTO);
711*fbadb1c4SDavid du Colombier patch(p1, pc);
712*fbadb1c4SDavid du Colombier patch(p2, pc);
713*fbadb1c4SDavid du Colombier goto com;
714*fbadb1c4SDavid du Colombier
715*fbadb1c4SDavid du Colombier case OEQ:
716*fbadb1c4SDavid du Colombier case ONE:
717*fbadb1c4SDavid du Colombier case OLE:
718*fbadb1c4SDavid du Colombier case OLT:
719*fbadb1c4SDavid du Colombier case OGE:
720*fbadb1c4SDavid du Colombier case OGT:
721*fbadb1c4SDavid du Colombier case OHI:
722*fbadb1c4SDavid du Colombier case OHS:
723*fbadb1c4SDavid du Colombier case OLO:
724*fbadb1c4SDavid du Colombier case OLS:
725*fbadb1c4SDavid du Colombier o = n->op;
726*fbadb1c4SDavid du Colombier if(true)
727*fbadb1c4SDavid du Colombier o = comrel[relindex(o)];
728*fbadb1c4SDavid du Colombier if(l->complex >= FNX && r->complex >= FNX) {
729*fbadb1c4SDavid du Colombier regret(&nod, r);
730*fbadb1c4SDavid du Colombier cgen(r, &nod);
731*fbadb1c4SDavid du Colombier regsalloc(&nod1, r);
732*fbadb1c4SDavid du Colombier gopcode(OAS, &nod, Z, &nod1);
733*fbadb1c4SDavid du Colombier regfree(&nod);
734*fbadb1c4SDavid du Colombier nod = *n;
735*fbadb1c4SDavid du Colombier nod.right = &nod1;
736*fbadb1c4SDavid du Colombier boolgen(&nod, true, nn);
737*fbadb1c4SDavid du Colombier break;
738*fbadb1c4SDavid du Colombier }
739*fbadb1c4SDavid du Colombier if(sconst(r)) {
740*fbadb1c4SDavid du Colombier regalloc(&nod, l, nn);
741*fbadb1c4SDavid du Colombier cgen(l, &nod);
742*fbadb1c4SDavid du Colombier gopcode(o, &nod, Z, r);
743*fbadb1c4SDavid du Colombier regfree(&nod);
744*fbadb1c4SDavid du Colombier goto com;
745*fbadb1c4SDavid du Colombier }
746*fbadb1c4SDavid du Colombier if(l->complex >= r->complex) {
747*fbadb1c4SDavid du Colombier regalloc(&nod1, l, nn);
748*fbadb1c4SDavid du Colombier cgen(l, &nod1);
749*fbadb1c4SDavid du Colombier regalloc(&nod, r, Z);
750*fbadb1c4SDavid du Colombier cgen(r, &nod);
751*fbadb1c4SDavid du Colombier } else {
752*fbadb1c4SDavid du Colombier regalloc(&nod, r, nn);
753*fbadb1c4SDavid du Colombier cgen(r, &nod);
754*fbadb1c4SDavid du Colombier regalloc(&nod1, l, Z);
755*fbadb1c4SDavid du Colombier cgen(l, &nod1);
756*fbadb1c4SDavid du Colombier }
757*fbadb1c4SDavid du Colombier gopcode(o, &nod1, Z, &nod);
758*fbadb1c4SDavid du Colombier regfree(&nod);
759*fbadb1c4SDavid du Colombier regfree(&nod1);
760*fbadb1c4SDavid du Colombier
761*fbadb1c4SDavid du Colombier com:
762*fbadb1c4SDavid du Colombier if(nn != Z) {
763*fbadb1c4SDavid du Colombier p1 = p;
764*fbadb1c4SDavid du Colombier gopcode(OAS, nodconst(1L), Z, nn);
765*fbadb1c4SDavid du Colombier gbranch(OGOTO);
766*fbadb1c4SDavid du Colombier p2 = p;
767*fbadb1c4SDavid du Colombier patch(p1, pc);
768*fbadb1c4SDavid du Colombier gopcode(OAS, nodconst(0L), Z, nn);
769*fbadb1c4SDavid du Colombier patch(p2, pc);
770*fbadb1c4SDavid du Colombier }
771*fbadb1c4SDavid du Colombier break;
772*fbadb1c4SDavid du Colombier }
773*fbadb1c4SDavid du Colombier cursafe = curs;
774*fbadb1c4SDavid du Colombier }
775*fbadb1c4SDavid du Colombier
776*fbadb1c4SDavid du Colombier void
sugen(Node * n,Node * nn,long w)777*fbadb1c4SDavid du Colombier sugen(Node *n, Node *nn, long w)
778*fbadb1c4SDavid du Colombier {
779*fbadb1c4SDavid du Colombier Prog *p1;
780*fbadb1c4SDavid du Colombier Node nod0, nod1, nod2, nod3, nod4, *l, *r;
781*fbadb1c4SDavid du Colombier Type *t;
782*fbadb1c4SDavid du Colombier long pc1;
783*fbadb1c4SDavid du Colombier int i, m, c;
784*fbadb1c4SDavid du Colombier
785*fbadb1c4SDavid du Colombier if(n == Z || n->type == T)
786*fbadb1c4SDavid du Colombier return;
787*fbadb1c4SDavid du Colombier if(debug['g']) {
788*fbadb1c4SDavid du Colombier prtree(nn, "sugen lhs");
789*fbadb1c4SDavid du Colombier prtree(n, "sugen");
790*fbadb1c4SDavid du Colombier }
791*fbadb1c4SDavid du Colombier if(nn == nodrat)
792*fbadb1c4SDavid du Colombier if(w > nrathole)
793*fbadb1c4SDavid du Colombier nrathole = w;
794*fbadb1c4SDavid du Colombier switch(n->op) {
795*fbadb1c4SDavid du Colombier case OIND:
796*fbadb1c4SDavid du Colombier if(nn == Z) {
797*fbadb1c4SDavid du Colombier nullwarn(n->left, Z);
798*fbadb1c4SDavid du Colombier break;
799*fbadb1c4SDavid du Colombier }
800*fbadb1c4SDavid du Colombier
801*fbadb1c4SDavid du Colombier default:
802*fbadb1c4SDavid du Colombier goto copy;
803*fbadb1c4SDavid du Colombier
804*fbadb1c4SDavid du Colombier case OCONST:
805*fbadb1c4SDavid du Colombier if(n->type && typev[n->type->etype]) {
806*fbadb1c4SDavid du Colombier if(nn == Z) {
807*fbadb1c4SDavid du Colombier nullwarn(n->left, Z);
808*fbadb1c4SDavid du Colombier break;
809*fbadb1c4SDavid du Colombier }
810*fbadb1c4SDavid du Colombier
811*fbadb1c4SDavid du Colombier t = nn->type;
812*fbadb1c4SDavid du Colombier nn->type = types[TLONG];
813*fbadb1c4SDavid du Colombier reglcgen(&nod1, nn, Z);
814*fbadb1c4SDavid du Colombier nn->type = t;
815*fbadb1c4SDavid du Colombier
816*fbadb1c4SDavid du Colombier if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
817*fbadb1c4SDavid du Colombier gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
818*fbadb1c4SDavid du Colombier else
819*fbadb1c4SDavid du Colombier gopcode(OAS, nod32const(n->vconst), Z, &nod1);
820*fbadb1c4SDavid du Colombier nod1.xoffset += SZ_LONG;
821*fbadb1c4SDavid du Colombier if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
822*fbadb1c4SDavid du Colombier gopcode(OAS, nod32const(n->vconst), Z, &nod1);
823*fbadb1c4SDavid du Colombier else
824*fbadb1c4SDavid du Colombier gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
825*fbadb1c4SDavid du Colombier
826*fbadb1c4SDavid du Colombier regfree(&nod1);
827*fbadb1c4SDavid du Colombier break;
828*fbadb1c4SDavid du Colombier }
829*fbadb1c4SDavid du Colombier goto copy;
830*fbadb1c4SDavid du Colombier
831*fbadb1c4SDavid du Colombier case ODOT:
832*fbadb1c4SDavid du Colombier l = n->left;
833*fbadb1c4SDavid du Colombier sugen(l, nodrat, l->type->width);
834*fbadb1c4SDavid du Colombier if(nn != Z) {
835*fbadb1c4SDavid du Colombier warn(n, "non-interruptable temporary");
836*fbadb1c4SDavid du Colombier nod1 = *nodrat;
837*fbadb1c4SDavid du Colombier r = n->right;
838*fbadb1c4SDavid du Colombier if(!r || r->op != OCONST) {
839*fbadb1c4SDavid du Colombier diag(n, "DOT and no offset");
840*fbadb1c4SDavid du Colombier break;
841*fbadb1c4SDavid du Colombier }
842*fbadb1c4SDavid du Colombier nod1.xoffset += (long)r->vconst;
843*fbadb1c4SDavid du Colombier nod1.type = n->type;
844*fbadb1c4SDavid du Colombier sugen(&nod1, nn, w);
845*fbadb1c4SDavid du Colombier }
846*fbadb1c4SDavid du Colombier break;
847*fbadb1c4SDavid du Colombier
848*fbadb1c4SDavid du Colombier case OSTRUCT:
849*fbadb1c4SDavid du Colombier /*
850*fbadb1c4SDavid du Colombier * rewrite so lhs has no side effects
851*fbadb1c4SDavid du Colombier */
852*fbadb1c4SDavid du Colombier if(nn != Z && side(nn)) {
853*fbadb1c4SDavid du Colombier nod1 = *n;
854*fbadb1c4SDavid du Colombier nod1.type = typ(TIND, n->type);
855*fbadb1c4SDavid du Colombier regalloc(&nod2, &nod1, Z);
856*fbadb1c4SDavid du Colombier lcgen(nn, &nod2);
857*fbadb1c4SDavid du Colombier regsalloc(&nod0, &nod1);
858*fbadb1c4SDavid du Colombier gopcode(OAS, &nod2, Z, &nod0);
859*fbadb1c4SDavid du Colombier regfree(&nod2);
860*fbadb1c4SDavid du Colombier
861*fbadb1c4SDavid du Colombier nod1 = *n;
862*fbadb1c4SDavid du Colombier nod1.op = OIND;
863*fbadb1c4SDavid du Colombier nod1.left = &nod0;
864*fbadb1c4SDavid du Colombier nod1.right = Z;
865*fbadb1c4SDavid du Colombier nod1.complex = 1;
866*fbadb1c4SDavid du Colombier
867*fbadb1c4SDavid du Colombier sugen(n, &nod1, w);
868*fbadb1c4SDavid du Colombier return;
869*fbadb1c4SDavid du Colombier }
870*fbadb1c4SDavid du Colombier
871*fbadb1c4SDavid du Colombier r = n->left;
872*fbadb1c4SDavid du Colombier for(t = n->type->link; t != T; t = t->down) {
873*fbadb1c4SDavid du Colombier l = r;
874*fbadb1c4SDavid du Colombier if(r->op == OLIST) {
875*fbadb1c4SDavid du Colombier l = r->left;
876*fbadb1c4SDavid du Colombier r = r->right;
877*fbadb1c4SDavid du Colombier }
878*fbadb1c4SDavid du Colombier if(nn == Z) {
879*fbadb1c4SDavid du Colombier cgen(l, nn);
880*fbadb1c4SDavid du Colombier continue;
881*fbadb1c4SDavid du Colombier }
882*fbadb1c4SDavid du Colombier /*
883*fbadb1c4SDavid du Colombier * hand craft *(&nn + o) = l
884*fbadb1c4SDavid du Colombier */
885*fbadb1c4SDavid du Colombier nod0 = znode;
886*fbadb1c4SDavid du Colombier nod0.op = OAS;
887*fbadb1c4SDavid du Colombier nod0.type = t;
888*fbadb1c4SDavid du Colombier nod0.left = &nod1;
889*fbadb1c4SDavid du Colombier nod0.right = l;
890*fbadb1c4SDavid du Colombier
891*fbadb1c4SDavid du Colombier nod1 = znode;
892*fbadb1c4SDavid du Colombier nod1.op = OIND;
893*fbadb1c4SDavid du Colombier nod1.type = t;
894*fbadb1c4SDavid du Colombier nod1.left = &nod2;
895*fbadb1c4SDavid du Colombier
896*fbadb1c4SDavid du Colombier nod2 = znode;
897*fbadb1c4SDavid du Colombier nod2.op = OADD;
898*fbadb1c4SDavid du Colombier nod2.type = typ(TIND, t);
899*fbadb1c4SDavid du Colombier nod2.left = &nod3;
900*fbadb1c4SDavid du Colombier nod2.right = &nod4;
901*fbadb1c4SDavid du Colombier
902*fbadb1c4SDavid du Colombier nod3 = znode;
903*fbadb1c4SDavid du Colombier nod3.op = OADDR;
904*fbadb1c4SDavid du Colombier nod3.type = nod2.type;
905*fbadb1c4SDavid du Colombier nod3.left = nn;
906*fbadb1c4SDavid du Colombier
907*fbadb1c4SDavid du Colombier nod4 = znode;
908*fbadb1c4SDavid du Colombier nod4.op = OCONST;
909*fbadb1c4SDavid du Colombier nod4.type = nod2.type;
910*fbadb1c4SDavid du Colombier nod4.vconst = t->offset;
911*fbadb1c4SDavid du Colombier
912*fbadb1c4SDavid du Colombier ccom(&nod0);
913*fbadb1c4SDavid du Colombier acom(&nod0);
914*fbadb1c4SDavid du Colombier xcom(&nod0);
915*fbadb1c4SDavid du Colombier nod0.addable = 0;
916*fbadb1c4SDavid du Colombier
917*fbadb1c4SDavid du Colombier /* prtree(&nod0, "hand craft"); /* */
918*fbadb1c4SDavid du Colombier cgen(&nod0, Z);
919*fbadb1c4SDavid du Colombier }
920*fbadb1c4SDavid du Colombier break;
921*fbadb1c4SDavid du Colombier
922*fbadb1c4SDavid du Colombier case OAS:
923*fbadb1c4SDavid du Colombier if(nn == Z) {
924*fbadb1c4SDavid du Colombier if(n->addable < INDEXED)
925*fbadb1c4SDavid du Colombier sugen(n->right, n->left, w);
926*fbadb1c4SDavid du Colombier break;
927*fbadb1c4SDavid du Colombier }
928*fbadb1c4SDavid du Colombier /* BOTCH -- functions can clobber rathole */
929*fbadb1c4SDavid du Colombier sugen(n->right, nodrat, w);
930*fbadb1c4SDavid du Colombier warn(n, "non-interruptable temporary");
931*fbadb1c4SDavid du Colombier sugen(nodrat, n->left, w);
932*fbadb1c4SDavid du Colombier sugen(nodrat, nn, w);
933*fbadb1c4SDavid du Colombier break;
934*fbadb1c4SDavid du Colombier
935*fbadb1c4SDavid du Colombier case OFUNC:
936*fbadb1c4SDavid du Colombier if(nn == Z) {
937*fbadb1c4SDavid du Colombier sugen(n, nodrat, w);
938*fbadb1c4SDavid du Colombier break;
939*fbadb1c4SDavid du Colombier }
940*fbadb1c4SDavid du Colombier if(nn->op != OIND) {
941*fbadb1c4SDavid du Colombier nn = new1(OADDR, nn, Z);
942*fbadb1c4SDavid du Colombier nn->type = types[TIND];
943*fbadb1c4SDavid du Colombier nn->addable = 0;
944*fbadb1c4SDavid du Colombier } else
945*fbadb1c4SDavid du Colombier nn = nn->left;
946*fbadb1c4SDavid du Colombier n = new(OFUNC, n->left, new(OLIST, nn, n->right));
947*fbadb1c4SDavid du Colombier n->type = types[TVOID];
948*fbadb1c4SDavid du Colombier n->left->type = types[TVOID];
949*fbadb1c4SDavid du Colombier cgen(n, Z);
950*fbadb1c4SDavid du Colombier break;
951*fbadb1c4SDavid du Colombier
952*fbadb1c4SDavid du Colombier case OCOND:
953*fbadb1c4SDavid du Colombier bcgen(n->left, 1);
954*fbadb1c4SDavid du Colombier p1 = p;
955*fbadb1c4SDavid du Colombier sugen(n->right->left, nn, w);
956*fbadb1c4SDavid du Colombier gbranch(OGOTO);
957*fbadb1c4SDavid du Colombier patch(p1, pc);
958*fbadb1c4SDavid du Colombier p1 = p;
959*fbadb1c4SDavid du Colombier sugen(n->right->right, nn, w);
960*fbadb1c4SDavid du Colombier patch(p1, pc);
961*fbadb1c4SDavid du Colombier break;
962*fbadb1c4SDavid du Colombier
963*fbadb1c4SDavid du Colombier case OCOMMA:
964*fbadb1c4SDavid du Colombier cgen(n->left, Z);
965*fbadb1c4SDavid du Colombier sugen(n->right, nn, w);
966*fbadb1c4SDavid du Colombier break;
967*fbadb1c4SDavid du Colombier }
968*fbadb1c4SDavid du Colombier return;
969*fbadb1c4SDavid du Colombier
970*fbadb1c4SDavid du Colombier copy:
971*fbadb1c4SDavid du Colombier if(nn == Z)
972*fbadb1c4SDavid du Colombier return;
973*fbadb1c4SDavid du Colombier if(n->complex >= FNX && nn->complex >= FNX) {
974*fbadb1c4SDavid du Colombier t = nn->type;
975*fbadb1c4SDavid du Colombier nn->type = types[TLONG];
976*fbadb1c4SDavid du Colombier regialloc(&nod1, nn, Z);
977*fbadb1c4SDavid du Colombier lcgen(nn, &nod1);
978*fbadb1c4SDavid du Colombier regsalloc(&nod2, nn);
979*fbadb1c4SDavid du Colombier nn->type = t;
980*fbadb1c4SDavid du Colombier
981*fbadb1c4SDavid du Colombier gopcode(OAS, &nod1, Z, &nod2);
982*fbadb1c4SDavid du Colombier regfree(&nod1);
983*fbadb1c4SDavid du Colombier
984*fbadb1c4SDavid du Colombier nod2.type = typ(TIND, t);
985*fbadb1c4SDavid du Colombier
986*fbadb1c4SDavid du Colombier nod1 = nod2;
987*fbadb1c4SDavid du Colombier nod1.op = OIND;
988*fbadb1c4SDavid du Colombier nod1.left = &nod2;
989*fbadb1c4SDavid du Colombier nod1.right = Z;
990*fbadb1c4SDavid du Colombier nod1.complex = 1;
991*fbadb1c4SDavid du Colombier nod1.type = t;
992*fbadb1c4SDavid du Colombier
993*fbadb1c4SDavid du Colombier sugen(n, &nod1, w);
994*fbadb1c4SDavid du Colombier return;
995*fbadb1c4SDavid du Colombier }
996*fbadb1c4SDavid du Colombier
997*fbadb1c4SDavid du Colombier if(n->complex > nn->complex) {
998*fbadb1c4SDavid du Colombier t = n->type;
999*fbadb1c4SDavid du Colombier n->type = types[TLONG];
1000*fbadb1c4SDavid du Colombier reglcgen(&nod1, n, Z);
1001*fbadb1c4SDavid du Colombier n->type = t;
1002*fbadb1c4SDavid du Colombier
1003*fbadb1c4SDavid du Colombier t = nn->type;
1004*fbadb1c4SDavid du Colombier nn->type = types[TLONG];
1005*fbadb1c4SDavid du Colombier reglcgen(&nod2, nn, Z);
1006*fbadb1c4SDavid du Colombier nn->type = t;
1007*fbadb1c4SDavid du Colombier } else {
1008*fbadb1c4SDavid du Colombier t = nn->type;
1009*fbadb1c4SDavid du Colombier nn->type = types[TLONG];
1010*fbadb1c4SDavid du Colombier reglcgen(&nod2, nn, Z);
1011*fbadb1c4SDavid du Colombier nn->type = t;
1012*fbadb1c4SDavid du Colombier
1013*fbadb1c4SDavid du Colombier t = n->type;
1014*fbadb1c4SDavid du Colombier n->type = types[TLONG];
1015*fbadb1c4SDavid du Colombier reglcgen(&nod1, n, Z);
1016*fbadb1c4SDavid du Colombier n->type = t;
1017*fbadb1c4SDavid du Colombier }
1018*fbadb1c4SDavid du Colombier
1019*fbadb1c4SDavid du Colombier w /= SZ_LONG;
1020*fbadb1c4SDavid du Colombier if(w <= 5) {
1021*fbadb1c4SDavid du Colombier layout(&nod1, &nod2, w, 0, Z);
1022*fbadb1c4SDavid du Colombier goto out;
1023*fbadb1c4SDavid du Colombier }
1024*fbadb1c4SDavid du Colombier
1025*fbadb1c4SDavid du Colombier /*
1026*fbadb1c4SDavid du Colombier * minimize space for unrolling loop
1027*fbadb1c4SDavid du Colombier * 3,4,5 times. (6 or more is never minimum)
1028*fbadb1c4SDavid du Colombier * if small structure, try 2 also.
1029*fbadb1c4SDavid du Colombier */
1030*fbadb1c4SDavid du Colombier c = 0; /* set */
1031*fbadb1c4SDavid du Colombier m = 100;
1032*fbadb1c4SDavid du Colombier i = 3;
1033*fbadb1c4SDavid du Colombier if(w <= 15)
1034*fbadb1c4SDavid du Colombier i = 2;
1035*fbadb1c4SDavid du Colombier for(; i<=5; i++)
1036*fbadb1c4SDavid du Colombier if(i + w%i <= m) {
1037*fbadb1c4SDavid du Colombier c = i;
1038*fbadb1c4SDavid du Colombier m = c + w%c;
1039*fbadb1c4SDavid du Colombier }
1040*fbadb1c4SDavid du Colombier
1041*fbadb1c4SDavid du Colombier regalloc(&nod3, ®node, Z);
1042*fbadb1c4SDavid du Colombier layout(&nod1, &nod2, w%c, w/c, &nod3);
1043*fbadb1c4SDavid du Colombier
1044*fbadb1c4SDavid du Colombier pc1 = pc;
1045*fbadb1c4SDavid du Colombier layout(&nod1, &nod2, c, 0, Z);
1046*fbadb1c4SDavid du Colombier
1047*fbadb1c4SDavid du Colombier gopcode(OSUB, nodconst(1L), Z, &nod3);
1048*fbadb1c4SDavid du Colombier nod1.op = OREGISTER;
1049*fbadb1c4SDavid du Colombier gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod1);
1050*fbadb1c4SDavid du Colombier nod2.op = OREGISTER;
1051*fbadb1c4SDavid du Colombier gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod2);
1052*fbadb1c4SDavid du Colombier
1053*fbadb1c4SDavid du Colombier gopcode(OGT, &nod3, Z, nodconst(0));
1054*fbadb1c4SDavid du Colombier patch(p, pc1);
1055*fbadb1c4SDavid du Colombier
1056*fbadb1c4SDavid du Colombier regfree(&nod3);
1057*fbadb1c4SDavid du Colombier out:
1058*fbadb1c4SDavid du Colombier regfree(&nod1);
1059*fbadb1c4SDavid du Colombier regfree(&nod2);
1060*fbadb1c4SDavid du Colombier }
1061*fbadb1c4SDavid du Colombier
1062*fbadb1c4SDavid du Colombier void
layout(Node * f,Node * t,int c,int cv,Node * cn)1063*fbadb1c4SDavid du Colombier layout(Node *f, Node *t, int c, int cv, Node *cn)
1064*fbadb1c4SDavid du Colombier {
1065*fbadb1c4SDavid du Colombier Node t1, t2;
1066*fbadb1c4SDavid du Colombier
1067*fbadb1c4SDavid du Colombier while(c > 3) {
1068*fbadb1c4SDavid du Colombier layout(f, t, 2, 0, Z);
1069*fbadb1c4SDavid du Colombier c -= 2;
1070*fbadb1c4SDavid du Colombier }
1071*fbadb1c4SDavid du Colombier
1072*fbadb1c4SDavid du Colombier regalloc(&t1, ®node, Z);
1073*fbadb1c4SDavid du Colombier regalloc(&t2, ®node, Z);
1074*fbadb1c4SDavid du Colombier if(c > 0) {
1075*fbadb1c4SDavid du Colombier gopcode(OAS, f, Z, &t1);
1076*fbadb1c4SDavid du Colombier f->xoffset += SZ_LONG;
1077*fbadb1c4SDavid du Colombier }
1078*fbadb1c4SDavid du Colombier if(cn != Z)
1079*fbadb1c4SDavid du Colombier gopcode(OAS, nodconst(cv), Z, cn);
1080*fbadb1c4SDavid du Colombier if(c > 1) {
1081*fbadb1c4SDavid du Colombier gopcode(OAS, f, Z, &t2);
1082*fbadb1c4SDavid du Colombier f->xoffset += SZ_LONG;
1083*fbadb1c4SDavid du Colombier }
1084*fbadb1c4SDavid du Colombier if(c > 0) {
1085*fbadb1c4SDavid du Colombier gopcode(OAS, &t1, Z, t);
1086*fbadb1c4SDavid du Colombier t->xoffset += SZ_LONG;
1087*fbadb1c4SDavid du Colombier }
1088*fbadb1c4SDavid du Colombier if(c > 2) {
1089*fbadb1c4SDavid du Colombier gopcode(OAS, f, Z, &t1);
1090*fbadb1c4SDavid du Colombier f->xoffset += SZ_LONG;
1091*fbadb1c4SDavid du Colombier }
1092*fbadb1c4SDavid du Colombier if(c > 1) {
1093*fbadb1c4SDavid du Colombier gopcode(OAS, &t2, Z, t);
1094*fbadb1c4SDavid du Colombier t->xoffset += SZ_LONG;
1095*fbadb1c4SDavid du Colombier }
1096*fbadb1c4SDavid du Colombier if(c > 2) {
1097*fbadb1c4SDavid du Colombier gopcode(OAS, &t1, Z, t);
1098*fbadb1c4SDavid du Colombier t->xoffset += SZ_LONG;
1099*fbadb1c4SDavid du Colombier }
1100*fbadb1c4SDavid du Colombier regfree(&t1);
1101*fbadb1c4SDavid du Colombier regfree(&t2);
1102*fbadb1c4SDavid du Colombier }
1103