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

Subversion Repositories eco32

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 hellwig
#include "c.h"
2
#include <float.h>
3
 
4
static char rcsid[] = "$Id: simp.c,v 1.1 2002/08/28 23:12:45 drh Exp $";
5
 
6
#define foldcnst(TYPE,VAR,OP) \
7
        if (l->op == CNST+TYPE && r->op == CNST+TYPE) \
8
                return cnsttree(ty, l->u.v.VAR OP r->u.v.VAR)
9
#define commute(L,R) \
10
        if (generic(R->op) == CNST && generic(L->op) != CNST) \
11
                do { Tree t = L; L = R; R = t; } while(0)
12
#define xfoldcnst(TYPE,VAR,OP,FUNC)\
13
        if (l->op == CNST+TYPE && r->op == CNST+TYPE\
14
        && FUNC(l->u.v.VAR,r->u.v.VAR,\
15
                ty->u.sym->u.limits.min.VAR,\
16
                ty->u.sym->u.limits.max.VAR, needconst)) \
17
                return cnsttree(ty, l->u.v.VAR OP r->u.v.VAR)
18
#define xcvtcnst(FTYPE,SRC,DST,VAR,EXPR) \
19
        if (l->op == CNST+FTYPE) do {\
20
                if (!explicitCast\
21
                &&  ((SRC) < DST->u.sym->u.limits.min.VAR || (SRC) > DST->u.sym->u.limits.max.VAR))\
22
                        warning("overflow in converting constant expression from `%t' to `%t'\n", l->type, DST);\
23
                if (needconst\
24
                || !((SRC) < DST->u.sym->u.limits.min.VAR || (SRC) > DST->u.sym->u.limits.max.VAR))\
25
                        return cnsttree(ty, (EXPR)); } while(0)
26
#define identity(X,Y,TYPE,VAR,VAL) \
27
        if (X->op == CNST+TYPE && X->u.v.VAR == VAL) return Y
28
#define zerofield(OP,TYPE,VAR) \
29
        if (l->op == FIELD \
30
        &&  r->op == CNST+TYPE && r->u.v.VAR == 0)\
31
                return eqtree(OP, bittree(BAND, l->kids[0],\
32
                        cnsttree(unsignedtype, \
33
                                (unsigned long)fieldmask(l->u.field)<<fieldright(l->u.field))), r)
34
#define cfoldcnst(TYPE,VAR,OP) \
35
        if (l->op == CNST+TYPE && r->op == CNST+TYPE) \
36
                return cnsttree(inttype, (long)(l->u.v.VAR OP r->u.v.VAR))
37
#define foldaddp(L,R,RTYPE,VAR) \
38
        if (L->op == CNST+P && R->op == CNST+RTYPE) { \
39
                Tree e = tree(CNST+P, ty, NULL, NULL);\
40
                e->u.v.p = (char *)L->u.v.p + R->u.v.VAR;\
41
                return e; }
42
#define ufoldcnst(TYPE,EXP) if (l->op == CNST+TYPE) return EXP
43
#define sfoldcnst(OP) \
44
        if (l->op == CNST+U && r->op == CNST+I \
45
        && r->u.v.i >= 0 && r->u.v.i < 8*l->type->size) \
46
                return cnsttree(ty, (unsigned long)(l->u.v.u OP r->u.v.i))
47
#define geu(L,R,V) \
48
        if (R->op == CNST+U && R->u.v.u == 0) do { \
49
                warning("result of unsigned comparison is constant\n"); \
50
                return tree(RIGHT, inttype, root(L), cnsttree(inttype, (long)(V))); } while(0)
51
#define idempotent(OP) if (l->op == OP) return l->kids[0]
52
 
53
int needconst;
54
int explicitCast;
55
static int addi(long x, long y, long min, long max, int needconst) {
56
        int cond = x == 0 || y == 0
57
        || x < 0 && y < 0 && x >= min - y
58
        || x < 0 && y > 0
59
        || x > 0 && y < 0
60
        || x > 0 && y > 0 && x <= max - y;
61
        if (!cond && needconst) {
62
                warning("overflow in constant expression\n");
63
                cond = 1;
64
        }
65
        return cond;
66
 
67
 
68
}
69
 
