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