⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simp.c

📁 window下的c编译器。
💻 C
📖 第 1 页 / 共 2 页
字号:
				break;
			if (r->op == CNST+U && (n = ispow2(r->u.v.u)) != 0)
				return simplify(RSH+U, unsignedtype, l, consttree(n, inttype));
			foldcnst(U,u,/,unsignedtype);
			break;
		case EQ+D:
		case EQ+L:
			cfoldcnst(D,d,==,inttype);
			commute(r,l);
			break;
		case EQ+F:
			cfoldcnst(F,f,==,inttype);
			commute(r,l);
			break;
		case EQ+U:
			cfoldcnst(U,u,==,inttype);
			commute(r,l);
			zerofield(EQ,U,u);
			op = EQ+I;
			break;
		case GE+D: cfoldcnst(D,d,>=,inttype); break;
		case GE+F: cfoldcnst(F,f,>=,inttype); break;
		case GE+I: cfoldcnst(I,i,>=,inttype); break;
		case GE+L: cfoldcnst(L,d,>=,inttype); break;
		case GE+U:
			geu(l,r,1);	/* l >= 0 => (l,1) */
			cfoldcnst(U,u,>=,inttype);
			if (l->op == CNST+U && l->u.v.u == 0)	/* 0 >= r => r == o */
				return tree(EQ+I, ty, r, l);
			break;
		case GT+D: cfoldcnst(D,d, >,inttype); break;
		case GT+L: cfoldcnst(L,d, >,inttype); break;
		case GT+F: cfoldcnst(F,f, >,inttype); break;
		case GT+I: cfoldcnst(I,i, >,inttype); break;
		case GT+U:
			geu(r,l,0);	/* 0 > r => (r,0) */
			cfoldcnst(U,u, >,inttype);
			if (r->op == CNST+U && r->u.v.u == 0)	/* l > 0 => l != 0 */
				return tree(NE+I, ty, l, r);
			break;
		case LE+D: cfoldcnst(D,d,<=,inttype); break;
		case LE+F: cfoldcnst(F,f,<=,inttype); break;
		case LE+I: cfoldcnst(I,i,<=,inttype); break;
		case LE+L: cfoldcnst(L,d, >,inttype); break;
		case LE+U:
			geu(r,l,1);	/* 0 <= r => (r,1) */
			cfoldcnst(U,u,<=,inttype);
			if (r->op == CNST+U && r->u.v.u == 0)	/* l <= 0 => l == 0 */
				return tree(EQ+I, ty, l, r);
			break;
		case LSH+I:
			identity(r,l,I,i,0);
			if (l->op == CNST+I && r->op == CNST+I
			&& r->u.v.i >= 0 && r->u.v.i < 8*l->type->size
			&& mul((double)l->u.v.i, (double)(1<<r->u.v.i), (double)INT_MIN, (double)INT_MAX, needconst))
				return consttree(l->u.v.i<<r->u.v.i, inttype);
			if (r->op == CNST+I && (r->u.v.i >= 8*l->type->size || r->u.v.i < 0)) {
				warning(StrTab[89], r->u.v.i);// <shift by %d is undefined\n>
				break;
			}
			break;
		case LSH+L:
		case RSH+L:
			if (r->op == CNST+I && (r->u.v.i >= 8*l->type->size || r->u.v.i < 0)) {
				warning(StrTab[90], r->u.v.i);// <shift by %d is undefined\n>
			}
			break;
		case LSH+U:
			identity(r,l,I,i,0);
			sfoldcnst(U,u,<<,unsignedtype);
			if (r->op == CNST+I && (r->u.v.i >= 8*l->type->size || r->u.v.i < 0)) {
				warning(StrTab[91], r->u.v.i);// <shift by %d is undefined\n>
				break;
			}
			break;
		case LT+D: cfoldcnst(D,d, <,inttype); break;
		case LT+F: cfoldcnst(F,f, <,inttype); break;
		case LT+I: cfoldcnst(I,i, <,inttype); break;
		case LT+L: cfoldcnst(L,i, <,inttype); break;
		case LT+U:
			geu(l,r,0);	/* l < 0 => (l,0) */
			cfoldcnst(U,u, <,inttype);
			if (l->op == CNST+U && l->u.v.u == 0)	/* 0 < r => r != 0 */
				return tree(NE+I, ty, r, l);
			break;
		case MOD+I:
			if (r->op == CNST+I && r->u.v.i == 1)	/* l%1 => (l,0) */
				return tree(RIGHT, inttype, root(l), consttree(0, inttype));
			if (r->op == CNST+I && r->u.v.i == 0)
				break;
#ifdef mips
			if (l->op == CNST+I && r->op == CNST+I && r->u.v.i == -1
			&& !div((double)l->u.v.i, (double)r->u.v.i, (double)INT_MIN, (double)INT_MAX, 0))
				break;
