Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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;