]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/cc/funct.c
ndb/dns: remove single-ip-address assuptions
[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         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;