#endif
			xfoldcnst(I,i,%,inttype,div,INT_MIN,INT_MAX,needconst);
			break;
		case MOD+L:
			break;
		case MOD+U:
			if (r->op == CNST+U && ispow2(r->u.v.u))	/* l%2^n => l&(2^n-1) */
				return bittree(BAND, l,
					consttree(r->u.v.u - 1, unsignedtype));
			if (r->op == CNST+U && r->u.v.u == 0)
				break;
			foldcnst(U,u,%,unsignedtype);
			break;
		case MUL+D:
			xfoldcnst(D,d,*,doubletype,mul,-DBL_MAX,DBL_MAX,0);
			commute(l,r);
			break;
		case MUL+L:
			xfoldcnst(L,d,*,longlongtype,mul,-DBL_MAX,DBL_MAX,0);
			commute(l,r);
			break;
		case MUL+F:
			xfoldcnst(F,f,*,floattype,mul,-FLT_MAX,FLT_MAX,0);
			commute(l,r);
			break;
		case MUL+I:
			if ((r->op == CNST+U || r->op == CNST+I) && r->u.v.i == 1)
				return l;
			commute(l,r);
			if (l->op == CNST+I && r->op == ADD+I && r->kids[1]->op == CNST+I)
				/* c1*(x + c2) => c1*x + c1*c2 */
				return simplify(ADD+I, inttype, simplify(MUL+I, inttype, l, r->kids[0]),
					simplify(MUL+I, inttype, l, r->kids[1]));
			if (l->op == CNST+I && r->op == SUB+I && r->kids[1]->op == CNST+I)
				/* c1*(x - c2) => c1*x - c1*c2 */
				return simplify(SUB+I, inttype, simplify(MUL+I, inttype, l, r->kids[0]),
					simplify(MUL+I, inttype, l, r->kids[1]));
			if (l->op == CNST+I && l->u.v.i > 0 && (n = ispow2(l->u.v.i)) != 0)
				/* 2^n * r => r<<n */
				return simplify(LSH+I, inttype, r, consttree(n, inttype));
			xfoldcnst(I,i,*,inttype,mul,INT_MIN,INT_MAX,needconst);
			break;
		case NE+D:
			foldcnst(D,d,!=,inttype);
			commute(r,l);
			break;
		case NE+L:
			foldcnst(L,d,!=,inttype);
			commute(r,l);
			break;
		case NE+F:
			cfoldcnst(F,f,!=,inttype);
			commute(r,l);
			break;
		case NE+U:
			cfoldcnst(U,u,!=,inttype);
			commute(r,l);
			zerofield(NE,U,u);
			op = NE+I;
			break;
		case NEG+D:
			ufoldcnst(D,(p = tree(CNST+D, doubletype, NULL, NULL), p->u.v.d = -l->u.v.d, p));
			idempotent(NEG+D);
			break;
		case NEG+F:
			ufoldcnst(F,(p = tree(CNST+F, floattype, NULL, NULL), p->u.v.f = -l->u.v.f, p));
			idempotent(NEG+F);
			break;
		case NEG+I:
			if (l->op == CNST+I) {
				if (needconst && l->u.v.i == INT_MIN)
					warning(StrTab[92]);// <overflow in constant expression\n>
				if (needconst || l->u.v.i != INT_MIN)
					return consttree(-l->u.v.i, inttype);
			}
			idempotent(NEG+I);
			break;
		case NEG+L:
			idempotent(NEG+L);
			break;
		case NOT+I:
			op = NOT;
			ufoldcnst(I,consttree(!l->u.v.i, inttype));
			break;
		case RSH+I:
			identity(r,l,I,i,0);
			if (l->op == CNST+I && r->op == CNST+I
			&& r->u.v.i >= 0 && r->u.v.i < 8*l->type->size) {
				int n = l->u.v.i>>r->u.v.i;
				if (l->u.v.i < 0)
					n |= ~0<<(8*l->type->size - r->u.v.i);
				return consttree(n, inttype);
			}
			if (r->op == CNST+I && (r->u.v.i >= 8*l->type->size || r->u.v.i < 0)) {
				warning(StrTab[93], r->u.v.i);// <shift by %d is undefined\n>
				break;
			}
			break;
		case RSH+U:
			identity(r,l,I,i,0);
			sfoldcnst(U,u,>>,unsignedtype);
			if (r->op == CNST+I && (r->u.v.i >= 8*l->type->size || r->u.v.i < 0)) {
				warning(StrTab[94], r->u.v.i);// <shift by %d is undefined\n>
				break;
			}
			break;
		case SUB+D:
			if (r->op == CNSTD &&
				r->u.v.d == 0.0)
				return l;
			xfoldcnst(D,d,-,doubletype,sub,-DBL_MAX,DBL_MAX,0);
			break;
		case SUB+L:
			if (r->op == CNSTD &&
				r->u.v.d == 0.0)
				return l;
			xfoldcnst(D,d,-,longlongtype,sub,-DBL_MAX,DBL_MAX,0);
			break;

		case SUB+F:
			xfoldcnst(F,f,-,floattype,sub,-FLT_MAX,FLT_MAX,0);
			break;
		case SUB+I:
			if (r->op == CNSTU || r->op == CNSTI) {
				if (r->u.v.i == 0)
					return l;
			}
			xfoldcnst(I,i,-,inttype,sub,INT_MIN,INT_MAX,needconst);
			break;
		case SUB+U:
			if (r->op == CNSTU || r->op == CNSTI) {
				if (r->u.v.i == 0)
					return l;
			}
			foldcnst(U,u,-,unsignedtype);
			break;
		case SUB+P:
			if (l->op == CNST+P && r->op == CNST+P)
				return consttree((char *)l->u.v.p - (char *)r->u.v.p, inttype);
			if (r->op == CNST+I || r->op == CNST+U)
				return simplify(ADD+P, ty, l,
					consttree(r->op == CNST+I ? -r->u.v.i : -(int)r->u.v.u, inttype));
			if (isaddrop(l->op) && r->op == ADD+I && r->kids[1]->op == CNST+I)
				/* l - (x + c) => l-c - x */
				return simplify(SUB+P, ty,
					simplify(SUB+P, ty, l, r->kids[1]), r->kids[0]);
			break;
		default:assert(0);
	}
	return tree(op, ty, l, r);
}

