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 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