OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

[/] [eco32/] [trunk/] [lcc/] [src/] [enode.c] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 hellwig
#include "c.h"
2
 
3
static char rcsid[] = "$Id: enode.c,v 1.1 2002/08/28 23:12:42 drh Exp $";
4
 
5
static Tree addtree(int, Tree, Tree);
6
static Tree andtree(int, Tree, Tree);
7
static Tree cmptree(int, Tree, Tree);
8
static int compatible(Type, Type);
9
static int isnullptr(Tree e);
10
static Tree multree(int, Tree, Tree);
11
static Tree subtree(int, Tree, Tree);
12
#define isvoidptr(ty) \
13
        (isptr(ty) && unqual(ty->type) == voidtype)
14
 
15
Tree (*optree[])(int, Tree, Tree) = {
16
#define xx(a,b,c,d,e,f,g) e,
17
#define yy(a,b,c,d,e,f,g) e,
18
#include "token.h"
19
};
20
Tree call(Tree f, Type fty, Coordinate src) {
21
        int n = 0;
22
        Tree args = NULL, r = NULL, e;
23
        Type *proto, rty = unqual(freturn(fty));
24
        Symbol t3 = NULL;
25
 
26
        if (fty->u.f.oldstyle)
27
                proto = NULL;
28
        else
29
                proto = fty->u.f.proto;
30
        if (hascall(f))
31
                r = f;
32
        if (isstruct(rty))
33
                {
34
                        t3 = temporary(AUTO, unqual(rty));
35
                        if (rty->size == 0)
36
                                error("illegal use of incomplete type `%t'\n", rty);
37
                }
38
        if (t != ')')
39
                for (;;) {
40
                        Tree q = pointer(expr1(0));
41
                        if (proto && *proto && *proto != voidtype)
42
                                {
43
                                        Type aty;
44
                                        q = value(q);
45
                                        aty = assign(*proto, q);
46
                                        if (aty)
47
                                                q = cast(q, aty);
48
                                        else
49
                                                error("type error in argument %d to %s; found `%t' expected `%t'\n", n + 1, funcname(f),
50
 
51
                                                        q->type, *proto);
52
                                        if ((isint(q->type) || isenum(q->type))
53
                                        && q->type->size != inttype->size)
54
                                                q = cast(q, promote(q->type));
55
                                        ++proto;
56
                                }
57
                        else
58
                                {
59
                                        if (!fty->u.f.oldstyle && *proto == NULL)
60
                                                error("too many arguments to %s\n", funcname(f));
61
                                        q = value(q);
62
                                        if (isarray(q->type) || q->type->size == 0)
63
                                                error("type error in argument %d to %s; `%t' is illegal\n", n + 1, funcname(f), q->type);
64
 
65
                                        else
66
                                                q = cast(q, promote(q->type));
67
                                }
68
                        if (!IR->wants_argb && isstruct(q->type))
69
                                if (iscallb(q))
70
                                        q = addrof(q);
71
                                else {
72
                                        Symbol t1 = temporary(AUTO, unqual(q->type));
73
                                        q = asgn(t1, q);
74
                                        q = tree(RIGHT, ptr(t1->type),
75
                                                root(q), lvalue(idtree(t1)));
76
                                }
77
                        if (q->type->size == 0)
78
                                q->type = inttype;
79
                        if (hascall(q))
80
                                r = r ? tree(RIGHT, voidtype, r, q) : q;
81
                        args = tree(mkop(ARG, q->type), q->type, q, args);
82
                        n++;
83
                        if (Aflag >= 2 && n == 32)
84
                                warning("more than 31 arguments in a call to %s\n",
85
                                        funcname(f));
86
                        if (t != ',')
87
                                break;
88
                        t = gettok();
89
                }
90
        expect(')');
91
        if (proto && *proto && *proto != voidtype)
92
                error("insufficient number of arguments to %s\n",
93
                        funcname(f));
94
        if (r)
95
                args = tree(RIGHT, voidtype, r, args);
96
        e = calltree(f, rty, args, t3);
97
        if (events.calls)
98
                apply(events.calls, &src, &e);
99
        return e;
100
}
101
Tree calltree(Tree f, Type ty, Tree args, Symbol t3) {
102
        Tree p;
103
 
104
        if (args)
105
                f = tree(RIGHT, f->type, args, f);
106
        if (isstruct(ty))
107
                assert(t3),
108
                p = tree(RIGHT, ty,
109
                        tree(CALL+B, ty, f, addrof(idtree(t3))),
110
                        idtree(t3));
111
        else {
112
                Type rty = ty;
113
                if (isenum(ty))
114
                        rty = unqual(ty)->type;
115
                if (!isfloat(rty))
116
                        rty = promote(rty);
117
                p = tree(mkop(CALL, rty), rty, f, NULL);
118
                if (isptr(ty) || p->type->size > ty->size)
119
                        p = cast(p, ty);
120
        }
121
        return p;
122
}
123
Tree vcall(Symbol func, Type ty, ...) {
124
        va_list ap;
125
        Tree args = NULL, e, f = pointer(idtree(func)), r = NULL;
126
 
127
        assert(isfunc(func->type));
128
        if (ty == NULL)
129
                ty = freturn(func->type);
130
        va_start(ap, ty);
131
        while ((e = va_arg(ap, Tree)) != NULL) {
132
                if (hascall(e))
133
                        r = r == NULL ? e : tree(RIGHT, voidtype, r, e);
134
                args = tree(mkop(ARG, e->type), e->type, e, args);
135
        }
136
        va_end(ap);
137
        if (r != NULL)
138
                args = tree(RIGHT, voidtype, r, args);
139
        return calltree(f, ty, args, NULL);
140
}
141
int iscallb(Tree e) {
142
        return e->op == RIGHT && e->kids[0] && e->kids[1]
143
                && e->kids[0]->op == CALL+B
144
                && e->kids[1]->op == INDIR+B
145
                && isaddrop(e->kids[1]->kids[0]->op)
146
                && e->kids[1]->kids[0]->u.sym->temporary;
147
}
148
 
