1 #include "gc.h"
2
3 void
noretval(int n)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
xcom(Node * n)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