xref: /plan9/sys/src/cmd/cc/pgen.c (revision 4ac975e2e38b792d24bc60de7fce5e6173f046ea)
1*4ac975e2SDavid du Colombier #include "gc.h"
2*4ac975e2SDavid du Colombier 
3*4ac975e2SDavid du Colombier void
4*4ac975e2SDavid du Colombier codgen(Node *n, Node *nn)
5*4ac975e2SDavid du Colombier {
6*4ac975e2SDavid du Colombier 	Prog *sp;
7*4ac975e2SDavid du Colombier 	Node *n1, nod, nod1;
8*4ac975e2SDavid du Colombier 
9*4ac975e2SDavid du Colombier 	cursafe = 0;
10*4ac975e2SDavid du Colombier 	curarg = 0;
11*4ac975e2SDavid du Colombier 	maxargsafe = 0;
12*4ac975e2SDavid du Colombier 
13*4ac975e2SDavid du Colombier 	/*
14*4ac975e2SDavid du Colombier 	 * isolate name
15*4ac975e2SDavid du Colombier 	 */
16*4ac975e2SDavid du Colombier 	for(n1 = nn;; n1 = n1->left) {
17*4ac975e2SDavid du Colombier 		if(n1 == Z) {
18*4ac975e2SDavid du Colombier 			diag(nn, "cant find function name");
19*4ac975e2SDavid du Colombier 			return;
20*4ac975e2SDavid du Colombier 		}
21*4ac975e2SDavid du Colombier 		if(n1->op == ONAME)
22*4ac975e2SDavid du Colombier 			break;
23*4ac975e2SDavid du Colombier 	}
24*4ac975e2SDavid du Colombier 	nearln = nn->lineno;
25*4ac975e2SDavid du Colombier 	gpseudo(ATEXT, n1->sym, nodconst(stkoff));
26*4ac975e2SDavid du Colombier 	sp = p;
27*4ac975e2SDavid du Colombier 
28*4ac975e2SDavid du Colombier 	/*
29*4ac975e2SDavid du Colombier 	 * isolate first argument
30*4ac975e2SDavid du Colombier 	 */
31*4ac975e2SDavid du Colombier 	if(REGARG >= 0) {
32*4ac975e2SDavid du Colombier 		if(typecmplx[thisfn->link->etype]) {
33*4ac975e2SDavid du Colombier 			nod1 = *nodret->left;
34*4ac975e2SDavid du Colombier 			nodreg(&nod, &nod1, REGARG);
35*4ac975e2SDavid du Colombier 			gmove(&nod, &nod1);
36*4ac975e2SDavid du Colombier 		} else
37*4ac975e2SDavid du Colombier 		if(firstarg && typeword[firstargtype->etype]) {
38*4ac975e2SDavid du Colombier 			nod1 = *nodret->left;
39*4ac975e2SDavid du Colombier 			nod1.sym = firstarg;
40*4ac975e2SDavid du Colombier 			nod1.type = firstargtype;
41*4ac975e2SDavid du Colombier 			nod1.xoffset = align(0, firstargtype, Aarg1);
42*4ac975e2SDavid du Colombier 			nod1.etype = firstargtype->etype;
43*4ac975e2SDavid du Colombier 			nodreg(&nod, &nod1, REGARG);
44*4ac975e2SDavid du Colombier 			gmove(&nod, &nod1);
45*4ac975e2SDavid du Colombier 		}
46*4ac975e2SDavid du Colombier 	}
47*4ac975e2SDavid du Colombier 
48*4ac975e2SDavid du Colombier 	retok = 0;
49*4ac975e2SDavid du Colombier 	gen(n);
50*4ac975e2SDavid du Colombier 	if(!retok)
51*4ac975e2SDavid du Colombier 		if(thisfn->link->etype != TVOID)
52*4ac975e2SDavid du Colombier 			warn(Z, "no return at end of function: %s", n1->sym->name);
53*4ac975e2SDavid du Colombier 	noretval(3);
54*4ac975e2SDavid du Colombier 	gbranch(ORETURN);
55*4ac975e2SDavid du Colombier 
56*4ac975e2SDavid du Colombier 	if(!debug['N'] || debug['R'] || debug['P'])
57*4ac975e2SDavid du Colombier 		regopt(sp);
58*4ac975e2SDavid du Colombier 
59*4ac975e2SDavid du Colombier 	if(thechar=='6' || thechar=='7')	/* [sic] */
60*4ac975e2SDavid du Colombier 		maxargsafe = round(maxargsafe, 8);
61*4ac975e2SDavid du Colombier 	sp->to.offset += maxargsafe;
62*4ac975e2SDavid du Colombier }
63*4ac975e2SDavid du Colombier 
64*4ac975e2SDavid du Colombier void
65*4ac975e2SDavid du Colombier supgen(Node *n)
66*4ac975e2SDavid du Colombier {
67*4ac975e2SDavid du Colombier 	long spc;
68*4ac975e2SDavid du Colombier 	Prog *sp;
69*4ac975e2SDavid du Colombier 
70*4ac975e2SDavid du Colombier 	if(n == Z)
71*4ac975e2SDavid du Colombier 		return;
72*4ac975e2SDavid du Colombier 	suppress++;
73*4ac975e2SDavid du Colombier 	spc = pc;
74*4ac975e2SDavid du Colombier 	sp = lastp;
75*4ac975e2SDavid du Colombier 	gen(n);
76*4ac975e2SDavid du Colombier 	lastp = sp;
77*4ac975e2SDavid du Colombier 	pc = spc;
78*4ac975e2SDavid du Colombier 	sp->link = nil;
79*4ac975e2SDavid du Colombier 	suppress--;
80*4ac975e2SDavid du Colombier }
81*4ac975e2SDavid du Colombier 
82*4ac975e2SDavid du Colombier void
83*4ac975e2SDavid du Colombier gen(Node *n)
84*4ac975e2SDavid du Colombier {
85*4ac975e2SDavid du Colombier 	Node *l, nod;
86*4ac975e2SDavid du Colombier 	Prog *sp, *spc, *spb;
87*4ac975e2SDavid du Colombier 	Case *cn;
88*4ac975e2SDavid du Colombier 	long sbc, scc;
89*4ac975e2SDavid du Colombier 	int snbreak;
90*4ac975e2SDavid du Colombier 	int f, o, ok;
91*4ac975e2SDavid du Colombier 
92*4ac975e2SDavid du Colombier loop:
93*4ac975e2SDavid du Colombier 	if(n == Z)
94*4ac975e2SDavid du Colombier 		return;
95*4ac975e2SDavid du Colombier 	nearln = n->lineno;
96*4ac975e2SDavid du Colombier 	o = n->op;
97*4ac975e2SDavid du Colombier 	if(debug['G'])
98*4ac975e2SDavid du Colombier 		if(o != OLIST)
99*4ac975e2SDavid du Colombier 			print("%L %O\n", nearln, o);
100*4ac975e2SDavid du Colombier 
101*4ac975e2SDavid du Colombier 	retok = 0;
102*4ac975e2SDavid du Colombier 	switch(o) {
103*4ac975e2SDavid du Colombier 
104*4ac975e2SDavid du Colombier 	default:
105*4ac975e2SDavid du Colombier 		complex(n);
106*4ac975e2SDavid du Colombier 		cgen(n, Z);
107*4ac975e2SDavid du Colombier 		break;
108*4ac975e2SDavid du Colombier 
109*4ac975e2SDavid du Colombier 	case OLIST:
110*4ac975e2SDavid du Colombier 		gen(n->left);
111*4ac975e2SDavid du Colombier 
112*4ac975e2SDavid du Colombier 	rloop:
113*4ac975e2SDavid du Colombier 		n = n->right;
114*4ac975e2SDavid du Colombier 		goto loop;
115*4ac975e2SDavid du Colombier 
116*4ac975e2SDavid du Colombier 	case ORETURN:
117*4ac975e2SDavid du Colombier 		retok = 1;
118*4ac975e2SDavid du Colombier 		complex(n);
119*4ac975e2SDavid du Colombier 		if(n->type == T)
120*4ac975e2SDavid du Colombier 			break;
121*4ac975e2SDavid du Colombier 		l = n->left;
122*4ac975e2SDavid du Colombier 		if(l == Z) {
123*4ac975e2SDavid du Colombier 			noretval(3);
124*4ac975e2SDavid du Colombier 			gbranch(ORETURN);
125*4ac975e2SDavid du Colombier 			break;
126*4ac975e2SDavid du Colombier 		}
127*4ac975e2SDavid du Colombier 		if(typecmplx[n->type->etype]) {
128*4ac975e2SDavid du Colombier 			sugen(l, nodret, n->type->width);
129*4ac975e2SDavid du Colombier 			noretval(3);
130*4ac975e2SDavid du Colombier 			gbranch(ORETURN);
131*4ac975e2SDavid du Colombier 			break;
132*4ac975e2SDavid du Colombier 		}
133*4ac975e2SDavid du Colombier 		regret(&nod, n);
134*4ac975e2SDavid du Colombier 		cgen(l, &nod);
135*4ac975e2SDavid du Colombier 		regfree(&nod);
136*4ac975e2SDavid du Colombier 		if(typefd[n->type->etype])
137*4ac975e2SDavid du Colombier 			noretval(1);
138*4ac975e2SDavid du Colombier 		else
139*4ac975e2SDavid du Colombier 			noretval(2);
140*4ac975e2SDavid du Colombier 		gbranch(ORETURN);
141*4ac975e2SDavid du Colombier 		break;
142*4ac975e2SDavid du Colombier 
143*4ac975e2SDavid du Colombier 	case OLABEL:
144*4ac975e2SDavid du Colombier 		l = n->left;
145*4ac975e2SDavid du Colombier 		if(l) {
146*4ac975e2SDavid du Colombier 			l->pc = pc;
147*4ac975e2SDavid du Colombier 			if(l->label)
148*4ac975e2SDavid du Colombier 				patch(l->label, pc);
149*4ac975e2SDavid du Colombier 		}
150*4ac975e2SDavid du Colombier 		gbranch(OGOTO);	/* prevent self reference in reg */
151*4ac975e2SDavid du Colombier 		patch(p, pc);
152*4ac975e2SDavid du Colombier 		goto rloop;
153*4ac975e2SDavid du Colombier 
154*4ac975e2SDavid du Colombier 	case OGOTO:
155*4ac975e2SDavid du Colombier 		retok = 1;
156*4ac975e2SDavid du Colombier 		n = n->left;
157*4ac975e2SDavid du Colombier 		if(n == Z)
158*4ac975e2SDavid du Colombier 			return;
159*4ac975e2SDavid du Colombier 		if(n->complex == 0) {
160*4ac975e2SDavid du Colombier 			diag(Z, "label undefined: %s", n->sym->name);
161*4ac975e2SDavid du Colombier 			return;
162*4ac975e2SDavid du Colombier 		}
163*4ac975e2SDavid du Colombier 		if(suppress)
164*4ac975e2SDavid du Colombier 			return;
165*4ac975e2SDavid du Colombier 		gbranch(OGOTO);
166*4ac975e2SDavid du Colombier 		if(n->pc) {
167*4ac975e2SDavid du Colombier 			patch(p, n->pc);
168*4ac975e2SDavid du Colombier 			return;
169*4ac975e2SDavid du Colombier 		}
170*4ac975e2SDavid du Colombier 		if(n->label)
171*4ac975e2SDavid du Colombier 			patch(n->label, pc-1);
172*4ac975e2SDavid du Colombier 		n->label = p;
173*4ac975e2SDavid du Colombier 		return;
174*4ac975e2SDavid du Colombier 
175*4ac975e2SDavid du Colombier 	case OCASE:
176*4ac975e2SDavid du Colombier 		l = n->left;
177*4ac975e2SDavid du Colombier 		if(cases == C)
178*4ac975e2SDavid du Colombier 			diag(n, "case/default outside a switch");
179*4ac975e2SDavid du Colombier 		if(l == Z) {
180*4ac975e2SDavid du Colombier 			cas();
181*4ac975e2SDavid du Colombier 			cases->val = 0;
182*4ac975e2SDavid du Colombier 			cases->def = 1;
183*4ac975e2SDavid du Colombier 			cases->label = pc;
184*4ac975e2SDavid du Colombier 			goto rloop;
185*4ac975e2SDavid du Colombier 		}
186*4ac975e2SDavid du Colombier 		complex(l);
187*4ac975e2SDavid du Colombier 		if(l->type == T)
188*4ac975e2SDavid du Colombier 			goto rloop;
189*4ac975e2SDavid du Colombier 		if(l->op == OCONST)
190*4ac975e2SDavid du Colombier 		if(typeword[l->type->etype] && l->type->etype != TIND) {
191*4ac975e2SDavid du Colombier 			cas();
192*4ac975e2SDavid du Colombier 			cases->val = l->vconst;
193*4ac975e2SDavid du Colombier 			cases->def = 0;
194*4ac975e2SDavid du Colombier 			cases->label = pc;
195*4ac975e2SDavid du Colombier 			cases->isv = typev[l->type->etype];
196*4ac975e2SDavid du Colombier 			goto rloop;
197*4ac975e2SDavid du Colombier 		}
198*4ac975e2SDavid du Colombier 		diag(n, "case expression must be integer constant");
199*4ac975e2SDavid du Colombier 		goto rloop;
200*4ac975e2SDavid du Colombier 
201*4ac975e2SDavid du Colombier 	case OSWITCH:
202*4ac975e2SDavid du Colombier 		l = n->left;
203*4ac975e2SDavid du Colombier 		complex(l);
204*4ac975e2SDavid du Colombier 		if(l->type == T)
205*4ac975e2SDavid du Colombier 			break;
206*4ac975e2SDavid du Colombier 		if(!typeword[l->type->etype] || l->type->etype == TIND) {
207*4ac975e2SDavid du Colombier 			diag(n, "switch expression must be integer");
208*4ac975e2SDavid du Colombier 			break;
209*4ac975e2SDavid du Colombier 		}
210*4ac975e2SDavid du Colombier 
211*4ac975e2SDavid du Colombier 		gbranch(OGOTO);		/* entry */
212*4ac975e2SDavid du Colombier 		sp = p;
213*4ac975e2SDavid du Colombier 
214*4ac975e2SDavid du Colombier 		cn = cases;
215*4ac975e2SDavid du Colombier 		cases = C;
216*4ac975e2SDavid du Colombier 		cas();
217*4ac975e2SDavid du Colombier 
218*4ac975e2SDavid du Colombier 		sbc = breakpc;
219*4ac975e2SDavid du Colombier 		breakpc = pc;
220*4ac975e2SDavid du Colombier 		snbreak = nbreak;
221*4ac975e2SDavid du Colombier 		nbreak = 0;
222*4ac975e2SDavid du Colombier 		gbranch(OGOTO);
223*4ac975e2SDavid du Colombier 		spb = p;
224*4ac975e2SDavid du Colombier 
225*4ac975e2SDavid du Colombier 		gen(n->right);		/* body */
226*4ac975e2SDavid du Colombier 		if(!retok){
227*4ac975e2SDavid du Colombier 			gbranch(OGOTO);
228*4ac975e2SDavid du Colombier 			patch(p, breakpc);
229*4ac975e2SDavid du Colombier 			nbreak++;
230*4ac975e2SDavid du Colombier 		}
231*4ac975e2SDavid du Colombier 
232*4ac975e2SDavid du Colombier 		patch(sp, pc);
233*4ac975e2SDavid du Colombier 		regalloc(&nod, l, Z);
234*4ac975e2SDavid du Colombier 		/* always signed */
235*4ac975e2SDavid du Colombier 		if(typev[l->type->etype])
236*4ac975e2SDavid du Colombier 			nod.type = types[TVLONG];
237*4ac975e2SDavid du Colombier 		else
238*4ac975e2SDavid du Colombier 			nod.type = types[TLONG];
239*4ac975e2SDavid du Colombier 		cgen(l, &nod);
240*4ac975e2SDavid du Colombier 		doswit(&nod);
241*4ac975e2SDavid du Colombier 		regfree(&nod);
242*4ac975e2SDavid du Colombier 		patch(spb, pc);
243*4ac975e2SDavid du Colombier 
244*4ac975e2SDavid du Colombier 		cases = cn;
245*4ac975e2SDavid du Colombier 		breakpc = sbc;
246*4ac975e2SDavid du Colombier 		retok = nbreak==0;
247*4ac975e2SDavid du Colombier 		nbreak = snbreak;
248*4ac975e2SDavid du Colombier 		break;
249*4ac975e2SDavid du Colombier 
250*4ac975e2SDavid du Colombier 	case OWHILE:
251*4ac975e2SDavid du Colombier 	case ODWHILE:
252*4ac975e2SDavid du Colombier 		l = n->left;
253*4ac975e2SDavid du Colombier 		gbranch(OGOTO);		/* entry */
254*4ac975e2SDavid du Colombier 		sp = p;
255*4ac975e2SDavid du Colombier 
256*4ac975e2SDavid du Colombier 		scc = continpc;
257*4ac975e2SDavid du Colombier 		continpc = pc;
258*4ac975e2SDavid du Colombier 		gbranch(OGOTO);
259*4ac975e2SDavid du Colombier 		spc = p;
260*4ac975e2SDavid du Colombier 
261*4ac975e2SDavid du Colombier 		sbc = breakpc;
262*4ac975e2SDavid du Colombier 		breakpc = pc;
263*4ac975e2SDavid du Colombier 		snbreak = nbreak;
264*4ac975e2SDavid du Colombier 		nbreak = 0;
265*4ac975e2SDavid du Colombier 		gbranch(OGOTO);
266*4ac975e2SDavid du Colombier 		spb = p;
267*4ac975e2SDavid du Colombier 
268*4ac975e2SDavid du Colombier 		patch(spc, pc);
269*4ac975e2SDavid du Colombier 		if(n->op == OWHILE)
270*4ac975e2SDavid du Colombier 			patch(sp, pc);
271*4ac975e2SDavid du Colombier 		bcomplex(l, Z);		/* test */
272*4ac975e2SDavid du Colombier 		patch(p, breakpc);
273*4ac975e2SDavid du Colombier 		if(l->op != OCONST || vconst(l) == 0)
274*4ac975e2SDavid du Colombier 			nbreak++;
275*4ac975e2SDavid du Colombier 
276*4ac975e2SDavid du Colombier 		if(n->op == ODWHILE)
277*4ac975e2SDavid du Colombier 			patch(sp, pc);
278*4ac975e2SDavid du Colombier 		gen(n->right);		/* body */
279*4ac975e2SDavid du Colombier 		gbranch(OGOTO);
280*4ac975e2SDavid du Colombier 		patch(p, continpc);
281*4ac975e2SDavid du Colombier 
282*4ac975e2SDavid du Colombier 		patch(spb, pc);
283*4ac975e2SDavid du Colombier 		continpc = scc;
284*4ac975e2SDavid du Colombier 		breakpc = sbc;
285*4ac975e2SDavid du Colombier 		retok = nbreak==0;
286*4ac975e2SDavid du Colombier 		nbreak = snbreak;
287*4ac975e2SDavid du Colombier 		break;
288*4ac975e2SDavid du Colombier 
289*4ac975e2SDavid du Colombier 	case OFOR:
290*4ac975e2SDavid du Colombier 		l = n->left;
291*4ac975e2SDavid du Colombier 		gen(l->right->left);	/* init */
292*4ac975e2SDavid du Colombier 		gbranch(OGOTO);		/* entry */
293*4ac975e2SDavid du Colombier 		sp = p;
294*4ac975e2SDavid du Colombier 
295*4ac975e2SDavid du Colombier 		scc = continpc;
296*4ac975e2SDavid du Colombier 		continpc = pc;
297*4ac975e2SDavid du Colombier 		gbranch(OGOTO);
298*4ac975e2SDavid du Colombier 		spc = p;
299*4ac975e2SDavid du Colombier 
300*4ac975e2SDavid du Colombier 		sbc = breakpc;
301*4ac975e2SDavid du Colombier 		breakpc = pc;
302*4ac975e2SDavid du Colombier 		snbreak = nbreak;
303*4ac975e2SDavid du Colombier 		nbreak = 0;
304*4ac975e2SDavid du Colombier 		gbranch(OGOTO);
305*4ac975e2SDavid du Colombier 		spb = p;
306*4ac975e2SDavid du Colombier 
307*4ac975e2SDavid du Colombier 		patch(spc, pc);
308*4ac975e2SDavid du Colombier 		gen(l->right->right);	/* inc */
309*4ac975e2SDavid du Colombier 		patch(sp, pc);
310*4ac975e2SDavid du Colombier 		if(l->left != Z) {	/* test */
311*4ac975e2SDavid du Colombier 			bcomplex(l->left, Z);
312*4ac975e2SDavid du Colombier 			patch(p, breakpc);
313*4ac975e2SDavid du Colombier 			if(l->left->op != OCONST || vconst(l->left) == 0)
314*4ac975e2SDavid du Colombier 				nbreak++;
315*4ac975e2SDavid du Colombier 		}
316*4ac975e2SDavid du Colombier 		gen(n->right);		/* body */
317*4ac975e2SDavid du Colombier 		gbranch(OGOTO);
318*4ac975e2SDavid du Colombier 		patch(p, continpc);
319*4ac975e2SDavid du Colombier 
320*4ac975e2SDavid du Colombier 		patch(spb, pc);
321*4ac975e2SDavid du Colombier 		continpc = scc;
322*4ac975e2SDavid du Colombier 		breakpc = sbc;
323*4ac975e2SDavid du Colombier 		retok = nbreak==0;
324*4ac975e2SDavid du Colombier 		nbreak = snbreak;
325*4ac975e2SDavid du Colombier 		break;
326*4ac975e2SDavid du Colombier 
327*4ac975e2SDavid du Colombier 	case OCONTINUE:
328*4ac975e2SDavid du Colombier 		if(continpc < 0) {
329*4ac975e2SDavid du Colombier 			diag(n, "continue not in a loop");
330*4ac975e2SDavid du Colombier 			break;
331*4ac975e2SDavid du Colombier 		}
332*4ac975e2SDavid du Colombier 		gbranch(OGOTO);
333*4ac975e2SDavid du Colombier 		patch(p, continpc);
334*4ac975e2SDavid du Colombier 		break;
335*4ac975e2SDavid du Colombier 
336*4ac975e2SDavid du Colombier 	case OBREAK:
337*4ac975e2SDavid du Colombier 		if(breakpc < 0) {
338*4ac975e2SDavid du Colombier 			diag(n, "break not in a loop");
339*4ac975e2SDavid du Colombier 			break;
340*4ac975e2SDavid du Colombier 		}
341*4ac975e2SDavid du Colombier 		gbranch(OGOTO);
342*4ac975e2SDavid du Colombier 		patch(p, breakpc);
343*4ac975e2SDavid du Colombier 		nbreak++;
344*4ac975e2SDavid du Colombier 		break;
345*4ac975e2SDavid du Colombier 
346*4ac975e2SDavid du Colombier 	case OIF:
347*4ac975e2SDavid du Colombier 		l = n->left;
348*4ac975e2SDavid du Colombier 		if(bcomplex(l, n->right)) {
349*4ac975e2SDavid du Colombier 			if(typefd[l->type->etype])
350*4ac975e2SDavid du Colombier 				f = !l->fconst;
351*4ac975e2SDavid du Colombier 			else
352*4ac975e2SDavid du Colombier 				f = !l->vconst;
353*4ac975e2SDavid du Colombier 			if(debug['c'])
354*4ac975e2SDavid du Colombier 				print("%L const if %s\n", nearln, f ? "false" : "true");
355*4ac975e2SDavid du Colombier 			if(f) {
356*4ac975e2SDavid du Colombier 				supgen(n->right->left);
357*4ac975e2SDavid du Colombier 				gen(n->right->right);
358*4ac975e2SDavid du Colombier 			}
359*4ac975e2SDavid du Colombier 			else {
360*4ac975e2SDavid du Colombier 				gen(n->right->left);
361*4ac975e2SDavid du Colombier 				ok = retok;
362*4ac975e2SDavid du Colombier 				supgen(n->right->right);
363*4ac975e2SDavid du Colombier 				retok = ok;
364*4ac975e2SDavid du Colombier 			}
365*4ac975e2SDavid du Colombier 		}
366*4ac975e2SDavid du Colombier 		else {
367*4ac975e2SDavid du Colombier 			sp = p;
368*4ac975e2SDavid du Colombier 			retok = 0;
369*4ac975e2SDavid du Colombier 			if(n->right->left != Z)
370*4ac975e2SDavid du Colombier 				gen(n->right->left);
371*4ac975e2SDavid du Colombier 			ok = retok;
372*4ac975e2SDavid du Colombier 			retok = 0;
373*4ac975e2SDavid du Colombier 			if(n->right->right != Z) {
374*4ac975e2SDavid du Colombier 				gbranch(OGOTO);
375*4ac975e2SDavid du Colombier 				patch(sp, pc);
376*4ac975e2SDavid du Colombier 				sp = p;
377*4ac975e2SDavid du Colombier 				gen(n->right->right);
378*4ac975e2SDavid du Colombier 			}
379*4ac975e2SDavid du Colombier 			patch(sp, pc);
380*4ac975e2SDavid du Colombier 			retok = retok && ok;
381*4ac975e2SDavid du Colombier 		}
382*4ac975e2SDavid du Colombier 		break;
383*4ac975e2SDavid du Colombier 
384*4ac975e2SDavid du Colombier 	case OSET:
385*4ac975e2SDavid du Colombier 	case OUSED:
386*4ac975e2SDavid du Colombier 		usedset(n->left, o);
387*4ac975e2SDavid du Colombier 		break;
388*4ac975e2SDavid du Colombier 	}
389*4ac975e2SDavid du Colombier }
390*4ac975e2SDavid du Colombier 
391*4ac975e2SDavid du Colombier void
392*4ac975e2SDavid du Colombier usedset(Node *n, int o)
393*4ac975e2SDavid du Colombier {
394*4ac975e2SDavid du Colombier 	if(n->op == OLIST) {
395*4ac975e2SDavid du Colombier 		usedset(n->left, o);
396*4ac975e2SDavid du Colombier 		usedset(n->right, o);
397*4ac975e2SDavid du Colombier 		return;
398*4ac975e2SDavid du Colombier 	}
399*4ac975e2SDavid du Colombier 	complex(n);
400*4ac975e2SDavid du Colombier 	switch(n->op) {
401*4ac975e2SDavid du Colombier 	case OADDR:	/* volatile */
402*4ac975e2SDavid du Colombier 		gins(ANOP, n, Z);
403*4ac975e2SDavid du Colombier 		break;
404*4ac975e2SDavid du Colombier 	case ONAME:
405*4ac975e2SDavid du Colombier 		if(o == OSET)
406*4ac975e2SDavid du Colombier 			gins(ANOP, Z, n);
407*4ac975e2SDavid du Colombier 		else
408*4ac975e2SDavid du Colombier 			gins(ANOP, n, Z);
409*4ac975e2SDavid du Colombier 		break;
410*4ac975e2SDavid du Colombier 	}
411*4ac975e2SDavid du Colombier }
412*4ac975e2SDavid du Colombier 
413*4ac975e2SDavid du Colombier int
414*4ac975e2SDavid du Colombier bcomplex(Node *n, Node *c)
415*4ac975e2SDavid du Colombier {
416*4ac975e2SDavid du Colombier 
417*4ac975e2SDavid du Colombier 	complex(n);
418*4ac975e2SDavid du Colombier 	if(n->type != T)
419*4ac975e2SDavid du Colombier 	if(tcompat(n, T, n->type, tnot))
420*4ac975e2SDavid du Colombier 		n->type = T;
421*4ac975e2SDavid du Colombier 	if(n->type == T) {
422*4ac975e2SDavid du Colombier 		gbranch(OGOTO);
423*4ac975e2SDavid du Colombier 		return 0;
424*4ac975e2SDavid du Colombier 	}
425*4ac975e2SDavid du Colombier 	if(c != Z && n->op == OCONST && deadheads(c))
426*4ac975e2SDavid du Colombier 		return 1;
427*4ac975e2SDavid du Colombier 	bool64(n);
428*4ac975e2SDavid du Colombier 	boolgen(n, 1, Z);
429*4ac975e2SDavid du Colombier 	return 0;
430*4ac975e2SDavid du Colombier }
431