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