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