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

📄 simp.c

📁 lcc,一个可变目标c语言编译器的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "c.h"#include <float.h>static char rcsid[] = "$Id: simp.c,v 1.1 2002/08/28 23:12:45 drh Exp $";#define foldcnst(TYPE,VAR,OP) \	if (l->op == CNST+TYPE && r->op == CNST+TYPE) \		return cnsttree(ty, l->u.v.VAR OP r->u.v.VAR)#define commute(L,R) \	if (generic(R->op) == CNST && generic(L->op) != CNST) \		do { Tree t = L; L = R; R = t; } while(0)#define xfoldcnst(TYPE,VAR,OP,FUNC)\	if (l->op == CNST+TYPE && r->op == CNST+TYPE\	&& FUNC(l->u.v.VAR,r->u.v.VAR,\		ty->u.sym->u.limits.min.VAR,\		ty->u.sym->u.limits.max.VAR, needconst)) \		return cnsttree(ty, l->u.v.VAR OP r->u.v.VAR)#define xcvtcnst(FTYPE,SRC,DST,VAR,EXPR) \	if (l->op == CNST+FTYPE) do {\		if (!explicitCast\		&&  ((SRC) < DST->u.sym->u.limits.min.VAR || (SRC) > DST->u.sym->u.limits.max.VAR))\			warning("overflow in converting constant expression from `%t' to `%t'\n", l->type, DST);\		if (needconst\		|| !((SRC) < DST->u.sym->u.limits.min.VAR || (SRC) > DST->u.sym->u.limits.max.VAR))\			return cnsttree(ty, (EXPR)); } while(0)#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],\			cnsttree(unsignedtype, \				(unsigned long)fieldmask(l->u.field)<<fieldright(l->u.field))), r)#define cfoldcnst(TYPE,VAR,OP) \	if (l->op == CNST+TYPE && r->op == CNST+TYPE) \		return cnsttree(inttype, (long)(l->u.v.VAR OP r->u.v.VAR))#define foldaddp(L,R,RTYPE,VAR) \	if (L->op == CNST+P && R->op == CNST+RTYPE) { \		Tree e = tree(CNST+P, ty, NULL, NULL);\		e->u.v.p = (char *)L->u.v.p + R->u.v.VAR;\		return e; }#define ufoldcnst(TYPE,EXP) if (l->op == CNST+TYPE) return EXP#define sfoldcnst(OP) \	if (l->op == CNST+U && r->op == CNST+I \	&& r->u.v.i >= 0 && r->u.v.i < 8*l->type->size) \		return cnsttree(ty, (unsigned long)(l->u.v.u OP r->u.v.i))#define geu(L,R,V) \	if (R->op == CNST+U && R->u.v.u == 0) do { \		warning("result of unsigned comparison is constant\n"); \		return tree(RIGHT, inttype, root(L), cnsttree(inttype, (long)(V))); } while(0)#define idempotent(OP) if (l->op == OP) return l->kids[0]int needconst;int explicitCast;static int addi(long x, long y, long min, long 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("overflow in constant expression\n");		cond = 1;	}	return cond;}static int addd(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("overflow in constant expression\n");		cond = 1;	}	return cond;}static Tree addrtree(Tree e, long n, Type ty) {	Symbol p = e->u.sym, q;	if (p->scope  == GLOBAL	||  p->sclass == STATIC || p->sclass == EXTERN)		NEW0(q, PERM);	else		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->defined = 1;	q->ref = 1;	assert(IR->address);	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;	return e;}/* div[id] - return 1 if min <= x/y <= max, 0 otherwise */static int divi(long x, long y, long min, long max, int needconst) {	int cond = y != 0 && !(x == min && y == -1);	if (!cond && needconst) {		warning("overflow in constant expression\n");		cond = 1;	}	return cond;}static int divd(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 && needconst) {		warning("overflow in constant expression\n");		cond = 1;	}	return cond;}/* mul[id] - return 1 if min <= x*y <= max, 0 otherwise */static int muli(long x, long y, long min, long 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 &&  y >= min/x	|| x > 0 && y > 0 &&  x <= max/y;	if (!cond && needconst) {		warning("overflow in constant expression\n");		cond = 1;	}	return cond;}static int muld(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 &&  y >= min/x	|| x > 0 && y > 0 &&  x <= max/y;	if (!cond && needconst) {		warning("overflow in constant expression\n");		cond = 1;	}	return cond;}/* sub[id] - return 1 if min <= x-y <= max, 0 otherwise */static int subi(long x, long y, long min, long max, int needconst) {	return addi(x, -y, min, max, needconst);}static int subd(double x, double y, double min, double max, int needconst) {	return addd(x, -y, min, max, needconst);}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 (p->op == CNST+I || p->op == CNST+U)		n = cast(p, inttype)->u.v.i;	else		error("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 = mkop(op, ty);	switch (op) {		case ADD+U:			foldcnst(U,u,+);			commute(r,l);			identity(r,l,U,u,0);			break;		case ADD+I:			xfoldcnst(I,i,+,addi);			commute(r,l);			identity(r,l,I,i,0);			break;		case CVI+I:			xcvtcnst(I,l->u.v.i,ty,i,(long)extend(l->u.v.i,ty));			break;		case CVU+I:			if (l->op == CNST+U) {				if (!explicitCast && l->u.v.u > ty->u.sym->u.limits.max.i)					warning("overflow in converting constant expression from `%t' to `%t'\n", l->type, ty);				if (needconst || !(l->u.v.u > ty->u.sym->u.limits.max.i))					return cnsttree(ty, (long)extend(l->u.v.u,ty));			}			break;		case CVP+U:			xcvtcnst(P,(unsigned long)l->u.v.p,ty,u,(unsigned long)l->u.v.p);			break;		case CVU+P:			xcvtcnst(U,(void*)l->u.v.u,ty,p,(void*)l->u.v.u);			break;		case CVP+P:			xcvtcnst(P,l->u.v.p,ty,p,l->u.v.p);			break;		case CVI+U:			xcvtcnst(I,l->u.v.i,ty,u,((unsigned long)l->u.v.i)&ones(8*ty->size));			break;		case CVU+U:			xcvtcnst(U,l->u.v.u,ty,u,l->u.v.u&ones(8*ty->size));			break;		case CVI+F:			xcvtcnst(I,l->u.v.i,ty,d,(long double)l->u.v.i);		case CVU+F:			xcvtcnst(U,l->u.v.u,ty,d,(long double)l->u.v.u);			break;		case CVF+I:			xcvtcnst(F,l->u.v.d,ty,i,(long)l->u.v.d);			break;		case CVF+F: {			float d;			if (l->op == CNST+F)				if (l->u.v.d < ty->u.sym->u.limits.min.d)					d = ty->u.sym->u.limits.min.d;				else if (l->u.v.d > ty->u.sym->u.limits.max.d)					d = ty->u.sym->u.limits.max.d;				else					d = l->u.v.d;			xcvtcnst(F,l->u.v.d,ty,d,(long double)d);			break;			}		case BAND+U:			foldcnst(U,u,&);			commute(r,l);			identity(r,l,U,u,ones(8*ty->size));			if (r->op == CNST+U && r->u.v.u == 0)				return tree(RIGHT, ty, root(l), cnsttree(ty, 0UL));			break;		case BAND+I:			foldcnst(I,i,&);			commute(r,l);			identity(r,l,I,i,ones(8*ty->size));			if (r->op == CNST+I && r->u.v.u == 0)				return tree(RIGHT, ty, root(l), cnsttree(ty, 0L));			break;		case MUL+U:			commute(l,r);			if (l->op == CNST+U && (n = ispow2(l->u.v.u)) != 0)				return simplify(LSH, ty, r, cnsttree(inttype, (long)n));			foldcnst(U,u,*);			identity(r,l,U,u,1);			break;		case NE+I:			cfoldcnst(I,i,!=);			commute(r,l);			zerofield(NE,I,i);			break;		case EQ+I:			cfoldcnst(I,i,==);			commute(r,l);

⌨️ 快捷键说明

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