149
static Tree addtree(int op, Tree l, Tree r) {
150
        Type ty = inttype;
151
 
152
        if (isarith(l->type) && isarith(r->type)) {
153
                ty = binary(l->type, r->type);
154
                l = cast(l, ty);
155
                r = cast(r, ty);
156
        } else if (isptr(l->type) && isint(r->type))
157
                return addtree(ADD, r, l);
158
        else if (  isptr(r->type) && isint(l->type)
159
        && !isfunc(r->type->type))
160
                {
161
                        long n;
162
                        ty = unqual(r->type);
163
                        n = unqual(ty->type)->size;
164
                        if (n == 0)
165
                                error("unknown size for type `%t'\n", ty->type);
166
                        l = cast(l, promote(l->type));
167
                        if (n > 1)
168
                                l = multree(MUL, cnsttree(signedptr, n), l);
169
                        if (isunsigned(l->type))
170
                                l = cast(l, unsignedptr);
171
                        else
172
                                l = cast(l, signedptr);
173
                        if (YYcheck && !isaddrop(r->op))                /* omit */
174
                                return nullcall(ty, YYcheck, r, l);     /* omit */
175
                        return simplify(ADD, ty, l, r);
176
                }
177
 
178
        else
179
                typeerror(op, l, r);
180
        return simplify(op, ty, l, r);
181
}
182
 
183
Tree cnsttree(Type ty, ...) {
184
        Tree p = tree(mkop(CNST,ty), ty, NULL, NULL);
185
        va_list ap;
186
 
187
        va_start(ap, ty);
188
        switch (ty->op) {
189
        case INT:     p->u.v.i = va_arg(ap, long); break;
190
        case UNSIGNED:p->u.v.u = va_arg(ap, unsigned long)&ones(8*ty->size); break;
191
        case FLOAT:   p->u.v.d = va_arg(ap, long double); break;
192
        case POINTER: p->u.v.p = va_arg(ap, void *); break;
193
        default: assert(0);
194
        }
195
        va_end(ap);
196
        return p;
197
}
198
 