70
static int addd(double x, double y, double min, double max, int needconst) {
71
        int cond = x == 0 || y == 0
72
        || x < 0 && y < 0 && x >= min - y
73
        || x < 0 && y > 0
74
        || x > 0 && y < 0
75
        || x > 0 && y > 0 && x <= max - y;
76
        if (!cond && needconst) {
77
                warning("overflow in constant expression\n");
78
                cond = 1;
79
        }
80
        return cond;
81
 
82
 
83
}
84
 
85
static Tree addrtree(Tree e, long n, Type ty) {
86
        Symbol p = e->u.sym, q;
87
 
88
        if (p->scope  == GLOBAL
89
        ||  p->sclass == STATIC || p->sclass == EXTERN)
90
                NEW0(q, PERM);
91
        else
92
                NEW0(q, FUNC);
93
        q->name = stringd(genlabel(1));
94
        q->sclass = p->sclass;
95
        q->scope = p->scope;
96
        assert(isptr(ty) || isarray(ty));
97
        q->type = isptr(ty) ? ty->type : ty;
98
        q->temporary = p->temporary;
99
        q->generated = p->generated;
100
        q->addressed = p->addressed;
101
        q->computed = 1;
102
        q->defined = 1;
103
        q->ref = 1;
104
        assert(IR->address);
105
        if (p->scope  == GLOBAL
106
        ||  p->sclass == STATIC || p->sclass == EXTERN) {
107
                if (p->sclass == AUTO)
108
                        q->sclass = STATIC;
109
                (*IR->address)(q, p, n);
110
        } else {
111
                Code cp;
112
                addlocal(p);
113
                cp = code(Address);
114
                cp->u.addr.sym = q;
115
                cp->u.addr.base = p;
116
                cp->u.addr.offset = n;
117
        }
118
        e = tree(e->op, ty, NULL, NULL);
119
        e->u.sym = q;
120
        return e;
121
}
122
 
123
/* div[id] - return 1 if min <= x/y <= max, 0 otherwise */
124
static int divi(long x, long y, long min, long max, int needconst) {
125
        int cond = y != 0 && !(x == min && y == -1);
126
        if (!cond && needconst) {
127
                warning("overflow in constant expression\n");
128
                cond = 1;
129
        }
130
        return cond;
131
 
132
 
133
}
134
 
135
static int divd(double x, double y, double min, double max, int needconst) {
136
        int cond;
137
 
138
        if (x < 0) x = -x;
139
        if (y < 0) y = -y;
140
        cond = y != 0 && !(y < 1 && x > max*y);
141
        if (!cond && needconst) {
142
                warning("overflow in constant expression\n");
143
                cond = 1;
144
        }
145
        return cond;
146
 
147
}
148
 
149
/* mul[id] - return 1 if min <= x*y <= max, 0 otherwise */
150
static int muli(long x, long y, long min, long max, int needconst) {
151
        int cond = x > -1 && x <= 1 || y > -1 && y <= 1
152
        || x < 0 && y < 0 && -x <= max/-y
153
        || x < 0 && y > 0 &&  x >= min/y
154
        || x > 0 && y < 0 &&  y >= min/x
155
        || x > 0 && y > 0 &&  x <= max/y;
156
        if (!cond && needconst) {
157
                warning("overflow in constant expression\n");
158
                cond = 1;
159
        }
160
        return cond;
161
 
162
 
163
}
164
 
165
static int muld(double x, double y, double min, double max, int needconst) {
166
        int cond = x >= -1 && x <= 1 || y >= -1 && y <= 1
167
        || x < 0 && y < 0 && -x <= max/-y
168
        || x < 0 && y > 0 &&  x >= min/y
169
        || x > 0 && y < 0 &&  y >= min/x
170
        || x > 0 && y > 0 &&  x <= max/y;
171
        if (!cond && needconst) {
172
                warning("overflow in constant expression\n");
173
                cond = 1;
174
        }
175
        return cond;
176
 
177
 
178
}
179
/* sub[id] - return 1 if min <= x-y <= max, 0 otherwise */
180
static int subi(long x, long y, long min, long max, int needconst) {
181
        return addi(x, -y, min, max, needconst);
182
}
183
 
184
static int subd(double x, double y, double min, double max, int needconst) {
185
        return addd(x, -y, min, max, needconst);
186
}
187
Tree constexpr(int tok) {
188
        Tree p;
189
 
190
        needconst++;
191
        p = expr1(tok);
192
        needconst--;
193
        return p;
194
}
195
 
196
int intexpr(int tok, int n) {
197
        Tree p = constexpr(tok);
198
 
199
        needconst++;
200
        if (p->op == CNST+I || p->op == CNST+U)
201
                n = cast(p, inttype)->u.v.i;
202
        else
203
                error("integer expression must be constant\n");
204
        needconst--;
205
        return n;
206
}
207
Tree simplify(int op, Type ty, Tree l, Tree r) {
208
        int n;
209
        Tree p;
210
 
211
        if (optype(op) == 0)
212
                op = mkop(op, ty);
213
        switch (op) {
214
                case ADD+U:
215
                        foldcnst(U,u,+);
216
                        commute(r,l);
217
                        identity(r,l,U,u,0);
218
                        break;
219
                case ADD+I:
220
                        xfoldcnst(I,i,+,addi);
221
                        commute(r,l);
222
                        identity(r,l,I,i,0);
223
                        break;
224
                case CVI+I:
225
                        xcvtcnst(I,l->u.v.i,ty,i,(long)extend(l->u.v.i,ty));
226
                        break;
227
                case CVU+I:
228
                        if (l->op == CNST+U) {
229
                                if (!explicitCast && l->u.v.u > ty->u.sym->u.limits.max.i)
230
                                        warning("overflow in converting constant expression from `%t' to `%t'\n", l->type, ty);
231
                                if (needconst || !(l->u.v.u > ty->u.sym->u.limits.max.i))
232
                                        return cnsttree(ty, (long)extend(l->u.v.u,ty));
233
                        }
234
                        break;
235
                case CVP+U:
236
                        xcvtcnst(P,(unsigned long)l->u.v.p,ty,u,(unsigned long)l->u.v.p);
237
                        break;
238
                case CVU+P:
239
                        xcvtcnst(U,(void*)l->u.v.u,ty,p,(void*)l->u.v.u);
240
                        break;
241
                case CVP+P:
242
                        xcvtcnst(P,l->u.v.p,ty,p,l->u.v.p);
243
                        break;
244
                case CVI+U:
245
                        xcvtcnst(I,l->u.v.i,ty,u,((unsigned long)l->u.v.i)&ones(8*ty->size));
246
                        break;
247
                case CVU+U:
248
                        xcvtcnst(U,l->u.v.u,ty,u,l->u.v.u&ones(8*ty->size));
249
                        break;
250
 
251
                case CVI+F:
252
                        xcvtcnst(I,l->u.v.i,ty,d,(long double)l->u.v.i);
253
                case CVU+F:
254
                        xcvtcnst(U,l->u.v.u,ty,d,(long double)l->u.v.u);
255
                        break;
256
                case CVF+I:
257
                        xcvtcnst(F,l->u.v.d,ty,i,(long)l->u.v.d);
258
                        break;
259
                case CVF+F: {
260
                        float d;
261
                        if (l->op == CNST+F)
262
                                if (l->u.v.d < ty->u.sym->u.limits.min.d)
263
                                        d = ty->u.sym->u.limits.min.d;
264
                                else if (l->u.v.d > ty->u.sym->u.limits.max.d)
265
                                        d = ty->u.sym->u.limits.max.d;
266
                                else
267
                                        d = l->u.v.d;
268
                        xcvtcnst(F,l->u.v.d,ty,d,(long double)d);
269
                        break;
270
                        }
271
                case BAND+U:
272
                        foldcnst(U,u,&);
273
                        commute(r,l);
274
                        identity(r,l,U,u,ones(8*ty->size));
275
                        if (r->op == CNST+U && r->u.v.u == 0)
276
                                return tree(RIGHT, ty, root(l), cnsttree(ty, 0UL));
277
                        break;
278
                case BAND+I:
279
                        foldcnst(I,i,&);
280
                        commute(r,l);
281
                        identity(r,l,I,i,ones(8*ty->size));
282
                        if (r->op == CNST+I && r->u.v.u == 0)
283
                                return tree(RIGHT, ty, root(l), cnsttree(ty, 0L));
284
                        break;
285
 
286
                case MUL+U:
287
                        commute(l,r);
288
                        if (l->op == CNST+U && (n = ispow2(l->u.v.u)) != 0)
289
                                return simplify(LSH, ty, r, cnsttree(inttype, (long)n));
290
                        foldcnst(U,u,*);
291
                        identity(r,l,U,u,1);
292
                        break;
293
                case NE+I:
294
                        cfoldcnst(I,i,!=);
295
                        commute(r,l);
296
                        zerofield(NE,I,i);
297
                        break;
298
 
299
                case EQ+I:
300
                        cfoldcnst(I,i,==);
301
                        commute(r,l);
302
                        zerofield(EQ,I,i);
303
                        break;
304
                case ADD+P:
305
                        foldaddp(l,r,I,i);
306
                        foldaddp(l,r,U,u);
307
                        foldaddp(r,l,I,i);
308
                        foldaddp(r,l,U,u);
309
                        commute(r,l);
310
                        identity(r,retype(l,ty),I,i,0);
311
                        identity(r,retype(l,ty),U,u,0);
312
                        /*
313
                        Some assemblers, e.g., the MIPS, can't handle offsets
314
                        larger than 16 bits. A better solution would be to change
315
                        the interface so that address() could fail.
316
                        */
317
                        if (l->op == ADDRG+P && l->u.sym->generated
318
                        && (r->op == CNST+I && (r->u.v.i > 32767 || r->u.v.i < -32768)
319
                        ||  r->op == CNST+U && r->u.v.u > 65536))
320
                                break;
321
                        if (IR->address
322
                        &&  isaddrop(l->op)
323
                        && (r->op == CNST+I && r->u.v.i <= longtype->u.sym->u.limits.max.i
324
                            && r->u.v.i >= longtype->u.sym->u.limits.min.i
325
                        ||  r->op == CNST+U && r->u.v.u <= longtype->u.sym->u.limits.max.i))
326
                                return addrtree(l, cast(r, longtype)->u.v.i, ty);
327
                        if (IR->address
328
                        &&  l->op == ADD+P && isaddrop(l->kids[1]->op)
329
                        && (r->op == CNST+I && r->u.v.i <= longtype->u.sym->u.limits.max.i
330
                            && r->u.v.i >= longtype->u.sym->u.limits.min.i
331
                        ||  r->op == CNST+U && r->u.v.u <= longtype->u.sym->u.limits.max.i))
332
                                return simplify(ADD+P, ty, l->kids[0],
333
                                        addrtree(l->kids[1], cast(r, longtype)->u.v.i, ty));
334
                        if ((l->op == ADD+I || l->op == SUB+I)
335
                        && l->kids[1]->op == CNST+I && isaddrop(r->op))
336
                                return simplify(ADD+P, ty, l->kids[0],
337
                                        simplify(generic(l->op)+P, ty, r, l->kids[1]));
338
                        if (l->op == ADD+P && generic(l->kids[1]->op) == CNST
339
                        && generic(r->op) == CNST)
340
                                return simplify(ADD+P, ty, l->kids[0],
341
                                        simplify(ADD, l->kids[1]->type, l->kids[1], r));
342
                        if (l->op == ADD+I && generic(l->kids[1]->op) == CNST
343
                        &&  r->op == ADD+P && generic(r->kids[1]->op) == CNST)
344
                                return simplify(ADD+P, ty, l->kids[0],
345
                                        simplify(ADD+P, ty, r->kids[0],
346
                                        simplify(ADD, r->kids[1]->type, l->kids[1], r->kids[1])));
347
                        if (l->op == RIGHT && l->kids[1])
348
                                return tree(RIGHT, ty, l->kids[0],
349
                                        simplify(ADD+P, ty, l->kids[1], r));
350
                        else if (l->op == RIGHT && l->kids[0])
351
                                return tree(RIGHT, ty,
352
                                        simplify(ADD+P, ty, l->kids[0], r), NULL);
353
                        break;
354
 
355
                case ADD+F:
356
                        xfoldcnst(F,d,+,addd);
357
                        commute(r,l);
358
                        break;
359
                case AND+I:
360
                        op = AND;
361
                        ufoldcnst(I,l->u.v.i ? cond(r) : l);    /* 0&&r => 0, 1&&r => r */
362
                        break;
363
                case OR+I:
364
                        op = OR;
365
                        /* 0||r => r, 1||r => 1 */
366
                        ufoldcnst(I,l->u.v.i ? cnsttree(ty, 1L) : cond(r));
367
                        break;
368
                case BCOM+I:
369
                        ufoldcnst(I,cnsttree(ty, (long)extend((~l->u.v.i)&ones(8*ty->size), ty)));
370
                        idempotent(BCOM+U);
371
                        break;
372
                case BCOM+U:
373
                        ufoldcnst(U,cnsttree(ty, (unsigned long)((~l->u.v.u)&ones(8*ty->size))));
374
                        idempotent(BCOM+U);
375
                        break;
376
                case BOR+U:
377
                        foldcnst(U,u,|);
378
                        commute(r,l);
379
                        identity(r,l,U,u,0);
380
                        break;
381
                case BOR+I:
382
                        foldcnst(I,i,|);
383
                        commute(r,l);
384
                        identity(r,l,I,i,0);
385
                        break;
386
                case BXOR+U:
387
                        foldcnst(U,u,^);
388
                        commute(r,l);
389
                        identity(r,l,U,u,0);
390
                        break;
391
                case BXOR+I:
392
                        foldcnst(I,i,^);
393
                        commute(r,l);
394
                        identity(r,l,I,i,0);
395
                        break;
396
                case DIV+F:
397
                        xfoldcnst(F,d,/,divd);
398
                        break;
399
                case DIV+I:
400
                        identity(r,l,I,i,1);
401
                        if (r->op == CNST+I && r->u.v.i == 0
402
                        ||  l->op == CNST+I && l->u.v.i == ty->u.sym->u.limits.min.i
403
                        &&  r->op == CNST+I && r->u.v.i == -1)
404
                                break;
405
                        xfoldcnst(I,i,/,divi);
406
                        break;
407
                case DIV+U:
408
                        identity(r,l,U,u,1);
409
                        if (r->op == CNST+U && r->u.v.u == 0)
410
                                break;
411
                        if (r->op == CNST+U && (n = ispow2(r->u.v.u)) != 0)
412
                                return simplify(RSH, ty, l, cnsttree(inttype, (long)n));
413
                        foldcnst(U,u,/);
414
                        break;
415
                case EQ+F:
416
                        cfoldcnst(F,d,==);
417
                        commute(r,l);
418
                        break;
419
                case EQ+U:
420
                        cfoldcnst(U,u,==);
421
                        commute(r,l);
422
                        zerofield(EQ,U,u);
423
                        break;
424
                case GE+F: cfoldcnst(F,d,>=); break;
425
                case GE+I: cfoldcnst(I,i,>=); break;
426
                case GE+U:
427
                        geu(l,r,1);     /* l >= 0 => (l,1) */
428
                        cfoldcnst(U,u,>=);
429
                        if (l->op == CNST+U && l->u.v.u == 0)    /* 0 >= r => r == 0 */
430
                                return eqtree(EQ, r, l);
431
                        break;
432
                case GT+F: cfoldcnst(F,d, >); break;
433
                case GT+I: cfoldcnst(I,i, >); break;
434
                case GT+U:
435
                        geu(r,l,0);      /* 0 > r => (r,0) */
436
                        cfoldcnst(U,u, >);
437
                        if (r->op == CNST+U && r->u.v.u == 0)    /* l > 0 => l != 0 */
438
                                return eqtree(NE, l, r);
439
                        break;
440
                case LE+F: cfoldcnst(F,d,<=); break;
441
                case LE+I: cfoldcnst(I,i,<=); break;
442
                case LE+U:
443
                        geu(r,l,1);     /* 0 <= r => (r,1) */
444
                        cfoldcnst(U,u,<=);
445
                        if (r->op == CNST+U && r->u.v.u == 0)    /* l <= 0 => l == 0 */
446
                                return eqtree(EQ, l, r);
447
                        break;
448
                case LSH+I:
449
                        identity(r,l,I,i,0);
450
                        if (l->op == CNST+I && r->op == CNST+I
451
                        && r->u.v.i >= 0 && r->u.v.i < 8*l->type->size
452
                        && muli(l->u.v.i, 1<<r->u.v.i, ty->u.sym->u.limits.min.i, ty->u.sym->u.limits.max.i, needconst))
453
                                return cnsttree(ty, (long)(l->u.v.i<<r->u.v.i));
454
                        if (r->op == CNST+I && (r->u.v.i >= 8*ty->size || r->u.v.i < 0)) {
455
                                warning("shifting an `%t' by %d bits is undefined\n", ty, r->u.v.i);
456
                                break;
457
                        }
458
 
459
                        break;
460
                case LSH+U:
461
                        identity(r,l,I,i,0);
462
                        sfoldcnst(<<);
463
                        if (r->op == CNST+I && (r->u.v.i >= 8*ty->size || r->u.v.i < 0)) {
464
                                warning("shifting an `%t' by %d bits is undefined\n", ty, r->u.v.i);
465
                                break;
466
                        }
467
 
468
                        break;
469
 
470
                case LT+F: cfoldcnst(F,d, <); break;
471
                case LT+I: cfoldcnst(I,i, <); break;
472
                case LT+U:
473
                        geu(l,r,0);      /* l < 0 => (l,0) */
474
                        cfoldcnst(U,u, <);
475
                        if (l->op == CNST+U && l->u.v.u == 0)    /* 0 < r => r != 0 */
476
                                return eqtree(NE, r, l);
477
                        break;
478
                case MOD+I:
479
                        if (r->op == CNST+I && r->u.v.i == 0
480
                        ||  l->op == CNST+I && l->u.v.i == ty->u.sym->u.limits.min.i
481
                        &&  r->op == CNST+I && r->u.v.i == -1)
482
                                break;
483
                        xfoldcnst(I,i,%,divi);
484
                        if (r->op == CNST+I && r->u.v.i == 1)   /* l%1 => (l,0) */
485
                                return tree(RIGHT, ty, root(l), cnsttree(ty, 0L));
486
                        break;
487
                case MOD+U:
488
                        if (r->op == CNST+U && ispow2(r->u.v.u)) /* l%2^n => l&(2^n-1) */
489
                                return bittree(BAND, l, cnsttree(ty, r->u.v.u - 1));
490
                        if (r->op == CNST+U && r->u.v.u == 0)
491
                                break;
492
                        foldcnst(U,u,%);
493
                        break;
494
                case MUL+F:
495
                        xfoldcnst(F,d,*,muld);
496
                        commute(l,r);
497
                        break;
498
                case MUL+I:
499
                        commute(l,r);
500
                        xfoldcnst(I,i,*,muli);
501
                        if (l->op == CNST+I && r->op == ADD+I && r->kids[1]->op == CNST+I)
502
                                /* c1*(x + c2) => c1*x + c1*c2 */
503
                                return simplify(ADD, ty, simplify(MUL, ty, l, r->kids[0]),
504
                                        simplify(MUL, ty, l, r->kids[1]));
505
                        if (l->op == CNST+I && r->op == SUB+I && r->kids[1]->op == CNST+I)
506
                                /* c1*(x - c2) => c1*x - c1*c2 */
507
                                return simplify(SUB, ty, simplify(MUL, ty, l, r->kids[0]),
508
                                        simplify(MUL, ty, l, r->kids[1]));
509
                        if (l->op == CNST+I && l->u.v.i > 0 && (n = ispow2(l->u.v.i)) != 0)
510
                                /* 2^n * r => r<<n */
511
                                return simplify(LSH, ty, r, cnsttree(inttype, (long)n));
512
                        identity(r,l,I,i,1);
513
                        break;
514
                case NE+F:
515
                        cfoldcnst(F,d,!=);
516
                        commute(r,l);
517
                        break;
518
                case NE+U:
519
                        cfoldcnst(U,u,!=);
520
                        commute(r,l);
521
                        zerofield(NE,U,u);
522
                        break;
523
                case NEG+F:
524
                        ufoldcnst(F,cnsttree(ty, -l->u.v.d));
525
                        idempotent(NEG+F);
526
                        break;
527
                case NEG+I:
528
                        if (l->op == CNST+I) {
529
                                if (needconst && l->u.v.i == ty->u.sym->u.limits.min.i)
530
                                        warning("overflow in constant expression\n");
531
                                if (needconst || l->u.v.i != ty->u.sym->u.limits.min.i)
532
                                        return cnsttree(ty, -l->u.v.i);
533
                        }
534
                        idempotent(NEG+I);
535
                        break;
536
                case NOT+I:
537
                        op = NOT;
538
                        ufoldcnst(I,cnsttree(ty, !l->u.v.i));
539
                        break;
540
                case RSH+I:
541
                        identity(r,l,I,i,0);
542
                        if (l->op == CNST+I && r->op == CNST+I
543
                        && r->u.v.i >= 0 && r->u.v.i < 8*l->type->size) {
544
                                long n = l->u.v.i>>r->u.v.i;
545
                                if (l->u.v.i < 0)
546
                                        n |= ~0UL<<(8*l->type->size - r->u.v.i);
547
                                return cnsttree(ty, n);
548
                        }
549
                        if (r->op == CNST+I && (r->u.v.i >= 8*ty->size || r->u.v.i < 0)) {
550
                                warning("shifting an `%t' by %d bits is undefined\n", ty, r->u.v.i);
551
                                break;
552
                        }
553
 
554
                        break;
555
                case RSH+U:
556
                        identity(r,l,I,i,0);
557
                        sfoldcnst(>>);
558
                        if (r->op == CNST+I && (r->u.v.i >= 8*ty->size || r->u.v.i < 0)) {
559
                                warning("shifting an `%t' by %d bits is undefined\n", ty, r->u.v.i);
560
                                break;
561
                        }
562
 
563
                        break;
564
                case SUB+F:
565
                        xfoldcnst(F,d,-,subd);
566
                        break;
567
                case SUB+I:
568
                        xfoldcnst(I,i,-,subi);
569
                        identity(r,l,I,i,0);
570
                        break;
571
                case SUB+U:
572
                        foldcnst(U,u,-);
573
                        identity(r,l,U,u,0);
574
                        break;
575
                case SUB+P:
576
                        if (l->op == CNST+P && r->op == CNST+P)
577
                                return cnsttree(ty, (long)((char *)l->u.v.p - (char *)r->u.v.p));
578
                        if (r->op == CNST+I || r->op == CNST+U)
579
                                return simplify(ADD, ty, l,
580
                                        cnsttree(inttype, r->op == CNST+I ? -r->u.v.i : -(long)r->u.v.u));
581
                        if (isaddrop(l->op) && r->op == ADD+I && r->kids[1]->op == CNST+I)
582
                                /* l - (x + c) => l-c - x */
583
                                return simplify(SUB, ty,
584
                                        simplify(SUB, ty, l, r->kids[1]), r->kids[0]);
585
                        break;
586
                default:assert(0);
587
        }
588
        return tree(op, ty, l, r);
589
}
590
/* ispow2 - if u > 1 && u == 2^n, return n, otherwise return 0 */
591
int ispow2(unsigned long u) {
592
        int n;
593
 
594
        if (u > 1 && (u&(u-1)) == 0)
595
                for (n = 0; u; u >>= 1, n++)
596
                        if (u&1)
597
                                return n;
598
        return 0;
599
}
600
 

powered by: WebSVN 2.1.0

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