xref: /inferno-os/utils/cc/funct.c (revision e45fa0eb0763b57d6fb0649c064bc3b95ccdea6c)
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;
401