xref: /plan9-contrib/sys/src/cmd/9c/sgen.c (revision fbadb1c4d4463e58337ffb1ed396c9caee5d1889)
1*fbadb1c4SDavid du Colombier #include "gc.h"
2*fbadb1c4SDavid du Colombier 
3*fbadb1c4SDavid du Colombier void
noretval(int n)4*fbadb1c4SDavid du Colombier noretval(int n)
5*fbadb1c4SDavid du Colombier {
6*fbadb1c4SDavid du Colombier 
7*fbadb1c4SDavid du Colombier 	if(n & 1) {
8*fbadb1c4SDavid du Colombier 		gins(ANOP, Z, Z);
9*fbadb1c4SDavid du Colombier 		p->to.type = D_REG;
10*fbadb1c4SDavid du Colombier 		p->to.reg = REGRET;
11*fbadb1c4SDavid du Colombier 	}
12*fbadb1c4SDavid du Colombier 	if(n & 2) {
13*fbadb1c4SDavid du Colombier 		gins(ANOP, Z, Z);
14*fbadb1c4SDavid du Colombier 		p->to.type = D_FREG;
15*fbadb1c4SDavid du Colombier 		p->to.reg = FREGRET;
16*fbadb1c4SDavid du Colombier 	}
17*fbadb1c4SDavid du Colombier }
18*fbadb1c4SDavid du Colombier 
19*fbadb1c4SDavid du Colombier /*
20*fbadb1c4SDavid du Colombier  *	calculate addressability as follows
21*fbadb1c4SDavid du Colombier  *		CONST ==> 20		$value
22*fbadb1c4SDavid du Colombier  *		NAME ==> 10		name
23*fbadb1c4SDavid du Colombier  *		REGISTER ==> 11		register
24*fbadb1c4SDavid du Colombier  *		INDREG ==> 12		*[(reg)+offset]
25*fbadb1c4SDavid du Colombier  *		&10 ==> 2		$name
26*fbadb1c4SDavid du Colombier  *		ADD(2, 20) ==> 2	$name+offset
27*fbadb1c4SDavid du Colombier  *		ADD(3, 20) ==> 3	$(reg)+offset
28*fbadb1c4SDavid du Colombier  *		&12 ==> 3		$(reg)+offset
29*fbadb1c4SDavid du Colombier  *		*11 ==> 11		??
30*fbadb1c4SDavid du Colombier  *		*2 ==> 10		name
31*fbadb1c4SDavid du Colombier  *		*3 ==> 12		*(reg)+offset
32*fbadb1c4SDavid du Colombier  *	calculate complexity (number of registers)
33*fbadb1c4SDavid du Colombier  */
34*fbadb1c4SDavid du Colombier void
xcom(Node * n)35*fbadb1c4SDavid du Colombier xcom(Node *n)
36*fbadb1c4SDavid du Colombier {
37*fbadb1c4SDavid du Colombier 	Node *l, *r;
38*fbadb1c4SDavid du Colombier 	int v;
39*fbadb1c4SDavid du Colombier 
40*fbadb1c4SDavid du Colombier 	if(n == Z)
41*fbadb1c4SDavid du Colombier 		return;
42*fbadb1c4SDavid du Colombier 	l = n->left;
43*fbadb1c4SDavid du Colombier 	r = n->right;
44*fbadb1c4SDavid du Colombier 	n->addable = 0;
45*fbadb1c4SDavid du Colombier 	n->complex = 0;
46*fbadb1c4SDavid du Colombier 	switch(n->op) {
47*fbadb1c4SDavid du Colombier 	case OCONST:
48*fbadb1c4SDavid du Colombier 		n->addable = 20;
49*fbadb1c4SDavid du Colombier 		return;
50*fbadb1c4SDavid du Colombier 
51*fbadb1c4SDavid du Colombier 	case OREGISTER:
52*fbadb1c4SDavid du Colombier 		n->addable = 11;
53*fbadb1c4SDavid du Colombier 		return;
54*fbadb1c4SDavid du Colombier 
55*fbadb1c4SDavid du Colombier 	case OINDREG:
56*fbadb1c4SDavid du Colombier 		n->addable = 12;
57*fbadb1c4SDavid du Colombier 		return;
58*fbadb1c4SDavid du Colombier 
59*fbadb1c4SDavid du Colombier 	case ONAME:
60*fbadb1c4SDavid du Colombier 		n->addable = 10;
61*fbadb1c4SDavid du Colombier 		return;
62*fbadb1c4SDavid du Colombier 
63*fbadb1c4SDavid du Colombier 	case OADDR:
64*fbadb1c4SDavid du Colombier 		xcom(l);
65*fbadb1c4SDavid du Colombier 		if(l->addable == 10)
66*fbadb1c4SDavid du Colombier 			n->addable = 2;
67*fbadb1c4SDavid du Colombier 		if(l->addable == 12)
68*fbadb1c4SDavid du Colombier 			n->addable = 3;
69*fbadb1c4SDavid du Colombier 		break;
70*fbadb1c4SDavid du Colombier 
71*fbadb1c4SDavid du Colombier 	case OIND:
72*fbadb1c4SDavid du Colombier 		xcom(l);
73*fbadb1c4SDavid du Colombier 		if(l->addable == 11)
74*fbadb1c4SDavid du Colombier 			n->addable = 12;
75*fbadb1c4SDavid du Colombier 		if(l->addable == 3)
76*fbadb1c4SDavid du Colombier 			n->addable = 12;
77*fbadb1c4SDavid du Colombier 		if(l->addable == 2)
78*fbadb1c4SDavid du Colombier 			n->addable = 10;
79*fbadb1c4SDavid du Colombier 		break;
80*fbadb1c4SDavid du Colombier 
81*fbadb1c4SDavid du Colombier 	case OADD:
82*fbadb1c4SDavid du Colombier 		xcom(l);
83*fbadb1c4SDavid du Colombier 		xcom(r);
84*fbadb1c4SDavid du Colombier 		if(l->addable == 20) {
85*fbadb1c4SDavid du Colombier 			if(r->addable == 2)
86*fbadb1c4SDavid du Colombier 				n->addable = 2;
87*fbadb1c4SDavid du Colombier 			if(r->addable == 3)
88*fbadb1c4SDavid du Colombier 				n->addable = 3;
89*fbadb1c4SDavid du Colombier 		}
90*fbadb1c4SDavid du Colombier 		if(r->addable == 20) {
91*fbadb1c4SDavid du Colombier 			if(l->addable == 2)
92*fbadb1c4SDavid du Colombier 				n->addable = 2;
93*fbadb1c4SDavid du Colombier 			if(l->addable == 3)
94*fbadb1c4SDavid du Colombier 				n->addable = 3;
95*fbadb1c4SDavid du Colombier 		}
96*fbadb1c4SDavid du Colombier 		break;
97*fbadb1c4SDavid du Colombier 
98*fbadb1c4SDavid du Colombier 	case OASMUL:
99*fbadb1c4SDavid du Colombier 	case OASLMUL:
100*fbadb1c4SDavid du Colombier 		xcom(l);
101*fbadb1c4SDavid du Colombier 		xcom(r);
102*fbadb1c4SDavid du Colombier 		v = vlog(r);
103*fbadb1c4SDavid du Colombier 		if(v >= 0) {
104*fbadb1c4SDavid du Colombier 			n->op = OASASHL;
105*fbadb1c4SDavid du Colombier 			r->vconst = v;
106*fbadb1c4SDavid du Colombier 			r->type = types[TINT];
107*fbadb1c4SDavid du Colombier 		}
108*fbadb1c4SDavid du Colombier 		break;
109*fbadb1c4SDavid du Colombier 
110*fbadb1c4SDavid du Colombier 	case OMUL:
111*fbadb1c4SDavid du Colombier 	case OLMUL:
112*fbadb1c4SDavid du Colombier 		xcom(l);
113*fbadb1c4SDavid du Colombier 		xcom(r);
114*fbadb1c4SDavid du Colombier 		v = vlog(r);
115*fbadb1c4SDavid du Colombier 		if(v >= 0) {
116*fbadb1c4SDavid du Colombier 			n->op = OASHL;
117*fbadb1c4SDavid du Colombier 			r->vconst = v;
118*fbadb1c4SDavid du Colombier 			r->type = types[TINT];
119*fbadb1c4SDavid du Colombier 		}
120*fbadb1c4SDavid du Colombier 		v = vlog(l);
121*fbadb1c4SDavid du Colombier 		if(v >= 0) {
122*fbadb1c4SDavid du Colombier 			n->op = OASHL;
123*fbadb1c4SDavid du Colombier 			n->left = r;
124*fbadb1c4SDavid du Colombier 			n->right = l;
125*fbadb1c4SDavid du Colombier 			r = l;
126*fbadb1c4SDavid du Colombier 			l = n->left;
127*fbadb1c4SDavid du Colombier 			r->vconst = v;
128*fbadb1c4SDavid du Colombier 			r->type = types[TINT];
129*fbadb1c4SDavid du Colombier 			simplifyshift(n);
130*fbadb1c4SDavid du Colombier 		}
131*fbadb1c4SDavid du Colombier 		break;
132*fbadb1c4SDavid du Colombier 
133*fbadb1c4SDavid du Colombier 	case OASLDIV:
134*fbadb1c4SDavid du Colombier 		xcom(l);
135*fbadb1c4SDavid du Colombier 		xcom(r);
136*fbadb1c4SDavid du Colombier 		v = vlog(r);
137*fbadb1c4SDavid du Colombier 		if(v >= 0) {
138*fbadb1c4SDavid du Colombier 			n->op = OASLSHR;
139*fbadb1c4SDavid du Colombier 			r->vconst = v;
140*fbadb1c4SDavid du Colombier 			r->type = types[TINT];
141*fbadb1c4SDavid du Colombier 		}
142*fbadb1c4SDavid du Colombier 		break;
143*fbadb1c4SDavid du Colombier 
144*fbadb1c4SDavid du Colombier 	case OLDIV:
145*fbadb1c4SDavid du Colombier 		xcom(l);
146*fbadb1c4SDavid du Colombier 		xcom(r);
147*fbadb1c4SDavid du Colombier 		v = vlog(r);
148*fbadb1c4SDavid du Colombier 		if(v >= 0) {
149*fbadb1c4SDavid du Colombier 			n->op = OLSHR;
150*fbadb1c4SDavid du Colombier 			r->vconst = v;
151*fbadb1c4SDavid du Colombier 			r->type = types[TINT];
152*fbadb1c4SDavid du Colombier 			simplifyshift(n);
153*fbadb1c4SDavid du Colombier 		}
154*fbadb1c4SDavid du Colombier 		break;
155*fbadb1c4SDavid du Colombier 
156*fbadb1c4SDavid du Colombier 	case OASLMOD:
157*fbadb1c4SDavid du Colombier 		xcom(l);
158*fbadb1c4SDavid du Colombier 		xcom(r);
159*fbadb1c4SDavid du Colombier 		v = vlog(r);
160*fbadb1c4SDavid du Colombier 		if(v >= 0) {
161*fbadb1c4SDavid du Colombier 			n->op = OASAND;
162*fbadb1c4SDavid du Colombier 			r->vconst--;
163*fbadb1c4SDavid du Colombier 		}
164*fbadb1c4SDavid du Colombier 		break;
165*fbadb1c4SDavid du Colombier 
166*fbadb1c4SDavid du Colombier 	case OLMOD:
167*fbadb1c4SDavid du Colombier 		xcom(l);
168*fbadb1c4SDavid du Colombier 		xcom(r);
169*fbadb1c4SDavid du Colombier 		v = vlog(r);
170*fbadb1c4SDavid du Colombier 		if(v >= 0) {
171*fbadb1c4SDavid du Colombier 			n->op = OAND;
172*fbadb1c4SDavid du Colombier 			r->vconst--;
173*fbadb1c4SDavid du Colombier 		}
174*fbadb1c4SDavid du Colombier 		break;
175*fbadb1c4SDavid du Colombier 
176*fbadb1c4SDavid du Colombier 	case OLSHR:
177*fbadb1c4SDavid du Colombier 	case OASHL:
178*fbadb1c4SDavid du Colombier 	case OASHR:
179*fbadb1c4SDavid du Colombier 		xcom(l);
180*fbadb1c4SDavid du Colombier 		xcom(r);
181*fbadb1c4SDavid du Colombier 		simplifyshift(n);
182*fbadb1c4SDavid du Colombier 		break;
183*fbadb1c4SDavid du Colombier 
184*fbadb1c4SDavid du Colombier 	default:
185*fbadb1c4SDavid du Colombier 		if(l != Z)
186*fbadb1c4SDavid du Colombier 			xcom(l);
187*fbadb1c4SDavid du Colombier 		if(r != Z)
188*fbadb1c4SDavid du Colombier 			xcom(r);
189*fbadb1c4SDavid du Colombier 		break;
190*fbadb1c4SDavid du Colombier 	}
191*fbadb1c4SDavid du Colombier 	if(n->addable >= 10)
192*fbadb1c4SDavid du Colombier 		return;
193*fbadb1c4SDavid du Colombier 	if(l != Z)
194*fbadb1c4SDavid du Colombier 		n->complex = l->complex;
195*fbadb1c4SDavid du Colombier 	if(r != Z) {
196*fbadb1c4SDavid du Colombier 		if(r->complex == n->complex)
197*fbadb1c4SDavid du Colombier 			n->complex = r->complex+1;
198*fbadb1c4SDavid du Colombier 		else
199*fbadb1c4SDavid du Colombier 		if(r->complex > n->complex)
200*fbadb1c4SDavid du Colombier 			n->complex = r->complex;
201*fbadb1c4SDavid du Colombier 	}
202*fbadb1c4SDavid du Colombier 	if(n->complex == 0)
203*fbadb1c4SDavid du Colombier 		n->complex++;
204*fbadb1c4SDavid du Colombier 
205*fbadb1c4SDavid du Colombier //	if(com64(n))
206*fbadb1c4SDavid du Colombier //		return;
207*fbadb1c4SDavid du Colombier 
208*fbadb1c4SDavid du Colombier 	switch(n->op) {
209*fbadb1c4SDavid du Colombier 
210*fbadb1c4SDavid du Colombier 	case OFUNC:
211*fbadb1c4SDavid du Colombier 		n->complex = FNX;
212*fbadb1c4SDavid du Colombier 		break;
213*fbadb1c4SDavid du Colombier 
214*fbadb1c4SDavid du Colombier 	case OEQ:
215*fbadb1c4SDavid du Colombier 	case ONE:
216*fbadb1c4SDavid du Colombier 	case OLE:
217*fbadb1c4SDavid du Colombier 	case OLT:
218*fbadb1c4SDavid du Colombier 	case OGE:
219*fbadb1c4SDavid du Colombier 	case OGT:
220*fbadb1c4SDavid du Colombier 	case OHI:
221*fbadb1c4SDavid du Colombier 	case OHS:
222*fbadb1c4SDavid du Colombier 	case OLO:
223*fbadb1c4SDavid du Colombier 	case OLS:
224*fbadb1c4SDavid du Colombier 		/*
225*fbadb1c4SDavid du Colombier 		 * immediate operators, make const on right
226*fbadb1c4SDavid du Colombier 		 */
227*fbadb1c4SDavid du Colombier 		if(l->op == OCONST) {
228*fbadb1c4SDavid du Colombier 			n->left = r;
229*fbadb1c4SDavid du Colombier 			n->right = l;
230*fbadb1c4SDavid du Colombier 			n->op = invrel[relindex(n->op)];
231*fbadb1c4SDavid du Colombier 		}
232*fbadb1c4SDavid du Colombier 		break;
233*fbadb1c4SDavid du Colombier 
234*fbadb1c4SDavid du Colombier 	case OADD:
235*fbadb1c4SDavid du Colombier 	case OXOR:
236*fbadb1c4SDavid du Colombier 	case OAND:
237*fbadb1c4SDavid du Colombier 	case OOR:
238*fbadb1c4SDavid du Colombier 		/*
239*fbadb1c4SDavid du Colombier 		 * immediate operators, make const on right
240*fbadb1c4SDavid du Colombier 		 */
241*fbadb1c4SDavid du Colombier 		if(l->op == OCONST) {
242*fbadb1c4SDavid du Colombier 			n->left = r;
243*fbadb1c4SDavid du Colombier 			n->right = l;
244*fbadb1c4SDavid du Colombier 		}
245*fbadb1c4SDavid du Colombier 		break;
246*fbadb1c4SDavid du Colombier 	}
247*fbadb1c4SDavid du Colombier }
248*fbadb1c4SDavid du Colombier 
249