199
Tree consttree(unsigned n, Type ty) {
200
        if (isarray(ty))
201
                ty = atop(ty);
202
        else assert(isint(ty));
203
        return cnsttree(ty, (unsigned long)n);
204
}
205
static Tree cmptree(int op, Tree l, Tree r) {
206
        Type ty;
207
 
208
        if (isarith(l->type) && isarith(r->type)) {
209
                ty = binary(l->type, r->type);
210
                l = cast(l, ty);
211
                r = cast(r, ty);
212
        } else if (compatible(l->type, r->type)) {
213
                ty = unsignedptr;
214
                l = cast(l, ty);
215
                r = cast(r, ty);
216
        } else {
217
                ty = unsignedtype;
218
                typeerror(op, l, r);
219
        }
220
        return simplify(mkop(op,ty), inttype, l, r);
221
}
222
static int compatible(Type ty1, Type ty2) {
223
        ty1 = unqual(ty1);
224
        ty2 = unqual(ty2);
225
        return isptr(ty1) && !isfunc(ty1->type)
226
            && isptr(ty2) && !isfunc(ty2->type)
227
            && eqtype(unqual(ty1->type), unqual(ty2->type), 0);
228
}
229
static int isnullptr(Tree e) {
230
        Type ty = unqual(e->type);
231
 
232
        return generic(e->op) == CNST
233
            && (ty->op == INT      && e->u.v.i == 0
234
             || ty->op == UNSIGNED && e->u.v.u == 0
235
             || isvoidptr(ty)      && e->u.v.p == NULL);
236
}
237
Tree eqtree(int op, Tree l, Tree r) {
238
        Type xty = unqual(l->type), yty = unqual(r->type);
239
 
240
        if (isptr(xty) && isnullptr(r)
241
        ||  isptr(xty) && !isfunc(xty->type) && isvoidptr(yty)
242
        ||  (isptr(xty) && isptr(yty)
243
            && eqtype(unqual(xty->type), unqual(yty->type), 1))) {
244
                Type ty = unsignedptr;
245
                l = cast(l, ty);
246
                r = cast(r, ty);
247
                return simplify(mkop(op,ty), inttype, l, r);
248
        }
249
        if (isptr(yty) && isnullptr(l)
250
        ||  isptr(yty) && !isfunc(yty->type) && isvoidptr(xty))
251
                return eqtree(op, r, l);
252
        return cmptree(op, l, r);
253
}
254
 
