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