📄 local2.c
字号:
pair pointed to by p (for LONGs)*/ CONSZ save; if( p->op == FLD ){ p = p->left; } save = p->lval; switch( p->op ){ case NAME: p->lval += SZINT/SZCHAR; acon( p ); break; case ICON: /* addressable value of the constant */ p->lval &= BITMASK(SZINT); printf( "$" ); acon( p ); break; case REG: printf( "%s", rnames[p->rval+1] ); break; case OREG: p->lval += SZINT/SZCHAR; if( p->rval == R5 ){ /* in the argument region */ if( p->name[0] != '\0' ) werror( "bad arg temp" ); } if( p->lval != 0 || p->name[0] != '\0' ) acon( p ); printf( "(%s)", rnames[p->rval] ); break; default: cerror( "illegal upper address" ); break; } p->lval = save; }adrput( p ) register NODE *p; { /* output an address, with offsets, from p */ if( p->op == FLD ){ p = p->left; } switch( p->op ){ case NAME: acon( p ); return; case ICON: /* addressable value of the constant */ if( szty( p->type ) == 2 ) { /* print the high order value */ CONSZ save; save = p->lval; p->lval = ( p->lval >> SZINT ) & BITMASK(SZINT); printf( "$" ); acon( p ); p->lval = save; return; } printf( "$" ); acon( p ); return; case REG: printf( "%s", rnames[p->rval] ); return; case OREG: if( p->rval == R5 ){ /* in the argument region */ if( p->name[0] != '\0' ) werror( "bad arg temp" ); printf( CONFMT, p->lval ); printf( ".(r5)" ); return; } if( p->lval != 0 || p->name[0] != '\0' ) acon( p ); printf( "(%s)", rnames[p->rval] ); return; case UNARY MUL: /* STARNM or STARREG found */ if( tshape(p, STARNM) ) { printf( "*" ); adrput( p->left); } else { /* STARREG - really auto inc or dec */ /* turn into OREG so replacement node will reflect the value of the expression */ register i; register NODE *q, *l; l = p->left; q = l->left; p->op = OREG; p->rall = q->rall; p->lval = q->lval; p->rval = q->rval; for( i=0; i<NCHNAM; i++ ) p->name[i] = q->name[i]; if( l->op == INCR ) { adrput( p ); printf( "+" ); p->lval -= l->right->lval; } else { /* l->op == ASG MINUS */ printf( "-" ); adrput( p ); } tfree( l ); } return; default: cerror( "illegal address" ); return; } }acon( p ) register NODE *p; { /* print out a constant */ if( p->name[0] == '\0' ){ /* constant only */ printf( CONFMT, p->lval); printf( "." ); } else if( p->lval == 0 ) { /* name only */ printf( "%.8s", p->name ); } else { /* name + offset */ printf( "%.8s+", p->name ); printf( CONFMT, p->lval ); printf( "." ); } }genscall( p, cookie ) register NODE *p; { /* structure valued call */ return( gencall( p, cookie ) ); }gencall( p, cookie ) register NODE *p; { /* generate the call given by p */ register temp; register m; if( p->right ) temp = argsize( p->right ); else temp = 0; if( p->right ){ /* generate args */ genargs( p->right ); } if( !shltype( p->left->op, p->left ) ) { order( p->left, INAREG|SOREG ); } p->op = UNARY CALL; m = match( p, INTAREG|INTBREG ); popargs( temp ); return(m != MDONE); }popargs( size ) register size; { /* pop arguments from stack */ toff -= size/2; if( toff == 0 && size >= 2 ) size -= 2; switch( size ) { case 0: break; case 2: printf( " tst (sp)+\n" ); break; case 4: printf( " cmp (sp)+,(sp)+\n" ); break; default: printf( " add $%d.,sp\n", size); } }char *ccbranches[] = { " jeq L%d\n", " jne L%d\n", " jle L%d\n", " jlt L%d\n", " jge L%d\n", " jgt L%d\n", " jlos L%d\n", " jlo L%d\n", " jhis L%d\n", " jhi L%d\n", };/* long branch table This table, when indexed by a logical operator, selects a set of three logical conditions required to generate long comparisons and branches. A zero entry indicates that no branch is required. E.G.: The <= operator would generate: cmp AL,AR jlt lable / 1st entry LT -> lable jgt 1f / 2nd entry GT -> 1f cmp UL,UR jlos lable / 3rd entry ULE -> lable 1: */int lbranches[][3] = { /*EQ*/ 0, NE, EQ, /*NE*/ NE, 0, NE, /*LE*/ LT, GT, ULE, /*LT*/ LT, GT, ULT, /*GE*/ GT, LT, UGE, /*GT*/ GT, LT, UGT, /*ULE*/ ULT, UGT, ULE, /*ULT*/ ULT, UGT, ULT, /*UGE*/ UGT, ULT, UGE, /*UGT*/ UGT, ULT, UGT, };/* logical relations when compared in reverse order (cmp R,L) */extern short revrel[] ;cbgen( o, lab, mode ) { /* printf conditional and unconditional branches */ register *plb; int lab1f; if( o == 0 ) printf( " jbr L%d\n", lab ); else if( o > UGT ) cerror( "bad conditional branch: %s", opst[o] ); else { switch( brcase ) { case 'A': case 'C': plb = lbranches[ o-EQ ]; lab1f = getlab(); expand( brnode, FORCC, brcase=='C' ? "\tcmp\tAL,AR\n" : "\ttst\tAR\n" ); if( *plb != 0 ) printf( ccbranches[*plb-EQ], lab); if( *++plb != 0 ) printf( ccbranches[*plb-EQ], lab1f); expand( brnode, FORCC, brcase=='C' ? "\tcmp\tUL,UR\n" : "\ttst\tUR\n" ); printf( ccbranches[*++plb-EQ], lab); deflab( lab1f ); reclaim( brnode, RNULL, 0 ); break; default: if( mode=='F' ) o = revrel[ o-EQ ]; printf( ccbranches[o-EQ], lab ); break; } brcase = 0; brnode = 0; } }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->op) ) return( INTEMP|INAREG|INTAREG|INTBREG|INBREG ); return( FORREW ); }lastchance( p, cook ) NODE *p; { /* forget it! */ return(0); }struct functbl { int fop; TWORD ftype; char *func; } opfunc[] = { MUL, LONG, "lmul", DIV, LONG, "ldiv", MOD, LONG, "lrem", ASG MUL, LONG, "almul", ASG DIV, LONG, "aldiv", ASG MOD, LONG, "alrem", MUL, ULONG, "lmul", DIV, ULONG, "uldiv", MOD, ULONG, "ulrem", ASG MUL, ULONG, "almul", ASG DIV, ULONG, "auldiv", ASG MOD, ULONG, "aulrem", 0, 0, 0 };hardops(p) register NODE *p; { /* change hard to do operators into function calls. for pdp11 do long * / % */ register NODE *q; register struct functbl *f; register o; register TWORD t; o = p->op; t = p->type; if( t!=LONG && t!=ULONG ) return; for( f=opfunc; f->fop; f++ ) { if( o==f->fop && t==f->ftype ) goto convert; } return; /* need address of left node for ASG OP */ /* WARNING - this won't work for long in a REG */ convert: if( asgop( o ) ) { switch( p->left->op ) { case UNARY MUL: /* convert to address */ p->left->op = FREE; p->left = p->left->left; break; case NAME: /* convert to ICON pointer */ p->left->op = ICON; p->left->type = INCREF( p->left->type ); break; case OREG: /* convert OREG to address */ p->left->op = REG; p->left->type = INCREF( p->left->type ); if( p->left->lval != 0 ) { q = talloc(); q->op = PLUS; q->rall = NOPREF; q->type = p->left->type; q->left = p->left; q->right = talloc(); q->right->op = ICON; q->right->rall = NOPREF; q->right->type = INT; q->right->name[0] = '\0'; q->right->lval = p->left->lval; q->right->rval = 0; p->left->lval = 0; p->left = q; } break; default: cerror( "Bad address for hard ops" ); /* NO RETURN */ } } /* build comma op for args to function */ q = talloc(); q->op = CM; q->rall = NOPREF; q->type = INT; q->left = p->left; q->right = p->right; p->op = CALL; p->right = q; /* put function name in left node of call */ p->left = q = talloc(); q->op = ICON; q->rall = NOPREF; q->type = INCREF( FTN + p->type ); strcpy( q->name, f->func ); q->lval = 0; q->rval = 0; return; }optim2( p ) register NODE *p; { /* do local tree transformations and optimizations */ register NODE *r; switch( p->op ) { case AND: /* commute L and R to eliminate compliments and constants */ if( p->left->op==ICON || p->left->op==COMPL ) { r = p->left; p->left = p->right; p->right = r; } case ASG AND: /* change meaning of AND to ~R&L - bic on pdp11 */ r = p->right; if( r->op==ICON ) { /* compliment constant */ r->lval = ~r->lval; } else if( r->op==COMPL ) { /* ~~A => A */ r->op = FREE; p->right = r->left; } else { /* insert complement node */ p->right = talloc(); p->right->op = COMPL; p->right->rall = NOPREF; p->right->type = r->type; p->right->left = r; p->right->right = NULL; } break; } }myreader(p) register NODE *p; { walkf( p, hardops ); /* convert ops to function calls */ canon( p ); /* expands r-vals for fileds */ walkf( p, optim2 ); toff = 0; /* stack offset swindle */ }special( p, shape ) register NODE *p; { /* special shape matching routine */ switch( shape ) { case SCCON: if( p->op == ICON && p->name[0]=='\0' && p->lval>= -128 && p->lval <=127 ) return( 1 ); break; case SICON: if( p->op == ICON && p->name[0]=='\0' && p->lval>= 0 && p->lval <=32767 ) return( 1 ); break; default: cerror( "bad special shape" ); } return( 0 ); }# ifndef ONEPASSmain( argc, argv ) char *argv[]; { return( mainp2( argc, argv ) ); }# endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -