home *** CD-ROM | disk | FTP | other *** search
/ Total Destruction / Total_Destruction.iso / addons / Lccwin32.exe / Lccwin32 / lccpub / src / Simp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-11  |  19.0 KB  |  652 lines

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