ref: 94443daf8e248e65afc8d3f17f26efea22748b51
dir: /utils/c2l/scon.c/
#include "cc.h"
void
evconst(Node *n)
{
Node *l, *r;
int et, isf;
vlong v;
double d;
if(n == Z || n->type == T)
return;
et = n->type->etype;
isf = typefd[et];
l = n->left;
r = n->right;
d = 0;
v = 0;
switch(n->op) {
default:
return;
case OCAST:
if(et == TVOID)
return;
et = l->type->etype;
if(isf) {
if(typefd[et])
d = l->fconst;
else
d = l->vconst;
} else {
if(typefd[et])
v = l->fconst;
else
v = convvtox(l->vconst, n->type->etype);
}
break;
case OCONST:
break;
case OADD:
if(isf)
d = l->fconst + r->fconst;
else {
v = l->vconst + r->vconst;
}
break;
case OSUB:
if(isf)
d = l->fconst - r->fconst;
else
v = l->vconst - r->vconst;
break;
case OMUL:
if(isf)
d = l->fconst * r->fconst;
else {
v = l->vconst * r->vconst;
}
break;
case OLMUL:
v = (uvlong)l->vconst * (uvlong)r->vconst;
break;
case ODIV:
if(vconst(r) == 0) {
warn(n, "divide by zero");
return;
}
if(isf)
d = l->fconst / r->fconst;
else
v = l->vconst / r->vconst;
break;
case OLDIV:
if(vconst(r) == 0) {
warn(n, "divide by zero");
return;
}
v = (uvlong)l->vconst / (uvlong)r->vconst;
break;
case OMOD:
if(vconst(r) == 0) {
warn(n, "modulo by zero");
return;
}
v = l->vconst % r->vconst;
break;
case OLMOD:
if(vconst(r) == 0) {
warn(n, "modulo by zero");
return;
}
v = (uvlong)l->vconst % (uvlong)r->vconst;
break;
case OAND:
v = l->vconst & r->vconst;
break;
case OOR:
v = l->vconst | r->vconst;
break;
case OXOR:
v = l->vconst ^ r->vconst;
break;
case OLSHR:
v = (uvlong)l->vconst >> r->vconst;
break;
case OASHR:
v = l->vconst >> r->vconst;
break;
case OASHL:
v = l->vconst << r->vconst;
break;
case OLO:
v = (uvlong)l->vconst < (uvlong)r->vconst;
break;
case OLT:
if(typefd[l->type->etype])
v = l->fconst < r->fconst;
else
v = l->vconst < r->vconst;
break;
case OHI:
v = (uvlong)l->vconst > (uvlong)r->vconst;
break;
case OGT:
if(typefd[l->type->etype])
v = l->fconst > r->fconst;
else
v = l->vconst > r->vconst;
break;
case OLS:
v = (uvlong)l->vconst <= (uvlong)r->vconst;
break;
case OLE:
if(typefd[l->type->etype])
v = l->fconst <= r->fconst;
else
v = l->vconst <= r->vconst;
break;
case OHS:
v = (uvlong)l->vconst >= (uvlong)r->vconst;
break;
case OGE:
if(typefd[l->type->etype])
v = l->fconst >= r->fconst;
else
v = l->vconst >= r->vconst;
break;
case OEQ:
if(typefd[l->type->etype])
v = l->fconst == r->fconst;
else
v = l->vconst == r->vconst;
break;
case ONE:
if(typefd[l->type->etype])
v = l->fconst != r->fconst;
else
v = l->vconst != r->vconst;
break;
case ONOT:
if(typefd[l->type->etype])
v = !l->fconst;
else
v = !l->vconst;
break;
case OANDAND:
if(typefd[l->type->etype])
v = l->fconst && r->fconst;
else
v = l->vconst && r->vconst;
break;
case OOROR:
if(typefd[l->type->etype])
v = l->fconst || r->fconst;
else
v = l->vconst || r->vconst;
break;
case OPOS:
if(isf)
d = l->fconst;
else
v = l->vconst;
break;
case ONEG:
if(isf)
d = -l->fconst;
else
v = -l->vconst;
break;
case OCOM:
if(typefd[l->type->etype])
v = 0; /* ~l->fconst */
else
v = ~l->vconst;
break;
}
n->left = ncopy(n);
n->op = OCONST;
/* n->left = Z; */
n->right = Z;
if(isf) {
n->fconst = d;
} else {
n->vconst = convvtox(v, n->type->etype);
}
}
void
acom(Node *n)
{
USED(n);
}