xref: /inferno-os/utils/ic/sgen.c (revision 6e84dc968bc4eaf047fbefcba2f670940718dda8)
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 t;
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 OASLMUL:
99 	case OASMUL:
100 		xcom(l);
101 		xcom(r);
102 		t = vlog(r);
103 		if(t >= 0) {
104 			n->op = OASASHL;
105 			r->vconst = t;
106 			r->type = types[TINT];
107 			goto shiftassign;
108 		}
109 		break;
110 
111 	case OMUL:
112 	case OLMUL:
113 		xcom(l);
114 		xcom(r);
115 		t = vlog(l);
116 		if(t >= 0) {
117 			n->left = r;
118 			n->right = l;
119 			l = r;
120 			r = n->right;
121 		}
122 		t = vlog(r);
123 		if(t >= 0) {
124 			n->op = OASHL;
125 			r->vconst = t;
126 			r->type = types[TINT];
127 			simplifyshift(n);
128 		}
129 		break;
130 
131 	case OASLDIV:
132 		xcom(l);
133 		xcom(r);
134 		t = vlog(r);
135 		if(t >= 0) {
136 			n->op = OASLSHR;
137 			r->vconst = t;
138 			r->type = types[TINT];
139 			goto shiftassign;
140 		}
141 		break;
142 
143 	case OLDIV:
144 		xcom(l);
145 		xcom(r);
146 		t = vlog(r);
147 		if(t >= 0) {
148 			n->op = OLSHR;
149 			r->vconst = t;
150 			r->type = types[TINT];
151 			simplifyshift(n);
152 		}
153 		break;
154 
155 	case OASLMOD:
156 		xcom(l);
157 		xcom(r);
158 		t = vlog(r);
159 		if(t >= 0) {
160 			n->op = OASAND;
161 			r->vconst--;
162 		}
163 		break;
164 
165 	case OLMOD:
166 		xcom(l);
167 		xcom(r);
168 		t = vlog(r);
169 		if(t >= 0) {
170 			n->op = OAND;
171 			r->vconst--;
172 		}
173 		break;
174 
175 	case OLSHR:
176 	case OASHL:
177 	case OASHR:
178 		xcom(l);
179 		xcom(r);
180 		simplifyshift(n);
181 		break;
182 
183 	case OASLSHR:
184 	case OASASHL:
185 	case OASASHR:
186 		xcom(l);
187 		xcom(r);
188 	shiftassign:
189 		if(typev[l->type->etype] && !machcap(n) && !typev[r->type->etype]){
190 			if(r->op == OCONST)
191 				r->type = types[TVLONG];
192 			else{
193 				n->right = r = new1(OCAST, r, Z);
194 				r->type = types[TVLONG];
195 				xcom(r);
196 			}
197 		}
198 		break;
199 
200 	default:
201 		if(l != Z)
202 			xcom(l);
203 		if(r != Z)
204 			xcom(r);
205 		break;
206 	}
207 	if(n->addable >= 10)
208 		return;
209 
210 	if(l != Z)
211 		n->complex = l->complex;
212 	if(r != Z) {
213 		if(r->complex == n->complex)
214 			n->complex = r->complex+1;
215 		else
216 		if(r->complex > n->complex)
217 			n->complex = r->complex;
218 	}
219 	if(n->complex == 0)
220 		n->complex++;
221 
222 	if(thechar == 'i' && com64(n))
223 		return;
224 
225 	switch(n->op) {
226 	case OFUNC:
227 		n->complex = FNX;
228 		break;
229 
230 	case OADD:
231 	case OXOR:
232 	case OAND:
233 	case OOR:
234 	case OEQ:
235 	case ONE:
236 		/*
237 		 * immediate operators, make const on right
238 		 */
239 		if(l->op == OCONST) {
240 			n->left = r;
241 			n->right = l;
242 		}
243 		break;
244 
245 	case OLT:
246 	case OLE:
247 	case OGT:
248 	case OGE:
249 	case OLO:
250 	case OLS:
251 	case OHI:
252 	case OHS:
253 		/*
254 		 * comparison operators, make const on right
255 		 */
256 		break;
257 	}
258 }
259 
260