📄 local2.c
字号:
return; case REG: putstr( rnames[p->tn.rval] ); return; default: cerror( "illegal conput" ); } }insput( p ) register NODE *p; { cerror( "insput" ); }upput( p ) register NODE *p; { cerror( "upput" ); }adrput( p ) register NODE *p; { register int r; /* output an address, with offsets, from p */ if( p->in.op == FLD ){ p = p->in.left; } switch( p->in.op ){ case NAME: acon( p ); return; case ICON: /* addressable value of the constant */ putchar( '$' ); acon( p ); return; case REG: putstr( rnames[p->tn.rval] ); return; case OREG: r = p->tn.rval; if( R2TEST(r) ){ /* double indexing */ register int flags; flags = R2UPK3(r); if( flags & 1 ) putchar('*'); if( flags & 4 ) putchar('-'); if( p->tn.lval != 0 || p->in.name[0] != '\0' ) acon(p); if( R2UPK1(r) != 100) printf( "(%s)", rnames[R2UPK1(r)] ); if( flags & 2 ) putchar('+'); printf( "[%s]", rnames[R2UPK2(r)] ); return; } if( r == AP ){ /* in the argument region */ if( p->tn.lval <= 0 || p->in.name[0] != '\0' ) werror( "bad arg temp" ); printf( CONFMT, p->tn.lval ); putstr( "(ap)" ); return; } if( p->tn.lval != 0 || p->in.name[0] != '\0') acon( p ); printf( "(%s)", rnames[p->tn.rval] ); return; case UNARY MUL: /* STARNM or STARREG found */ if( tshape(p, STARNM) ) { putchar( '*' ); adrput( p->in.left); } else { /* STARREG - really auto inc or dec */ register NODE *q;/* tbl p = p->in.left; p->in.left->in.op = OREG; if( p->in.op == INCR ) { adrput( p->in.left ); putchar( '+' ); } else { putchar( '-' ); adrput( p->in.left ); } tbl */ q = p->in.left; printf("%s(%s)%s", (q->in.op==INCR ? "" : "-"), rnames[q->in.left->tn.rval], (q->in.op==INCR ? "+" : "") ); p->in.op = OREG; p->tn.rval = q->in.left->tn.rval; p->tn.lval = (q->in.op == INCR ? -q->in.right->tn.lval : 0);#ifndef FLEXNAMES p->in.name[0] = '\0';#else p->in.name = "";#endif tfree(q); } return; default: cerror( "illegal address" ); return; } }acon( p ) register NODE *p; { /* print out a constant */ if( p->in.name[0] == '\0' ){ printf( CONFMT, p->tn.lval); } else if( p->tn.lval == 0 ) {#ifndef FLEXNAMES printf( "%.8s", p->in.name );#else putstr( p->in.name );#endif } else {#ifndef FLEXNAMES printf( "%.8s+", p->in.name );#else printf( "%s+", p->in.name );#endif printf( CONFMT, p->tn.lval ); } }/*aacon( p ) register NODE *p; { /* print out a constant *//* if( p->in.name[0] == '\0' ){ printf( CONFMT, p->tn.lval); return( 0 ); } else if( p->tn.lval == 0 ) {#ifndef FLEXNAMES printf( "$%.8s", p->in.name );#else printf( "$%s", p->in.name );#endif return( 1 ); } else { printf( "$(" ); printf( CONFMT, p->tn.lval ); printf( "+" );#ifndef FLEXNAMES printf( "%.8s)", p->in.name );#else printf( "%s)", p->in.name );#endif return(1); } } */genscall( p, cookie ) register NODE *p; { /* structure valued call */ return( gencall( p, cookie ) ); }/* tbl */int gc_numbytes;/* tbl */gencall( p, cookie ) register NODE *p; { /* generate the call given by p */ register NODE *p1, *ptemp; register temp, temp1; register m; if( p->in.right ) temp = argsize( p->in.right ); else temp = 0; if( p->in.op == STCALL || p->in.op == UNARY STCALL ){ /* set aside room for structure return */ if( p->stn.stsize > temp ) temp1 = p->stn.stsize; else temp1 = temp; } if( temp > maxargs ) maxargs = temp; SETOFF(temp1,4); if( p->in.right ){ /* make temp node, put offset in, and generate args */ ptemp = talloc(); ptemp->in.op = OREG; ptemp->tn.lval = -1; ptemp->tn.rval = SP;#ifndef FLEXNAMES ptemp->in.name[0] = '\0';#else ptemp->in.name = "";#endif ptemp->in.rall = NOPREF; ptemp->in.su = 0; genargs( p->in.right, ptemp ); ptemp->in.op = FREE; } p1 = p->in.left; if( p1->in.op != ICON ){ if( p1->in.op != REG ){ if( p1->in.op != OREG || R2TEST(p1->tn.rval) ){ if( p1->in.op != NAME ){ order( p1, INAREG ); } } } }/* if( p1->in.op == REG && p->tn.rval == R5 ){ cerror( "call register overwrite" ); } *//* tbl setup gc_numbytes so reference to ZC works */ gc_numbytes = temp&(0x3ff);/* tbl */ p->in.op = UNARY CALL; m = match( p, INTAREG|INTBREG ); /* compensate for deficiency in 'ret' instruction ... wah,kre */ /* (plus in assignment to gc_numbytes above, for neatness only) */ if (temp >= 1024) printf(" addl2 $%d,sp\n", (temp&(~0x3ff)));/* tbl switch( temp ) { case 0: break; case 2: printf( " tst (sp)+\n" ); break; case 4: printf( " cmp (sp)+,(sp)+\n" ); break; default: printf( " add $%d,sp\n", temp); } tbl */ return(m != MDONE); }/* tbl */char *ccbranches[] = { " jeql L%d\n", " jneq L%d\n", " jleq L%d\n", " jlss L%d\n", " jgeq L%d\n", " jgtr L%d\n", " jlequ L%d\n", " jlssu L%d\n", " jgequ L%d\n", " jgtru L%d\n", };/* tbl */cbgen( o, lab, mode ) { /* printf conditional and unconditional branches *//* tbl */ if( o == 0 ) printf( " jbr L%d\n", lab );/* tbl */ else { if( o > UGT ) cerror( "bad conditional branch: %s", opst[o] ); printf( ccbranches[o-EQ], lab ); } }nextcook( p, cookie ) NODE *p; { /* we have failed to match p with cookie; try another */ if( cookie == FORREW ) return( 0 ); /* hopeless! */ if( !(cookie&(INTAREG|INTBREG)) ) return( INTAREG|INTBREG ); if( !(cookie&INTEMP) && asgop(p->in.op) ) return( INTEMP|INAREG|INTAREG|INTBREG|INBREG ); return( FORREW ); }lastchance( p, cook ) NODE *p; { /* forget it! */ return(0); }optim2( p ) register NODE *p; { /* do local tree transformations and optimizations */ register NODE *l, *r; switch( p->in.op ) { case AND: /* commute L and R to eliminate complements and constants */ if( (l = p->in.left)->in.op == ICON && l->in.name[0] == 0 || l->in.op == COMPL ) { p->in.left = p->in.right; p->in.right = l; } case ASG AND: /* change meaning of AND to ~R&L - bic on pdp11 */ r = p->in.right; if( r->in.op==ICON && r->in.name[0]==0 ) { /* complement constant */ r->tn.lval = ~r->tn.lval; switch(p->in.type) { case CHAR: case UCHAR: r->tn.lval = (char)r->tn.lval; break; case SHORT: case USHORT: r->tn.lval = (short)r->tn.lval; break; default: break; } } else if( r->in.op==COMPL ) { /* ~~A => A */ r->in.op = FREE; p->in.right = r->in.left; } else { /* insert complement node */ p->in.right = talloc(); p->in.right->in.op = COMPL; p->in.right->in.rall = NOPREF; p->in.right->in.type = r->in.type; p->in.right->in.left = r; p->in.right->in.right = NULL; } break; } }NODE * addroreg(l) NODE *l; /* OREG was built in clocal() * for an auto or formal parameter * now its address is being taken * local code must unwind it * back to PLUS/MINUS REG ICON * according to local conventions */{ cerror("address of OREG taken"); /*NOTREACHED*/}# ifndef ONEPASSmain( argc, argv ) char *argv[]; { return( mainp2( argc, argv ) ); }# endif/* added by jwf */struct functbl { int fop; TWORD ftype; char *func; } opfunc[] = { DIV, TANY, "udiv", MOD, TANY, "urem", ASG DIV, TANY, "udiv", ASG MOD, TANY, "urem", 0, 0, 0 };hardops(p) register NODE *p; { /* change hard to do operators into function calls. */ register NODE *q; register struct functbl *f; register o; register TWORD t; o = p->in.op; t = p->in.type; if( t!=UNSIGNED && t!=ULONG ) return; for( f=opfunc; f->fop; f++ ) { if( o==f->fop ) goto convert; } return; /* need to rewrite tree for ASG OP */ /* must change ASG OP to a simple OP */ convert: if( asgop( o ) ) { q = talloc(); switch( p->in.op ) { case ASG DIV: q->in.op = DIV; break; case ASG MOD: q->in.op = MOD; break; } q->in.rall = NOPREF; q->in.type = p->in.type; q->in.left = tcopy(p->in.left); q->in.right = p->in.right; p->in.op = ASSIGN; p->in.right = q; zappost(q->in.left); /* remove post-INCR(DECR) from new node */ fixpre(q->in.left); /* change pre-INCR(DECR) to +/- */ p = q; } /* build comma op for args to function */ q = talloc(); q->in.op = CM; q->in.rall = NOPREF; q->in.type = INT; q->in.left = p->in.left; q->in.right = p->in.right; p->in.op = CALL; p->in.right = q; /* put function name in left node of call */ p->in.left = q = talloc(); q->in.op = ICON; q->in.rall = NOPREF; q->in.type = INCREF( FTN + p->in.type );#ifndef FLEXNAMES strcpy( q->in.name, f->func );#else q->in.name = f->func;#endif q->tn.lval = 0; q->tn.rval = 0; return; }zappost(p) NODE *p; { /* look for ++ and -- operators and remove them */ register o, ty; register NODE *q; o = p->in.op; ty = optype( o ); switch( o ){ case INCR: case DECR: q = p->in.left; p->in.right->in.op = FREE; /* zap constant */ ncopy( p, q ); q->in.op = FREE; return; } if( ty == BITYPE ) zappost( p->in.right ); if( ty != LTYPE ) zappost( p->in.left );}fixpre(p) NODE *p; { register o, ty; o = p->in.op; ty = optype( o ); switch( o ){ case ASG PLUS: p->in.op = PLUS; break; case ASG MINUS: p->in.op = MINUS; break; } if( ty == BITYPE ) fixpre( p->in.right ); if( ty != LTYPE ) fixpre( p->in.left );}myreader(p) register NODE *p; { walkf( p, hardops ); /* convert ops to function calls */ canon( p ); /* expands r-vals for fields */ walkf( p, optim2 ); /* jwf toff = 0; /* stack offset swindle */ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -