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

📄 simp.c

📁 window下的c编译器。
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "c.h"

#define foldcnst(TYPE,VAR,OP,RTYPE) \
	if (l->op == CNST+TYPE && r->op == CNST+TYPE) {\
		p = tree(CNST+ttob(RTYPE), RTYPE, NULL, NULL);\
		p->u.v.VAR = l->u.v.VAR OP r->u.v.VAR;\
		return p; }
#define commute(L,R) \
	if (generic(R->op) == CNST && generic(L->op) != CNST) {\
		Tree t = L; L = R; R = t; }
#define xfoldcnst(TYPE,VAR,OP,RTYPE,FUNC,MIN,MAX,needconst)\
	if (l->op == CNST+TYPE && r->op == CNST+TYPE\
	&& FUNC((double)l->u.v.VAR,(double)r->u.v.VAR,\
		(double)MIN,(double)MAX, needconst)) {\
		p = tree(CNST+ttob(RTYPE), RTYPE, NULL, NULL);\
		p->u.v.VAR = l->u.v.VAR OP r->u.v.VAR;\
		return p; }
#define cvtcnst(FTYPE,TTYPE,EXPR) \
	if (l->op == CNST+FTYPE) {\
		p = tree(CNST+ttob(TTYPE), TTYPE, NULL, NULL);\
		EXPR;\
		return p; }
#define xcvtcnst(FTYPE,TTYPE,VAR,MIN,MAX,EXPR) \
	if (l->op == CNST+FTYPE) {\
		if (needconst && (VAR < MIN || VAR > MAX))\
			warning("overflow in constant expression\n");\
		if (needconst || VAR >= MIN && VAR <= MAX) {\
			p = tree(CNST+ttob(TTYPE), TTYPE, NULL, NULL);\
			EXPR;\
			return p; } }
#define identity(X,Y,TYPE,VAR,VAL) \
	if (X->op == CNST+TYPE && X->u.v.VAR == VAL)\
		return Y
#define zerofield(OP,TYPE,VAR) \
	if (l->op == FIELD\
	&&  r->op == CNST+TYPE && r->u.v.VAR == 0)\
		return eqtree(OP, bittree(BAND, l->kids[0],\
			consttree(\
				fieldmask(l->u.field)<<fieldright(l->u.field),\
				unsignedtype)), r);
#define cfoldcnst(TYPE,VAR,OP,RTYPE) \
	if (l->op == CNST+TYPE && r->op == CNST+TYPE) {\
		p = tree(CNST+ttob(RTYPE), RTYPE, NULL, NULL);\
		p->u.v.i = l->u.v.VAR OP r->u.v.VAR;\
		return p; }
#define foldaddp(L,R,RTYPE,VAR) \
	if (L->op == CNST+P && R->op == CNST+RTYPE) {\
		p = tree(CNST+P, ty, NULL, NULL);\
		p->u.v.p = (char *)L->u.v.p + R->u.v.VAR;\
		return p; }
#define ufoldcnst(TYPE,EXP) if (l->op == CNST+TYPE) return EXP
#define sfoldcnst(TYPE,VAR,OP,RTYPE) \
	if (l->op == CNST+TYPE && r->op == CNST+I \
	&& r->u.v.i >= 0 && r->u.v.i < 8*l->type->size) { \
		p = tree(CNST+ttob(RTYPE), RTYPE, NULL, NULL); \
		p->u.v.VAR = l->u.v.VAR OP r->u.v.i; return p; }
#define geu(L,R,V) \
	if (R->op == CNST+U && R->u.v.u == 0) { \
		warning("result of unsigned comparison is constant\n"); \
		return tree(RIGHT, inttype, root(L), consttree(V, inttype)); }
#define idempotent(OP) if (l->op == OP) return l->kids[0];
#define utod(x)	(2.*(int)((unsigned)(x)>>1)+(int)((x)&1))
#define checkrange(val,minimum,maximum) \
	if (val < minimum || val > maximum) warning("Overflow in constant expression\n");

int needconst;
static int add ARGS((double, double, double, double, int));
static Tree addrtree ARGS((Tree, int, Type));
static int div ARGS((double, double, double, double, int));
static int mul ARGS((double, double, double, double, int));
static int sub ARGS((double, double, double, double, int));
Tree constexpr(int tok)
{
	Tree p;

	needconst++;
	p = expr1(tok);
	needconst--;
	return p;
}

int intexpr(int tok,int n)
{
	Tree p = constexpr(tok);

	needconst++;
	if (generic(p->op) == CNST && isint(p->type))
		n = cast(p, inttype)->u.v.i;
	else
		error(StrTab[85]);// <integer expression must be constant\n>
	needconst--;
	return n;
}
Tree simplify(int op,Type ty,Tree l,Tree r)
{
	int n;
	Tree p;

	if (optype(op) == 0)
		op += ttob(ty);
	switch (op) {
		case ADD+U:
			if (r->op == CNSTU || r->op == CNSTI) {
				if (r->u.v.i == 0)
					return l;
				if (l->op == ADD+U && l->kids[1]->op == CNSTU) {
					l->kids[1]->u.v.i += r->u.v.i;
					return l;
				}
			}
			foldcnst(U,u,+,unsignedtype);
			commute(r,l);
			break;
		case ADD+I:
			if (r->op == CNSTU || r->op == CNSTI) {
				if (r->u.v.i == 0)
					return l;
				if (l->op == ADD+I && l->kids[1]->op == CNSTI) {
					l->kids[1]->u.v.i += r->u.v.i;
					return l;
				}
			}
			xfoldcnst(I,i,+,inttype,add,INT_MIN,INT_MAX,needconst);
			commute(r,l);
			break;
		case ADD+L:
			commute(r,l);
			break;
		case CVC+I:
			cvtcnst(C,inttype, p->u.v.i =
				(l->u.v.sc&0200 ? (~0<<8) : 0)|(l->u.v.sc&0377));
			break;
		case CVU+S:
			if (l->op == CNSTU) {
				if (l->u.v.u > 0xffff && (int)l->u.v.u < -32766)
					warning(StrTab[86]);// <Overflow in constant expression\n>
			}
			cvtcnst(U,unsignedshort,p->u.v.us = l->u.v.u);
			break;
		case CVI+L:
		case CVU+L:
			cvtcnst(I,longlongtype,p->u.v.d = l->u.v.i); break;
		case CVL+I:
		case CVL+U:
			op = CVL+I;
//			xcvtcnst(L,  inttype,l->u.v.d,  INT_MIN,INT_MAX,
//				p->u.v.i  = (int)l->u.v.d); break;
			break;
		case CVL+D:
			break;

		case CVP+U:
			cvtcnst(P,unsignedtype, p->u.v.u  = (unsigned)l->u.v.p);
			break;
		case CVI+U:
			cvtcnst(I,unsignedtype, p->u.v.u  = l->u.v.i); break;

		case CVC+U:
			cvtcnst(C, unsignedtype,p->u.v.u  = l->u.v.uc);
			break;
		case CVF+D:  cvtcnst(F,   doubletype,p->u.v.d  = l->u.v.f);  break;
		case CVI+D:  cvtcnst(I,   doubletype,p->u.v.d  = l->u.v.i);  break;
		case CVS+I:  cvtcnst(S,      inttype,p->u.v.i  = l->u.v.ss); break;
		case CVS+U:  cvtcnst(S, unsignedtype,p->u.v.u  = l->u.v.us); break;
		case CVU+C:
			if (l->op == CNSTU && l->u.v.u > 255)
				warning(StrTab[87]);// <Overflow in constat expression\n>

			cvtcnst(U, unsignedchar,p->u.v.uc = l->u.v.u);
			break;
		case CVU+D:  cvtcnst(U,   doubletype,p->u.v.d  = utod(l->u.v.u)); break;
		case CVU+I:
			if (needconst && l->u.v.u > INT_MAX)
				warning(StrTab[88]);// <overflow in constant expression\n>
			if (needconst || l->u.v.u <= INT_MAX)
				cvtcnst(U,   inttype,p->u.v.i  = l->u.v.u);
			break;
		case CVU+P:  cvtcnst(U,    voidptype,p->u.v.p  = (void *)l->u.v.u);  break;
		case CVD+L:
			break;
		case CVI+C:
			if (l->op == CNSTI) {
				checkrange(l->u.v.i,SCHAR_MIN,SCHAR_MAX);
			}
			xcvtcnst(I, chartype,l->u.v.i,SCHAR_MIN,SCHAR_MAX,
				p->u.v.sc = l->u.v.i);
			break;
		case CVD+F:
			if (l->op == CNSTD)
				checkrange(l->u.v.d, -FLT_MAX,FLT_MAX);
			xcvtcnst(D,floattype,l->u.v.d, -FLT_MAX,FLT_MAX,
				p->u.v.f  = (float)l->u.v.d);
			break;
		case CVD+I:
			if (l->op == CNSTD)
				checkrange(l->u.v.d,INT_MIN,INT_MAX);
			xcvtcnst(D,  inttype,l->u.v.d,  INT_MIN,INT_MAX,
				p->u.v.i  = (int)l->u.v.d);
			break;
		case CVI+S:
			if (l->op == CNSTI)
				checkrange(l->u.v.i,SHRT_MIN,SHRT_MAX);
			xcvtcnst(I,shorttype,l->u.v.i, SHRT_MIN,SHRT_MAX,
				p->u.v.ss = l->u.v.i);
			break;

		case BAND+U:
			foldcnst(U,u,&,unsignedtype);
			commute(r,l);
			identity(r,l,U,u,(~(unsigned)0));
			if (r->op == CNST+U && r->u.v.u == 0)
				return tree(RIGHT, unsignedtype, root(l),
					consttree(0, unsignedtype));
			break;

		case MUL+U:
			if ((r->op == CNST+U || r->op == CNST+I) && r->u.v.u == 1)
				return l;
			commute(l,r);
			if (l->op == CNST+U && (n = ispow2(l->u.v.u)) != 0)
				return simplify(LSH+U, unsignedtype, r,
					consttree(n, inttype));
			foldcnst(U,u,*,unsignedtype);
			break;
		case NE+I:
			cfoldcnst(I,i,!=,inttype);
			commute(r,l);
			zerofield(NE,I,i);
			break;

		case EQ+I:
			cfoldcnst(I,i,==,inttype);
			commute(r,l);
			zerofield(EQ,I,i);
			break;
		case ADD+P:
			if (r->op == CNST+P) {
				if (r->u.v.i == 0)
					return retype(l,ty);
			}
			foldaddp(l,r,I,i);
			foldaddp(l,r,U,u);
			foldaddp(r,l,I,i);
			foldaddp(r,l,U,u);
			commute(r,l);
			identity(r,retype(l,ty),I,i,0);
			identity(r,retype(l,ty),U,u,0);
			if (isaddrop(l->op)
			&& (r->op == CNST+I || r->op == CNST+U))
				return addrtree(l, cast(r, inttype)->u.v.i, ty);
			if (l->op == ADD+P && isaddrop(l->kids[1]->op)
			&& (r->op == CNST+I || r->op == CNST+U))
				return simplify(ADD+P, ty, l->kids[0],
					addrtree(l->kids[1], cast(r, inttype)->u.v.i, ty));
			if ((l->op == ADD+I || l->op == SUB+I)
			&& l->kids[1]->op == CNST+I && isaddrop(r->op))
				return simplify(ADD+P, ty, l->kids[0],
					simplify(generic(l->op)+P, ty, r, l->kids[1]));
			if (l->op == ADD+P && generic(l->kids[1]->op) == CNST
			&& generic(r->op) == CNST)
				return simplify(ADD+P, ty, l->kids[0],
					(*optree['+'])(ADD, l->kids[1], r));
			if (l->op == ADD+I && generic(l->kids[1]->op) == CNST
			&&  r->op == ADD+P && generic(r->kids[1]->op) == CNST)
				return simplify(ADD+P, ty, l->kids[0],
					simplify(ADD+P, ty, r->kids[0],
					(*optree['+'])(ADD, l->kids[1], r->kids[1])));
			if (l->op == RIGHT && l->kids[1])
				return tree(RIGHT, ty, l->kids[0],
					simplify(ADD+P, ty, l->kids[1], r));
			else if (l->op == RIGHT && l->kids[0])
				return tree(RIGHT, ty,
					simplify(ADD+P, ty, l->kids[0], r), NULL);
			break;

		case ADD+D:
			if (r->op == CNST+D &&
				r->u.v.d == 0.0)
				return l;
			xfoldcnst(D,d,+,doubletype,add,-DBL_MAX,DBL_MAX,0);
			commute(r,l);
			break;
		case ADD+F:
			if (r->op == CNST+D &&
				r->u.v.d == 0.0)
				return l;
			xfoldcnst(F,f,+,floattype,add,-FLT_MAX,FLT_MAX,0);
			commute(r,l);
			break;
		case AND+I:
			op = AND;
			ufoldcnst(I,l->u.v.i ? cond(r) : l);	/* 0&&r => 0, 1&&r => r */
			break;
		case AND+L:
		case BAND+L:
			break;
		case OR+I:
			op = OR;
			/* 0||r => r, 1||r => 1 */
			ufoldcnst(I,l->u.v.i ? consttree(1, inttype) : cond(r));
			break;
		case BCOM+I:
			ufoldcnst(I,consttree(~l->u.v.i, inttype));
			idempotent(BCOM+U);
			op = BCOM+U;
			break;
		case BCOM+L:
			ufoldcnst(I,consttree(~l->u.v.i, inttype));
			break;
		case BCOM+U:
			ufoldcnst(U,consttree(~l->u.v.u, unsignedtype));
			idempotent(BCOM+U);
			break;
		case BOR+U:
			foldcnst(U,u,|,unsignedtype);
			commute(r,l);
			identity(r,l,U,u,0);
			break;
		case BXOR+U:
			foldcnst(U,u,^,unsignedtype);
			commute(r,l);
			identity(r,l,U,u,0);
			break;
		case DIV+D:
			xfoldcnst(D,d,/,doubletype,div,-DBL_MAX,DBL_MAX,0);
			break;
		case DIV+L:
			xfoldcnst(L,d,/,longlongtype,div,-DBL_MAX,DBL_MAX,0);
			break;
		case DIV+F:
			xfoldcnst(F,f,/,floattype,div,-FLT_MAX,FLT_MAX,0);
			break;
		case DIV+I:
			identity(r,l,I,i,1);
#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 DIV+U:
			identity(r,l,U,u,1);
			if (r->op == CNST+U && r->u.v.u == 0)

⌨️ 快捷键说明

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