Annotation of researchv10no/cmd/lcc/c/simp.c, revision 1.1.1.1

1.1       root        1: /* C compiler: tree simplification and constant folding */
                      2: 
                      3: #include "c.h"
                      4: 
                      5: int needconst;         /* >=1 if parsing a constant expression */
                      6: 
                      7: dclproto(static int add,(double, double, double, double, int));
                      8: dclproto(static Tree addrnode,(Symbol, int, Type));
                      9: dclproto(static int div,(double, double, double, double, int));
                     10: dclproto(static int mul,(double, double, double, double, int));
                     11: dclproto(static int sub,(double, double, double, double, int));
                     12: 
                     13: /* add - return 1 if min <= x+y <= max, 0 otherwise */
                     14: static int add(x, y, min, max, needconst) double x, y, min, max; {
                     15:        int cond = x == 0 || y == 0
                     16:        || x < 0 && y < 0 && x >= min - y
                     17:        || x < 0 && y > 0
                     18:        || x > 0 && y < 0
                     19:        || x > 0 && y > 0 && x <= max - y;
                     20:        if (!cond && needconst) {
                     21:                warning("overflow in constant expression\n");
                     22:                cond = 1;
                     23:        }
                     24:        return cond;
                     25: }
                     26: 
                     27: /* addrnode - create a tree for addressing expression p+n, type ty */
                     28: static Tree addrnode(p, n, ty) Symbol p; Type ty; {
                     29:        Symbol q = (Symbol)talloc(sizeof *q);
                     30:        Tree e;
                     31:        static struct symbol z;
                     32: 
                     33:        *q = z;
                     34:        q->name = stringd(genlabel(1));
                     35:        q->sclass = p->sclass;
                     36:        q->scope = p->scope;
                     37:        q->type = ty;
                     38:        q->defined = 1;
                     39:        q->temporary = p->temporary;
                     40:        q->generated = p->generated;
                     41:        q->computed = 1;
                     42:        q->addressed = p->addressed;
                     43:        q->ref = 1;
                     44:        if (p->scope == GLOBAL || p->sclass == STATIC || p->sclass == EXTERN) {
                     45:                q->sclass = p->sclass == AUTO ? STATIC : p->sclass;
                     46:                (*IR->address)(q, p, n);
                     47:                e = tree(ADDRG+P, ty, 0, 0);
                     48:        } else {
                     49:                Code cp;
                     50:                if (!p->defined)
                     51:                        addlocal(p);
                     52:                cp = code(Address);
                     53:                cp->u.addr.sym = q;
                     54:                cp->u.addr.base = p;
                     55:                cp->u.addr.offset = n;
                     56:                e = tree(p->scope == PARAM ? ADDRF+P : ADDRL+P, ty, 0, 0);
                     57:        }
                     58:        e->u.sym = q;
                     59:        return e;
                     60: }
                     61: 
                     62: /* div - return 1 if min <= x/y <= max, 0 otherwise */
                     63: static int div(x, y, min, max, needconst) double x, y, min, max; {
                     64:        int cond;
                     65: 
                     66:        if (x < 0) x = -x;
                     67:        if (y < 0) y = -y;
                     68:        cond = y != 0 && (y > 1 || x <= max*y);
                     69:        if (!cond && y != 0 && needconst) {
                     70:                warning("overflow in constant expression\n");
                     71:                cond = 1;
                     72:        }
                     73:        return cond;
                     74: }
                     75: 
                     76: /* ispow2 - if u > 1 && u == 2^n, return n, otherwise return 0 */
                     77: int ispow2(u) unsigned u; {
                     78:        int n;
                     79: 
                     80:        if (u > 1 && (u&(u-1)) == 0)
                     81:                for (n = 0; u; u >>= 1, n++)
                     82:                        if (u&1)
                     83:                                return n;
                     84:        return 0;
                     85: }
                     86: 
                     87: /* mul - return 1 if min <= x*y <= max, 0 otherwise */
                     88: static int mul(x, y, min, max, needconst) double x, y, min, max; {
                     89:        int cond = x > -1 && x <= 1 || y > -1 && y <= 1
                     90:        || x < 0 && y < 0 && -x <= max/-y
                     91:        || x < 0 && y > 0 &&  x >= min/y
                     92:        || x > 0 && y < 0 &&  x >= min/y
                     93:        || x > 0 && y > 0 &&  x <= max/y;
                     94:        if (!cond && needconst) {
                     95:                warning("overflow in constant expression\n");
                     96:                cond = 1;
                     97:        }
                     98:        return cond;
                     99: }
                    100: 
                    101: #define xcvtcnst(FTYPE,TTYPE,EXP,VAR,MIN,MAX) \
                    102:        if (l->op == CNST+FTYPE) { \
                    103:                if (needconst && (VAR < MIN || VAR > MAX)) \
                    104:                        warning("overflow in constant expression\n"); \
                    105:                if (needconst || VAR >= MIN && VAR <= MAX) { \
                    106:                        p = tree(CNST+ttob(TTYPE), TTYPE, 0, 0); EXP; return p; } }
                    107: #define cvtcnst(FTYPE,TTYPE,EXP) \
                    108:        if (l->op == CNST+FTYPE) { \
                    109:                p = tree(CNST+ttob(TTYPE), TTYPE, 0, 0); EXP; return p; }
                    110: #define commute(L,R) \
                    111:        if (generic(R->op) == CNST && generic(L->op) != CNST) { \
                    112:                Tree t = L; L = R; R = t; }
                    113: #define zerofield(OP,TYPE,VAR) \
                    114:        if (l->op == FIELD && r->op == CNST+TYPE && r->u.v.VAR == 0) \
                    115:                return eqnode(OP, bitnode(BAND, l->kids[0], \
                    116:                        constnode(fieldmask(l->u.field)<<fieldright(l->u.field), \
                    117:                                unsignedtype)), r);
                    118: #define ufoldcnst(TYPE,EXP) if (l->op == CNST+TYPE) return EXP
                    119: #define xfoldcnst(TYPE,VAR,OP,RTYPE,FUNC,MIN,MAX,needconst) \
                    120:        if (l->op == CNST+TYPE && r->op == CNST+TYPE \
                    121:        && FUNC((double)l->u.v.VAR,(double)r->u.v.VAR,(double)MIN,(double)MAX, needconst)) { \
                    122:                p = tree(CNST+ttob(RTYPE), RTYPE, 0, 0); \
                    123:                p->u.v.VAR = l->u.v.VAR OP r->u.v.VAR; return p; }
                    124: #define foldcnst(TYPE,VAR,OP,RTYPE) \
                    125:        if (l->op == CNST+TYPE && r->op == CNST+TYPE) { \
                    126:                p = tree(CNST+ttob(RTYPE), RTYPE, 0, 0); \
                    127:                p->u.v.VAR = l->u.v.VAR OP r->u.v.VAR; return p; }
                    128: #define cfoldcnst(TYPE,VAR,OP,RTYPE) \
                    129:        if (l->op == CNST+TYPE && r->op == CNST+TYPE) { \
                    130:                p = tree(CNST+ttob(RTYPE), RTYPE, 0, 0); \
                    131:                p->u.v.i = l->u.v.VAR OP r->u.v.VAR; return p; }
                    132: #define sfoldcnst(TYPE,VAR,OP,RTYPE) \
                    133:        if (l->op == CNST+TYPE && r->op == CNST+I \
                    134:        && r->u.v.i >= 0 && r->u.v.i < 8*l->type->size) { \
                    135:                p = tree(CNST+ttob(RTYPE), RTYPE, 0, 0); \
                    136:                p->u.v.VAR = l->u.v.VAR OP r->u.v.i; return p; }
                    137: #define foldaddp(L,R,RTYPE,VAR) \
                    138:        if (L->op == CNST+P && R->op == CNST+RTYPE) { \
                    139:                p = tree(CNST+P, ty, 0, 0); \
                    140:                p->u.v.p = L->u.v.p + R->u.v.VAR; return p; }
                    141: #define geu(L,R,V) \
                    142:        if (R->op == CNST+U && R->u.v.u == 0) { \
                    143:                warning("result of unsigned comparison is constant\n"); \
                    144:                return tree(RIGHT, inttype, root(L), constnode(V, inttype)); }
                    145: #define idempotent(OP) if (l->op == OP) return l->kids[0];
                    146: #define identity(X,Y,TYPE,VAR,VAL) if (X->op == CNST+TYPE && X->u.v.VAR == VAL) return Y
                    147: 
                    148: /* simplify - build node for op, simplifying and folding constants, if possible */
                    149: Tree simplify(op, ty, l, r) Type ty; Tree l, r; {
                    150:        int n;
                    151:        Tree p;
                    152: 
                    153:        if (optype(op) == 0)
                    154:                op += ttob(ty);
                    155:        switch (op) {
                    156:        case ADD+D:
                    157:                xfoldcnst(D,d,+,doubletype,add,-DBL_MAX,DBL_MAX,0);
                    158:                commute(r,l);
                    159:                break;
                    160:        case ADD+F:
                    161:                xfoldcnst(F,f,+,floattype,add,-FLT_MAX,FLT_MAX,0);
                    162:                commute(r,l);
                    163:                break;
                    164:        case ADD+I:
                    165:                xfoldcnst(I,i,+,inttype,add,INT_MIN,INT_MAX,needconst);
                    166:                commute(r,l);
                    167:                break;
                    168:        case ADD+P:
                    169:                foldaddp(l,r,I,i);
                    170:                foldaddp(l,r,U,u);
                    171:                foldaddp(r,l,I,i);
                    172:                foldaddp(r,l,U,u);
                    173:                commute(r,l);
                    174:                identity(r,retype(l,ty),I,i,0);
                    175:                identity(r,retype(l,ty),U,u,0);
                    176:                if (isaddrop(l->op) && (r->op == CNST+I || r->op == CNST+U))
                    177:                        /* l + c => l+c, where l is a symbolic address */
                    178:                        return addrnode(l->u.sym, r->op == CNST+I ? r->u.v.i : r->u.v.u, ty);
                    179:                if ((l->op == ADD+I || l->op == SUB+I)
                    180:                && l->kids[1]->op == CNST+I && isaddrop(r->op))
                    181:                        /* (x +- c) + r => x + r+-c, where r is a symbolic address */
                    182:                        return simplify(ADD+P, ty, l->kids[0],
                    183:                                simplify(l->op == ADD+I ? ADD+P : SUB+P, ty, r, l->kids[1]));
                    184:                if (l->op == ADD+P && isaddrop(l->kids[1]->op)
                    185:                && (r->op == CNST+I || r->op == CNST+U))
                    186:                        /* (x + a) + r => x + a+r */
                    187:                        return simplify(ADD+P, ty, l->kids[0],
                    188:                                addrnode(l->kids[1]->u.sym, r->op == CNST+I ? r->u.v.i : r->u.v.u, ty));
                    189:                if (l->op == ADD+P && generic(l->kids[1]->op) == CNST && generic(r->op) == CNST)
                    190:                        /* (x + c) + r => x + c+r */
                    191:                        return simplify(ADD+P, ty, l->kids[0], (*opnode['+'])(ADD, l->kids[1], r));
                    192:                if (l->op == ADD+I && generic(l->kids[1]->op) == CNST
                    193:                &&  r->op == ADD+P && generic(r->kids[1]->op) == CNST)
                    194:                        /* (x + c1) + (y + c2) => x + (y + c1+c2) */
                    195:                        return simplify(ADD+P, ty, l->kids[0],
                    196:                                simplify(ADD+P, ty, r->kids[0],
                    197:                                (*opnode['+'])(ADD, l->kids[1], r->kids[1])));
                    198:                if (l->op == RIGHT && isstruct(l->type))        /* f().x */
                    199:                        return tree(RIGHT, ty, l->kids[0],
                    200:                                simplify(ADD+P, ty, l->kids[1], r));
                    201:                if (l->op == RIGHT)
                    202:                        if (l->kids[1])
                    203:                                return tree(RIGHT, ty, l->kids[0],
                    204:                                        simplify(ADD+P, ty, l->kids[1], r));
                    205:                        else
                    206:                                return tree(RIGHT, ty,
                    207:                                        simplify(ADD+P, ty, l->kids[0], r), 0);
                    208:                break;
                    209:        case ADD+U:
                    210:                foldcnst(U,u,+,unsignedtype);
                    211:                commute(r,l);
                    212:                break;
                    213:        case AND+I:
                    214:                op = AND;
                    215:                ufoldcnst(I,l->u.v.i ? cond(r) : l);    /* 0&&r => 0, 1&&r => r */
                    216:                break;
                    217:        case OR+I:
                    218:                op = OR;
                    219:                /* 0||r => r, 1||r => 1 */
                    220:                ufoldcnst(I,l->u.v.i ? constnode(1, inttype) : cond(r));
                    221:                break;
                    222:        case BAND+U:
                    223:                foldcnst(U,u,&,unsignedtype);
                    224:                commute(r,l);
                    225:                identity(r,l,U,u,(~0));
                    226:                if (r->op == CNST+U && r->u.v.u == 0)   /* l&0 => (l,0) */
                    227:                        return tree(RIGHT, unsignedtype, root(l),
                    228:                                constnode(0, unsignedtype));
                    229:                break;
                    230:        case BCOM+I:
                    231:                ufoldcnst(I,constnode(~l->u.v.i, inttype));
                    232:                idempotent(BCOM+U);
                    233:                op = BCOM+U;
                    234:                break;
                    235:        case BCOM+U:
                    236:                ufoldcnst(U,constnode(~l->u.v.u, unsignedtype));
                    237:                idempotent(BCOM+U);
                    238:                break;
                    239:        case BOR+U:
                    240:                foldcnst(U,u,|,unsignedtype);
                    241:                commute(r,l);
                    242:                identity(r,l,U,u,0);
                    243:                break;
                    244:        case BXOR+U:
                    245:                foldcnst(U,u,^,unsignedtype);
                    246:                commute(r,l);
                    247:                identity(r,l,U,u,0);
                    248:                break;
                    249:        case CVC+I:  cvtcnst(C,      inttype,p->u.v.i  = (l->u.v.sc&0200 ? (~0<<8) : 0)|(l->u.v.sc&0377)); break;
                    250:        case CVC+U:  cvtcnst(C, unsignedtype,p->u.v.u  = l->u.v.uc); break;
                    251:        case CVD+F: xcvtcnst(D,    floattype,p->u.v.f  = l->u.v.d,l->u.v.d,-FLT_MAX,FLT_MAX); break;
                    252:        case CVD+I: xcvtcnst(D,      inttype,p->u.v.i  = l->u.v.d,l->u.v.d,INT_MIN,INT_MAX); break;
                    253:        case CVF+D:  cvtcnst(F,   doubletype,p->u.v.d  = l->u.v.f);  break;
                    254:        case CVI+C: xcvtcnst(I,     chartype,p->u.v.sc = l->u.v.i,l->u.v.i,SCHAR_MIN,SCHAR_MAX); break;
                    255:        case CVI+D:  cvtcnst(I,   doubletype,p->u.v.d  = l->u.v.i);  break;
                    256:        case CVI+S: xcvtcnst(I,    shorttype,p->u.v.ss = l->u.v.i,l->u.v.i,SHRT_MIN,SHRT_MAX); break;
                    257:        case CVI+U:  cvtcnst(I, unsignedtype,p->u.v.u  = l->u.v.i);  break;
                    258:        case CVP+U:  cvtcnst(P, unsignedtype,p->u.v.u  = (unsigned)l->u.v.p); break;
                    259:        case CVS+I:  cvtcnst(S,      inttype,p->u.v.i  = l->u.v.ss); break;
                    260:        case CVS+U:  cvtcnst(S, unsignedtype,p->u.v.u  = l->u.v.us); break;
                    261:        case CVU+C:  cvtcnst(U, unsignedchar,p->u.v.uc = l->u.v.u);  break;
                    262:        case CVU+D:  cvtcnst(U,   doubletype,p->u.v.d  = utod(l->u.v.u));  break;
                    263:        case CVU+I:
                    264:                if (needconst && l->u.v.u > INT_MAX)
                    265:                        warning("overflow in constant expression\n");
                    266:                if (needconst || l->u.v.u <= INT_MAX)
                    267:                        cvtcnst(U,   inttype,p->u.v.i  = l->u.v.u);
                    268:                break;
                    269:        case CVU+P:  cvtcnst(U,    voidptype,p->u.v.p  = (char *)l->u.v.u);  break;
                    270:        case CVU+S:  cvtcnst(U,unsignedshort,p->u.v.us = l->u.v.u);  break;
                    271:        case DIV+D:
                    272:                xfoldcnst(D,d,/,doubletype,div,-DBL_MAX,DBL_MAX,0);
                    273:                break;
                    274:        case DIV+F:
                    275:                xfoldcnst(F,f,/,floattype,div,-FLT_MAX,FLT_MAX,0);
                    276:                break;
                    277:        case DIV+I:
                    278:                identity(r,l,I,i,1);
                    279: #ifdef mips
                    280:                if (l->op == CNST+I && r->op == CNST+I && r->u.v.i == -1
                    281:                && !div((double)l->u.v.i, (double)r->u.v.i, (double)INT_MIN, (double)INT_MAX, 0))
                    282:                        break;
                    283: #endif
                    284:                xfoldcnst(I,i,/,inttype,div,INT_MIN,INT_MAX,needconst);
                    285:                break;
                    286:        case DIV+U:             
                    287:                identity(r,l,U,u,1);
                    288:                if (r->op == CNST+U && r->u.v.u == 0)
                    289:                        break;
                    290:                if (r->op == CNST+U && (n = ispow2(r->u.v.u)))
                    291:                        return simplify(RSH+U, unsignedtype, l, constnode(n, inttype));
                    292:                foldcnst(U,u,/,unsignedtype);
                    293:                break;
                    294:        case EQ+D:
                    295:                cfoldcnst(D,d,==,inttype);
                    296:                commute(r,l);
                    297:                break;
                    298:        case EQ+F:
                    299:                cfoldcnst(F,f,==,inttype);
                    300:                commute(r,l);
                    301:                break;
                    302:        case EQ+I:
                    303:                cfoldcnst(I,i,==,inttype);
                    304:                commute(r,l);
                    305:                zerofield(EQ,I,i);
                    306:                break;
                    307:        case EQ+U:
                    308:                cfoldcnst(U,u,==,inttype);
                    309:                commute(r,l);
                    310:                zerofield(EQ,U,u);
                    311:                op = EQ+I;
                    312:                break;
                    313:        case GE+D: cfoldcnst(D,d,>=,inttype); break;
                    314:        case GE+F: cfoldcnst(F,f,>=,inttype); break;
                    315:        case GE+I: cfoldcnst(I,i,>=,inttype); break;
                    316:        case GE+U:
                    317:                geu(l,r,1);     /* l >= 0 => (l,1) */
                    318:                cfoldcnst(U,u,>=,inttype);
                    319:                if (l->op == CNST+U && l->u.v.u == 0)   /* 0 >= r => 0 == r */
                    320:                        return tree(EQ+I, ty, l, r);
                    321:                break;
                    322:        case GT+D: cfoldcnst(D,d, >,inttype); break;
                    323:        case GT+F: cfoldcnst(F,f, >,inttype); break;
                    324:        case GT+I: cfoldcnst(I,i, >,inttype); break;
                    325:        case GT+U:
                    326:                geu(r,l,0);     /* 0 > r => (r,0) */
                    327:                cfoldcnst(U,u, >,inttype);
                    328:                if (r->op == CNST+U && r->u.v.u == 0)   /* l > 0 => l != 0 */
                    329:                        return tree(NE+I, ty, l, r);
                    330:                break;
                    331:        case LE+D: cfoldcnst(D,d,<=,inttype); break;
                    332:        case LE+F: cfoldcnst(F,f,<=,inttype); break;
                    333:        case LE+I: cfoldcnst(I,i,<=,inttype); break;
                    334:        case LE+U:
                    335:                geu(r,l,1);     /* 0 <= r => (r,1) */
                    336:                cfoldcnst(U,u,<=,inttype);
                    337:                if (r->op == CNST+U && r->u.v.u == 0)   /* l <= 0 => l == 0 */
                    338:                        return tree(EQ+I, ty, l, r);
                    339:                break;
                    340:        case LSH+I:
                    341:                identity(r,l,I,i,0);
                    342:                if (l->op == CNST+I && r->op == CNST+I
                    343:                && r->u.v.i >= 0 && r->u.v.i < 8*l->type->size
                    344:                && mul((double)l->u.v.i, (double)(1<<r->u.v.i), (double)INT_MIN, (double)INT_MAX, needconst))
                    345:                        return constnode(l->u.v.i<<r->u.v.i, inttype);
                    346:                break;
                    347:        case LSH+U:
                    348:                identity(r,l,I,i,0);
                    349:                sfoldcnst(U,u,<<,unsignedtype);
                    350:                break;
                    351:        case LT+D: cfoldcnst(D,d, <,inttype); break;
                    352:        case LT+F: cfoldcnst(F,f, <,inttype); break;
                    353:        case LT+I: cfoldcnst(I,i, <,inttype); break;
                    354:        case LT+U:
                    355:                geu(l,r,0);     /* l < 0 => (l,0) */
                    356:                cfoldcnst(U,u, <,inttype);
                    357:                if (l->op == CNST+U && l->u.v.u == 0)   /* 0 < r => 0 != r */
                    358:                        return tree(NE+I, ty, l, r);
                    359:                break;
                    360:        case MOD+I:
                    361:                if (r->op == CNST+I && r->u.v.i == 1)   /* l%1 => (l,0) */
                    362:                        return tree(RIGHT, inttype, root(l), constnode(0, inttype));
                    363:                if (r->op == CNST+I && r->u.v.i == 0)
                    364:                        break;
                    365: #ifdef mips
                    366:                if (l->op == CNST+I && r->op == CNST+I && r->u.v.i == -1
                    367:                && !div((double)l->u.v.i, (double)r->u.v.i, (double)INT_MIN, (double)INT_MAX, 0))
                    368:                        break;
                    369: #endif
                    370:                xfoldcnst(I,i,%,inttype,div,INT_MIN,INT_MAX,needconst);
                    371:                break;
                    372:        case MOD+U:             
                    373:                if (r->op == CNST+U && ispow2(r->u.v.u))        /* l%2^n => l&(2^n-1) */
                    374:                        return bitnode(BAND, l,
                    375:                                constnode(r->u.v.u - 1, unsignedtype));
                    376:                if (r->op == CNST+U && r->u.v.u == 0)
                    377:                        break;
                    378:                foldcnst(U,u,%,unsignedtype);
                    379:                break;
                    380:        case MUL+D:
                    381:                xfoldcnst(D,d,*,doubletype,mul,-DBL_MAX,DBL_MAX,0);
                    382:                commute(l,r);
                    383:                break;
                    384:        case MUL+F:
                    385:                xfoldcnst(F,f,*,floattype,mul,-FLT_MAX,FLT_MAX,0);
                    386:                commute(l,r);
                    387:                break;
                    388:        case MUL+I:
                    389:                commute(l,r);
                    390:                if (l->op == CNST+I && r->op == ADD+I && r->kids[1]->op == CNST+I)
                    391:                        /* c1*(x + c2) => c1*x + c1*c2 */
                    392:                        return simplify(ADD+I, inttype, simplify(MUL+I, inttype, l, r->kids[0]),
                    393:                                simplify(MUL+I, inttype, l, r->kids[1]));
                    394:                if (l->op == CNST+I && r->op == SUB+I && r->kids[1]->op == CNST+I)
                    395:                        /* c1*(x - c2) => c1*x - c1*c2 */
                    396:                        return simplify(SUB+I, inttype, simplify(MUL+I, inttype, l, r->kids[0]),
                    397:                                simplify(MUL+I, inttype, l, r->kids[1]));
                    398:                if (l->op == CNST+I && l->u.v.i > 0 && (n = ispow2(l->u.v.i)))
                    399:                        /* 2^n * r => r<<n */
                    400:                        return simplify(LSH+I, inttype, r, constnode(n, inttype));
                    401:                xfoldcnst(I,i,*,inttype,mul,INT_MIN,INT_MAX,needconst);
                    402:                break;
                    403:        case MUL+U:
                    404:                commute(l,r);
                    405:                if (l->op == CNST+U && (n = ispow2(l->u.v.u)))
                    406:                        /* 2^n * r => r<<n */
                    407:                        return simplify(LSH+U, unsignedtype, r, constnode(n, inttype));
                    408:                foldcnst(U,u,*,unsignedtype);
                    409:                break;
                    410:        case NE+D:
                    411:                foldcnst(D,d,!=,inttype);
                    412:                commute(r,l);
                    413:                break;
                    414:        case NE+F:
                    415:                cfoldcnst(F,f,!=,inttype);
                    416:                commute(r,l);
                    417:                break;
                    418:        case NE+I:
                    419:                cfoldcnst(I,i,!=,inttype);
                    420:                commute(r,l);
                    421:                zerofield(NE,I,i);
                    422:                break;
                    423:        case NE+U:
                    424:                cfoldcnst(U,u,!=,inttype);
                    425:                commute(r,l);
                    426:                zerofield(NE,U,u);
                    427:                op = NE+I;
                    428:                break;
                    429:        case NEG+D:
                    430:                ufoldcnst(D,(p = tree(CNST+D, doubletype, 0, 0), p->u.v.d = -l->u.v.d, p));
                    431:                idempotent(NEG+D);
                    432:                break;
                    433:        case NEG+F:
                    434:                ufoldcnst(F,(p = tree(CNST+F, floattype, 0, 0), p->u.v.f = -l->u.v.f, p));
                    435:                idempotent(NEG+F);
                    436:                break;
                    437:        case NEG+I:
                    438:                if (l->op == CNST+I) {
                    439:                        if (needconst && l->u.v.i == INT_MIN)
                    440:                                warning("overflow in constant expression\n");
                    441:                        if (needconst || l->u.v.i != INT_MIN)
                    442:                                return constnode(-l->u.v.i, inttype);
                    443:                }
                    444:                idempotent(NEG+I);
                    445:                break;
                    446:        case NOT+I:
                    447:                op = NOT;
                    448:                ufoldcnst(I,constnode(!l->u.v.i, inttype));
                    449:                break;
                    450:        case RSH+I:
                    451:                identity(r,l,I,i,0);
                    452:                if (l->op == CNST+I && r->op == CNST+I
                    453:                && r->u.v.i >= 0 && r->u.v.i < 8*l->type->size) {
                    454:                        int n = l->u.v.i>>r->u.v.i;
                    455:                        if (l->u.v.i < 0)
                    456:                                n |= ~0<<(8*l->type->size - r->u.v.i);
                    457:                        return constnode(n, inttype);
                    458:                }
                    459:                break;
                    460:        case RSH+U:
                    461:                identity(r,l,I,i,0);
                    462:                sfoldcnst(U,u,>>,unsignedtype);
                    463:                break;
                    464:        case SUB+D:
                    465:                xfoldcnst(D,d,-,doubletype,sub,-DBL_MAX,DBL_MAX,0);
                    466:                break;
                    467:        case SUB+F:
                    468:                xfoldcnst(F,f,-,floattype,sub,-FLT_MAX,FLT_MAX,0);
                    469:                break;
                    470:        case SUB+I:
                    471:                xfoldcnst(I,i,-,inttype,sub,INT_MIN,INT_MAX,needconst);
                    472:                break;
                    473:        case SUB+U:
                    474:                foldcnst(U,u,-,unsignedtype);
                    475:                break;
                    476:        case SUB+P:
                    477:                if (l->op == CNST+P && r->op == CNST+P)
                    478:                        return constnode(l->u.v.p - r->u.v.p, inttype);
                    479:                if (r->op == CNST+I || r->op == CNST+U)
                    480:                        return simplify(ADD+P, ty, l,
                    481:                                constnode(r->op == CNST+I ? -r->u.v.i : -(int)r->u.v.u, inttype));
                    482:                if (isaddrop(l->op) && r->op == ADD+I && r->kids[1]->op == CNST+I)
                    483:                        /* l - (x + c) => l-c - x */
                    484:                        return simplify(SUB+P, ty,
                    485:                                simplify(SUB+P, ty, l, r->kids[1]), r->kids[0]);
                    486:                break;
                    487:        default:assert(0);
                    488:        }
                    489:        return tree(op, ty, l, r);
                    490: }
                    491: 
                    492: /* sub - return 1 if min <= x-y <= max, 0 otherwise */
                    493: static int sub(x, y, min, max, needconst) double x, y, min, max; {
                    494:        return add(x, -y, min, max, needconst);
                    495: }
                    496: 
                    497: /* vtoa - return string for the constant v of type ty */
                    498: char *vtoa(ty, v) Type ty; Value v; {
                    499:        char buf[50];
                    500: 
                    501:        ty = unqual(ty);
                    502:        switch (ty->op) {
                    503:        case CHAR:
                    504:                return stringf("%d", v.uc);
                    505:        case SHORT:
                    506:                return stringf("%d", v.ss);
                    507:        case INT:
                    508:                return stringf("%d", v.i);
                    509:        case UNSIGNED:
                    510:                if ((v.u&~0x7fff) == 0)
                    511:                        return stringf("%d", v.u);
                    512:                else
                    513:                        return stringf("0x%x", v.u);
                    514:        case FLOAT:
                    515:                if (v.f == 0.0)
                    516:                        return "0";
                    517:                sprintf(buf, "%.*g", 8, v.f);
                    518:                return string(buf);
                    519:        case DOUBLE:
                    520:                if (v.d == 0.0)
                    521:                        return "0";
                    522:                sprintf(buf, "%.*g", 18, v.d);
                    523:                return string(buf);
                    524:        case ARRAY:
                    525:                if (ty->type->op == CHAR)
                    526:                        return v.p;
                    527:                /* else fall thru */
                    528:        case POINTER: case FUNCTION:
                    529:                if (((unsigned)v.p&~0x7fff) == 0)
                    530:                        return stringf("%d", v.p);
                    531:                else
                    532:                        return stringf("0x%x", v.p);
                    533:        default:assert(0);
                    534:        }
                    535:        return 0;
                    536: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.