]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/qc/sgen.c
merge
[plan9front.git] / sys / src / cmd / qc / sgen.c
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