255
Type assign(Type xty, Tree e) {
256
        Type yty = unqual(e->type);
257
 
258
        xty = unqual(xty);
259
        if (isenum(xty))
260
                xty = xty->type;
261
        if (xty->size == 0 || yty->size == 0)
262
                return NULL;
263
        if ( isarith(xty) && isarith(yty)
264
        ||  isstruct(xty) && xty == yty)
265
                return xty;
266
        if (isptr(xty) && isnullptr(e))
267
                return xty;
268
        if ((isvoidptr(xty) && isptr(yty)
269
          || isptr(xty)     && isvoidptr(yty))
270
        && (  (isconst(xty->type)    || !isconst(yty->type))
271
           && (isvolatile(xty->type) || !isvolatile(yty->type))))
272
                return xty;
273
 
274
        if ((isptr(xty) && isptr(yty)
275
            && eqtype(unqual(xty->type), unqual(yty->type), 1))
276
        &&  (  (isconst(xty->type)    || !isconst(yty->type))
277
            && (isvolatile(xty->type) || !isvolatile(yty->type))))
278
                return xty;
279
        if (isptr(xty) && isptr(yty)
280
        && (  (isconst(xty->type)    || !isconst(yty->type))
281
           && (isvolatile(xty->type) || !isvolatile(yty->type)))) {
282
                Type lty = unqual(xty->type), rty = unqual(yty->type);
283
                if (isenum(lty) && rty == inttype
284
                ||  isenum(rty) && lty == inttype) {
285
                        if (Aflag >= 1)
286
                                warning("assignment between `%t' and `%t' is compiler-dependent\n",
287
                                        xty, yty);
288
                        return xty;
289
                }
290
        }
291
        return NULL;
292
}
293
Tree asgntree(int op, Tree l, Tree r) {
294
        Type aty, ty;
295
 
296
        r = pointer(r);
297
        ty = assign(l->type, r);
298
        if (ty)
299
                r = cast(r, ty);
300
        else {
301
                typeerror(ASGN, l, r);
302
                if (r->type == voidtype)
303
                        r = retype(r, inttype);
304
                ty = r->type;
305
        }
306
        if (l->op != FIELD)
307
                l = lvalue(l);
308
        aty = l->type;
309
        if (isptr(aty))
310
                aty = unqual(aty)->type;
311
        if ( isconst(aty)
312
        ||  isstruct(aty) && unqual(aty)->u.sym->u.s.cfields)
313
                if (isaddrop(l->op)
314
                && !l->u.sym->computed && !l->u.sym->generated)
315
                        error("assignment to const identifier `%s'\n",
316
                                l->u.sym->name);
317
                else
318
                        error("assignment to const location\n");
319
        if (l->op == FIELD) {
320
                long n = 8*l->u.field->type->size - fieldsize(l->u.field);
321
                if (n > 0 && isunsigned(l->u.field->type))
322
                        r = bittree(BAND, r,
323
                                cnsttree(r->type, (unsigned long)fieldmask(l->u.field)));
324
                else if (n > 0) {
325
                        if (r->op == CNST+I) {
326
                                n = r->u.v.i;
327
                                if (n&(1<<(fieldsize(l->u.field)-1)))
328
                                        n |= ~0UL<<fieldsize(l->u.field);
329
                                r = cnsttree(r->type, n);
330
                        } else
331
                                r = shtree(RSH,
332
                                        shtree(LSH, r, cnsttree(inttype, n)),
333
                                        cnsttree(inttype, n));
334
                }
335
        }
336
        if (isstruct(ty) && isaddrop(l->op) && iscallb(r))
337
                return tree(RIGHT, ty,
338
                        tree(CALL+B, ty, r->kids[0]->kids[0], l),
339
                        idtree(l->u.sym));
340
        return tree(mkop(op,ty), ty, l, r);
341
}
342
Tree condtree(Tree e, Tree l, Tree r) {
343
        Symbol t1;
344
        Type ty, xty = l->type, yty = r->type;
345
        Tree p;
346
 
347
        if (isarith(xty) && isarith(yty))
348
                ty = binary(xty, yty);
349
        else if (eqtype(xty, yty, 1))
350
                ty = unqual(xty);
351
        else if (isptr(xty)   && isnullptr(r))
352
                ty = xty;
353
        else if (isnullptr(l) && isptr(yty))
354
                ty = yty;
355
        else if (isptr(xty) && !isfunc(xty->type) && isvoidptr(yty)
356
        ||       isptr(yty) && !isfunc(yty->type) && isvoidptr(xty))
357
                ty = voidptype;
358
        else if ((isptr(xty) && isptr(yty)
359
                 && eqtype(unqual(xty->type), unqual(yty->type), 1)))
360
                ty = xty;
361
        else {
362
                typeerror(COND, l, r);
363
                return consttree(0, inttype);
364
        }
365
        if (isptr(ty)) {
366
                ty = unqual(unqual(ty)->type);
367
                if (isptr(xty) && isconst(unqual(xty)->type)
368
                ||  isptr(yty) && isconst(unqual(yty)->type))
369
                        ty = qual(CONST, ty);
370
                if (isptr(xty) && isvolatile(unqual(xty)->type)
371
                ||  isptr(yty) && isvolatile(unqual(yty)->type))
372
                        ty = qual(VOLATILE, ty);
373
                ty = ptr(ty);
374
        }
375
        switch (e->op) {
376
        case CNST+I: return cast(e->u.v.i != 0   ? l : r, ty);
377
        case CNST+U: return cast(e->u.v.u != 0   ? l : r, ty);
378
        case CNST+P: return cast(e->u.v.p != 0   ? l : r, ty);
379
        case CNST+F: return cast(e->u.v.d != 0.0 ? l : r, ty);
380
        }
381
        if (ty != voidtype && ty->size > 0) {
382
                t1 = genident(REGISTER, unqual(ty), level);
383
        /*      t1 = temporary(REGISTER, unqual(ty)); */
384
                l = asgn(t1, l);
385
                r = asgn(t1, r);
386
        } else
387
                t1 = NULL;
388
        p = tree(COND, ty, cond(e),
389
                tree(RIGHT, ty, root(l), root(r)));
390
        p->u.sym = t1;
391
        return p;
392
}
393
/* addrof - address of p */
394
Tree addrof(Tree p) {
395
        Tree q = p;
396
 
397
        for (;;)
398
                switch (generic(q->op)) {
399
                case RIGHT:
400
                        assert(q->kids[0] || q->kids[1]);
401
                        q = q->kids[1] ? q->kids[1] : q->kids[0];
402
                        continue;
403
                case ASGN:
404
                        q = q->kids[1];
405
                        continue;
406
                case COND: {
407
                        Symbol t1 = q->u.sym;
408
                        q->u.sym = 0;
409
                        q = idtree(t1);
410
                        /* fall thru */
411
                        }
412
                case INDIR:
413
                        if (p == q)
414
                                return q->kids[0];
415
                        q = q->kids[0];
416
                        return tree(RIGHT, q->type, root(p), q);
417
                default:
418
                        error("addressable object required\n");
419
                        return value(p);
420
                }
421
}
422
 
423
/* andtree - construct tree for l [&& ||] r */
424
static Tree andtree(int op, Tree l, Tree r) {
425
        if (!isscalar(l->type) || !isscalar(r->type))
426
                typeerror(op, l, r);
427
        return simplify(op, inttype, cond(l), cond(r));
428
}
429
 
