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