📄 local2.c
字号:
# include "mfile2"/* a lot of the machine dependent parts of the second pass */# define BITMASK(n) ((1L<<n)-1)lineid( l, fn ) char *fn; { /* identify line l and file fn */ printf( "/ line %d, file %s\n", l, fn ); }eobl2(){ OFFSZ spoff; /* offset from stack pointer */ spoff = maxoff; if( spoff >= AUTOINIT ) spoff -= AUTOINIT; spoff /= SZCHAR; SETOFF(spoff,2); printf( " .F%d = %Ld.\n", ftnno, spoff ); if( fltused ) { fltused = 0; printf( " .globl fltused\n" ); } }struct hoptab { int opmask; char * opstring; } ioptab[]= { ASG PLUS, "add", ASG MINUS, "sub", ASG OR, "bis", ASG AND, "bic", ASG ER, "xor", ASG MUL, "mul", ASG DIV, "div", ASG MOD, "div", ASG LS, "asl", ASG RS, "asr", -1, "" };hopcode( f, o ){ /* output the appropriate string from the above table */ register struct hoptab *q; for( q = ioptab; q->opmask>=0; ++q ){ if( q->opmask == o ){ printf( "%s", q->opstring ); if( f == 'F' ) printf( "f" ); return; } } cerror( "no hoptab for %s", opst[o] ); }char *rnames[]= { /* keyed to register number tokens */ "r0", "r1", "r2", "r3", "r4", "r5", "sp", "pc", "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", /* not accumulators - used for temps */ };int rstatus[] = { SAREG|STAREG, SAREG|STAREG, SAREG|STAREG, SAREG|STAREG, SAREG|STAREG, /* use as scratch if not reg var */ SAREG, SAREG, SAREG, SBREG|STBREG, SBREG|STBREG, SBREG|STBREG, SBREG|STBREG, SBREG, SBREG, };NODE *brnode;int brcase;int toff = 0; /* number of stack locations used for args */zzzcode( p, c ) NODE *p; { register m; switch( c ){ case 'B': /* output b if type is byte */ if( p->type == CHAR || p->type == UCHAR ) printf( "b" ); return; case 'N': /* logical ops, turned into 0-1 */ /* use register given by register 1 */ cbgen( 0, m=getlab(), 'I' ); deflab( p->label ); printf( " clr %s\n", rnames[getlr( p, '1' )->rval] ); if( p->type == LONG || p->type == ULONG ) printf( " clr %s\n", rnames[getlr( p, '1' )->rval + 1] ); deflab( m ); return; case 'I': case 'F': cbgen( p->op, p->label, c ); return; case 'A': case 'C': /* logical operators for longs defer comparisons until branch occurs */ brnode = tcopy( p ); brcase = c; return; case 'H': /* fix up unsigned shifts */ { register NODE *q; register r, l; TWORD t; if( p->op == ASG LS ) return; if( p->op != ASG RS ) cerror( "ZH bad" ); if( p->left->op != REG ) cerror( "SH left bad" ); r = p->left->rval; t = p->left->type; l = (t==LONG || t == ULONG ); if( t != UNSIGNED && t != UCHAR && t != ULONG ) return; /* signed is ok */ /* there are three cases: right side is a constant, and has the shift value; right side is a temporary reg, and has the - shift value, and right side is something else: A1 has the - shift value then */ /* in the case where the value is known (rhs a constant), the mask is just computed and put out... */ if( p->right->op == ICON ){ int s; s = p->right->lval; if( l ){ if( s >= 16 ){ printf( " clr r%d\n", r ); s -= 16; ++r; } } if( s >= 16 ) printf( " clr r%d\n", r ); else { m = 0100000; m >>= s; /* sign extends... */ m <<= 1; printf( " bic $%o,r%d\n", m, r ); } return; } /* general case */ if( istnode( p->right ) ) q = p->right; else q = getlr( p, '1' ); /* where -shift is stored */ /* first, we store the shifted value on the stack */ printf( " mov r%d,-(sp)\n", r ); if( l ) printf( " mov r%d,-(sp)\n", r+1 ); /* now, make a mask */ printf( " mov $100000,r%d\n", r ); if( l ) printf( " clr r%d\n", r+1 ); /* shift (arithmetically ) */ if( l ) expand( q, RNOP, " ashc AR" ); else expand( q, RNOP, " ash AR" ); printf( ",r%d\n", r ); if( l ) printf( " ashc $1,r%d\n", r ); else printf( " asl r%d\n", r ); /* now, we have a mask: use it to clear sp, and reload */ if( l ){ printf( "\tbic\tr%d,(sp)\n\tmov\t(sp)+,r%d\n", r+1, r+1 ); } printf( "\tbic\tr%d,(sp)\n\tmov\t(sp)+,r%d\n", r, r ); /* whew! */ return; } case 'V': /* sign extend or not -- register is one less than the left descendent */ m = p->left->rval - 1; if( ISUNSIGNED(p->type) ){ printf( " clr r%d\n", m ); } else { printf( " sxt r%d\n", m ); } return; /* stack management macros */ case '-': if( toff ++ ) printf( "-" ); printf( "(sp)" ); return; case '4': if( toff == 0 ) ++toff; /* can't push doubles that way */ printf( "-(sp)" ); toff += 4; return; case '~': /* complimented CR */ p->right->lval = ~p->right->lval; conput( getlr( p, 'R' ) ); p->right->lval = ~p->right->lval; return; case 'M': /* negated CR */ p->right->lval = -p->right->lval; conput( getlr( p, 'R' ) ); p->right->lval = -p->right->lval; return; case 'L': /* INIT for long constants */ { unsigned hi, lo; lo = p->left->lval & BITMASK(SZINT); hi = ( p->left->lval >> SZINT ) & BITMASK(SZINT); printf( " %o; %o\n", hi, lo ); return; } case 'T': /* Truncate longs for type conversions: LONG|ULONG -> CHAR|UCHAR|INT|UNSIGNED increment offset to second word */ m = p->type; p = p->left; switch( p->op ){ case NAME: case OREG: p->lval += SZINT/SZCHAR; return; case REG: rfree( p->rval, p->type ); p->rval += 1; p->type = m; rbusy( p->rval, p->type ); return; default: cerror( "Illegal ZT type conversion" ); return; } case 'U': /* same as AL for exp under U* */ if( p->left->op == UNARY MUL ) { adrput( getlr( p->left, 'L' ) ); return; } cerror( "Illegal ZU" ); /* NO RETURN */ case 'W': /* structure size */ if( p->op == STASG ) printf( "%d", p->stsize); else cerror( "Not a structure" ); return; case 'S': /* structure assignment */ { register NODE *l, *r; register size, count; if( p->op == STASG ){ l = p->left; r = p->right; } else if( p->op == STARG ){ /* store an arg onto the stack */ r = p->left; } else cerror( "STASG bad" ); if( r->op == ICON ) r->op = NAME; else if( r->op == REG ) r->op = OREG; else if( r->op != OREG ) cerror( "STASG-r" ); size = p->stsize; count = size / 2; r->lval += size; if( p->op == STASG ) l->lval += size; while( count-- ){ /* simple load/store loop */ r->lval -= 2; expand( r, FOREFF, " mov AR," ); if( p->op == STASG ){ l->lval -= 2; expand( l, FOREFF, "AR\n" ); } else { printf( "-(sp)\n" ); } } if( r->op == NAME ) r->op = ICON; else if( r->op == OREG ) r->op = REG; } break; default: cerror( "illegal zzzcode" ); } }rmove( rt, rs, t ) TWORD t; { printf( " %s %s,%s\n", (t==FLOAT||t==DOUBLE)?"movf":"mov", rnames[rs], rnames[rt] ); }struct resprefrespref[] = { INTAREG|INTBREG, INTAREG|INTBREG, INAREG|INBREG, INAREG|INBREG|SOREG|STARREG|SNAME|STARNM|SCON, INTEMP, INTEMP, FORARG, FORARG, INTAREG, SOREG|SNAME, 0, 0 };setregs(){ /* set up temporary registers */ register i; /* use any unused variable registers as scratch registers */ fregs = maxtreg>=MINRVAR ? maxtreg + 1 : MINRVAR; if( xdebug ){ /* -x changes number of free regs to 2, -xx to 3, etc. */ if( (xdebug+1) < fregs ) fregs = xdebug+1; } /* NOTE: for pdp11 fregs <= 4 for float regs */ if( fregs > 4 ) fregs = 4; for( i=MINRVAR; i<=MAXRVAR; i++ ) rstatus[i] = i<fregs ? SAREG|STAREG : SAREG; }szty(t) TWORD t; { /* size, in words, needed to hold thing of type t */ /* really is the number of registers to hold type t */ switch( t ) { case LONG: case ULONG: return( SZLONG/SZINT ); default: return(1); } }rewfld( p ) NODE *p; { return(1); }callreg(p) NODE *p; { return( (p->type==DOUBLE||p->type==FLOAT) ? FR0 : R0 ); }shltype( o, p ) NODE *p; { if( o == NAME|| o==REG || o == ICON || o == OREG ) return( 1 ); return( o==UNARY MUL && shumul(p->left) ); }flshape( p ) register NODE *p; { register o = p->op; if( o==NAME || o==REG || o==ICON || o==OREG ) return( 1 ); return( o==UNARY MUL && shumul(p->left)==STARNM ); }shtemp( p ) register NODE *p; { if( p->op == UNARY MUL ) p = p->left; if( p->op == REG || p->op == OREG ) return( !istreg( p->rval ) ); return( p->op == NAME || p->op == ICON ); }spsz( t, v ) TWORD t; CONSZ v; { /* is v the size to increment something of type t */ if( !ISPTR(t) ) return( 0 ); t = DECREF(t); if( ISPTR(t) ) return( v == 2 ); switch( t ){ case UCHAR: case CHAR: return( v == 1 ); case INT: case UNSIGNED: return( v == 2 ); case FLOAT: return( v == 4 ); case DOUBLE: return( v == 8 ); } return( 0 ); }shumul( p ) register NODE *p; { register o; o = p->op; if( o == NAME || o == OREG || o == ICON ) return( STARNM ); if( ( o == INCR || o == ASG MINUS ) && ( p->left->op == REG && p->right->op == ICON ) && p->right->name[0] == '\0' && spsz( p->left->type, p->right->lval ) ) return( STARREG ); return( 0 ); }adrcon( val ) CONSZ val; { printf( CONFMT, val ); }conput( p ) register NODE *p; { switch( p->op ){ case ICON: acon( p ); return; case REG: printf( "%s", rnames[p->rval] ); return; default: cerror( "illegal conput" ); } }insput( p ) NODE *p; { cerror( "insput" ); }upput( p ) NODE *p; { /* output the address of the second word in the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -