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

📄 putdmr.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  INTERMEDIATE CODE GENERATION FOR D. M. RITCHIE C COMPILERS */#if FAMILY != DMR	WRONG put FILE !!!!#endif#include "defs"#include "dmrdefs"extern int ops2[];extern int types2[];puthead(s, class)char *s;int class;{if( ! headerdone )	{	p2op2(P2SETREG, ARGREG-maxregvar);	p2op(P2PROG);	headerdone = YES;#if TARGET == PDP11	/* fake jump to start the optimizer */	if(class != CLBLOCK)		putgoto( fudgelabel = newlabel() );#endif	}}putnreg(){p2op2(P2SETREG, ARGREG-nregvar);}puteof(){p2op(P2EOF);}putstmt(){p2op2(P2EXPR, lineno);}/* put out code for if( ! p) goto l  */putif(p,l)register expptr p;int l;{register int k;if( (k = (p = fixtype(p))->vtype) != TYLOGICAL)	{	if(k != TYERROR)		err("non-logical expression in IF statement");	frexpr(p);	}else	{	putex1(p);	p2op2(P2CBRANCH, l);	p2i(0);	p2i(lineno);	}}/* put out code for  goto l   */putgoto(label)int label;{p2op2(P2GOTO, label);}/* branch to address constant or integer variable */putbranch(p)register struct addrblock *p;{register int type;type = p->vtype;if(p->tag != TADDR)	fatal("invalid goto label");putaddr(p, YES);if(type != TYINT)	p2op2(P2LTOI, P2INT);p2op2(P2INDIRECT, P2INT);p2op2(P2JUMP, P2INT);putstmt();}/* put out label  l:     */putlabel(label)int label;{p2op2(P2LABEL, label);}putexpr(p)expptr p;{putex1(p);putstmt();}prarif(p, neg, zero, pos)expptr p;int neg ,zero, pos;{putx(p);p2op(P2ARIF);p2i(neg);p2i(zero);p2i(pos);p2i(lineno);}putcmgo(index, nlab, labs)expptr index;int nlab;struct labelblock *labs[];{register int i;int skiplabel;if(! ISINT(index->vtype) )	{	execerr("computed goto index must be integer", NULL);	return;	}putforce(TYINT, mkconv(TYINT, index) );p2op(P2SWITCH);p2i(skiplabel = newlabel() );p2i(lineno);for(i = 0 ; i<nlab ; ++i)	{	p2i(labs[i]->labelno);	p2i(i+1);	}p2i(0);putlabel(skiplabel);}putx(p)register expptr p;{struct addrblock *putcall(), *putcx1(), *realpart();char *memname();int opc;int type, ncomma;switch(p->tag)	{	case TERROR:		free(p);		break;	case TCONST:		switch(type = p->vtype)			{			case TYLOGICAL:				type = tylogical;			case TYLONG:			case TYSHORT:				if(type == TYSHORT)					{					p2op2(P2ICON, P2SHORT);					p2i( (short)(p->const.ci) );					}				else					{					p2op2(P2LCON, P2LONG);					p2li(p->const.ci);					}				free(p);				break;			case TYADDR:				p2op(P2NAME);				p2i(P2STATIC);				p2i(P2INT);				p2i( (int) p->const.ci);				p2op2(P2ADDR, P2PTR);				free(p);				break;			default:				putx( putconst(p) );				break;			}		break;	case TEXPR:		switch(opc = p->opcode)			{			case OPCALL:			case OPCCALL:				if( ISCOMPLEX(p->vtype) )					putcxop(p);				else	putcall(p);				break;			case OPMIN:			case OPMAX:				putmnmx(p);				break;			case OPASSIGN:				if( ISCOMPLEX(p->leftp->vtype) || ISCOMPLEX(p->rightp->vtype) )					frexpr( putcxeq(p) );				else if( ISCHAR(p) )					putcheq(p);				else					goto putopp;				break;			case OPEQ:			case OPNE:				if( ISCOMPLEX(p->leftp->vtype) || ISCOMPLEX(p->rightp->vtype) )					{					putcxcmp(p);					break;					}			case OPLT:			case OPLE:			case OPGT:			case OPGE:				if(ISCHAR(p->leftp))					putchcmp(p);				else					goto putopp;				break;			case OPPOWER:				putpower(p);				break;			case OPMOD:				goto putopp;			case OPSTAR:			case OPPLUS:			case OPMINUS:			case OPSLASH:			case OPNEG:				if( ISCOMPLEX(p->vtype) )					putcxop(p);				else	goto putopp;				break;			case OPCONV:				if( ISCOMPLEX(p->vtype) )					putcxop(p);				else if( ISCOMPLEX(p->leftp->vtype) )					{					ncomma = 0;					putx( mkconv(p->vtype,						realpart(putcx1(p->leftp, &ncomma))));					putcomma(ncomma, p->vtype, NO);					free(p);					}				else	goto putopp;				break;			case OPNOT:			case OPOR:			case OPAND:			case OPEQV:			case OPNEQV:			case OPADDR:			case OPPLUSEQ:			case OPSTAREQ:			case OPCOMMA:			case OPQUEST:			case OPCOLON:			case OPBITOR:			case OPBITAND:			case OPBITXOR:			case OPBITNOT:			case OPLSHIFT:			case OPRSHIFT:		putopp:				putop(p);				break;			default:				fatal1("putx: invalid opcode %d", opc);			}		break;	case TADDR:		putaddr(p, YES);		break;	default:		fatal1("putx: impossible tag %d", p->tag);	}}LOCAL putop(p)register expptr p;{int k, ncomma;int type2, ptype, ltype;int convop;register expptr lp, tp;switch(p->opcode)	/* check for special cases and rewrite */	{	case OPCONV:		lp = p->leftp;		while(p->tag==TEXPR && p->opcode==OPCONV &&		     (	( (ptype = p->vtype) == (ltype = lp->vtype) ) ||		     (ISREAL(ptype)&&ISREAL(ltype)) ||		     (ONEOF(ptype, M(TYSHORT)|M(TYADDR)) &&			ONEOF(ltype, M(TYSHORT)|M(TYADDR))) ||		        (ptype==TYINT && ONEOF(ltype, M(TYSUBR)|M(TYCHAR))) ))				{				free(p);				p = lp;				lp = p->leftp;				}		if(p->tag!=TEXPR || p->opcode!=OPCONV || ISCOMPLEX((ltype = lp->vtype)) )			{			putx(p);			return;			}		ltype = lp->vtype;		switch(ptype = p->vtype)			{			case TYCHAR:				p->leftp = lp = mkconv(TYSHORT, lp);				convop = P2ITOC;				break;			case TYSHORT:			case TYADDR:				switch(ltype)					{					case TYLONG:						convop = P2LTOI; break;					case TYREAL:					case TYDREAL:						convop = P2FTOI; break;					default:						goto badconv;					}				break;			case TYLONG:				switch(ltype)					{					case TYCHAR:					case TYSHORT:					case TYADDR:						convop = P2ITOL; break;					case TYREAL:					case TYDREAL:						convop = P2FTOL; break;					default:						goto badconv;					}				break;			case TYREAL:			case TYDREAL:				switch(ltype)					{					case TYCHAR:					case TYSHORT:					case TYADDR:						convop = P2ITOF; break;					case TYLONG:						convop = P2LTOF; break;					default:						goto badconv;					}				break;			default:			badconv:				fatal("putop: impossible conversion");			}		putx(lp);		p2op2(convop, types2[ptype]);		free(p);		return;	case OPADDR:		lp = p->leftp;		if(lp->tag != TADDR)			{			tp = mktemp(lp->vtype, lp->vleng);			putx( mkexpr(OPASSIGN, cpexpr(tp), lp) );			ncomma = 1;			lp = tp;			}		else	ncomma = 0;		putaddr(lp, NO);		putcomma(ncomma, TYINT, NO);		free(p);		return;	case OPASSIGN:		if(p->vtype==TYLOGICAL && tylogical!=TYINT &&		   p->rightp->tag==TEXPR && p->rightp->opcode!=OPCALL && p->rightp->opcode!=OPCCALL)			{			p->rightp->vtype = TYINT;			p->rightp = mkconv(tylogical, p->rightp);			}		break;	}if( (k = ops2[p->opcode]) <= 0)	fatal1("putop: invalid opcode %d", p->opcode);putx(p->leftp);if(p->rightp)	putx(p->rightp);type2 = (p->vtype==TYLOGICAL ? P2INT : types2[p->vtype]);p2op2(k, type2);if(p->vleng)	frexpr(p->vleng);free(p);}putforce(t, p)int t;expptr p;{p = mkconv(t, fixtype(p));putx(p);p2op2(P2FORCE, (t==TYSHORT ? P2SHORT : (t==TYLONG ? P2LONG : P2DREAL)) );putstmt();}LOCAL putpower(p)expptr p;{expptr base;struct addrblock *t1, *t2;ftnint k;int type;int ncomma;if(!ISICON(p->rightp) || (k = p->rightp->const.ci)<2)	fatal("putpower: bad call");base = p->leftp;type = base->vtype;t1 = mktemp(type, NULL);t2 = NULL;ncomma = 1;putassign(cpexpr(t1), cpexpr(base) );for( ; (k&1)==0 && k>2 ; k>>=1 )	{	++ncomma;	putsteq(t1, t1);	}if(k == 2)	putx( mkexpr(OPSTAR, cpexpr(t1), cpexpr(t1)) );else	{	t2 = mktemp(type, NULL);	++ncomma;	putassign(cpexpr(t2), cpexpr(t1));		for(k>>=1 ; k>1 ; k>>=1)		{		++ncomma;		putsteq(t1, t1);		if(k & 1)			{			++ncomma;			putsteq(t2, t1);			}		}	putx( mkexpr(OPSTAR, cpexpr(t2),		mkexpr(OPSTAR, cpexpr(t1), cpexpr(t1)) ));	}putcomma(ncomma, type, NO);frexpr(t1);if(t2)	frexpr(t2);frexpr(p);}LOCAL struct addrblock *intdouble(p, ncommap)struct addrblock *p;int *ncommap;{register struct addrblock *t;t = mktemp(TYDREAL, NULL);++*ncommap;putassign(cpexpr(t), p);return(t);}LOCAL putcxeq(p)register struct exprblock *p;{register struct addrblock *lp, *rp;int ncomma;ncomma = 0;lp = putcx1(p->leftp, &ncomma);rp = putcx1(p->rightp, &ncomma);putassign(realpart(lp), realpart(rp));if( ISCOMPLEX(p->vtype) )	{	++ncomma;	putassign(imagpart(lp), imagpart(rp));	}putcomma(ncomma, TYREAL, NO);frexpr(rp);free(p);return(lp);}LOCAL putcxop(p)expptr p;{struct addrblock *putcx1();int ncomma;ncomma = 0;putaddr( putcx1(p, &ncomma), NO);putcomma(ncomma, TYINT, NO);}LOCAL struct addrblock *putcx1(p, ncommap)register expptr p;int *ncommap;{struct addrblock *q, *lp, *rp;register struct addrblock *resp;int opcode;int ltype, rtype;if(p == NULL)	return(NULL);switch(p->tag)	{	case TCONST:		if( ISCOMPLEX(p->vtype) )			p = putconst(p);		return( p );	case TADDR:		if( ! addressable(p) )			{			++*ncommap;			resp = mktemp(tyint, NULL);			putassign( cpexpr(resp), p->memoffset );			p->memoffset = resp;			}		return( p );	case TEXPR:		if( ISCOMPLEX(p->vtype) )			break;		++*ncommap;		resp = mktemp(TYDREAL, NO);		putassign( cpexpr(resp), p);		return(resp);	default:		fatal1("putcx1: bad tag %d", p->tag);	}opcode = p->opcode;if(opcode==OPCALL || opcode==OPCCALL)	{	++*ncommap;	return( putcall(p) );	}else if(opcode == OPASSIGN)	{	++*ncommap;	return( putcxeq(p) );	}resp = mktemp(p->vtype, NULL);if(lp = putcx1(p->leftp, ncommap) )	ltype = lp->vtype;if(rp = putcx1(p->rightp, ncommap) )	rtype = rp->vtype;switch(opcode)	{	case OPCOMMA:		frexpr(resp);		resp = rp;

⌨️ 快捷键说明

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