]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/5c/sgen.c
mothra: fix alt display resizing, filter control characters in panel entries, use...
[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                 xcom(l);
113                 xcom(r);
114                 t = vlog(r);
115                 if(t >= 0) {
116                         n->op = OASHL;
117                         r->vconst = t;
118                         r->type = types[TINT];
119                 }
120                 t = vlog(l);
121                 if(t >= 0) {
122                         n->op = OASHL;
123                         n->left = r;
124                         n->right = l;
125                         r = l;
126                         l = n->left;
127                         r->vconst = t;
128                         r->type = types[TINT];
129                 }
130                 break;
131
132         case OASLDIV:
133                 xcom(l);
134                 xcom(r);
135                 t = vlog(r);
136                 if(t >= 0) {
137                         n->op = OASLSHR;
138                         r->vconst = t;
139                         r->type = types[TINT];
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                 }
152                 break;
153
154         case OASLMOD:
155                 xcom(l);
156                 xcom(r);
157                 t = vlog(r);
158                 if(t >= 0) {
159                         n->op = OASAND;
160                         r->vconst--;
161                 }
162                 break;
163
164         case OLMOD:
165                 xcom(l);
166                 xcom(r);
167                 t = vlog(r);
168                 if(t >= 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
184         if(l != Z)
185                 n->complex = l->complex;
186         if(r != Z) {
187                 if(r->complex == n->complex)
188                         n->complex = r->complex+1;
189                 else
190                 if(r->complex > n->complex)
191                         n->complex = r->complex;
192         }
193         if(n->complex == 0)
194                 n->complex++;
195
196         if(com64(n))
197                 return;
198
199         switch(n->op) {
200         case OFUNC:
201                 n->complex = FNX;
202                 break;
203
204         case OADD:
205         case OXOR:
206         case OAND:
207         case OOR:
208         case OEQ:
209         case ONE:
210                 /*
211                  * immediate operators, make const on right
212                  */
213                 if(l->op == OCONST) {
214                         n->left = r;
215                         n->right = l;
216                 }
217                 break;
218         }
219 }