📄 reader.c
字号:
order( p2, INTBREG|INTAREG ); goto again; case ASSIGN: if( setasg( p ) ) goto again; goto nomat; case BITYPE: if( setbin( p ) ) goto again; /* try to replace binary ops by =ops */ switch(o){ case PLUS: case MINUS: case MUL: case DIV: case MOD: case AND: case OR: case ER: case LS: case RS: p->op = ASG o; goto again; } goto nomat; } cleanup: /* if it is not yet in the right state, put it there */ if( cook & FOREFF ){ reclaim( p, RNULL, 0 ); return; } if( p->op==FREE ) return; if( tshape( p, cook ) ) return; if( (m=match(p,cook) ) == MDONE ) return; /* we are in bad shape, try one last chance */ if( lastchance( p, cook ) ) goto again; goto nomat; }int callflag;int fregs;store( p ) register NODE *p; { /* find a subtree of p which should be stored */ register o, ty; o = p->op; ty = optype(o); if( ty == LTYPE ) return; switch( o ){ case UNARY CALL: case UNARY FORTCALL: case UNARY STCALL: ++callflag; break; case UNARY MUL: if( asgop(p->left->op) ) stoasg( p->left, UNARY MUL ); break; case CALL: case FORTCALL: case STCALL: store( p->left ); stoarg( p->right, o ); ++callflag; return; case COMOP: markcall( p->right ); if( p->right->su > fregs ) SETSTO( p, INTEMP ); store( p->left ); return; case ANDAND: case OROR: case QUEST: markcall( p->right ); if( p->right->su > fregs ) SETSTO( p, INTEMP ); case CBRANCH: /* to prevent complicated expressions on the LHS from being stored */ case NOT: constore( p->left ); return; } if( ty == UTYPE ){ store( p->left ); return; } if( asgop( p->right->op ) ) stoasg( p->right, o ); if( p->su>fregs ){ /* must store */ mkadrs( p ); /* set up stotree and stocook to subtree that must be stored */ } store( p->right ); store( p->left ); }constore( p ) register NODE *p; { /* store conditional expressions */ /* the point is, avoid storing expressions in conditional conditional context, since the evaluation order is predetermined */ switch( p->op ) { case ANDAND: case OROR: case QUEST: markcall( p->right ); case NOT: constore( p->left ); return; } store( p ); }markcall( p ) register NODE *p; { /* mark off calls below the current node */ again: switch( p->op ){ case UNARY CALL: case UNARY STCALL: case UNARY FORTCALL: case CALL: case STCALL: case FORTCALL: ++callflag; return; } switch( optype( p->op ) ){ case BITYPE: markcall( p->right ); case UTYPE: p = p->left; /* eliminate recursion (aren't I clever...) */ goto again; case LTYPE: return; } }stoarg( p, calltype ) register NODE *p; { /* arrange to store the args */ if( p->op == CM ){ stoarg( p->left, calltype ); p = p->right ; } if( calltype == CALL ){ STOARG(p); } else if( calltype == STCALL ){ STOSTARG(p); } else { STOFARG(p); } callflag = 0; store(p);# ifndef NESTCALLS if( callflag ){ /* prevent two calls from being active at once */ SETSTO(p,INTEMP); store(p); /* do again to preserve bottom up nature.... */ }#endif }int negrel[] = { NE, EQ, GT, GE, LT, LE, UGT, UGE, ULT, ULE } ; /* negatives of relationals */cbranch( p, true, false ) NODE *p; { /* evaluate p for truth value, and branch to true or false /* accordingly: label <0 means fall through */ register o, lab, flab, tlab; lab = -1; switch( o=p->op ){ case ULE: case ULT: case UGE: case UGT: case EQ: case NE: case LE: case LT: case GE: case GT: if( true < 0 ){ o = p->op = negrel[ o-EQ ]; true = false; false = -1; }#ifndef NOOPT if( p->right->op == ICON && p->right->lval == 0 && p->right->name[0] == '\0' ){ switch( o ){ case UGT: case ULE: o = p->op = (o==UGT)?NE:EQ; case EQ: case NE: case LE: case LT: case GE: case GT: if( logop(p->left->op) ){ /* strange situation: e.g., (a!=0) == 0 */ /* must prevent reference to p->left->lable, so get 0/1 */ /* we could optimize, but why bother */ codgen( p->left, INAREG|INBREG ); } codgen( p->left, FORCC ); cbgen( o, true, 'I' ); break; case UGE: cbgen( 0, true, 'I' ); /* unconditional branch */ case ULT: ; /* do nothing for LT */ } } else#endif { p->label = true; codgen( p, FORCC ); } if( false>=0 ) cbgen( 0, false, 'I' ); reclaim( p, RNULL, 0 ); return; case ANDAND: lab = false<0 ? getlab() : false ; cbranch( p->left, -1, lab ); cbranch( p->right, true, false ); if( false < 0 ) deflab( lab ); p->op = FREE; return; case OROR: lab = true<0 ? getlab() : true; cbranch( p->left, lab, -1 ); cbranch( p->right, true, false ); if( true < 0 ) deflab( lab ); p->op = FREE; return; case NOT: cbranch( p->left, false, true ); p->op = FREE; break; case COMOP: codgen( p->left, FOREFF ); p->op = FREE; cbranch( p->right, true, false ); return; case QUEST: flab = false<0 ? getlab() : false; tlab = true<0 ? getlab() : true; cbranch( p->left, -1, lab = getlab() ); cbranch( p->right->left, tlab, flab ); deflab( lab ); cbranch( p->right->right, true, false ); if( true < 0 ) deflab( tlab); if( false < 0 ) deflab( flab ); p->right->op = FREE; p->op = FREE; return; case ICON: if( p->type != FLOAT && p->type != DOUBLE ){ if( p->lval || p->name[0] ){ /* addresses of C objects are never 0 */ if( true>=0 ) cbgen( 0, true, 'I' ); } else if( false>=0 ) cbgen( 0, false, 'I' ); p->op = FREE; return; } /* fall through to default with other strange constants */ default: /* get condition codes */ codgen( p, FORCC ); if( true >= 0 ) cbgen( NE, true, 'I' ); if( false >= 0 ) cbgen( true >= 0 ? 0 : EQ, false, 'I' ); reclaim( p, RNULL, 0 ); return; } }rcount(){ /* count recursions */ if( ++nrecur > NRECUR ){ cerror( "expression causes compiler loop: try simplifying" ); } }eprint( p, down, a, b ) NODE *p; int *a, *b; { *a = *b = down+1; while( down >= 2 ){ printf( "\t" ); down -= 2; } if( down-- ) printf( " " ); printf( "%o) %s", p, opst[p->op] ); switch( p->op ) { /* special cases */ case REG: printf( " %s", rnames[p->rval] ); break; case ICON: case NAME: case OREG: printf( " " ); adrput( p ); break; case STCALL: case UNARY STCALL: case STARG: case STASG: printf( " size=%d", p->stsize ); printf( " align=%d", p->stalign ); break; } printf( ", " ); tprint( p->type ); printf( ", " ); if( p->rall == NOPREF ) printf( "NOPREF" ); else { if( p->rall & MUSTDO ) printf( "MUSTDO " ); else printf( "PREF " ); printf( "%s", rnames[p->rall&~MUSTDO]); } printf( ", SU= %d\n", p->su ); }# ifndef NOMAINNODE *eread(){ /* call eread recursively to get subtrees, if any */ register NODE *p; register i, c; register char *pc; register j; i = rdin( 10 ); p = talloc(); p->op = i; i = optype(i); if( i == LTYPE ) p->lval = rdin( 10 ); if( i != BITYPE ) p->rval = rdin( 10 ); p->type = rdin(8 ); p->rall = NOPREF; /* register allocation information */ if( p->op == STASG || p->op == STARG || p->op == STCALL || p->op == UNARY STCALL ){ p->stsize = (rdin( 10 ) + (SZCHAR-1) )/SZCHAR; p->stalign = rdin(10) / SZCHAR; if( getchar() != '\n' ) cerror( "illegal \n" ); } else { /* usual case */ if( p->op == REG ) rbusy( p->rval, p->type ); /* non usually, but sometimes justified */ for( pc=p->name,j=0; ( c = getchar() ) != '\n'; ++j ){ if( j < NCHNAM ) *pc++ = c; } if( j < NCHNAM ) *pc = '\0'; } /* now, recursively read descendents, if any */ if( i != LTYPE ) p->left = eread(); if( i == BITYPE ) p->right = eread(); return( p ); }CONSZrdin( base ){ register sign, c; CONSZ val; sign = 1; val = 0; while( (c=getchar()) > 0 ) { if( c == '-' ){ if( val != 0 ) cerror( "illegal -"); sign = -sign; continue; } if( c == '\t' ) break; if( c>='0' && c<='9' ) { val *= base; if( sign > 0 ) val += c-'0'; else val -= c-'0'; continue; } cerror( "illegal character `%c' on intermediate file", c ); break; } if( c <= 0 ) { cerror( "unexpected EOF"); } return( val ); }# endif#ifndef FIELDOPS /* do this if there is no special hardware support for fields */ffld( p, down, down1, down2 ) NODE *p; int *down1, *down2; { /* look for fields that are not in an lvalue context, and rewrite them... */ register NODE *shp; register s, o, v, ty; *down1 = asgop( p->op ); *down2 = 0; if( !down && p->op == FLD ){ /* rewrite the node */ if( !rewfld(p) ) return; ty = (szty(p->type) == 2)? LONG: INT; v = p->rval; s = UPKFSZ(v);# ifdef RTOLBYTES o = UPKFOFF(v); /* amount to shift */# else o = szty(p->type)*SZINT - s - UPKFOFF(v); /* amount to shift */#endif /* make & mask part */ p->left->type = ty; p->op = AND; p->right = talloc(); p->right->op = ICON; p->right->rall = NOPREF; p->right->type = ty; p->right->lval = 1; p->right->rval = 0; p->right->name[0] = '\0'; p->right->lval <<= s; p->right->lval--; /* now, if a shift is needed, do it */ if( o != 0 ){ shp = talloc(); shp->op = RS; shp->rall = NOPREF; shp->type = ty; shp->left = p->left; shp->right = talloc(); shp->right->op = ICON; shp->right->rall = NOPREF; shp->right->type = ty; shp->right->rval = 0; shp->right->lval = o; /* amount to shift */ shp->right->name[0] = '\0'; p->left = shp; /* whew! */ } } }#endiforeg2( p ) register NODE *p; { /* look for situations where we can turn * into OREG */ NODE *q; register i; register r; register char *cp; register NODE *ql, *qr; CONSZ temp; if( p->op == UNARY MUL ){ q = p->left; if( q->op == REG ){ temp = q->lval; r = q->rval; cp = q->name; goto ormake; } if( q->op != PLUS && q->op != MINUS ) return; ql = q->left; qr = q->right;#ifdef R2REGS /* look for doubly indexed expressions */ if( q->op==PLUS && qr->op==REG && ql->op==REG && (szty(ql->type)==1||szty(qr->type)==1) ) { temp = 0; cp = ql->name; if( *cp ){ if( *qr->name ) return; } else { cp = qr->name; } if( szty(qr->type)>1) r = R2PACK(qr->rval,ql->rval); else r = R2PACK(ql->rval,qr->rval); goto ormake; } if( (q->op==PLUS||q->op==MINUS) && qr->op==ICON && ql->op==PLUS && ql->left->op==REG && ql->right->op==REG ){ temp = qr->lval; cp = qr->name; if( q->op == MINUS ){ if( *cp ) return; temp = -temp; } if( *cp ){ if( *ql->name ) return; } else { cp = ql->name; } r = R2PACK(ql->left->rval,ql->right->rval); goto ormake; }#endif if( (q->op==PLUS || q->op==MINUS) && qr->op == ICON && ql->op==REG && szty(qr->type)==1) { temp = qr->lval; if( q->op == MINUS ) temp = -temp; r = ql->rval; temp += ql->lval; cp = qr->name; if( *cp && ( q->op == MINUS || *ql->name ) ) return; if( !*cp ) cp = ql->name; ormake: if( notoff( p->type, r, temp, cp ) ) return; p->op = OREG; p->rval = r; p->lval = temp; for( i=0; i<NCHNAM; ++i ) p->name[i] = *cp++; tfree(q); return; } } }canon(p) NODE *p; { /* put p in canonical form */ int oreg2(), sucomp();#ifndef FIELDOPS int ffld(); fwalk( p, ffld, 0 ); /* look for field operators */# endif walkf( p, oreg2 ); /* look for and create OREG nodes */#ifdef MYCANON MYCANON(p); /* your own canonicalization routine(s) */#endif walkf( p, sucomp ); /* do the Sethi-Ullman computation */ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -