1 #include "cc.h"
2
3 typedef struct Ftab Ftab;
4 struct Ftab
5 {
6 char op;
7 char* name;
8 char typ;
9 };
10 typedef struct Gtab Gtab;
11 struct Gtab
12 {
13 char etype;
14 char* name;
15 };
16
17 Ftab ftabinit[OEND];
18 Gtab gtabinit[NTYPE];
19
20 int
isfunct(Node * n)21 isfunct(Node *n)
22 {
23 Type *t, *t1;
24 Funct *f;
25 Node *l;
26 Sym *s;
27 int o;
28
29 o = n->op;
30 if(n->left == Z)
31 goto no;
32 t = n->left->type;
33 if(t == T)
34 goto no;
35 f = t->funct;
36
37 switch(o) {
38 case OAS: // put cast on rhs
39 case OASI:
40 case OASADD:
41 case OASAND:
42 case OASASHL:
43 case OASASHR:
44 case OASDIV:
45 case OASLDIV:
46 case OASLMOD:
47 case OASLMUL:
48 case OASLSHR:
49 case OASMOD:
50 case OASMUL:
51 case OASOR:
52 case OASSUB:
53 case OASXOR:
54 if(n->right == Z)
55 goto no;
56 t1 = n->right->type;
57 if(t1 == T)
58 goto no;
59 if(t1->funct == f)
60 break;
61
62 l = new(OXXX, Z, Z);
63 *l = *n->right;
64
65 n->right->left = l;
66 n->right->right = Z;
67 n->right->type = t;
68 n->right->op = OCAST;
69
70 if(!isfunct(n->right))
71 prtree(n, "isfunc !");
72 break;
73
74 case OCAST: // t f(T) or T f(t)
75 t1 = n->type;
76 if(t1 == T)
77 goto no;
78 if(f != nil) {
79 s = f->castfr[t1->etype];
80 if(s == S)
81 goto no;
82 n->right = n->left;
83 goto build;
84 }
85 f = t1->funct;
86 if(f != nil) {
87 s = f->castto[t->etype];
88 if(s == S)
89 goto no;
90 n->right = n->left;
91 goto build;
92 }
93 goto no;
94 }
95
96 if(f == nil)
97 goto no;
98 s = f->sym[o];
99 if(s == S)
100 goto no;
101
102 /*
103 * the answer is yes,
104 * now we rewrite the node
105 * and give diagnostics
106 */
107 switch(o) {
108 default:
109 diag(n, "isfunct op missing %O\n", o);
110 goto bad;
111
112 case OADD: // T f(T, T)
113 case OAND:
114 case OASHL:
115 case OASHR:
116 case ODIV:
117 case OLDIV:
118 case OLMOD:
119 case OLMUL:
120 case OLSHR:
121 case OMOD:
122 case OMUL:
123 case OOR:
124 case OSUB:
125 case OXOR:
126
127 case OEQ: // int f(T, T)
128 case OGE:
129 case OGT:
130 case OHI:
131 case OHS:
132 case OLE:
133 case OLO:
134 case OLS:
135 case OLT:
136 case ONE:
137 if(n->right == Z)
138 goto bad;
139 t1 = n->right->type;
140 if(t1 == T)
141 goto bad;
142 if(t1->funct != f)
143 goto bad;
144 n->right = new(OLIST, n->left, n->right);
145 break;
146
147 case OAS: // structure copies done by the compiler
148 case OASI:
149 goto no;
150
151 case OASADD: // T f(T*, T)
152 case OASAND:
153 case OASASHL:
154 case OASASHR:
155 case OASDIV:
156 case OASLDIV:
157 case OASLMOD:
158 case OASLMUL:
159 case OASLSHR:
160 case OASMOD:
161 case OASMUL:
162 case OASOR:
163 case OASSUB:
164 case OASXOR:
165 if(n->right == Z)
166 goto bad;
167 t1 = n->right->type;
168 if(t1 == T)
169 goto bad;
170 if(t1->funct != f)
171 goto bad;
172 n->right = new(OLIST, new(OADDR, n->left, Z), n->right);
173 break;
174
175 case OPOS: // T f(T)
176 case ONEG:
177 case ONOT:
178 case OCOM:
179 n->right = n->left;
180 break;
181
182
183 }
184
185 build:
186 l = new(ONAME, Z, Z);
187 l->sym = s;
188 l->type = s->type;
189 l->etype = s->type->etype;
190 l->xoffset = s->offset;
191 l->class = s->class;
192 tcomo(l, 0);
193
194 n->op = OFUNC;
195 n->left = l;
196 n->type = l->type->link;
197 if(tcompat(n, T, l->type, tfunct))
198 goto bad;
199 if(tcoma(n->left, n->right, l->type->down, 1))
200 goto bad;
201 return 1;
202
203 no:
204 return 0;
205
206 bad:
207 diag(n, "cant rewrite typestr for op %O\n", o);
208 prtree(n, "isfunct");
209 n->type = T;
210 return 1;
211 }
212
213 void
dclfunct(Type * t,Sym * s)214 dclfunct(Type *t, Sym *s)
215 {
216 Funct *f;
217 Node *n;
218 Type *f1, *f2, *f3, *f4;
219 int o, i, c;
220 char str[100];
221
222 if(t->funct)
223 return;
224
225 // recognize generated tag of dorm _%d_
226 if(t->tag == S)
227 goto bad;
228 for(i=0; c = t->tag->name[i]; i++) {
229 if(c == '_') {
230 if(i == 0 || t->tag->name[i+1] == 0)
231 continue;
232 break;
233 }
234 if(c < '0' || c > '9')
235 break;
236 }
237 if(c == 0)
238 goto bad;
239
240 f = alloc(sizeof(*f));
241 for(o=0; o<nelem(f->sym); o++)
242 f->sym[o] = S;
243
244 t->funct = f;
245
246 f1 = typ(TFUNC, t);
247 f1->down = copytyp(t);
248 f1->down->down = t;
249
250 f2 = typ(TFUNC, types[TINT]);
251 f2->down = copytyp(t);
252 f2->down->down = t;
253
254 f3 = typ(TFUNC, t);
255 f3->down = typ(TIND, t);
256 f3->down->down = t;
257
258 f4 = typ(TFUNC, t);
259 f4->down = t;
260
261 for(i=0;; i++) {
262 o = ftabinit[i].op;
263 if(o == OXXX)
264 break;
265 sprint(str, "%s_%s_", t->tag->name, ftabinit[i].name);
266 n = new(ONAME, Z, Z);
267 n->sym = slookup(str);
268 f->sym[o] = n->sym;
269 switch(ftabinit[i].typ) {
270 default:
271 diag(Z, "dclfunct op missing %d\n", ftabinit[i].typ);
272 break;
273
274 case 1: // T f(T,T) +
275 dodecl(xdecl, CEXTERN, f1, n);
276 break;
277
278 case 2: // int f(T,T) ==
279 dodecl(xdecl, CEXTERN, f2, n);
280 break;
281
282 case 3: // void f(T*,T) +=
283 dodecl(xdecl, CEXTERN, f3, n);
284 break;
285
286 case 4: // T f(T) ~
287 dodecl(xdecl, CEXTERN, f4, n);
288 break;
289 }
290 }
291 for(i=0;; i++) {
292 o = gtabinit[i].etype;
293 if(o == TXXX)
294 break;
295
296 /*
297 * OCAST types T1 _T2_T1_(T2)
298 */
299 sprint(str, "_%s%s_", gtabinit[i].name, t->tag->name);
300 n = new(ONAME, Z, Z);
301 n->sym = slookup(str);
302 f->castto[o] = n->sym;
303
304 f1 = typ(TFUNC, t);
305 f1->down = types[o];
306 dodecl(xdecl, CEXTERN, f1, n);
307
308 sprint(str, "%s_%s_", t->tag->name, gtabinit[i].name);
309 n = new(ONAME, Z, Z);
310 n->sym = slookup(str);
311 f->castfr[o] = n->sym;
312
313 f1 = typ(TFUNC, types[o]);
314 f1->down = t;
315 dodecl(xdecl, CEXTERN, f1, n);
316 }
317 return;
318 bad:
319 diag(Z, "dclfunct bad %T %s\n", t, s->name);
320 }
321
322 Gtab gtabinit[NTYPE] =
323 {
324 TCHAR, "c",
325 TUCHAR, "uc",
326 TSHORT, "h",
327 TUSHORT, "uh",
328 TINT, "i",
329 TUINT, "ui",
330 TLONG, "l",
331 TULONG, "ul",
332 TVLONG, "v",
333 TUVLONG, "uv",
334 TFLOAT, "f",
335 TDOUBLE, "d",
336 TXXX
337 };
338
339 Ftab ftabinit[OEND] =
340 {
341 OADD, "add", 1,
342 OAND, "and", 1,
343 OASHL, "ashl", 1,
344 OASHR, "ashr", 1,
345 ODIV, "div", 1,
346 OLDIV, "ldiv", 1,
347 OLMOD, "lmod", 1,
348 OLMUL, "lmul", 1,
349 OLSHR, "lshr", 1,
350 OMOD, "mod", 1,
351 OMUL, "mul", 1,
352 OOR, "or", 1,
353 OSUB, "sub", 1,
354 OXOR, "xor", 1,
355
356 OEQ, "eq", 2,
357 OGE, "ge", 2,
358 OGT, "gt", 2,
359 OHI, "hi", 2,
360 OHS, "hs", 2,
361 OLE, "le", 2,
362 OLO, "lo", 2,
363 OLS, "ls", 2,
364 OLT, "lt", 2,
365 ONE, "ne", 2,
366
367 OASADD, "asadd", 3,
368 OASAND, "asand", 3,
369 OASASHL, "asashl", 3,
370 OASASHR, "asashr", 3,
371 OASDIV, "asdiv", 3,
372 OASLDIV, "asldiv", 3,
373 OASLMOD, "aslmod", 3,
374 OASLMUL, "aslmul", 3,
375 OASLSHR, "aslshr", 3,
376 OASMOD, "asmod", 3,
377 OASMUL, "asmul", 3,
378 OASOR, "asor", 3,
379 OASSUB, "assub", 3,
380 OASXOR, "asxor", 3,
381
382 OPOS, "pos", 4,
383 ONEG, "neg", 4,
384 OCOM, "com", 4,
385 ONOT, "not", 4,
386
387 // OPOSTDEC,
388 // OPOSTINC,
389 // OPREDEC,
390 // OPREINC,
391
392 OXXX,
393 };
394
395 // Node* nodtestv;
396
397 // Node* nodvpp;
398 // Node* nodppv;
399 // Node* nodvmm;
400 // Node* nodmmv;
401