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
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
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
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);
00349 break;
00350 case OR+I:
00351 op = OR;
00352
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);
00415 cfoldcnst(U,u,>=);
00416 if (l->op == CNST+U && l->u.v.u == 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);
00423 cfoldcnst(U,u, >);
00424 if (r->op == CNST+U && r->u.v.u == 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);
00431 cfoldcnst(U,u,<=);
00432 if (r->op == CNST+U && r->u.v.u == 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);
00461 cfoldcnst(U,u, <);
00462 if (l->op == CNST+U && l->u.v.u == 0)
00463 return eqtree(NE, r, l);
00464 break;
00465 case MOD+I:
00466 if (r->op == CNST+I && r->u.v.i == 1)
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))
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
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
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
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
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
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