]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/cc/funct.c
?c: get rid of sprint(), strcpy() and strcat()/strncat(), cleanup
[plan9front.git] / sys / src / cmd / cc / funct.c
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
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
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
221         if(t->funct)
222                 return;
223
224         // recognize generated tag of dorm _%d_
225         if(t->tag == S)
226                 goto bad;
227         for(i=0; c = t->tag->name[i]; i++) {
228                 if(c == '_') {
229                         if(i == 0 || t->tag->name[i+1] == 0)
230                                 continue;
231                         break;
232                 }
233                 if(c < '0' || c > '9')
234                         break;
235         }
236         if(c == 0)
237                 goto bad;
238
239         f = alloc(sizeof(*f));
240         for(o=0; o<nelem(f->sym); o++)
241                 f->sym[o] = S;
242
243         t->funct = f;
244
245         f1 = typ(TFUNC, t);
246         f1->down = copytyp(t);
247         f1->down->down = t;
248
249         f2 = typ(TFUNC, types[TINT]);
250         f2->down = copytyp(t);
251         f2->down->down = t;
252
253         f3 = typ(TFUNC, t);
254         f3->down = typ(TIND, t);
255         f3->down->down = t;
256
257         f4 = typ(TFUNC, t);
258         f4->down = t;
259
260         for(i=0;; i++) {
261                 o = ftabinit[i].op;
262                 if(o == OXXX)
263                         break;
264                 snprint(symb, NSYMB, "%s_%s_", t->tag->name, ftabinit[i].name);
265                 n = new(ONAME, Z, Z);
266                 n->sym = lookup();
267                 f->sym[o] = n->sym;
268                 switch(ftabinit[i].typ) {
269                 default:
270                         diag(Z, "dclfunct op missing %d\n", ftabinit[i].typ);
271                         break;
272
273                 case 1: // T f(T,T)     +
274                         dodecl(xdecl, CEXTERN, f1, n);
275                         break;
276
277                 case 2: // int f(T,T)   ==
278                         dodecl(xdecl, CEXTERN, f2, n);
279                         break;
280
281                 case 3: // void f(T*,T) +=
282                         dodecl(xdecl, CEXTERN, f3, n);
283                         break;
284
285                 case 4: // T f(T)       ~
286                         dodecl(xdecl, CEXTERN, f4, n);
287                         break;
288                 }
289         }
290         for(i=0;; i++) {
291                 o = gtabinit[i].etype;
292                 if(o == TXXX)
293                         break;
294
295                 /*
296                  * OCAST types T1 _T2_T1_(T2)
297                  */
298                 snprint(symb, NSYMB, "_%s%s_", gtabinit[i].name, t->tag->name);
299                 n = new(ONAME, Z, Z);
300                 n->sym = lookup();
301                 f->castto[o] = n->sym;
302
303                 f1 = typ(TFUNC, t);
304                 f1->down = types[o];
305                 dodecl(xdecl, CEXTERN, f1, n);
306
307                 snprint(symb, NSYMB, "%s_%s_", t->tag->name, gtabinit[i].name);
308                 n = new(ONAME, Z, Z);
309                 n->sym = lookup();
310                 f->castfr[o] = n->sym;
311
312                 f1 = typ(TFUNC, types[o]);
313                 f1->down = t;
314                 dodecl(xdecl, CEXTERN, f1, n);
315         }
316         return;
317 bad:
318         diag(Z, "dclfunct bad %T %s\n", t, s->name);
319 }
320
321 Gtab    gtabinit[NTYPE] =
322 {
323         TCHAR,          "c",
324         TUCHAR,         "uc",
325         TSHORT,         "h",
326         TUSHORT,        "uh",
327         TINT,           "i",
328         TUINT,          "ui",
329         TLONG,          "l",
330         TULONG,         "ul",
331         TVLONG,         "v",
332         TUVLONG,        "uv",
333         TFLOAT,         "f",
334         TDOUBLE,        "d",
335         TXXX
336 };
337
338 Ftab    ftabinit[OEND] =
339 {
340         OADD,           "add",          1,
341         OAND,           "and",          1,
342         OASHL,          "ashl",         1,
343         OASHR,          "ashr",         1,
344         ODIV,           "div",          1,
345         OLDIV,          "ldiv",         1,
346         OLMOD,          "lmod",         1,
347         OLMUL,          "lmul",         1,
348         OLSHR,          "lshr",         1,
349         OMOD,           "mod",          1,
350         OMUL,           "mul",          1,
351         OOR,            "or",           1,
352         OSUB,           "sub",          1,
353         OXOR,           "xor",          1,
354
355         OEQ,            "eq",           2,
356         OGE,            "ge",           2,
357         OGT,            "gt",           2,
358         OHI,            "hi",           2,
359         OHS,            "hs",           2,
360         OLE,            "le",           2,
361         OLO,            "lo",           2,
362         OLS,            "ls",           2,
363         OLT,            "lt",           2,
364         ONE,            "ne",           2,
365
366         OASADD,         "asadd",        3,
367         OASAND,         "asand",        3,
368         OASASHL,        "asashl",       3,
369         OASASHR,        "asashr",       3,
370         OASDIV,         "asdiv",        3,
371         OASLDIV,        "asldiv",       3,
372         OASLMOD,        "aslmod",       3,
373         OASLMUL,        "aslmul",       3,
374         OASLSHR,        "aslshr",       3,
375         OASMOD,         "asmod",        3,
376         OASMUL,         "asmul",        3,
377         OASOR,          "asor",         3,
378         OASSUB,         "assub",        3,
379         OASXOR,         "asxor",        3,
380
381         OPOS,           "pos",          4,
382         ONEG,           "neg",          4,
383         OCOM,           "com",          4,
384         ONOT,           "not",          4,
385
386 //      OPOSTDEC,
387 //      OPOSTINC,
388 //      OPREDEC,
389 //      OPREINC,
390
391         OXXX,
392 };
393
394 //      Node*   nodtestv;
395
396 //      Node*   nodvpp;
397 //      Node*   nodppv;
398 //      Node*   nodvmm;
399 //      Node*   nodmmv;