|
|
1.1 ! root 1: # include "mfile2" ! 2: ! 3: ! 4: int fldsz, fldshf; ! 5: ! 6: static int mamask[] = { /* masks for matching dope with shapes */ ! 7: SIMPFLG, /* OPSIMP */ ! 8: SIMPFLG|ASGFLG, /* ASG OPSIMP */ ! 9: COMMFLG, /* OPCOMM */ ! 10: COMMFLG|ASGFLG, /* ASG OPCOMM */ ! 11: MULFLG, /* OPMUL */ ! 12: MULFLG|ASGFLG, /* ASG OPMUL */ ! 13: DIVFLG, /* OPDIV */ ! 14: DIVFLG|ASGFLG, /* ASG OPDIV */ ! 15: UTYPE, /* OPUNARY */ ! 16: TYFLG, /* ASG OPUNARY is senseless */ ! 17: LTYPE, /* OPLEAF */ ! 18: TYFLG, /* ASG OPLEAF is senseless */ ! 19: 0, /* OPANY */ ! 20: ASGOPFLG|ASGFLG, /* ASG OPANY */ ! 21: LOGFLG, /* OPLOG */ ! 22: TYFLG, /* ASG OPLOG is senseless */ ! 23: FLOFLG, /* OPFLOAT */ ! 24: FLOFLG|ASGFLG, /* ASG OPFLOAT */ ! 25: SHFFLG, /* OPSHFT */ ! 26: SHFFLG|ASGFLG, /* ASG OPSHIFT */ ! 27: SPFLG, /* OPLTYPE */ ! 28: TYFLG, /* ASG OPLTYPE is senseless */ ! 29: }; ! 30: ! 31: int sdebug = 0; ! 32: ! 33: tshape( p, shape ) NODE *p; { ! 34: /* return true if shape is appropriate for the node p ! 35: side effect for SFLD is to set up fldsz,etc */ ! 36: register o, mask; ! 37: ! 38: o = p->op; ! 39: ! 40: if( sdebug ){ ! 41: printf( "tshape( %o, %o), op = %d\n", p, shape, o ); ! 42: } ! 43: ! 44: if( shape & SPECIAL ){ ! 45: ! 46: switch( shape ){ ! 47: ! 48: case SZERO: ! 49: case SONE: ! 50: case SMONE: ! 51: case SSCON: ! 52: case SCCON: ! 53: if( o != ICON || p->name[0] ) return(0); ! 54: if( p->lval == 0 && shape == SZERO ) return(1); ! 55: else if( p->lval == 1 && shape == SONE ) return(1); ! 56: else if( p->lval == -1 && shape == SMONE ) return(1); ! 57: else if( p->lval > -257 && p->lval < 256 && shape == SCCON ) return(1); ! 58: else if( p->lval > -32769 && p->lval < 32768 && shape == SSCON ) return(1); ! 59: else return(0); ! 60: ! 61: case SSOREG: /* non-indexed OREG */ ! 62: if( o == OREG && !R2TEST(p->rval) ) return(1); ! 63: else return(0); ! 64: ! 65: default: ! 66: return( special( p, shape ) ); ! 67: } ! 68: } ! 69: ! 70: if( shape & SANY ) return(1); ! 71: ! 72: if( (shape&INTEMP) && shtemp(p) ) return(1); ! 73: ! 74: if( (shape&SWADD) && (o==NAME||o==OREG) ){ ! 75: if( BYTEOFF(p->lval) ) return(0); ! 76: } ! 77: ! 78: switch( o ){ ! 79: ! 80: case NAME: ! 81: return( shape&SNAME ); ! 82: case ICON: ! 83: mask = SCON; ! 84: return( shape & mask ); ! 85: ! 86: case FLD: ! 87: if( shape & SFLD ){ ! 88: if( !flshape( p->left ) ) return(0); ! 89: /* it is a FIELD shape; make side-effects */ ! 90: o = p->rval; ! 91: fldsz = UPKFSZ(o); ! 92: # ifdef RTOLBYTES ! 93: fldshf = UPKFOFF(o); ! 94: # else ! 95: fldshf = SZINT - fldsz - UPKFOFF(o); ! 96: # endif ! 97: return(1); ! 98: } ! 99: return(0); ! 100: ! 101: case CCODES: ! 102: return( shape&SCC ); ! 103: ! 104: case REG: ! 105: /* distinctions: ! 106: SAREG any scalar register ! 107: STAREG any temporary scalar register ! 108: SBREG any lvalue (index) register ! 109: STBREG any temporary lvalue register ! 110: */ ! 111: mask = isbreg( p->rval ) ? SBREG : SAREG; ! 112: if( istreg( p->rval ) && busy[p->rval]<=1 ) mask |= mask==SAREG ? STAREG : STBREG; ! 113: return( shape & mask ); ! 114: ! 115: case OREG: ! 116: return( shape & SOREG ); ! 117: ! 118: case UNARY MUL: ! 119: /* return STARNM or STARREG or 0 */ ! 120: return( shumul(p->left) & shape ); ! 121: ! 122: } ! 123: ! 124: return(0); ! 125: } ! 126: ! 127: int tdebug = 0; ! 128: ! 129: ttype( t, tword ) TWORD t; { ! 130: /* does the type t match tword */ ! 131: ! 132: if( tword & TANY ) return(1); ! 133: ! 134: if( tdebug ){ ! 135: printf( "ttype( %o, %o )\n", t, tword ); ! 136: } ! 137: if( ISPTR(t) && (tword&TPTRTO) ) { ! 138: do { ! 139: t = DECREF(t); ! 140: } while ( ISARY(t) ); ! 141: /* arrays that are left are usually only ! 142: in structure references... */ ! 143: return( ttype( t, tword&(~TPTRTO) ) ); ! 144: } ! 145: if( t != BTYPE(t) ) return( tword & TPOINT ); /* TPOINT means not simple! */ ! 146: if( tword & TPTRTO ) return(0); ! 147: ! 148: switch( t ){ ! 149: ! 150: case CHAR: ! 151: return( tword & TCHAR ); ! 152: case SHORT: ! 153: return( tword & TSHORT ); ! 154: case STRTY: ! 155: case UNIONTY: ! 156: return( tword & TSTRUCT ); ! 157: case INT: ! 158: return( tword & TINT ); ! 159: case UNSIGNED: ! 160: return( tword & TUNSIGNED ); ! 161: case USHORT: ! 162: return( tword & TUSHORT ); ! 163: case UCHAR: ! 164: return( tword & TUCHAR ); ! 165: case ULONG: ! 166: return( tword & TULONG ); ! 167: case LONG: ! 168: return( tword & TLONG ); ! 169: case FLOAT: ! 170: return( tword & TFLOAT ); ! 171: case DOUBLE: ! 172: return( tword & TDOUBLE ); ! 173: } ! 174: ! 175: return(0); ! 176: } ! 177: ! 178: struct optab *rwtable; ! 179: ! 180: struct optab *opptr[DSIZE]; ! 181: ! 182: setrew(){ ! 183: /* set rwtable to first value which allows rewrite */ ! 184: register struct optab *q; ! 185: register int i; ! 186: ! 187: for( q = table; q->op != FREE; ++q ){ ! 188: if( q->needs == REWRITE ){ ! 189: rwtable = q; ! 190: goto more; ! 191: } ! 192: } ! 193: cerror( "bad setrew" ); ! 194: ! 195: ! 196: more: ! 197: for( i=0; i<DSIZE; ++i ){ ! 198: if( dope[i] ){ /* there is an op... */ ! 199: for( q=table; q->op != FREE; ++q ){ ! 200: /* beware; things like LTYPE that match ! 201: multiple things in the tree must ! 202: not try to look at the NIL at this ! 203: stage of things! Put something else ! 204: first in table.c */ ! 205: /* at one point, the operator matching was 15% of the ! 206: total comile time; thus, the function ! 207: call that was here was removed... ! 208: */ ! 209: ! 210: if( q->op < OPSIMP ){ ! 211: if( q->op==i ) break; ! 212: } ! 213: else { ! 214: register opmtemp; ! 215: if((opmtemp=mamask[q->op - OPSIMP])&SPFLG){ ! 216: if( i==NAME || i==ICON || i==OREG ) break; ! 217: else if( shltype( i, NIL ) ) break; ! 218: } ! 219: else if( (dope[i]&(opmtemp|ASGFLG)) == opmtemp ) break; ! 220: } ! 221: } ! 222: opptr[i] = q; ! 223: } ! 224: } ! 225: } ! 226: ! 227: match( p, cookie ) NODE *p; { ! 228: /* called by: order, gencall ! 229: look for match in table and generate code if found unless ! 230: entry specified REWRITE. ! 231: returns MDONE, MNOPE, or rewrite specification from table */ ! 232: ! 233: register struct optab *q; ! 234: register NODE *r; ! 235: ! 236: rcount(); ! 237: if( cookie == FORREW ) q = rwtable; ! 238: else q = opptr[p->op]; ! 239: ! 240: for( ; q->op != FREE; ++q ){ ! 241: ! 242: /* at one point the call that was here was over 15% of the total time; ! 243: thus the function call was expanded inline */ ! 244: if( q->op < OPSIMP ){ ! 245: if( q->op!=p->op ) continue; ! 246: } ! 247: else { ! 248: register opmtemp; ! 249: if((opmtemp=mamask[q->op - OPSIMP])&SPFLG){ ! 250: if( p->op!=NAME && p->op!=ICON && p->op!= OREG && ! 251: ! shltype( p->op, p ) ) continue; ! 252: } ! 253: else if( (dope[p->op]&(opmtemp|ASGFLG)) != opmtemp ) continue; ! 254: } ! 255: ! 256: if( !(q->visit & cookie ) ) continue; ! 257: r = getlr( p, 'L' ); /* see if left child matches */ ! 258: if( !tshape( r, q->lshape ) ) continue; ! 259: if( !ttype( r->type, q->ltype ) ) continue; ! 260: r = getlr( p, 'R' ); /* see if right child matches */ ! 261: if( !tshape( r, q->rshape ) ) continue; ! 262: if( !ttype( r->type, q->rtype ) ) continue; ! 263: ! 264: /* REWRITE means no code from this match but go ahead ! 265: and rewrite node to help future match */ ! 266: if( q->needs & REWRITE ) return( q->rewrite ); ! 267: if( !allo( p, q ) ) continue; /* if can't generate code, skip entry */ ! 268: ! 269: /* resources are available */ ! 270: ! 271: expand( p, cookie, q->cstring ); /* generate code */ ! 272: reclaim( p, q->rewrite, cookie ); ! 273: ! 274: return(MDONE); ! 275: ! 276: } ! 277: ! 278: return(MNOPE); ! 279: } ! 280: ! 281: expand( p, cookie, cp ) NODE *p; register char *cp; { ! 282: /* generate code by interpreting table entry */ ! 283: ! 284: CONSZ val; ! 285: ! 286: for( ; *cp; ++cp ){ ! 287: switch( *cp ){ ! 288: ! 289: default: ! 290: PUTCHAR( *cp ); ! 291: continue; /* this is the usual case... */ ! 292: ! 293: case 'Z': /* special machine dependent operations */ ! 294: zzzcode( p, *++cp ); ! 295: continue; ! 296: ! 297: case 'F': /* this line deleted if FOREFF is active */ ! 298: if( cookie & FOREFF ) while( *++cp != '\n' ) ; /* VOID */ ! 299: continue; ! 300: ! 301: case 'S': /* field size */ ! 302: printf( "$%d", fldsz ); ! 303: continue; ! 304: ! 305: case 'H': /* field shift */ ! 306: printf( "$%d", fldshf ); ! 307: continue; ! 308: ! 309: case 'M': /* field mask */ ! 310: case 'N': /* complement of field mask */ ! 311: val = 1; ! 312: val <<= fldsz; ! 313: --val; ! 314: val <<= fldshf; ! 315: adrcon( *cp=='M' ? val : ~val ); ! 316: continue; ! 317: ! 318: case 'L': /* output special label field */ ! 319: printf( "%d", p->label ); ! 320: continue; ! 321: ! 322: case 'O': /* opcode string */ ! 323: hopcode( *++cp, p->op ); ! 324: continue; ! 325: ! 326: case 'B': /* byte offset in word */ ! 327: val = getlr(p,*++cp)->lval; ! 328: val = BYTEOFF(val); ! 329: printf( CONFMT, val ); ! 330: continue; ! 331: ! 332: case 'C': /* for constant value only */ ! 333: conput( getlr( p, *++cp ) ); ! 334: continue; ! 335: ! 336: case 'I': /* in instruction */ ! 337: insput( getlr( p, *++cp ) ); ! 338: continue; ! 339: ! 340: case 'A': /* address of */ ! 341: adrput( getlr( p, *++cp ) ); ! 342: continue; ! 343: ! 344: case 'U': /* for upper half of address, only */ ! 345: upput( getlr( p, *++cp ) ); ! 346: continue; ! 347: ! 348: } ! 349: ! 350: } ! 351: ! 352: } ! 353: ! 354: NODE * ! 355: getlr( p, c ) NODE *p; { ! 356: ! 357: /* return the pointer to the left or right side of p, or p itself, ! 358: depending on the optype of p */ ! 359: ! 360: switch( c ) { ! 361: ! 362: case '1': ! 363: case '2': ! 364: case '3': ! 365: return( &resc[c-'1'] ); ! 366: ! 367: case 'L': ! 368: return( optype( p->op ) == LTYPE ? p : p->left ); ! 369: ! 370: case 'R': ! 371: return( optype( p->op ) != BITYPE ? p : p->right ); ! 372: ! 373: } ! 374: cerror( "bad getlr: %c", c ); ! 375: /* NOTREACHED */ ! 376: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.