430
/* asgn - generate tree for assignment of expr e to symbol p sans qualifiers */
431
Tree asgn(Symbol p, Tree e) {
432
        if (isarray(p->type))
433
                e = tree(ASGN+B, p->type, idtree(p),
434
                        tree(INDIR+B, e->type, e, NULL));
435
        else {
436
                Type ty = p->type;
437
                p->type = unqual(p->type);
438
                if (isstruct(p->type) && p->type->u.sym->u.s.cfields) {
439
                        p->type->u.sym->u.s.cfields = 0;
440
                        e = asgntree(ASGN, idtree(p), e);
441
                        p->type->u.sym->u.s.cfields = 1;
442
                } else
443
                        e = asgntree(ASGN, idtree(p), e);
444
                p->type = ty;
445
        }
446
        return e;
447
}
448
 
449
/* bittree - construct tree for l [& | ^ %] r */
450
Tree bittree(int op, Tree l, Tree r) {
451
        Type ty = inttype;
452
 
453
        if (isint(l->type) && isint(r->type)) {
454
                ty = binary(l->type, r->type);
455
                l = cast(l, ty);
456
                r = cast(r, ty);
457
        } else
458
                typeerror(op, l, r);
459
        return simplify(op, ty, l, r);
460
}
461
 
462
/* multree - construct tree for l [* /] r */
463
static Tree multree(int op, Tree l, Tree r) {
464
        Type ty = inttype;
465
 
466
        if (isarith(l->type) && isarith(r->type)) {
467
                ty = binary(l->type, r->type);
468
                l = cast(l, ty);
469
                r = cast(r, ty);
470
        } else
471
                typeerror(op, l, r);
472
        return simplify(op, ty, l, r);
473
}
474
 
475
/* shtree - construct tree for l [>> <<] r */
476
Tree shtree(int op, Tree l, Tree r) {
477
        Type ty = inttype;
478
 
479
        if (isint(l->type) && isint(r->type)) {
480
                ty = promote(l->type);
481
                l = cast(l, ty);
482
                r = cast(r, inttype);
483
        } else
484
                typeerror(op, l, r);
485
        return simplify(op, ty, l, r);
486
}
487
 
488
/* subtree - construct tree for l - r */
489
static Tree subtree(int op, Tree l, Tree r) {
490
        long n;
491
        Type ty = inttype;
492
 
493
        if (isarith(l->type) && isarith(r->type)) {
494
                ty = binary(l->type, r->type);
495
                l = cast(l, ty);
496
                r = cast(r, ty);
497
        } else if (isptr(l->type) && !isfunc(l->type->type) && isint(r->type)) {
498
                ty = unqual(l->type);
499
                n = unqual(ty->type)->size;
500
                if (n == 0)
501
                        error("unknown size for type `%t'\n", ty->type);
502
                r = cast(r, promote(r->type));
503
                if (n > 1)
504
                        r = multree(MUL, cnsttree(signedptr, n), r);
505
                if (isunsigned(r->type))
506
                        r = cast(r, unsignedptr);
507
                else
508
                        r = cast(r, signedptr);
509
                return simplify(SUB+P, ty, l, r);
510
        } else if (compatible(l->type, r->type)) {
511
                ty = unqual(l->type);
512
                n = unqual(ty->type)->size;
513
                if (n == 0)
514
                        error("unknown size for type `%t'\n", ty->type);
515
                l = simplify(SUB+U, unsignedptr,
516
                        cast(l, unsignedptr), cast(r, unsignedptr));
517
                return simplify(DIV+I, longtype,
518
                        cast(l, longtype), cnsttree(longtype, n));
519
        } else
520
                typeerror(op, l, r);
521
        return simplify(op, ty, l, r);
522
}
523
 
524
/* typeerror - issue "operands of op have illegal types `l' and `r'" */
525
void typeerror(int op, Tree l, Tree r) {
526
        int i;
527
        static struct { int op; char *name; } ops[] = {
528
                ASGN, "=",      INDIR, "*",     NEG,  "-",
529
                ADD,  "+",      SUB,   "-",     LSH,  "<<",
530
                MOD,  "%",      RSH,   ">>",    BAND, "&",
531
                BCOM, "~",      BOR,   "|",     BXOR, "^",
532
                DIV,  "/",      MUL,   "*",     EQ,   "==",
533
                GE,   ">=",     GT,    ">",     LE,   "<=",
534
                LT,   "<",      NE,    "!=",    AND,  "&&",
535
                NOT,  "!",      OR,    "||",    COND, "?:",
536
                0, 0
537
        };
538
 
539
        op = generic(op);
540
        for (i = 0; ops[i].op; i++)
541
                if (op == ops[i].op)
542
                        break;
543
        assert(ops[i].name);
544
        if (r)
545
                error("operands of %s have illegal types `%t' and `%t'\n",
546
                        ops[i].name, l->type, r->type);
547
        else
548
                error("operand of unary %s has illegal type `%t'\n", ops[i].name,
549
                        l->type);
550
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.