]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/5c/sgen.c
ndb/dnsquery, ndb/csquery: handle long lines
[plan9front.git] / sys / src / cmd / 5c / 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 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                 }
108                 break;
109
110         case OMUL:
111         case OLMUL:
112                 if(typev[n->type->etype]){
113                         /* try to lift 32->64 bit cast */
114                         if(typev[l->type->etype] && l->op == OCAST && typeil[l->left->type->etype]
115                         && typeu[n->type->etype] == typeu[l->left->type->etype])
116                                 l = l->left;
117                         if(typev[r->type->etype] && r->op == OCAST && typeil[r->left->type->etype]
118                         && typeu[n->type->etype] == typeu[r->left->type->etype])
119                                 r = r->left;
120
121                         if(typeil[l->type->etype] && typeil[r->type->etype]){
122                                 n->left = l;
123                                 n->right = r;
124                                 xcom(l);
125                                 xcom(r);
126                                 break;
127                         }
128                         l = n->left;
129                         r = n->right;
130                 }
131                 xcom(l);
132                 xcom(r);
133                 t = vlog(r);
134                 if(t >= 0) {
135                         n->op = OASHL;
136                         r->vconst = t;
137                         r->type = types[TINT];
138                 }
139                 t = vlog(l);
140                 if(t >= 0) {
141                         n->op = OASHL;
142                         n->left = r;
143                         n->right = l;
144                         r = l;
145                         r->vconst = t;
146                         r->type = types[TINT];
147                 }
148                 break;
149
150         case OASLDIV:
151                 xcom(l);
152                 xcom(r);
153                 t = vlog(r);
154                 if(t >= 0) {
155                         n->op = OASLSHR;
156                         r->vconst = t;
157                         r->type = types[TINT];
158                 }
159                 break;
160
161         case OLDIV:
162                 xcom(l);
163                 xcom(r);
164                 t = vlog(r);
165                 if(t >= 0) {
166                         n->op = OLSHR;
167                         r->vconst = t;
168                         r->type = types[TINT];
169                 }
170                 break;
171
172         case OASLMOD:
173                 xcom(l);
174                 xcom(r);
175                 t = vlog(r);
176                 if(t >= 0) {
177                         n->op = OASAND;
178                         r->vconst--;
179                 }
180                 break;
181
182         case OLMOD:
183                 xcom(l);
184                 xcom(r);
185                 t = vlog(r);
186                 if(t >= 0) {
187                         n->op = OAND;
188                         r->vconst--;
189                 }
190                 break;
191
192         case OOR:
193                 xcom(l);
194                 xcom(r);
195                 if(typeil[n->type->etype])
196                         rolor(n);
197                 break;
198
199         default:
200                 if(l != Z)
201                         xcom(l);
202                 if(r != Z)
203                         xcom(r);
204                 break;
205         }
206         if(n->addable >= 10)
207                 return;
208         l = n->left;
209         r = n->right;
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(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 }