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