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