static int add(double x,double y,double min,double max,int needconst)
{
	int cond = x == 0 || y == 0
	|| x < 0 && y < 0 && x >= min - y
	|| x < 0 && y > 0
	|| x > 0 && y < 0
	|| x > 0 && y > 0 && x <= max - y;
	if (!cond && needconst) {
		warning(StrTab[95]);// <overflow in constant expression\n>
		cond = 1;
	}
	return cond;
}
static Tree addrtree(Tree e,int n,Type ty)
{
	Symbol p = e->u.sym, q;

	NEW0(q, FUNC);
	q->name = stringd(genlabel(1));
	q->sclass = p->sclass;
	q->scope = p->scope;
	assert(isptr(ty) || isarray(ty));
	q->type = isptr(ty) ? ty->type : ty;
	q->temporary = p->temporary;
	q->generated = p->generated;
	q->addressed = p->addressed;
	q->computed = 1;
	q->assigned = 1;
	q->defined = 1;
	q->ref = (float)1.0;
	q->firstuse = q->lastuse = StatementCount;
	if (p->scope  == GLOBAL
	||  p->sclass == STATIC || p->sclass == EXTERN) {
		if (p->sclass == AUTO)
			q->sclass = STATIC;
		(*IR->address)(q, p, n);
	} else {
		Code cp;
		addlocal(p);
		cp = code(Address);
		cp->u.addr.sym = q;
		cp->u.addr.base = p;
		cp->u.addr.offset = n;
	}
	e = tree(e->op, ty, NULL, NULL);
	e->u.sym = q;
	q->x.ArraySymbol = p;
	return e;
}

/* div - return 1 if min <= x/y <= max, 0 otherwise */
static int div(double x,double y,double min,double max,int needconst)
{
	int cond;

	if (x < 0) x = -x;
	if (y < 0) y = -y;
	cond = y != 0 && (y > 1 || x <= max*y);
	if (!cond && y != 0 && needconst) {
		warning(StrTab[96]);// <overflow in constant expression\n>
		cond = 1;
	}
	return cond;
}

/* ispow2 - if u > 1 && u == 2^n, return n, otherwise return 0 */
int ispow2(unsigned u)
{
	int n;

	if (u > 1 && (u&(u-1)) == 0)
		for (n = 0; u; u >>= 1, n++)
			if (u&1)
				return n;
	return 0;
}

/* mul - return 1 if min <= x*y <= max, 0 otherwise */
static int mul(double x,double y,double min,double max,int needconst)
{
	int cond = x > -1 && x <= 1 || y > -1 && y <= 1
	|| x < 0 && y < 0 && -x <= max/-y
	|| x < 0 && y > 0 &&  x >= min/y
	|| x > 0 && y < 0 &&  x >= min/y
	|| x > 0 && y > 0 &&  x <= max/y;
	if (!cond && needconst) {
		warning(StrTab[97]);// <overflow in constant expression\n>
		cond = 1;
	}
	return cond;
}

/* sub - return 1 if min <= x-y <= max, 0 otherwise */
static int sub(double x,double y,double min,double max,int needconst)
{
	return add(x, -y, min, max, needconst);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -