Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

simp.c

Go to the documentation of this file.
00001 #include "c.h"
00002 #include <float.h>
00003 
00004 
00005 #define foldcnst(TYPE,VAR,OP) \
00006     if (l->op == CNST+TYPE && r->op == CNST+TYPE) \
00007         return cnsttree(ty, l->u.v.VAR OP r->u.v.VAR)
00008 #define commute(L,R) \
00009     if (generic(R->op) == CNST && generic(L->op) != CNST) \
00010         do { Tree t = L; L = R; R = t; } while(0)
00011 #define xfoldcnst(TYPE,VAR,OP,FUNC)\
00012     if (l->op == CNST+TYPE && r->op == CNST+TYPE\
00013     && FUNC(l->u.v.VAR,r->u.v.VAR,\
00014         ty->u.sym->u.limits.min.VAR,\
00015         ty->u.sym->u.limits.max.VAR, needconst)) \
00016         return cnsttree(ty, l->u.v.VAR OP r->u.v.VAR)
00017 #define xcvtcnst(FTYPE,SRC,DST,VAR,EXPR) \
00018     if (l->op == CNST+FTYPE) do {\
00019         if (!explicitCast\
00020         &&  ((SRC) < DST->u.sym->u.limits.min.VAR || (SRC) > DST->u.sym->u.limits.max.VAR))\
00021             warning("overflow in converting constant expression from `%t' to `%t'\n", l->type, DST);\
00022         if (needconst\
00023         || !((SRC) < DST->u.sym->u.limits.min.VAR || (SRC) > DST->u.sym->u.limits.max.VAR))\
00024             return cnsttree(ty, (EXPR)); } while(0)
00025 #define identity(X,Y,TYPE,VAR,VAL) \
00026     if (X->op == CNST+TYPE && X->u.v.VAR == VAL) return Y
00027 #define zerofield(OP,TYPE,VAR) \
00028     if (l->op == FIELD \
00029     &&  r->op == CNST+TYPE && r->u.v.VAR == 0)\
00030         return eqtree(OP, bittree(BAND, l->kids[0],\
00031             cnsttree(unsignedtype, \
00032                 (unsigned long)fieldmask(l->u.field)<<fieldright(l->u.field))), r)
00033 #define cfoldcnst(TYPE,VAR,OP) \
00034     if (l->op == CNST+TYPE && r->op == CNST+TYPE) \
00035         return cnsttree(inttype, (long)(l->u.v.VAR OP r->u.v.VAR))
00036 #define foldaddp(L,R,RTYPE,VAR) \
00037     if (L->op == CNST+P && R->op == CNST+RTYPE) { \
00038         Tree e = tree(CNST+P, ty, NULL, NULL);\
00039         e->u.v.p = (char *)L->u.v.p + R->u.v.VAR;\
00040         return e; }
00041 #define ufoldcnst(TYPE,EXP) if (l->op == CNST+TYPE) return EXP
00042 #define sfoldcnst(OP) \
00043     if (l->op == CNST+U && r->op == CNST+I \
00044     && r->u.v.i >= 0 && r->u.v.i < 8*l->type->size) \
00045         return cnsttree(ty, (unsigned long)(l->u.v.u OP r->u.v.i))
00046 #define geu(L,R,V) \
00047     if (R->op == CNST+U && R->u.v.u == 0) do { \
00048         warning("result of unsigned comparison is constant\n"); \
00049         return tree(RIGHT, inttype, root(L), cnsttree(inttype, (long)(V))); } while(0)
00050 #define idempotent(OP) if (l->op == OP) return l->kids[0]
00051 
00052 int needconst;
00053 int explicitCast;
00054 static int addi(long x, long y, long min, long max, int needconst) {
00055     int cond = x == 0 || y == 0
00056     || x < 0 && y < 0 && x >= min - y
00057     || x < 0 && y > 0
00058     || x > 0 && y < 0
00059     || x > 0 && y > 0 && x <= max - y;
00060     if (!cond && needconst) {
00061         warning("overflow in constant expression\n");
00062         cond = 1;
00063     }
00064     return cond;
00065 
00066 
00067 }
00068 
00069 static int addd(double x, double y, double min, double max, int needconst) {
00070     int cond = x == 0 || y == 0
00071     || x < 0 && y < 0 && x >= min - y
00072     || x < 0 && y > 0
00073     || x > 0 && y < 0
00074     || x > 0 && y > 0 && x <= max - y;
00075     if (!cond && needconst) {
00076         warning("overflow in constant expression\n");
00077         cond = 1;
00078     }
00079     return cond;
00080 
00081 
00082 }
00083 
00084 static Tree addrtree(Tree e, long n, Type ty) {
00085     Symbol p = e->u.sym, q;
00086 
00087     if (p->scope  == GLOBAL
00088     ||  p->sclass == STATIC || p->sclass == EXTERN)
00089         NEW0(q, PERM);
00090     else
00091         NEW0(q, FUNC);
00092     q->name = stringd(genlabel(1));
00093     q->sclass = p->sclass;
00094     q->scope = p->scope;
00095     assert(isptr(ty) || isarray(ty));
00096     q->type = isptr(ty) ? ty->type : ty;
00097     q->temporary = p->temporary;
00098     q->generated = p->generated;
00099     q->addressed = p->addressed;
00100     q->computed = 1;
00101     q->defined = 1;
00102     q->ref = 1;
00103     if (p->scope  == GLOBAL
00104     ||  p->sclass == STATIC || p->sclass == EXTERN) {
00105         if (p->sclass == AUTO)
00106             q->sclass = STATIC;
00107         (*IR->address)(q, p, n);
00108     } else {
00109         Code cp;
00110         addlocal(p);
00111         cp = code(Address);
00112         cp->u.addr.sym = q;
00113         cp->u.addr.base = p;
00114         cp->u.addr.offset = n;
00115     }
00116     e = tree(e->op, ty, NULL, NULL);
00117     e->u.sym = q;
00118     return e;
00119 }
00120 
00121 /* div[id] - return 1 if min <= x/y <= max, 0 otherwise */
00122 static int divi(long x, long y, long min, long max, int needconst) {
00123     int cond = y != 0 && !(x == min && y == -1);
00124     if (!cond && needconst) {
00125         warning("overflow in constant expression\n");
00126         cond = 1;
00127     }
00128     return cond;
00129 
00130 
00131 }
00132 
00133 static int divd(double x, double y, double min, double max, int needconst) {
00134     int cond;
00135 
00136     if (x < 0) x = -x;
00137     if (y < 0) y = -y;
00138     cond = y != 0 && !(y < 1 && x > max*y);
00139     if (!cond && needconst) {
00140         warning("overflow in constant expression\n");
00141         cond = 1;
00142     }
00143     return cond;
00144 
00145 }
00146 
00147 /* mul[id] - return 1 if min <= x*y <= max, 0 otherwise */
00148 static int muli(long x, long y, long min, long max, int needconst) {
00149     int cond = x > -1 && x <= 1 || y > -1 && y <= 1
00150     || x < 0 && y < 0 && -x <= max/-y
00151     || x < 0 && y > 0 &&  x >= min/y
00152     || x > 0 && y < 0 &&  y >= min/x
00153     || x > 0 && y > 0 &&  x <= max/y;
00154     if (!cond && needconst) {
00155         warning("overflow in constant expression\n");
00156         cond = 1;
00157     }
00158     return cond;
00159 
00160 
00161 }
00162 
00163 static int muld(double x, double y, double min, double max, int needconst) {
00164     int cond = x >= -1 && x <= 1 || y >= -1 && y <= 1
00165     || x < 0 && y < 0 && -x <= max/-y
00166     || x < 0 && y > 0 &&  x >= min/y
00167     || x > 0 && y < 0 &&  y >= min/x
00168     || x > 0 && y > 0 &&  x <= max/y;
00169     if (!cond && needconst) {
00170         warning("overflow in constant expression\n");
00171         cond = 1;
00172     }
00173     return cond;
00174 
00175 
00176 }
00177 /* sub[id] - return 1 if min <= x-y <= max, 0 otherwise */
00178 static int subi(long x, long y, long min, long max, int needconst) {
00179     return addi(x, -y, min, max, needconst);
00180 }
00181 
00182 static int subd(double x, double y, double min, double max, int needconst) {
00183     return addd(x, -y, min, max, needconst);
00184 }
00185 Tree constexpr(int tok) {
00186     Tree p;
00187 
00188     needconst++;
00189     p = expr1(tok);
00190     needconst--;
00191     return p;
00192 }
00193 
00194 int intexpr(int tok, int n) {
00195     Tree p = constexpr(tok);
00196 
00197     needconst++;
00198     if (p->op == CNST+I || p->op == CNST+U)
00199         n = cast(p, inttype)->u.v.i;
00200     else
00201         error("integer expression must be constant\n");
00202     needconst--;
00203     return n;
00204 }
00205 Tree simplify(int op, Type ty, Tree l, Tree r) {
00206     int n;
00207     Tree p;
00208 
00209     if (optype(op) == 0)
00210         op = mkop(op, ty);
00211     switch (op) {
00212         case ADD+U:
00213             foldcnst(U,u,+);
00214             commute(r,l);
00215             identity(r,l,U,u,0);
00216             break;
00217         case ADD+I:
00218             xfoldcnst(I,i,+,addi);
00219             commute(r,l);
00220             identity(r,l,I,i,0);
00221             break;
00222         case CVI+I:
00223             xcvtcnst(I,l->u.v.i,ty,i,(long)extend(l->u.v.i,ty));
00224             break;
00225         case CVU+I:
00226             if (l->op == CNST+U) {
00227                 if (!explicitCast && l->u.v.u > ty->u.sym->u.limits.max.i)
00228                     warning("overflow in converting constant expression from `%t' to `%t'\n", l->type, ty);
00229                 if (needconst || !(l->u.v.u > ty->u.sym->u.limits.max.i))
00230                     return cnsttree(ty, (long)extend(l->u.v.u,ty));
00231             }
00232             break;
00233         case CVP+U:
00234             xcvtcnst(P,(unsigned long)l->u.v.p,ty,u,(unsigned long)l->u.v.p);
00235             break;
00236         case CVU+P:
00237             xcvtcnst(U,(void*)l->u.v.u,ty,p,(void*)l->u.v.u);
00238             break;
00239         case CVP+P:
00240             xcvtcnst(P,l->u.v.p,ty,p,l->u.v.p);
00241             break;
00242         case CVI+U:
00243             xcvtcnst(I,l->u.v.i,ty,u,((unsigned long)l->u.v.i)&ones(8*ty->size));
00244             break;
00245         case CVU+U:
00246             xcvtcnst(U,l->u.v.u,ty,u,l->u.v.u&ones(8*ty->size));
00247             break;
00248 
00249         case CVI+F:
00250             xcvtcnst(I,l->u.v.i,ty,d,(long double)l->u.v.i);
00251         case CVU+F:
00252             xcvtcnst(U,l->u.v.u,ty,d,(long double)l->u.v.u);
00253             break;
00254         case CVF+I:
00255             xcvtcnst(F,l->u.v.d,ty,i,(long)l->u.v.d);
00256             break;
00257         case CVF+F: {
00258             float d;
00259             if (l->op == CNST+F)
00260                 if (l->u.v.d < ty->u.sym->u.limits.min.d)
00261                     d = ty->u.sym->u.limits.min.d;
00262                 else if (l->u.v.d > ty->u.sym->u.limits.max.d)
00263                     d = ty->u.sym->u.limits.max.d;
00264                 else
00265                     d = l->u.v.d;
00266             xcvtcnst(F,l->u.v.d,ty,d,(long double)d);
00267             break;
00268             }
00269         case BAND+U:
00270             foldcnst(U,u,&);
00271             commute(r,l);
00272             identity(r,l,U,u,ones(8*ty->size));
00273             if (r->op == CNST+U && r->u.v.u == 0)
00274                 return tree(RIGHT, ty, root(l), cnsttree(ty, 0UL));
00275             break;
00276         case BAND+I:
00277             foldcnst(I,i,&);
00278             commute(r,l);
00279             identity(r,l,I,i,ones(8*ty->size));
00280             if (r->op == CNST+I && r->u.v.u == 0)
00281                 return tree(RIGHT, ty, root(l), cnsttree(ty, 0L));
00282             break;
00283 
00284         case MUL+U:
00285             commute(l,r);
00286             if (l->op == CNST+U && (n = ispow2(l->u.v.u)) != 0)
00287                 return simplify(LSH, ty, r, cnsttree(inttype, (long)n));
00288             foldcnst(U,u,*);
00289             identity(r,l,U,u,1);
00290             break;
00291         case NE+I:
00292             cfoldcnst(I,i,!=);
00293             commute(r,l);
00294             zerofield(NE,I,i);
00295             break;
00296 
00297         case EQ+I:
00298             cfoldcnst(I,i,==);
00299             commute(r,l);
00300             zerofield(EQ,I,i);
00301             break;
00302         case ADD+P:
00303             foldaddp(l,r,I,i);
00304             foldaddp(l,r,U,u);
00305             foldaddp(r,l,I,i);
00306             foldaddp(r,l,U,u);
00307             commute(r,l);
00308             identity(r,retype(l,ty),I,i,0);
00309             identity(r,retype(l,ty),U,u,0);
00310             if (isaddrop(l->op)
00311             && (r->op == CNST+I && r->u.v.i <= longtype->u.sym->u.limits.max.i
00312                 && r->u.v.i >= longtype->u.sym->u.limits.min.i
00313             || r->op == CNST+U && r->u.v.u <= longtype->u.sym->u.limits.max.i))
00314                 return addrtree(l, cast(r, longtype)->u.v.i, ty);
00315             if (l->op == ADD+P && isaddrop(l->kids[1]->op)
00316             && (r->op == CNST+I && r->u.v.i <= longtype->u.sym->u.limits.max.i
00317                 && r->u.v.i >= longtype->u.sym->u.limits.min.i
00318             ||  r->op == CNST+U && r->u.v.u <= longtype->u.sym->u.limits.max.i))
00319                 return simplify(ADD+P, ty, l->kids[0],
00320                     addrtree(l->kids[1], cast(r, longtype)->u.v.i, ty));
00321             if ((l->op == ADD+I || l->op == SUB+I)
00322             && l->kids[1]->op == CNST+I && isaddrop(r->op))
00323                 return simplify(ADD+P, ty, l->kids[0],
00324                     simplify(generic(l->op)+P, ty, r, l->kids[1]));
00325             if (l->op == ADD+P && generic(l->kids[1]->op) == CNST
00326             && generic(r->op) == CNST)
00327                 return simplify(ADD+P, ty, l->kids[0],
00328                     simplify(ADD, l->kids[1]->type, l->kids[1], r));
00329             if (l->op == ADD+I && generic(l->kids[1]->op) == CNST
00330             &&  r->op == ADD+P && generic(r->kids[1]->op) == CNST)
00331                 return simplify(ADD+P, ty, l->kids[0],
00332                     simplify(ADD+P, ty, r->kids[0],
00333                     simplify(ADD, r->kids[1]->type, l->kids[1], r->kids[1])));
00334             if (l->op == RIGHT && l->kids[1])
00335                 return tree(RIGHT, ty, l->kids[0],
00336                     simplify(ADD+P, ty, l->kids[1], r));
00337             else if (l->op == RIGHT && l->kids[0])
00338                 return tree(RIGHT, ty,
00339                     simplify(ADD+P, ty, l->kids[0], r), NULL);
00340             break;
00341 
00342         case ADD+F:
00343             xfoldcnst(F,d,+,addd);
00344             commute(r,l);
00345             break;
00346         case AND+I:
00347             op = AND;
00348             ufoldcnst(I,l->u.v.i ? cond(r) : l);    /* 0&&r => 0, 1&&r => r */
00349             break;
00350         case OR+I:
00351             op = OR;
00352             /* 0||r => r, 1||r => 1 */
00353             ufoldcnst(I,l->u.v.i ? cnsttree(ty, 1L) : cond(r));
00354             break;
00355         case BCOM+I:
00356             ufoldcnst(I,cnsttree(ty, (long)extend((~l->u.v.i)&ones(8*ty->size), ty)));
00357             idempotent(BCOM+U);
00358             break;
00359         case BCOM+U:
00360             ufoldcnst(U,cnsttree(ty, (unsigned long)((~l->u.v.u)&ones(8*ty->size))));
00361             idempotent(BCOM+U);
00362             break;
00363         case BOR+U:
00364             foldcnst(U,u,|);
00365             commute(r,l);
00366             identity(r,l,U,u,0);
00367             break;
00368         case BOR+I:
00369             foldcnst(I,i,|);
00370             commute(r,l);
00371             identity(r,l,I,i,0);
00372             break;
00373         case BXOR+U:
00374             foldcnst(U,u,^);
00375             commute(r,l);
00376             identity(r,l,U,u,0);
00377             break;
00378         case BXOR+I:
00379             foldcnst(I,i,^);
00380             commute(r,l);
00381             identity(r,l,I,i,0);
00382             break;
00383         case DIV+F:
00384             xfoldcnst(F,d,/,divd);
00385             break;
00386         case DIV+I:
00387             identity(r,l,I,i,1);
00388             if (r->op == CNST+I && r->u.v.i == 0
00389             ||  l->op == CNST+I && l->u.v.i == ty->u.sym->u.limits.min.i
00390             &&  r->op == CNST+I && r->u.v.i == -1)
00391                 break;
00392             xfoldcnst(I,i,/,divi);
00393             break;
00394         case DIV+U:     
00395             identity(r,l,U,u,1);
00396             if (r->op == CNST+U && r->u.v.u == 0)
00397                 break;
00398             if (r->op == CNST+U && (n = ispow2(r->u.v.u)) != 0)
00399                 return simplify(RSH, ty, l, cnsttree(inttype, (long)n));
00400             foldcnst(U,u,/);
00401             break;
00402         case EQ+F:
00403             cfoldcnst(F,d,==);
00404             commute(r,l);
00405             break;
00406         case EQ+U:
00407             cfoldcnst(U,u,==);
00408             commute(r,l);
00409             zerofield(EQ,U,u);
00410             break;
00411         case GE+F: cfoldcnst(F,d,>=); break;
00412         case GE+I: cfoldcnst(I,i,>=); break;
00413         case GE+U:
00414             geu(l,r,1); /* l >= 0 => (l,1) */
00415             cfoldcnst(U,u,>=);
00416             if (l->op == CNST+U && l->u.v.u == 0)   /* 0 >= r => r == 0 */
00417                 return eqtree(EQ, r, l);
00418             break;
00419         case GT+F: cfoldcnst(F,d, >); break;
00420         case GT+I: cfoldcnst(I,i, >); break;
00421         case GT+U:
00422             geu(r,l,0); /* 0 > r => (r,0) */
00423             cfoldcnst(U,u, >);
00424             if (r->op == CNST+U && r->u.v.u == 0)   /* l > 0 => l != 0 */
00425                 return eqtree(NE, l, r);
00426             break;
00427         case LE+F: cfoldcnst(F,d,<=); break;
00428         case LE+I: cfoldcnst(I,i,<=); break;
00429         case LE+U:
00430             geu(r,l,1); /* 0 <= r => (r,1) */
00431             cfoldcnst(U,u,<=);
00432             if (r->op == CNST+U && r->u.v.u == 0)   /* l <= 0 => l == 0 */
00433                 return eqtree(EQ, l, r);
00434             break;
00435         case LSH+I:
00436             identity(r,l,I,i,0);
00437             if (l->op == CNST+I && r->op == CNST+I
00438             && r->u.v.i >= 0 && r->u.v.i < 8*l->type->size
00439             && 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))
00440                 return cnsttree(ty, (long)(l->u.v.i<<r->u.v.i));
00441             if (r->op == CNST+I && (r->u.v.i >= 8*ty->size || r->u.v.i < 0)) {
00442                 warning("shifting an `%t' by %d bits is undefined\n", ty, r->u.v.i);
00443                 break;
00444             }
00445 
00446             break;
00447         case LSH+U:
00448             identity(r,l,I,i,0);
00449             sfoldcnst(<<);
00450             if (r->op == CNST+I && (r->u.v.i >= 8*ty->size || r->u.v.i < 0)) {
00451                 warning("shifting an `%t' by %d bits is undefined\n", ty, r->u.v.i);
00452                 break;
00453             }
00454 
00455             break;
00456 
00457         case LT+F: cfoldcnst(F,d, <); break;
00458         case LT+I: cfoldcnst(I,i, <); break;
00459         case LT+U:
00460             geu(l,r,0); /* l < 0 => (l,0) */
00461             cfoldcnst(U,u, <);
00462             if (l->op == CNST+U && l->u.v.u == 0)   /* 0 < r => r != 0 */
00463                 return eqtree(NE, r, l);
00464             break;
00465         case MOD+I:
00466             if (r->op == CNST+I && r->u.v.i == 1)   /* l%1 => (l,0) */
00467                 return tree(RIGHT, ty, root(l), cnsttree(ty, 0L));
00468             if (r->op == CNST+I && r->u.v.i == 0
00469             ||  l->op == CNST+I && l->u.v.i == ty->u.sym->u.limits.min.i
00470             &&  r->op == CNST+I && r->u.v.i == -1)
00471                 break;
00472             xfoldcnst(I,i,%,divi);
00473             break;
00474         case MOD+U:     
00475             if (r->op == CNST+U && ispow2(r->u.v.u)) /* l%2^n => l&(2^n-1) */
00476                 return bittree(BAND, l, cnsttree(ty, r->u.v.u - 1));
00477             if (r->op == CNST+U && r->u.v.u == 0)
00478                 break;
00479             foldcnst(U,u,%);
00480             break;
00481         case MUL+F:
00482             xfoldcnst(F,d,*,muld);
00483             commute(l,r);
00484             break;
00485         case MUL+I:
00486             commute(l,r);
00487             xfoldcnst(I,i,*,muli);
00488             if (l->op == CNST+I && r->op == ADD+I && r->kids[1]->op == CNST+I)
00489                 /* c1*(x + c2) => c1*x + c1*c2 */
00490                 return simplify(ADD, ty, simplify(MUL, ty, l, r->kids[0]),
00491                     simplify(MUL, ty, l, r->kids[1]));
00492             if (l->op == CNST+I && r->op == SUB+I && r->kids[1]->op == CNST+I)
00493                 /* c1*(x - c2) => c1*x - c1*c2 */
00494                 return simplify(SUB, ty, simplify(MUL, ty, l, r->kids[0]),
00495                     simplify(MUL, ty, l, r->kids[1]));
00496             if (l->op == CNST+I && l->u.v.i > 0 && (n = ispow2(l->u.v.i)) != 0)
00497                 /* 2^n * r => r<<n */
00498                 return simplify(LSH, ty, r, cnsttree(inttype, (long)n));
00499             identity(r,l,I,i,1);
00500             break;
00501         case NE+F:
00502             cfoldcnst(F,d,!=);
00503             commute(r,l);
00504             break;
00505         case NE+U:
00506             cfoldcnst(U,u,!=);
00507             commute(r,l);
00508             zerofield(NE,U,u);
00509             break;
00510         case NEG+F:
00511             ufoldcnst(F,cnsttree(ty, -l->u.v.d));
00512             idempotent(NEG+F);
00513             break;
00514         case NEG+I:
00515             if (l->op == CNST+I) {
00516                 if (needconst && l->u.v.i == ty->u.sym->u.limits.min.i)
00517                     warning("overflow in constant expression\n");
00518                 if (needconst || l->u.v.i != ty->u.sym->u.limits.min.i)
00519                     return cnsttree(ty, -l->u.v.i);
00520             }
00521             idempotent(NEG+I);
00522             break;
00523         case NOT+I:
00524             op = NOT;
00525             ufoldcnst(I,cnsttree(ty, !l->u.v.i));
00526             break;
00527         case RSH+I:
00528             identity(r,l,I,i,0);
00529             if (l->op == CNST+I && r->op == CNST+I
00530             && r->u.v.i >= 0 && r->u.v.i < 8*l->type->size) {
00531                 long n = l->u.v.i>>r->u.v.i;
00532                 if (l->u.v.i < 0)
00533                     n |= ~0UL<<(8*l->type->size - r->u.v.i);
00534                 return cnsttree(ty, n);
00535             }
00536             if (r->op == CNST+I && (r->u.v.i >= 8*ty->size || r->u.v.i < 0)) {
00537                 warning("shifting an `%t' by %d bits is undefined\n", ty, r->u.v.i);
00538                 break;
00539             }
00540 
00541             break;
00542         case RSH+U:
00543             identity(r,l,I,i,0);
00544             sfoldcnst(>>);
00545             if (r->op == CNST+I && (r->u.v.i >= 8*ty->size || r->u.v.i < 0)) {
00546                 warning("shifting an `%t' by %d bits is undefined\n", ty, r->u.v.i);
00547                 break;
00548             }
00549 
00550             break;
00551         case SUB+F:
00552             xfoldcnst(F,d,-,subd);
00553             break;
00554         case SUB+I:
00555             xfoldcnst(I,i,-,subi);
00556             identity(r,l,I,i,0);
00557             break;
00558         case SUB+U:
00559             foldcnst(U,u,-);
00560             identity(r,l,U,u,0);
00561             break;
00562         case SUB+P:
00563             if (l->op == CNST+P && r->op == CNST+P)
00564                 return cnsttree(ty, (long)((char *)l->u.v.p - (char *)r->u.v.p));
00565             if (r->op == CNST+I || r->op == CNST+U)
00566                 return simplify(ADD, ty, l,
00567                     cnsttree(inttype, r->op == CNST+I ? -r->u.v.i : -(long)r->u.v.u));
00568             if (isaddrop(l->op) && r->op == ADD+I && r->kids[1]->op == CNST+I)
00569                 /* l - (x + c) => l-c - x */
00570                 return simplify(SUB, ty,
00571                     simplify(SUB, ty, l, r->kids[1]), r->kids[0]);
00572             break;
00573         default:assert(0);
00574     }
00575     return tree(op, ty, l, r);
00576 }
00577 /* ispow2 - if u > 1 && u == 2^n, return n, otherwise return 0 */
00578 int ispow2(unsigned long u) {
00579     int n;
00580 
00581     if (u > 1 && (u&(u-1)) == 0)
00582         for (n = 0; u; u >>= 1, n++)
00583             if (u&1)
00584                 return n;
00585     return 0;
00586 }
00587 

Generated on Thu Aug 25 12:38:14 2005 for Quake III Arena by  doxygen 1.3.9.1