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