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