📄 putdmr.c
字号:
/* 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 + -