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