📄 local2.c
字号:
s = talloc(); rt = r->in.type; s->in.op = SCONV; s->in.left = l; s->in.type = rt; zzzcode(s, 'A'); putstr("\n\t"); hopcode(rt == FLOAT ? 'F' : 'D', p->in.op); putstr("2\t"); adrput(r); putchar(','); adrput(resc); putstr("\n\t"); s->in.op = ASSIGN; s->in.left = l; s->in.right = resc; s->in.type = l->in.type; zzzcode(s, 'A'); s->in.op = FREE; return; } case 'B': /* get oreg value in temp register for left shift */ { register NODE *r; if (xdebug) eprint(p, 0, &val, &val); r = p->in.right; if( tlen(r) == sizeof(int) && r->in.type != FLOAT ) putstr("movl"); else { putstr("cvt"); prtype(r); putchar('l'); } return; } case 'C': /* num words pushed on arg stack */ { extern int gc_numbytes; extern int xdebug; if (xdebug) printf("->%d<-",gc_numbytes); printf("$%d", gc_numbytes/(SZLONG/SZCHAR) ); return; } case 'D': /* INCR and DECR */ zzzcode(p->in.left, 'A'); putchar('\n'); putchar('\t'); case 'E': /* INCR and DECR, FOREFF */ if (p->in.right->tn.lval == 1) { putstr( p->in.op == INCR ? "inc" : "dec" ); prtype(p->in.left); putchar('\t'); adrput(p->in.left); return; } putstr( p->in.op == INCR ? "add" : "sub" ); prtype(p->in.left); putchar('2'); putchar('\t'); adrput(p->in.right); putchar(','); adrput(p->in.left); return; case 'F': /* register type of right operand */ { register NODE *n; extern int xdebug; register int ty; n = getlr( p, 'R' ); ty = n->in.type; if (xdebug) printf("->%d<-", ty); if ( ty==DOUBLE) { /* * If -M flag is set then use gfloat suffix * */ if ( Mflag ) /* slr001 */ putchar('g'); /* slr001 */ else /* slr001 */ putchar('d'); /* slr001 */ } else if ( ty==FLOAT ) putchar('f'); else putchar('l'); return; } case 'L': /* type of left operand */ case 'R': /* type of right operand */ { register NODE *n; extern int xdebug; n = getlr( p, c ); if (xdebug) printf("->%d<-", n->in.type); prtype(n); return; } case 'Z': /* complement mask for bit instr */ printf("$%ld", ~p->in.right->tn.lval); return; case 'U': /* 32 - n, for unsigned right shifts */ printf("$%d", 32 - p->in.right->tn.lval ); return; case 'T': /* rounded structure length for arguments */ { int size; size = p->stn.stsize; SETOFF( size, 4); printf("$%d", size); return; } case 'S': /* structure assignment */ { register NODE *l, *r; register size; if( p->in.op == STASG ){ l = p->in.left; r = p->in.right; } else if( p->in.op == STARG ){ /* store an arg into a temporary */ l = getlr( p, '3' ); r = p->in.left; } else cerror( "STASG bad" ); if( r->in.op == ICON ) r->in.op = NAME; else if( r->in.op == REG ) r->in.op = OREG; else if( r->in.op != OREG ) cerror( "STASG-r" ); size = p->stn.stsize; if( size <= 0 || size > 65535 ) cerror("structure size <0=0 or >65535"); switch(size) { case 1: putstr(" movb "); break; case 2: putstr(" movw "); break; case 4: putstr(" movl "); break; case 8: putstr(" movq "); break; default: printf(" movc3 $%d,", size); break; } adrput(r); putchar(','); adrput(l); putchar('\n'); if( r->in.op == NAME ) r->in.op = ICON; else if( r->in.op == OREG ) r->in.op = REG; } break; case 'V': /* slr001 Data type used for float instruction */ /* * If Mflag is set it indicates that gfloat instruction * are wanted * */ if ( Mflag ) /* slr001 */ putchar('g'); /* slr001 */ else /* slr001 */ putchar('d'); /* slr001 */ break; /* slr001 */ case 'W': /* vdp004 Data type used for float instruction either * f, d, or g. * If Mflag is set it indicates that gfloat instruction * are wanted * If fflag is set it indicates that floating point * arithmetic should be done in float. * */ if (fflag) /* call prtype to give it a chance to print * out float vdp04 */ prtype(p) ; /* vdp004 */ else if ( Mflag ) /* vdp004 */ putchar('g'); /* vdp004 */ else /* vdp004 */ putchar('d'); /* vdp004 */ break; /* vdp004 */ default: cerror( "illegal zzzcode" ); } }/* * collapsible(dest, src) -- if a conversion with a register destination * can be accomplished in one instruction, return the type of src * that will do the job correctly; otherwise return 0. Note that * a register must always end up having type INT or UNSIGNED. */intcollapsible(dest, src)NODE *dest, *src;{ int st = src->in.type; int dt = dest->in.type; int newt = 0; /* * Are there side effects of evaluating src? * If the derived type will not be the same size as src, * we may have to use two steps. */ if (tlen(src) > tlen(dest)) { if (tshape(src, STARREG)) return (0); if (src->in.op == OREG && R2TEST(src->tn.rval)) return (0); } /* * Can we get an object of dest's type by punning src? * Praises be to great Cthulhu for little-endian machines... */ if (st == CHAR && dt == USHORT) /* * Special case -- we must sign-extend to 16 bits. */ return (0); if (tlen(src) < tlen(dest)) newt = st; else newt = dt; return (newt); }rmove( rt, rs, t ) TWORD t; { printf( " %s %s,%s\n",#ifdef FORT !Oflag ? (t==DOUBLE ? "movq" : "movl") :#endif (t==FLOAT ? "movf" : /* slr001 */ (t==DOUBLE ? ( Mflag ? "movg" : "movd" ) : "movl")), rnames[rs], rnames[rt] ); }struct resprefrespref[] = { INTAREG|INTBREG, INTAREG|INTBREG, INAREG|INBREG, INAREG|INBREG|SOREG|STARREG|STARNM|SNAME|SCON, INTEMP, INTEMP, FORARG, FORARG, INTEMP, INTAREG|INAREG|INTBREG|INBREG|SOREG|STARREG|STARNM, 0, 0 };setregs(){ /* set up temporary registers */ fregs = 6; /* tbl- 6 free regs on VAX (0-5) */ ; }szty(t){ /* size, in registers, needed to hold thing of type t *vdp004 for f floats with fflag only need 1 register */ if (fflag) return ( (t==DOUBLE) ? 2 : 1 ); else return( (t==DOUBLE||t==FLOAT) ? 2 : 1 ); }rewfld( p ) NODE *p; { return(1); }callreg(p) NODE *p; { return( R0 ); }base( p ) register NODE *p; { register int o = p->in.op; if( (o==ICON && p->in.name[0] != '\0')) return( 100 ); /* ie no base reg */ if( o==REG ) return( p->tn.rval ); if( (o==PLUS || o==MINUS) && p->in.left->in.op == REG && p->in.right->in.op==ICON) return( p->in.left->tn.rval ); if( o==OREG && !R2TEST(p->tn.rval) && (p->in.type==INT || p->in.type==UNSIGNED || ISPTR(p->in.type)) ) return( p->tn.rval + 0200*1 ); if( o==INCR && p->in.left->in.op==REG ) return( p->in.left->tn.rval + 0200*2 ); if( o==ASG MINUS && p->in.left->in.op==REG) return( p->in.left->tn.rval + 0200*4 ); if( o==UNARY MUL && p->in.left->in.op==INCR && p->in.left->in.left->in.op==REG && (p->in.type==INT || p->in.type==UNSIGNED || ISPTR(p->in.type)) ) return( p->in.left->in.left->tn.rval + 0200*(1+2) ); return( -1 ); }offset( p, tyl ) register NODE *p; int tyl; { if( tyl==1 && p->in.op==REG && (p->in.type==INT || p->in.type==UNSIGNED) ) return( p->tn.rval ); if( p->in.op==LS && p->in.left->in.op==REG && (p->in.left->in.type==INT || p->in.left->in.type==UNSIGNED) && p->in.right->in.op==ICON && p->in.right->in.name[0]=='\0' && (1<<p->in.right->tn.lval)==tyl) return( p->in.left->tn.rval ); return( -1 ); }makeor2( p, q, b, o) register NODE *p, *q; register int b, o; { register NODE *t; register int i; NODE *f; p->in.op = OREG; f = p->in.left; /* have to free this subtree later */ /* init base */ switch (q->in.op) { case ICON: case REG: case OREG: t = q; break; case MINUS: q->in.right->tn.lval = -q->in.right->tn.lval; case PLUS: t = q->in.right; break; case INCR: case ASG MINUS: t = q->in.left; break; case UNARY MUL: t = q->in.left->in.left; break; default: cerror("illegal makeor2"); } p->tn.lval = t->tn.lval;#ifndef FLEXNAMES for(i=0; i<NCHNAM; ++i) p->in.name[i] = t->in.name[i];#else p->in.name = t->in.name;#endif /* init offset */ p->tn.rval = R2PACK( (b & 0177), o, (b>>7) ); tfree(f); return; }canaddr( p ) NODE *p; { register int o = p->in.op; if( o==NAME || o==REG || o==ICON || o==OREG || (o==UNARY MUL && shumul(p->in.left)) ) return(1); return(0); }shltype( o, p ) register NODE *p; { return( o== REG || o == NAME || o == ICON || o == OREG || ( o==UNARY MUL && shumul(p->in.left)) ); }flshape( p ) register NODE *p; { return( p->in.op == REG || p->in.op == NAME || p->in.op == ICON || (p->in.op == OREG && (!R2TEST(p->tn.rval) || tlen(p) == 1)) ); }shtemp( p ) register NODE *p; { if( p->in.op == STARG ) p = p->in.left; return( p->in.op==NAME || p->in.op ==ICON || p->in.op == OREG || (p->in.op==UNARY MUL && shumul(p->in.left)) ); }shumul( p ) register NODE *p; { register o; extern int xdebug; if (xdebug) { printf("\nshumul:op=%d,lop=%d,rop=%d", p->in.op, p->in.left->in.op, p->in.right->in.op); printf(" prname=%s,plty=%d, prlval=%D\n", p->in.right->in.name, p->in.left->in.type, p->in.right->tn.lval); } o = p->in.op; if( o == NAME || (o == OREG && !R2TEST(p->tn.rval)) || o == ICON ) return( STARNM ); if( ( o == INCR || o == ASG MINUS ) && ( p->in.left->in.op == REG && p->in.right->in.op == ICON ) && p->in.right->in.name[0] == '\0' ) { switch (p->in.type) { case CHAR|PTR: case UCHAR|PTR: o = 1; break; case SHORT|PTR: case USHORT|PTR: o = 2; break; case INT|PTR: case UNSIGNED|PTR: case LONG|PTR: case ULONG|PTR: case FLOAT|PTR: o = 4; break; case DOUBLE|PTR: o = 8; break; default: /* * To fix the problem when the increment * of a structure class is a register * and is part of a condition test. */ if ( (ISPTR(p->in.left->in.type)) && /*RAP003*/ (p->in.type == p->in.left->in.type)) { o = p->in.right->tn.lval; if (o==1|o==2|o==4|o==8) return(STARREG); } return(0); } return( p->in.right->tn.lval == o ? STARREG : 0); } return( 0 ); }adrcon( val ) CONSZ val; { putchar( '$' ); printf( CONFMT, val ); }conput( p ) register NODE *p; { switch( p->in.op ){ case ICON: acon( p );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -