|
|
1.1 ! root 1: # include "mfile2" ! 2: ! 3: # ifdef WCARD1 ! 4: # ifdef WCARD2 ! 5: # define NOINDIRECT ! 6: # endif ! 7: # endif ! 8: ! 9: extern vdebug; ! 10: ! 11: int fldsz, fldshf; ! 12: ! 13: static int mamask[] = { /* masks for matching dope with shapes */ ! 14: SIMPFLG, /* OPSIMP */ ! 15: SIMPFLG|ASGFLG, /* ASG OPSIMP */ ! 16: COMMFLG, /* OPCOMM */ ! 17: COMMFLG|ASGFLG, /* ASG OPCOMM */ ! 18: MULFLG, /* OPMUL */ ! 19: MULFLG|ASGFLG, /* ASG OPMUL */ ! 20: DIVFLG, /* OPDIV */ ! 21: DIVFLG|ASGFLG, /* ASG OPDIV */ ! 22: UTYPE, /* OPUNARY */ ! 23: TYFLG, /* ASG OPUNARY is senseless */ ! 24: LTYPE, /* OPLEAF */ ! 25: TYFLG, /* ASG OPLEAF is senseless */ ! 26: 0, /* OPANY */ ! 27: ASGOPFLG|ASGFLG, /* ASG OPANY */ ! 28: LOGFLG, /* OPLOG */ ! 29: TYFLG, /* ASG OPLOG is senseless */ ! 30: FLOFLG, /* OPFLOAT */ ! 31: FLOFLG|ASGFLG, /* ASG OPFLOAT */ ! 32: SHFFLG, /* OPSHFT */ ! 33: SHFFLG|ASGFLG, /* ASG OPSHIFT */ ! 34: SPFLG, /* OPLTYPE */ ! 35: TYFLG, /* ASG OPLTYPE is senseless */ ! 36: }; ! 37: ! 38: int sdebug = 0; ! 39: ! 40: tshape( p, shape ) NODE *p; { ! 41: /* return true if shape is appropriate for the node p ! 42: side effect for SFLD is to set up fldsz,etc */ ! 43: register o, mask; ! 44: ! 45: o = p->in.op; ! 46: ! 47: # ifndef BUG3 ! 48: if( sdebug ){ ! 49: printf( "tshape( %o, %o), op = %d\n", p, shape, o ); ! 50: } ! 51: # endif ! 52: ! 53: if( shape & SPECIAL ){ ! 54: ! 55: switch( shape ){ ! 56: ! 57: case SZERO: ! 58: case SONE: ! 59: case SMONE: ! 60: case SSCON: ! 61: case SCCON: ! 62: if( o != ICON || p->in.name[0] ) return(0); ! 63: if( p->tn.lval == 0 && shape == SZERO ) return(1); ! 64: else if( p->tn.lval == 1 && shape == SONE ) return(1); ! 65: else if( p->tn.lval == -1 && shape == SMONE ) return(1); ! 66: else if( p->tn.lval > -129 && p->tn.lval < 128 && shape == SCCON ) return(1); ! 67: else if( p->tn.lval > -32769 && p->tn.lval < 32768 && shape == SSCON ) return(1); ! 68: else return(0); ! 69: ! 70: case SSOREG: /* non-indexed OREG */ ! 71: if( o == OREG && !R2TEST(p->tn.rval) ) return(1); ! 72: else return(0); ! 73: ! 74: default: ! 75: # ifdef MULTILEVEL ! 76: if( shape & MULTILEVEL ) ! 77: return( mlmatch(p,shape,0) ); ! 78: else ! 79: # endif ! 80: return( special( p, shape ) ); ! 81: } ! 82: } ! 83: ! 84: if( shape & SANY ) return(1); ! 85: ! 86: if( (shape&INTEMP) && shtemp(p) ) return(1); ! 87: ! 88: if( (shape&SWADD) && (o==NAME||o==OREG) ){ ! 89: if( BYTEOFF(p->tn.lval) ) return(0); ! 90: } ! 91: ! 92: # ifdef WCARD1 ! 93: if( shape & WCARD1 ) ! 94: return( wcard1(p) & shape ); ! 95: # endif ! 96: ! 97: # ifdef WCARD2 ! 98: if( shape & WCARD2 ) ! 99: return( wcard2(p) & shape ); ! 100: # endif ! 101: switch( o ){ ! 102: ! 103: case NAME: ! 104: return( shape&SNAME ); ! 105: case ICON: ! 106: mask = SCON; ! 107: return( shape & mask ); ! 108: ! 109: case FLD: ! 110: if( shape & SFLD ){ ! 111: if( !flshape( p->in.left ) ) return(0); ! 112: /* it is a FIELD shape; make side-effects */ ! 113: o = p->tn.rval; ! 114: fldsz = UPKFSZ(o); ! 115: # ifdef RTOLBYTES ! 116: fldshf = UPKFOFF(o); ! 117: # else ! 118: fldshf = SZINT - fldsz - UPKFOFF(o); ! 119: # endif ! 120: return(1); ! 121: } ! 122: return(0); ! 123: ! 124: case CCODES: ! 125: return( shape&SCC ); ! 126: ! 127: case REG: ! 128: /* distinctions: ! 129: SAREG any scalar register ! 130: STAREG any temporary scalar register ! 131: SBREG any lvalue (index) register ! 132: STBREG any temporary lvalue register ! 133: */ ! 134: mask = isbreg( p->tn.rval ) ? SBREG : SAREG; ! 135: if( istreg( p->tn.rval ) && busy[p->tn.rval]<=1 ) mask |= mask==SAREG ? STAREG : STBREG; ! 136: return( shape & mask ); ! 137: ! 138: case OREG: ! 139: return( shape & SOREG ); ! 140: ! 141: # ifndef NOINDIRECT ! 142: case UNARY MUL: ! 143: /* return STARNM or STARREG or 0 */ ! 144: return( shumul(p->in.left) & shape ); ! 145: # endif ! 146: ! 147: } ! 148: ! 149: return(0); ! 150: } ! 151: ! 152: int tdebug = 0; ! 153: ! 154: ttype( t, tword ) TWORD t; { ! 155: /* does the type t match tword */ ! 156: ! 157: if( tword & TANY ) return(1); ! 158: ! 159: if( t == UNDEF ) t=INT; /* void functions eased thru tables */ ! 160: # ifndef BUG3 ! 161: if( tdebug ){ ! 162: printf( "ttype( %o, %o )\n", t, tword ); ! 163: } ! 164: # endif ! 165: if( ISPTR(t) && (tword&TPTRTO) ) { ! 166: do { ! 167: t = DECREF(t); ! 168: } while ( ISARY(t) ); ! 169: /* arrays that are left are usually only ! 170: in structure references... */ ! 171: return( ttype( t, tword&(~TPTRTO) ) ); ! 172: } ! 173: if( t != BTYPE(t) ) return( tword & TPOINT ); /* TPOINT means not simple! */ ! 174: if( tword & TPTRTO ) return(0); ! 175: ! 176: switch( t ){ ! 177: ! 178: case CHAR: ! 179: return( tword & TCHAR ); ! 180: case SHORT: ! 181: return( tword & TSHORT ); ! 182: case STRTY: ! 183: case UNIONTY: ! 184: return( tword & TSTRUCT ); ! 185: case INT: ! 186: return( tword & TINT ); ! 187: case UNSIGNED: ! 188: return( tword & TUNSIGNED ); ! 189: case USHORT: ! 190: return( tword & TUSHORT ); ! 191: case UCHAR: ! 192: return( tword & TUCHAR ); ! 193: case ULONG: ! 194: return( tword & TULONG ); ! 195: case LONG: ! 196: return( tword & TLONG ); ! 197: case FLOAT: ! 198: return( tword & TFLOAT ); ! 199: case DOUBLE: ! 200: return( tword & TDOUBLE ); ! 201: } ! 202: ! 203: return(0); ! 204: } ! 205: ! 206: struct optab *rwtable; ! 207: ! 208: struct optab *opptr[DSIZE]; ! 209: ! 210: setrew(){ ! 211: /* set rwtable to first value which allows rewrite */ ! 212: register struct optab *q; ! 213: register int i; ! 214: ! 215: # ifdef MULTILEVEL ! 216: /* also initialize multi-level tree links */ ! 217: mlinit(); ! 218: # endif ! 219: ! 220: for( q = table; q->op != FREE; ++q ){ ! 221: if( q->needs == REWRITE ){ ! 222: rwtable = q; ! 223: goto more; ! 224: } ! 225: } ! 226: cerror( "bad setrew" ); ! 227: ! 228: ! 229: more: ! 230: for( i=0; i<DSIZE; ++i ){ ! 231: if( dope[i] ){ /* there is an op... */ ! 232: for( q=table; q->op != FREE; ++q ){ ! 233: /* beware; things like LTYPE that match ! 234: multiple things in the tree must ! 235: not try to look at the NIL at this ! 236: stage of things! Put something else ! 237: first in table.c */ ! 238: /* at one point, the operator matching was 15% of the ! 239: total comile time; thus, the function ! 240: call that was here was removed... ! 241: */ ! 242: ! 243: if( q->op < OPSIMP ){ ! 244: if( q->op==i ) break; ! 245: } ! 246: else { ! 247: register opmtemp; ! 248: if((opmtemp=mamask[q->op - OPSIMP])&SPFLG){ ! 249: if( i==NAME || i==ICON || i==OREG ) break; ! 250: else if( shltype( i, NIL ) ) break; ! 251: } ! 252: else if( (dope[i]&(opmtemp|ASGFLG)) == opmtemp ) break; ! 253: } ! 254: } ! 255: opptr[i] = q; ! 256: } ! 257: } ! 258: } ! 259: ! 260: match( p, cookie ) NODE *p; { ! 261: /* called by: order, gencall ! 262: look for match in table and generate code if found unless ! 263: entry specified REWRITE. ! 264: returns MDONE, MNOPE, or rewrite specification from table */ ! 265: ! 266: register struct optab *q; ! 267: register NODE *r; ! 268: ! 269: rcount(); ! 270: if( cookie == FORREW ) q = rwtable; ! 271: else q = opptr[p->in.op]; ! 272: ! 273: for( ; q->op != FREE; ++q ){ ! 274: ! 275: /* at one point the call that was here was over 15% of the total time; ! 276: thus the function call was expanded inline */ ! 277: if( q->op < OPSIMP ){ ! 278: if( q->op!=p->in.op ) continue; ! 279: } ! 280: else { ! 281: register opmtemp; ! 282: if((opmtemp=mamask[q->op - OPSIMP])&SPFLG){ ! 283: if( p->in.op!=NAME && p->in.op!=ICON && p->in.op!= OREG && ! 284: ! shltype( p->in.op, p ) ) continue; ! 285: } ! 286: else if( (dope[p->in.op]&(opmtemp|ASGFLG)) != opmtemp ) continue; ! 287: } ! 288: ! 289: if( !(q->visit & cookie ) ) continue; ! 290: r = getlr( p, 'L' ); /* see if left child matches */ ! 291: if( !tshape( r, q->lshape ) ) continue; ! 292: if( !ttype( r->in.type, q->ltype ) ) continue; ! 293: r = getlr( p, 'R' ); /* see if right child matches */ ! 294: if( !tshape( r, q->rshape ) ) continue; ! 295: if( !ttype( r->in.type, q->rtype ) ) continue; ! 296: ! 297: /* REWRITE means no code from this match but go ahead ! 298: and rewrite node to help future match */ ! 299: if( q->needs & REWRITE ) return( q->rewrite ); ! 300: if( !allo( p, q ) ) continue; /* if can't generate code, skip entry */ ! 301: ! 302: /* resources are available */ ! 303: ! 304: expand( p, cookie, q->cstring ); /* generate code */ ! 305: reclaim( p, q->rewrite, cookie ); ! 306: ! 307: return(MDONE); ! 308: ! 309: } ! 310: ! 311: return(MNOPE); ! 312: } ! 313: ! 314: int rtyflg = 0; ! 315: ! 316: expand( p, cookie, cp ) NODE *p; register char *cp; { ! 317: /* generate code by interpreting table entry */ ! 318: ! 319: register char c; ! 320: CONSZ val; ! 321: ! 322: rtyflg = 0; ! 323: ! 324: for( ; *cp; ++cp ){ ! 325: switch( *cp ){ ! 326: ! 327: default: ! 328: PUTCHAR( *cp ); ! 329: continue; /* this is the usual case... */ ! 330: ! 331: case 'T': ! 332: /* rewrite register type is suppressed */ ! 333: rtyflg = 1; ! 334: continue; ! 335: ! 336: case 'Z': /* special machine dependent operations */ ! 337: # ifdef NEWZZZ ! 338: switch( c = *++cp ) { ! 339: ! 340: case '1': ! 341: case '2': ! 342: case '3': ! 343: case 'R': ! 344: case 'L': /* get down first */ ! 345: zzzcode( getlr( p, c ), *++cp ); ! 346: break; ! 347: default: /* normal zzzcode processing otherwise */ ! 348: zzzcode( p, c ); ! 349: break; ! 350: } ! 351: # else ! 352: zzzcode( p, *++cp ); ! 353: # endif ! 354: continue; ! 355: ! 356: case 'F': /* this line deleted if FOREFF is active */ ! 357: if( cookie & FOREFF ) while( *++cp != '\n' ) ; /* VOID */ ! 358: continue; ! 359: ! 360: case 'S': /* field size */ ! 361: printf( "%d", fldsz ); ! 362: continue; ! 363: ! 364: case 'H': /* field shift */ ! 365: printf( "%d", fldshf ); ! 366: continue; ! 367: ! 368: case 'M': /* field mask */ ! 369: case 'N': /* complement of field mask */ ! 370: val = 1; ! 371: val <<= fldsz; ! 372: --val; ! 373: val <<= fldshf; ! 374: adrcon( *cp=='M' ? val : ~val ); ! 375: continue; ! 376: ! 377: case 'L': /* output special label field */ ! 378: printf( "%d", p->bn.label ); ! 379: continue; ! 380: ! 381: case 'O': /* opcode string */ ! 382: hopcode( *++cp, p->in.op ); ! 383: continue; ! 384: ! 385: case 'B': /* byte offset in word */ ! 386: val = getlr(p,*++cp)->tn.lval; ! 387: val = BYTEOFF(val); ! 388: printf( CONFMT, val ); ! 389: continue; ! 390: ! 391: case 'C': /* for constant value only */ ! 392: conput( getlr( p, *++cp ) ); ! 393: continue; ! 394: ! 395: case 'I': /* in instruction */ ! 396: insput( getlr( p, *++cp ) ); ! 397: continue; ! 398: ! 399: case 'A': /* address of */ ! 400: adrput( getlr( p, *++cp ) ); ! 401: continue; ! 402: ! 403: case 'U': /* for upper half of address, only */ ! 404: upput( getlr( p, *++cp ) ); ! 405: continue; ! 406: ! 407: } ! 408: ! 409: } ! 410: ! 411: } ! 412: ! 413: NODE * ! 414: getlr( p, c ) NODE *p; { ! 415: ! 416: /* return the pointer to the left or right side of p, or p itself, ! 417: depending on the optype of p */ ! 418: ! 419: switch( c ) { ! 420: ! 421: case '1': ! 422: case '2': ! 423: case '3': ! 424: return( &resc[c-'1'] ); ! 425: ! 426: case 'L': ! 427: return( optype( p->in.op ) == LTYPE ? p : p->in.left ); ! 428: ! 429: case 'R': ! 430: return( optype( p->in.op ) != BITYPE ? p : p->in.right ); ! 431: ! 432: } ! 433: cerror( "bad getlr: %c", c ); ! 434: /* NOTREACHED */ ! 435: } ! 436: # ifdef MULTILEVEL ! 437: ! 438: union mltemplate{ ! 439: struct ml_head{ ! 440: int tag; /* identifies class of tree */ ! 441: int subtag; /* subclass of tree */ ! 442: union mltemplate * nexthead; /* linked by mlinit() */ ! 443: } mlhead; ! 444: struct ml_node{ ! 445: int op; /* either an operator or op description */ ! 446: int nshape; /* shape of node */ ! 447: /* both op and nshape must match the node. ! 448: * where the work is to be done entirely by ! 449: * op, nshape can be SANY, visa versa, op can ! 450: * be OPANY. ! 451: */ ! 452: int ntype; /* type descriptor from mfile2 */ ! 453: } mlnode; ! 454: }; ! 455: ! 456: # define MLSZ 30 ! 457: ! 458: extern union mltemplate mltree[]; ! 459: int mlstack[MLSZ]; ! 460: int *mlsp; /* pointing into mlstack */ ! 461: NODE * ststack[MLSZ]; ! 462: NODE **stp; /* pointing into ststack */ ! 463: ! 464: mlinit(){ ! 465: union mltemplate **lastlink; ! 466: register union mltemplate *n; ! 467: register mlop; ! 468: ! 469: lastlink = &(mltree[0].nexthead); ! 470: n = &mltree[0]; ! 471: for( ; (n++)->mlhead.tag != 0; ! 472: *lastlink = ++n, lastlink = &(n->mlhead.nexthead) ){ ! 473: # ifndef BUG3 ! 474: if( vdebug )printf("mlinit: %d\n",(n-1)->mlhead.tag); ! 475: # endif ! 476: /* wander thru a tree with a stack finding ! 477: * its structure so the next header can be located. ! 478: */ ! 479: mlsp = mlstack; ! 480: ! 481: for( ;; ++n ){ ! 482: if( (mlop = n->mlnode.op) < OPSIMP ){ ! 483: switch( optype(mlop) ){ ! 484: ! 485: default: ! 486: cerror("(1)unknown opcode: %o",mlop); ! 487: case BITYPE: ! 488: goto binary; ! 489: case UTYPE: ! 490: break; ! 491: case LTYPE: ! 492: goto leaf; ! 493: } ! 494: } ! 495: else{ ! 496: if( mamask[mlop-OPSIMP] & ! 497: (SIMPFLG|COMMFLG|MULFLG|DIVFLG|LOGFLG|FLOFLG|SHFFLG) ){ ! 498: binary: ! 499: *mlsp++ = BITYPE; ! 500: } ! 501: else if( ! (mamask[mlop-OPSIMP] & UTYPE) ){/* includes OPANY */ ! 502: ! 503: leaf: ! 504: if( mlsp == mlstack ) ! 505: goto tree_end; ! 506: else if ( *--mlsp != BITYPE ) ! 507: cerror("(1)bad multi-level tree descriptor around mltree[%d]", ! 508: n-mltree); ! 509: } ! 510: } ! 511: } ! 512: tree_end: /* n points to final leaf */ ! 513: ; ! 514: } ! 515: # ifndef BUG3 ! 516: if( vdebug > 3 ){ ! 517: printf("mltree={\n"); ! 518: for( n= &(mltree[0]); n->mlhead.tag != 0; ++n) ! 519: printf("%o: %d, %d, %o,\n",n, ! 520: n->mlhead.tag,n->mlhead.subtag,n->mlhead.nexthead); ! 521: printf(" }\n"); ! 522: } ! 523: # endif ! 524: } ! 525: ! 526: mlmatch( subtree, target, subtarget ) NODE * subtree; int target,subtarget;{ ! 527: /* ! 528: * does subtree match a multi-level tree with ! 529: * tag "target"? Return zero on failure, ! 530: * non-zero subtag on success (or MDONE if ! 531: * there is a zero subtag field). ! 532: */ ! 533: union mltemplate *head; /* current template header */ ! 534: register union mltemplate *n; /* node being matched */ ! 535: NODE * st; /* subtree being matched */ ! 536: register int mlop; ! 537: ! 538: # ifndef BUG3 ! 539: if( vdebug ) printf("mlmatch(%o,%d)\n",subtree,target); ! 540: # endif ! 541: for( head = &(mltree[0]); head->mlhead.tag != 0; ! 542: head=head->mlhead.nexthead){ ! 543: # ifndef BUG3 ! 544: if( vdebug > 1 )printf("mlmatch head(%o) tag(%d)\n", ! 545: head->mlhead.tag); ! 546: # endif ! 547: if( head->mlhead.tag != target )continue; ! 548: if( subtarget && head->mlhead.subtag != subtarget)continue; ! 549: # ifndef BUG3 ! 550: if( vdebug ) printf("mlmatch for %d\n",target); ! 551: # endif ! 552: ! 553: /* potential for match */ ! 554: ! 555: n = head + 1; ! 556: st = subtree; ! 557: stp = ststack; ! 558: mlsp = mlstack; ! 559: /* compare n->op, ->nshape, ->ntype to ! 560: * the subtree node st ! 561: */ ! 562: for( ;; ++n ){ /* for each node in multi-level template */ ! 563: /* opmatch */ ! 564: if( n->op < OPSIMP ){ ! 565: if( st->op != n->op )break; ! 566: } ! 567: else { ! 568: register opmtemp; ! 569: if((opmtemp=mamask[n->op-OPSIMP])&SPFLG){ ! 570: if(st->op!=NAME && st->op!=ICON && st->op!=OREG && ! 571: ! shltype(st->op,st)) break; ! 572: } ! 573: else if((dope[st->op]&(opmtemp|ASGFLG))!=opmtemp) break; ! 574: } ! 575: /* check shape and type */ ! 576: ! 577: if( ! tshape( st, n->mlnode.nshape ) ) break; ! 578: if( ! ttype( st->type, n->mlnode.ntype ) ) break; ! 579: ! 580: /* that node matched, let's try another */ ! 581: /* must advance both st and n and halt at right time */ ! 582: ! 583: if( (mlop = n->mlnode.op) < OPSIMP ){ ! 584: switch( optype(mlop) ){ ! 585: ! 586: default: ! 587: cerror("(2)unknown opcode: %o",mlop); ! 588: case BITYPE: ! 589: goto binary; ! 590: case UTYPE: ! 591: st = st->left; ! 592: break; ! 593: case LTYPE: ! 594: goto leaf; ! 595: } ! 596: } ! 597: else{ ! 598: if( mamask[mlop - OPSIMP] & ! 599: (SIMPFLG|COMMFLG|MULFLG|DIVFLG|LOGFLG|FLOFLG|SHFFLG) ){ ! 600: binary: ! 601: *mlsp++ = BITYPE; ! 602: *stp++ = st; ! 603: st = st->left; ! 604: } ! 605: else if( ! (mamask[mlop-OPSIMP] & UTYPE) ){/* includes OPANY */ ! 606: ! 607: leaf: ! 608: if( mlsp == mlstack ) ! 609: goto matched; ! 610: else if ( *--mlsp != BITYPE ) ! 611: cerror("(2)bad multi-level tree descriptor around mltree[%d]", ! 612: n-mltree); ! 613: st = (*--stp)->right; ! 614: } ! 615: else /* UNARY */ st = st->left; ! 616: } ! 617: continue; ! 618: ! 619: matched: ! 620: /* complete multi-level match successful */ ! 621: # ifndef BUG3 ! 622: if( vdebug ) printf("mlmatch() success\n"); ! 623: # endif ! 624: if( head->mlhead.subtag == 0 ) return( MDONE ); ! 625: else { ! 626: # ifndef BUG3 ! 627: if( vdebug )printf("\treturns %d\n", ! 628: head->mlhead.subtag ); ! 629: # endif ! 630: return( head->mlhead.subtag ); ! 631: } ! 632: } ! 633: } ! 634: return( 0 ); ! 635: } ! 636: # endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.