|
|
1.1 ! root 1: # include "pass2.h" ! 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 int 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: /* ! 196: case LONG: ! 197: return( tword & TLONG ); ! 198: */ ! 199: case FLOAT: ! 200: return( tword & TFLOAT ); ! 201: case DOUBLE: ! 202: return( tword & TDOUBLE ); ! 203: } ! 204: ! 205: return(0); ! 206: } ! 207: ! 208: struct optab *rwtable; ! 209: ! 210: struct optab *opptr[DSIZE]; ! 211: ! 212: setrew(){ ! 213: /* set rwtable to first value which allows rewrite */ ! 214: register struct optab *q; ! 215: register int i; ! 216: ! 217: # ifdef MULTILEVEL ! 218: /* also initialize multi-level tree links */ ! 219: mlinit(); ! 220: # endif ! 221: ! 222: for( q = table; q->op != FREE; ++q ){ ! 223: if( q->needs == REWRITE ){ ! 224: rwtable = q; ! 225: goto more; ! 226: } ! 227: } ! 228: cerror( "bad setrew" ); ! 229: ! 230: ! 231: more: ! 232: for( i=0; i<DSIZE; ++i ){ ! 233: if( dope[i] ){ /* there is an op... */ ! 234: for( q=table; q->op != FREE; ++q ){ ! 235: /* beware; things like LTYPE that match ! 236: multiple things in the tree must ! 237: not try to look at the NIL at this ! 238: stage of things! Put something else ! 239: first in table.c */ ! 240: /* at one point, the operator matching was 15% of the ! 241: total comile time; thus, the function ! 242: call that was here was removed... ! 243: */ ! 244: ! 245: if( q->op < OPSIMP ){ ! 246: if( q->op==i ) break; ! 247: } ! 248: else { ! 249: register int opmtemp; ! 250: if((opmtemp=mamask[q->op - OPSIMP])&SPFLG){ ! 251: if( i==NAME || i==ICON || i==OREG ) break; ! 252: else if( shltype( i, NIL ) ) break; ! 253: } ! 254: else if( (dope[i]&(opmtemp|ASGFLG)) == opmtemp ) break; ! 255: } ! 256: } ! 257: opptr[i] = q; ! 258: } ! 259: } ! 260: } ! 261: ! 262: match( p, cookie ) NODE *p; { ! 263: /* called by: order, gencall ! 264: look for match in table and generate code if found unless ! 265: entry specified REWRITE. ! 266: returns MDONE, MNOPE, or rewrite specification from table */ ! 267: ! 268: register struct optab *q; ! 269: register NODE *r; ! 270: ! 271: rcount(); ! 272: if( cookie == FORREW ) q = rwtable; ! 273: else q = opptr[p->in.op]; ! 274: ! 275: for( ; q->op != FREE; ++q ){ ! 276: ! 277: /* at one point the call that was here was over 15% of the total time; ! 278: thus the function call was expanded inline */ ! 279: if( q->op < OPSIMP ){ ! 280: if( q->op!=p->in.op ) continue; ! 281: } ! 282: else { ! 283: register int opmtemp; ! 284: if((opmtemp=mamask[q->op - OPSIMP])&SPFLG){ ! 285: if( p->in.op!=NAME && p->in.op!=ICON && p->in.op!= OREG && ! 286: ! shltype( p->in.op, p ) ) continue; ! 287: } ! 288: else if( (dope[p->in.op]&(opmtemp|ASGFLG)) != opmtemp ) continue; ! 289: } ! 290: ! 291: if( !(q->visit & cookie ) ) continue; ! 292: r = getlr( p, 'L' ); /* see if left child matches */ ! 293: if( !tshape( r, q->lshape ) ) continue; ! 294: if( !ttype( r->in.type, q->ltype ) ) continue; ! 295: r = getlr( p, 'R' ); /* see if right child matches */ ! 296: if( !tshape( r, q->rshape ) ) continue; ! 297: if( !ttype( r->in.type, q->rtype ) ) continue; ! 298: ! 299: /* REWRITE means no code from this match but go ahead ! 300: and rewrite node to help future match */ ! 301: if( q->needs & REWRITE ) return( q->rewrite ); ! 302: if( !allo( p, q ) ) continue; /* if can't generate code, skip entry */ ! 303: ! 304: /* resources are available */ ! 305: ! 306: expand( p, cookie, q->cstring ); /* generate code */ ! 307: reclaim( p, q->rewrite, cookie ); ! 308: ! 309: return(MDONE); ! 310: ! 311: } ! 312: ! 313: return(MNOPE); ! 314: } ! 315: ! 316: int rtyflg = 0; ! 317: ! 318: expand( p, cookie, cp ) NODE *p; register char *cp; { ! 319: /* generate code by interpreting table entry */ ! 320: ! 321: register char c; ! 322: CONSZ val; ! 323: ! 324: rtyflg = 0; ! 325: ! 326: for( ; *cp; ++cp ){ ! 327: switch( *cp ){ ! 328: ! 329: default: ! 330: PUTCHAR( *cp ); ! 331: continue; /* this is the usual case... */ ! 332: ! 333: case 'T': ! 334: /* rewrite register type is suppressed */ ! 335: rtyflg = 1; ! 336: continue; ! 337: ! 338: case 'Z': /* special machine dependent operations */ ! 339: # ifdef NEWZZZ ! 340: switch( c = *++cp ) { ! 341: ! 342: case '1': ! 343: case '2': ! 344: case '3': ! 345: case 'R': ! 346: case 'L': /* get down first */ ! 347: zzzcode( getlr( p, c ), *++cp ); ! 348: break; ! 349: default: /* normal zzzcode processing otherwise */ ! 350: zzzcode( p, c ); ! 351: break; ! 352: } ! 353: # else ! 354: zzzcode( p, *++cp ); ! 355: # endif ! 356: continue; ! 357: ! 358: case 'F': /* this line deleted if FOREFF is active */ ! 359: if( cookie & FOREFF ) while( *++cp != '\n' ) ; /* VOID */ ! 360: continue; ! 361: ! 362: case 'S': /* field size */ ! 363: printf( "%d", fldsz ); ! 364: continue; ! 365: ! 366: case 'H': /* field shift */ ! 367: printf( "%d", fldshf ); ! 368: continue; ! 369: ! 370: case 'M': /* field mask */ ! 371: case 'N': /* complement of field mask */ ! 372: val = 1; ! 373: val <<= fldsz; ! 374: --val; ! 375: val <<= fldshf; ! 376: adrcon( *cp=='M' ? val : ~val ); ! 377: continue; ! 378: ! 379: case 'L': /* output special label field */ ! 380: printf( "%d", p->bn.label ); ! 381: continue; ! 382: ! 383: case 'O': /* opcode string */ ! 384: hopcode( *++cp, p->in.op ); ! 385: continue; ! 386: ! 387: case 'B': /* byte offset in word */ ! 388: val = getlr(p,*++cp)->tn.lval; ! 389: val = BYTEOFF(val); ! 390: printf( CONFMT, val ); ! 391: continue; ! 392: ! 393: case 'C': /* for constant value only */ ! 394: conput( getlr( p, *++cp ) ); ! 395: continue; ! 396: ! 397: case 'I': /* in instruction */ ! 398: insput( getlr( p, *++cp ) ); ! 399: continue; ! 400: ! 401: case 'A': /* address of */ ! 402: adrput( getlr( p, *++cp ) ); ! 403: continue; ! 404: ! 405: case 'U': /* for upper half of address, only */ ! 406: upput( getlr( p, *++cp ) ); ! 407: continue; ! 408: ! 409: } ! 410: ! 411: } ! 412: ! 413: } ! 414: ! 415: NODE * ! 416: getlr( p, c ) NODE *p; { ! 417: ! 418: /* return the pointer to the left or right side of p, or p itself, ! 419: depending on the optype of p */ ! 420: ! 421: switch( c ) { ! 422: ! 423: case '1': ! 424: case '2': ! 425: case '3': ! 426: return( &resc[c-'1'] ); ! 427: ! 428: case 'L': ! 429: return( optype( p->in.op ) == LTYPE ? p : p->in.left ); ! 430: ! 431: case 'R': ! 432: return( optype( p->in.op ) != BITYPE ? p : p->in.right ); ! 433: ! 434: } ! 435: cerror( "bad getlr: %c", c ); ! 436: /* NOTREACHED */ ! 437: } ! 438: # ifdef MULTILEVEL ! 439: ! 440: union mltemplate{ ! 441: struct ml_head{ ! 442: int tag; /* identifies class of tree */ ! 443: int subtag; /* subclass of tree */ ! 444: union mltemplate * nexthead; /* linked by mlinit() */ ! 445: } mlhead; ! 446: struct ml_node{ ! 447: int op; /* either an operator or op description */ ! 448: int nshape; /* shape of node */ ! 449: /* both op and nshape must match the node. ! 450: * where the work is to be done entirely by ! 451: * op, nshape can be SANY, visa versa, op can ! 452: * be OPANY. ! 453: */ ! 454: int ntype; /* type descriptor from mfile2 */ ! 455: } mlnode; ! 456: }; ! 457: ! 458: # define MLSZ 30 ! 459: ! 460: extern union mltemplate mltree[]; ! 461: int mlstack[MLSZ]; ! 462: int *mlsp; /* pointing into mlstack */ ! 463: NODE * ststack[MLSZ]; ! 464: NODE **stp; /* pointing into ststack */ ! 465: ! 466: mlinit(){ ! 467: union mltemplate **lastlink; ! 468: register int union mltemplate *n; ! 469: register int mlop; ! 470: ! 471: lastlink = &(mltree[0].nexthead); ! 472: n = &mltree[0]; ! 473: for( ; (n++)->mlhead.tag != 0; ! 474: *lastlink = ++n, lastlink = &(n->mlhead.nexthead) ){ ! 475: # ifndef BUG3 ! 476: if( vdebug )printf("mlinit: %d\n",(n-1)->mlhead.tag); ! 477: # endif ! 478: /* wander thru a tree with a stack finding ! 479: * its structure so the next header can be located. ! 480: */ ! 481: mlsp = mlstack; ! 482: ! 483: for( ;; ++n ){ ! 484: if( (mlop = n->mlnode.op) < OPSIMP ){ ! 485: switch( optype(mlop) ){ ! 486: ! 487: default: ! 488: cerror("(1)unknown opcode: %o",mlop); ! 489: case BITYPE: ! 490: goto binary; ! 491: case UTYPE: ! 492: break; ! 493: case LTYPE: ! 494: goto leaf; ! 495: } ! 496: } ! 497: else{ ! 498: if( mamask[mlop-OPSIMP] & ! 499: (SIMPFLG|COMMFLG|MULFLG|DIVFLG|LOGFLG|FLOFLG|SHFFLG) ){ ! 500: binary: ! 501: *mlsp++ = BITYPE; ! 502: } ! 503: else if( ! (mamask[mlop-OPSIMP] & UTYPE) ){/* includes OPANY */ ! 504: ! 505: leaf: ! 506: if( mlsp == mlstack ) ! 507: goto tree_end; ! 508: else if ( *--mlsp != BITYPE ) ! 509: cerror("(1)bad multi-level tree descriptor around mltree[%d]", ! 510: n-mltree); ! 511: } ! 512: } ! 513: } ! 514: tree_end: /* n points to final leaf */ ! 515: ; ! 516: } ! 517: # ifndef BUG3 ! 518: if( vdebug > 3 ){ ! 519: printf("mltree={\n"); ! 520: for( n= &(mltree[0]); n->mlhead.tag != 0; ++n) ! 521: printf("%o: %d, %d, %o,\n",n, ! 522: n->mlhead.tag,n->mlhead.subtag,n->mlhead.nexthead); ! 523: printf(" }\n"); ! 524: } ! 525: # endif ! 526: } ! 527: ! 528: mlmatch( subtree, target, subtarget ) NODE * subtree; int target,subtarget;{ ! 529: /* ! 530: * does subtree match a multi-level tree with ! 531: * tag "target"? Return zero on failure, ! 532: * non-zero subtag on success (or MDONE if ! 533: * there is a zero subtag field). ! 534: */ ! 535: union mltemplate *head; /* current template header */ ! 536: register union mltemplate *n; /* node being matched */ ! 537: NODE * st; /* subtree being matched */ ! 538: register int mlop; ! 539: ! 540: # ifndef BUG3 ! 541: if( vdebug ) printf("mlmatch(%o,%d)\n",subtree,target); ! 542: # endif ! 543: for( head = &(mltree[0]); head->mlhead.tag != 0; ! 544: head=head->mlhead.nexthead){ ! 545: # ifndef BUG3 ! 546: if( vdebug > 1 )printf("mlmatch head(%o) tag(%d)\n", ! 547: head->mlhead.tag); ! 548: # endif ! 549: if( head->mlhead.tag != target )continue; ! 550: if( subtarget && head->mlhead.subtag != subtarget)continue; ! 551: # ifndef BUG3 ! 552: if( vdebug ) printf("mlmatch for %d\n",target); ! 553: # endif ! 554: ! 555: /* potential for match */ ! 556: ! 557: n = head + 1; ! 558: st = subtree; ! 559: stp = ststack; ! 560: mlsp = mlstack; ! 561: /* compare n->op, ->nshape, ->ntype to ! 562: * the subtree node st ! 563: */ ! 564: for( ;; ++n ){ /* for each node in multi-level template */ ! 565: /* opmatch */ ! 566: if( n->op < OPSIMP ){ ! 567: if( st->op != n->op )break; ! 568: } ! 569: else { ! 570: register int opmtemp; ! 571: if((opmtemp=mamask[n->op-OPSIMP])&SPFLG){ ! 572: if(st->op!=NAME && st->op!=ICON && st->op!=OREG && ! 573: ! shltype(st->op,st)) break; ! 574: } ! 575: else if((dope[st->op]&(opmtemp|ASGFLG))!=opmtemp) break; ! 576: } ! 577: /* check shape and type */ ! 578: ! 579: if( ! tshape( st, n->mlnode.nshape ) ) break; ! 580: if( ! ttype( st->type, n->mlnode.ntype ) ) break; ! 581: ! 582: /* that node matched, let's try another */ ! 583: /* must advance both st and n and halt at right time */ ! 584: ! 585: if( (mlop = n->mlnode.op) < OPSIMP ){ ! 586: switch( optype(mlop) ){ ! 587: ! 588: default: ! 589: cerror("(2)unknown opcode: %o",mlop); ! 590: case BITYPE: ! 591: goto binary; ! 592: case UTYPE: ! 593: st = st->left; ! 594: break; ! 595: case LTYPE: ! 596: goto leaf; ! 597: } ! 598: } ! 599: else{ ! 600: if( mamask[mlop - OPSIMP] & ! 601: (SIMPFLG|COMMFLG|MULFLG|DIVFLG|LOGFLG|FLOFLG|SHFFLG) ){ ! 602: binary: ! 603: *mlsp++ = BITYPE; ! 604: *stp++ = st; ! 605: st = st->left; ! 606: } ! 607: else if( ! (mamask[mlop-OPSIMP] & UTYPE) ){/* includes OPANY */ ! 608: ! 609: leaf: ! 610: if( mlsp == mlstack ) ! 611: goto matched; ! 612: else if ( *--mlsp != BITYPE ) ! 613: cerror("(2)bad multi-level tree descriptor around mltree[%d]", ! 614: n-mltree); ! 615: st = (*--stp)->right; ! 616: } ! 617: else /* UNARY */ st = st->left; ! 618: } ! 619: continue; ! 620: ! 621: matched: ! 622: /* complete multi-level match successful */ ! 623: # ifndef BUG3 ! 624: if( vdebug ) printf("mlmatch() success\n"); ! 625: # endif ! 626: if( head->mlhead.subtag == 0 ) return( MDONE ); ! 627: else { ! 628: # ifndef BUG3 ! 629: if( vdebug )printf("\treturns %d\n", ! 630: head->mlhead.subtag ); ! 631: # endif ! 632: return( head->mlhead.subtag ); ! 633: } ! 634: } ! 635: } ! 636: return( 0 ); ! 637: } ! 638: # endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.