]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/kc/sgen.c
mothra: never snarf the "Go:" box
[plan9front.git] / sys / src / cmd / kc / 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;
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                 }
130                 break;
131
132         case OASLDIV:
133                 xcom(l);
134                 xcom(r);
135                 v = vlog(r);
136                 if(v >= 0) {
137                         n->op = OASLSHR;
138                         r->vconst = v;
139                         r->type = types[TINT];
140                 }
141                 break;
142
143         case OLDIV:
144                 xcom(l);
145                 xcom(r);
146                 v = vlog(r);
147                 if(v >= 0) {
148                         n->op = OLSHR;
149                         r->vconst = v;
150                         r->type = types[TINT];
151                 }
152                 break;
153
154         case OASLMOD:
155                 xcom(l);
156                 xcom(r);
157                 v = vlog(r);
158                 if(v >= 0) {
159                         n->op = OASAND;
160                         r->vconst--;
161                 }
162                 break;
163
164         case OLMOD:
165                 xcom(l);
166                 xcom(r);
167                 v = vlog(r);
168                 if(v >= 0) {
169                         n->op = OAND;
170                         r->vconst--;
171                 }
172                 break;
173
174         default:
175                 if(l != Z)
176                         xcom(l);
177                 if(r != Z)
178                         xcom(r);
179                 break;
180         }
181         if(n->addable >= 10)
182                 return;
183         if(l != Z)
184                 n->complex = l->complex;
185         if(r != Z) {
186                 if(r->complex == n->complex)
187                         n->complex = r->complex+1;
188                 else
189                 if(r->complex > n->complex)
190                         n->complex = r->complex;
191         }
192         if(n->complex == 0)
193                 n->complex++;
194
195         if(com64(n))
196                 return;
197
198         switch(n->op) {
199
200         case OFUNC:
201                 n->complex = FNX;
202                 break;
203
204         case OEQ:
205         case ONE:
206         case OLE:
207         case OLT:
208         case OGE:
209         case OGT:
210         case OHI:
211         case OHS:
212         case OLO:
213         case OLS:
214                 /*
215                  * immediate operators, make const on right
216                  */
217                 if(l->op == OCONST) {
218                         n->left = r;
219                         n->right = l;
220                         n->op = invrel[relindex(n->op)];
221                 }
222                 break;
223
224         case OADD:
225         case OXOR:
226         case OAND:
227         case OOR:
228                 /*
229                  * immediate operators, make const on right
230                  */
231                 if(l->op == OCONST) {
232                         n->left = r;
233                         n->right = l;
234                 }
235                 break;
236         }
237 }
238