1: # include "mfile2" 2: /* a lot of the machine dependent parts of the second pass */ 3: 4: # define BITMASK(n) ((1L<<n)-1) 5: where(c) { 6: printf("where() was called!"); 7: } 8: 9: lineid( l, fn ) char *fn; { 10: /* identify line l and file fn */ 11: printf( "/ line %d, file %s\n", l, fn ); 12: } 13: 14: eobl2(){ 15: OFFSZ spoff; /* offset from stack pointer */ 16: 17: spoff = maxoff; 18: if( spoff >= AUTOINIT ) spoff -= AUTOINIT; 19: spoff /= SZCHAR; 20: SETOFF(spoff,2); 21: printf( " .F%d = %Ld.\n", ftnno, spoff ); 22: if( fltused ) { 23: fltused = 0; 24: printf( " .globl fltused\n" ); 25: } 26: } 27: 28: struct hoptab { int opmask; char * opstring; } ioptab[]= { 29: 30: ASG PLUS, "add", 31: ASG MINUS, "sub", 32: ASG OR, "bis", 33: ASG AND, "bic", 34: ASG ER, "xor", 35: ASG MUL, "mul", 36: ASG DIV, "div", 37: ASG MOD, "div", 38: ASG LS, "asl", 39: ASG RS, "asr", 40: 41: -1, "" }; 42: 43: hopcode( f, o ){ 44: /* output the appropriate string from the above table */ 45: 46: register struct hoptab *q; 47: 48: for( q = ioptab; q->opmask>=0; ++q ){ 49: if( q->opmask == o ){ 50: printf( "%s", q->opstring ); 51: if( f == 'F' ) printf( "f" ); 52: return; 53: } 54: } 55: cerror( "no hoptab for %s", opst[o] ); 56: } 57: 58: char * 59: rnames[]= { /* keyed to register number tokens */ 60: 61: "r0", "r1", 62: "r2", "r3", "r4", 63: "r5", "sp", "pc", 64: 65: "fr0", "fr1", "fr2", "fr3", 66: "fr4", "fr5", /* not accumulators - used for temps */ 67: }; 68: 69: int rstatus[] = { 70: SAREG|STAREG, SAREG|STAREG, 71: SAREG|STAREG, SAREG|STAREG, SAREG|STAREG, /* use as scratch if not reg var */ 72: SAREG, SAREG, SAREG, 73: 74: SBREG|STBREG, SBREG|STBREG, SBREG|STBREG, SBREG|STBREG, 75: SBREG, SBREG, 76: }; 77: 78: NODE *brnode; 79: int brcase; 80: 81: int toff = 0; /* number of stack locations used for args */ 82: 83: zzzcode( p, c ) NODE *p; { 84: register m; 85: switch( c ){ 86: 87: case 'B': /* output b if type is byte */ 88: if( p->type == CHAR || p->type == UCHAR ) printf( "b" ); 89: return; 90: 91: case 'N': /* logical ops, turned into 0-1 */ 92: /* use register given by register 1 */ 93: cbgen( 0, m=getlab(), 'I' ); 94: deflab( p->label ); 95: printf( " clr %s\n", rnames[getlr( p, '1' )->rval] ); 96: if( p->type == LONG || p->type == ULONG ) 97: printf( " clr %s\n", rnames[getlr( p, '1' )->rval + 1] ); 98: deflab( m ); 99: return; 100: 101: case 'I': 102: case 'F': 103: cbgen( p->op, p->label, c ); 104: return; 105: 106: case 'A': 107: case 'C': 108: /* logical operators for longs 109: defer comparisons until branch occurs */ 110: 111: brnode = tcopy( p ); 112: brcase = c; 113: return; 114: 115: case 'H': /* fix up unsigned shifts */ 116: { register NODE *q; 117: register r, l; 118: TWORD t; 119: 120: if( p->op == ASG LS ) return; 121: if( p->op != ASG RS ) cerror( "ZH bad" ); 122: if( p->left->op != REG ) cerror( "SH left bad" ); 123: 124: r = p->left->rval; 125: t = p->left->type; 126: l = (t==LONG || t == ULONG ); 127: 128: if( t != UNSIGNED && t != UCHAR && t != ULONG ) return; /* signed is ok */ 129: 130: /* there are three cases: right side is a constant, 131: and has the shift value; right side is 132: a temporary reg, and has the - shift value, 133: and right side is something else: A1 has the 134: - shift value then */ 135: 136: /* in the case where the value is known (rhs a constant), 137: the mask is just computed and put out... */ 138: 139: if( p->right->op == ICON ){ 140: int s; 141: s = p->right->lval; 142: if( l ){ 143: if( s >= 16 ){ 144: printf( " clr r%d\n", r ); 145: s -= 16; 146: ++r; 147: } 148: } 149: if( s >= 16 ) printf( " clr r%d\n", r ); 150: else { 151: m = 0100000; 152: m >>= s; /* sign extends... */ 153: m <<= 1; 154: printf( " bic $%o,r%d\n", m, r ); 155: } 156: return; 157: } 158: 159: /* general case */ 160: 161: if( istnode( p->right ) ) q = p->right; 162: else q = getlr( p, '1' ); /* where -shift is stored */ 163: 164: /* first, we store the shifted value on the stack */ 165: printf( " mov r%d,-(sp)\n", r ); 166: if( l ) printf( " mov r%d,-(sp)\n", r+1 ); 167: 168: /* now, make a mask */ 169: 170: printf( " mov $100000,r%d\n", r ); 171: if( l ) printf( " clr r%d\n", r+1 ); 172: 173: /* shift (arithmetically ) */ 174: if( l ) expand( q, RNOP, " ashc AR" ); 175: else expand( q, RNOP, " ash AR" ); 176: printf( ",r%d\n", r ); 177: 178: if( l ) printf( " ashc $1,r%d\n", r ); 179: else printf( " asl r%d\n", r ); 180: 181: /* now, we have a mask: use it to clear sp, and reload */ 182: 183: if( l ){ 184: printf( "\tbic\tr%d,(sp)\n\tmov\t(sp)+,r%d\n", r+1, r+1 ); 185: } 186: printf( "\tbic\tr%d,(sp)\n\tmov\t(sp)+,r%d\n", r, r ); 187: /* whew! */ 188: return; 189: } 190: 191: case 'V': 192: /* sign extend or not -- register is one less than the 193: left descendent */ 194: 195: m = p->left->rval - 1; 196: 197: if( ISUNSIGNED(p->type) ){ 198: printf( " clr r%d\n", m ); 199: } 200: else { 201: printf( " sxt r%d\n", m ); 202: } 203: return; 204: 205: /* stack management macros */ 206: case '-': 207: if( toff ++ ) printf( "-" ); 208: printf( "(sp)" ); 209: return; 210: 211: case '4': 212: if( toff == 0 ) ++toff; /* can't push doubles that way */ 213: printf( "-(sp)" ); 214: toff += 4; 215: return; 216: 217: case '~': 218: /* complimented CR */ 219: p->right->lval = ~p->right->lval; 220: conput( getlr( p, 'R' ) ); 221: p->right->lval = ~p->right->lval; 222: return; 223: 224: case 'M': 225: /* negated CR */ 226: p->right->lval = -p->right->lval; 227: conput( getlr( p, 'R' ) ); 228: p->right->lval = -p->right->lval; 229: return; 230: 231: case 'L': /* INIT for long constants */ 232: { 233: unsigned hi, lo; 234: lo = p->left->lval & BITMASK(SZINT); 235: hi = ( p->left->lval >> SZINT ) & BITMASK(SZINT); 236: printf( " %o; %o\n", hi, lo ); 237: return; 238: } 239: 240: case 'T': 241: /* Truncate longs for type conversions: 242: LONG|ULONG -> CHAR|UCHAR|INT|UNSIGNED 243: increment offset to second word */ 244: 245: m = p->type; 246: p = p->left; 247: switch( p->op ){ 248: case NAME: 249: case OREG: 250: p->lval += SZINT/SZCHAR; 251: return; 252: case REG: 253: rfree( p->rval, p->type ); 254: p->rval += 1; 255: p->type = m; 256: rbusy( p->rval, p->type ); 257: return; 258: default: 259: cerror( "Illegal ZT type conversion" ); 260: return; 261: 262: } 263: 264: case 'U': 265: /* same as AL for exp under U* */ 266: if( p->left->op == UNARY MUL ) { 267: adrput( getlr( p->left, 'L' ) ); 268: return; 269: } 270: cerror( "Illegal ZU" ); 271: /* NO RETURN */ 272: 273: case 'W': /* structure size */ 274: if( p->op == STASG ) 275: printf( "%d", p->stsize); 276: else cerror( "Not a structure" ); 277: return; 278: 279: case 'S': /* structure assignment */ 280: { 281: register NODE *l, *r; 282: register size, count; 283: 284: if( p->op == STASG ){ 285: l = p->left; 286: r = p->right; 287: } 288: else if( p->op == STARG ){ /* store an arg onto the stack */ 289: r = p->left; 290: } 291: else cerror( "STASG bad" ); 292: 293: if( r->op == ICON ) r->op = NAME; 294: else if( r->op == REG ) r->op = OREG; 295: else if( r->op != OREG ) cerror( "STASG-r" ); 296: 297: size = p->stsize; 298: count = size / 2; 299: 300: r->lval += size; 301: if( p->op == STASG ) l->lval += size; 302: 303: while( count-- ){ /* simple load/store loop */ 304: r->lval -= 2; 305: expand( r, FOREFF, " mov AR," ); 306: if( p->op == STASG ){ 307: l->lval -= 2; 308: expand( l, FOREFF, "AR\n" ); 309: } 310: else { 311: printf( "-(sp)\n" ); 312: } 313: 314: } 315: 316: if( r->op == NAME ) r->op = ICON; 317: else if( r->op == OREG ) r->op = REG; 318: 319: } 320: break; 321: 322: default: 323: cerror( "illegal zzzcode" ); 324: } 325: } 326: 327: rmove( rt, rs, t ) TWORD t; { 328: printf( " %s %s,%s\n", (t==FLOAT||t==DOUBLE)?"movf":"mov", rnames[rs], rnames[rt] ); 329: } 330: 331: struct respref 332: respref[] = { 333: INTAREG|INTBREG, INTAREG|INTBREG, 334: INAREG|INBREG, INAREG|INBREG|SOREG|STARREG|SNAME|STARNM|SCON, 335: INTEMP, INTEMP, 336: FORARG, FORARG, 337: INTAREG, SOREG|SNAME, 338: 0, 0 }; 339: 340: setregs(){ /* set up temporary registers */ 341: register i; 342: 343: /* use any unused variable registers as scratch registers */ 344: fregs = maxtreg>=MINRVAR ? maxtreg + 1 : MINRVAR; 345: if( xdebug ){ 346: /* -x changes number of free regs to 2, -xx to 3, etc. */ 347: if( (xdebug+1) < fregs ) fregs = xdebug+1; 348: } 349: /* NOTE: for pdp11 fregs <= 4 for float regs */ 350: if( fregs > 4 ) fregs = 4; 351: for( i=MINRVAR; i<=MAXRVAR; i++ ) 352: rstatus[i] = i<fregs ? SAREG|STAREG : SAREG; 353: } 354: 355: szty(t) TWORD t; { /* size, in words, needed to hold thing of type t */ 356: /* really is the number of registers to hold type t */ 357: switch( t ) { 358: 359: case LONG: 360: case ULONG: 361: return( SZLONG/SZINT ); 362: 363: default: 364: return(1); 365: 366: } 367: } 368: 369: rewfld( p ) NODE *p; { 370: return(1); 371: } 372: 373: callreg(p) NODE *p; { 374: return( (p->type==DOUBLE||p->type==FLOAT) ? FR0 : R0 ); 375: } 376: 377: shltype( o, p ) NODE *p; { 378: if( o == NAME|| o==REG || o == ICON || o == OREG ) return( 1 ); 379: return( o==UNARY MUL && shumul(p->left) ); 380: } 381: 382: flshape( p ) register NODE *p; { 383: register o = p->op; 384: if( o==NAME || o==REG || o==ICON || o==OREG ) return( 1 ); 385: return( o==UNARY MUL && shumul(p->left)==STARNM ); 386: } 387: 388: shtemp( p ) register NODE *p; { 389: if( p->op == UNARY MUL ) p = p->left; 390: if( p->op == REG || p->op == OREG ) return( !istreg( p->rval ) ); 391: return( p->op == NAME || p->op == ICON ); 392: } 393: 394: spsz( t, v ) TWORD t; CONSZ v; { 395: 396: /* is v the size to increment something of type t */ 397: 398: if( !ISPTR(t) ) return( 0 ); 399: t = DECREF(t); 400: 401: if( ISPTR(t) ) return( v == 2 ); 402: 403: switch( t ){ 404: 405: case UCHAR: 406: case CHAR: 407: return( v == 1 ); 408: 409: case INT: 410: case UNSIGNED: 411: return( v == 2 ); 412: 413: case FLOAT: 414: return( v == 4 ); 415: 416: case DOUBLE: 417: return( v == 8 ); 418: } 419: 420: return( 0 ); 421: } 422: 423: shumul( p ) register NODE *p; { 424: register o; 425: 426: o = p->op; 427: if( o == NAME || o == OREG || o == ICON ) return( STARNM ); 428: 429: if( ( o == INCR || o == ASG MINUS ) && 430: ( p->left->op == REG && p->right->op == ICON ) && 431: p->right->name[0] == '\0' && 432: spsz( p->left->type, p->right->lval ) ) 433: return( STARREG ); 434: 435: return( 0 ); 436: } 437: 438: adrcon( val ) CONSZ val; { 439: printf( CONFMT, val ); 440: } 441: 442: conput( p ) register NODE *p; { 443: switch( p->op ){ 444: 445: case ICON: 446: acon( p ); 447: return; 448: 449: case REG: 450: printf( "%s", rnames[p->rval] ); 451: return; 452: 453: default: 454: cerror( "illegal conput" ); 455: } 456: } 457: 458: insput( p ) NODE *p; { 459: cerror( "insput" ); 460: } 461: 462: upput( p ) NODE *p; { 463: /* output the address of the second word in the 464: pair pointed to by p (for LONGs)*/ 465: CONSZ save; 466: 467: if( p->op == FLD ){ 468: p = p->left; 469: } 470: 471: save = p->lval; 472: switch( p->op ){ 473: 474: case NAME: 475: p->lval += SZINT/SZCHAR; 476: acon( p ); 477: break; 478: 479: case ICON: 480: /* addressable value of the constant */ 481: p->lval &= BITMASK(SZINT); 482: printf( "$" ); 483: acon( p ); 484: break; 485: 486: case REG: 487: printf( "%s", rnames[p->rval+1] ); 488: break; 489: 490: case OREG: 491: p->lval += SZINT/SZCHAR; 492: if( p->rval == R5 ){ /* in the argument region */ 493: if( p->name[0] != '\0' ) werror( "bad arg temp" ); 494: } 495: if( p->lval != 0 || p->name[0] != '\0' ) acon( p ); 496: printf( "(%s)", rnames[p->rval] ); 497: break; 498: 499: default: 500: cerror( "illegal upper address" ); 501: break; 502: 503: } 504: p->lval = save; 505: 506: } 507: 508: adrput( p ) register NODE *p; { 509: /* output an address, with offsets, from p */ 510: 511: if( p->op == FLD ){ 512: p = p->left; 513: } 514: switch( p->op ){ 515: 516: case NAME: 517: acon( p ); 518: return; 519: 520: case ICON: 521: /* addressable value of the constant */ 522: if( szty( p->type ) == 2 ) { 523: /* print the high order value */ 524: CONSZ save; 525: save = p->lval; 526: p->lval = ( p->lval >> SZINT ) & BITMASK(SZINT); 527: printf( "$" ); 528: acon( p ); 529: p->lval = save; 530: return; 531: } 532: printf( "$" ); 533: acon( p ); 534: return; 535: 536: case REG: 537: printf( "%s", rnames[p->rval] ); 538: return; 539: 540: case OREG: 541: if( p->rval == R5 ){ /* in the argument region */ 542: if( p->name[0] != '\0' ) werror( "bad arg temp" ); 543: printf( CONFMT, p->lval ); 544: printf( ".(r5)" ); 545: return; 546: } 547: if( p->lval != 0 || p->name[0] != '\0' ) acon( p ); 548: printf( "(%s)", rnames[p->rval] ); 549: return; 550: 551: case UNARY MUL: 552: /* STARNM or STARREG found */ 553: if( tshape(p, STARNM) ) { 554: printf( "*" ); 555: adrput( p->left); 556: } 557: else { /* STARREG - really auto inc or dec */ 558: /* turn into OREG so replacement node will 559: reflect the value of the expression */ 560: register i; 561: register NODE *q, *l; 562: 563: l = p->left; 564: q = l->left; 565: p->op = OREG; 566: p->rall = q->rall; 567: p->lval = q->lval; 568: p->rval = q->rval; 569: for( i=0; i<NCHNAM; i++ ) 570: p->name[i] = q->name[i]; 571: if( l->op == INCR ) { 572: adrput( p ); 573: printf( "+" ); 574: p->lval -= l->right->lval; 575: } 576: else { /* l->op == ASG MINUS */ 577: printf( "-" ); 578: adrput( p ); 579: } 580: tfree( l ); 581: } 582: return; 583: 584: default: 585: cerror( "illegal address" ); 586: return; 587: 588: } 589: 590: } 591: 592: acon( p ) register NODE *p; { /* print out a constant */ 593: 594: if( p->name[0] == '\0' ){ /* constant only */ 595: printf( CONFMT, p->lval); 596: printf( "." ); 597: } 598: else if( p->lval == 0 ) { /* name only */ 599: printf( "%.8s", p->name ); 600: } 601: else { /* name + offset */ 602: printf( "%.8s+", p->name ); 603: printf( CONFMT, p->lval ); 604: printf( "." ); 605: } 606: } 607: 608: genscall( p, cookie ) register NODE *p; { 609: /* structure valued call */ 610: return( gencall( p, cookie ) ); 611: } 612: 613: gencall( p, cookie ) register NODE *p; { 614: /* generate the call given by p */ 615: register temp; 616: register m; 617: 618: if( p->right ) temp = argsize( p->right ); 619: else temp = 0; 620: 621: if( p->right ){ /* generate args */ 622: genargs( p->right ); 623: } 624: 625: if( !shltype( p->left->op, p->left ) ) { 626: order( p->left, INAREG|SOREG ); 627: } 628: 629: p->op = UNARY CALL; 630: m = match( p, INTAREG|INTBREG ); 631: popargs( temp ); 632: return(m != MDONE); 633: } 634: 635: popargs( size ) register size; { 636: /* pop arguments from stack */ 637: 638: toff -= size/2; 639: if( toff == 0 && size >= 2 ) size -= 2; 640: switch( size ) { 641: case 0: 642: break; 643: case 2: 644: printf( " tst (sp)+\n" ); 645: break; 646: case 4: 647: printf( " cmp (sp)+,(sp)+\n" ); 648: break; 649: default: 650: printf( " add $%d.,sp\n", size); 651: } 652: } 653: 654: char * 655: ccbranches[] = { 656: " jeq L%d\n", 657: " jne L%d\n", 658: " jle L%d\n", 659: " jlt L%d\n", 660: " jge L%d\n", 661: " jgt L%d\n", 662: " jlos L%d\n", 663: " jlo L%d\n", 664: " jhis L%d\n", 665: " jhi L%d\n", 666: }; 667: 668: /* long branch table 669: 670: This table, when indexed by a logical operator, 671: selects a set of three logical conditions required 672: to generate long comparisons and branches. A zero 673: entry indicates that no branch is required. 674: E.G.: The <= operator would generate: 675: cmp AL,AR 676: jlt lable / 1st entry LT -> lable 677: jgt 1f / 2nd entry GT -> 1f 678: cmp UL,UR 679: jlos lable / 3rd entry ULE -> lable 680: 1: 681: */ 682: 683: int lbranches[][3] = { 684: /*EQ*/ 0, NE, EQ, 685: /*NE*/ NE, 0, NE, 686: /*LE*/ LT, GT, ULE, 687: /*LT*/ LT, GT, ULT, 688: /*GE*/ GT, LT, UGE, 689: /*GT*/ GT, LT, UGT, 690: /*ULE*/ ULT, UGT, ULE, 691: /*ULT*/ ULT, UGT, ULT, 692: /*UGE*/ UGT, ULT, UGE, 693: /*UGT*/ UGT, ULT, UGT, 694: }; 695: 696: /* logical relations when compared in reverse order (cmp R,L) */ 697: #ifdef FORT 698: short revrel[] ={ EQ, NE, GE, GT, LE, LT, UGE, UGT, ULE, ULT }; 699: #else 700: extern short revrel[]; 701: #endif 702: 703: cbgen( o, lab, mode ) { /* printf conditional and unconditional branches */ 704: register *plb; 705: int lab1f; 706: 707: if( o == 0 ) printf( " jbr L%d\n", lab ); 708: else if( o > UGT ) cerror( "bad conditional branch: %s", opst[o] ); 709: else { 710: switch( brcase ) { 711: 712: case 'A': 713: case 'C': 714: plb = lbranches[ o-EQ ]; 715: lab1f = getlab(); 716: expand( brnode, FORCC, brcase=='C' ? "\tcmp\tAL,AR\n" : "\ttst\tAR\n" ); 717: if( *plb != 0 ) 718: printf( ccbranches[*plb-EQ], lab); 719: if( *++plb != 0 ) 720: printf( ccbranches[*plb-EQ], lab1f); 721: expand( brnode, FORCC, brcase=='C' ? "\tcmp\tUL,UR\n" : "\ttst\tUR\n" ); 722: printf( ccbranches[*++plb-EQ], lab); 723: deflab( lab1f ); 724: reclaim( brnode, RNULL, 0 ); 725: break; 726: 727: default: 728: if( mode=='F' ) o = revrel[ o-EQ ]; 729: printf( ccbranches[o-EQ], lab ); 730: break; 731: } 732: 733: brcase = 0; 734: brnode = 0; 735: } 736: } 737: 738: nextcook( p, cookie ) NODE *p; { 739: /* we have failed to match p with cookie; try another */ 740: if( cookie == FORREW ) return( 0 ); /* hopeless! */ 741: if( !(cookie&(INTAREG|INTBREG)) ) return( INTAREG|INTBREG ); 742: if( !(cookie&INTEMP) && asgop(p->op) ) return( INTEMP|INAREG|INTAREG|INTBREG|INBREG ); 743: return( FORREW ); 744: } 745: 746: lastchance( p, cook ) NODE *p; { 747: /* forget it! */ 748: return(0); 749: } 750: 751: struct functbl { 752: int fop; 753: TWORD ftype; 754: char *func; 755: } opfunc[] = { 756: MUL, LONG, "lmul", 757: DIV, LONG, "ldiv", 758: MOD, LONG, "lrem", 759: ASG MUL, LONG, "almul", 760: ASG DIV, LONG, "aldiv", 761: ASG MOD, LONG, "alrem", 762: MUL, ULONG, "lmul", 763: DIV, ULONG, "uldiv", 764: MOD, ULONG, "ulrem", 765: ASG MUL, ULONG, "almul", 766: ASG DIV, ULONG, "auldiv", 767: ASG MOD, ULONG, "aulrem", 768: 0, 0, 0 }; 769: 770: hardops(p) register NODE *p; { 771: /* change hard to do operators into function calls. 772: for pdp11 do long * / % */ 773: register NODE *q; 774: register struct functbl *f; 775: register o; 776: register TWORD t; 777: 778: o = p->op; 779: t = p->type; 780: if( t!=LONG && t!=ULONG ) return; 781: 782: for( f=opfunc; f->fop; f++ ) { 783: if( o==f->fop && t==f->ftype ) goto convert; 784: } 785: return; 786: 787: /* need address of left node for ASG OP */ 788: /* WARNING - this won't work for long in a REG */ 789: convert: 790: if( asgop( o ) ) { 791: switch( p->left->op ) { 792: 793: case UNARY MUL: /* convert to address */ 794: p->left->op = FREE; 795: p->left = p->left->left; 796: break; 797: 798: case NAME: /* convert to ICON pointer */ 799: p->left->op = ICON; 800: p->left->type = INCREF( p->left->type ); 801: break; 802: 803: case OREG: /* convert OREG to address */ 804: p->left->op = REG; 805: p->left->type = INCREF( p->left->type ); 806: if( p->left->lval != 0 ) { 807: q = talloc(); 808: q->op = PLUS; 809: q->rall = NOPREF; 810: q->type = p->left->type; 811: q->left = p->left; 812: q->right = talloc(); 813: 814: q->right->op = ICON; 815: q->right->rall = NOPREF; 816: q->right->type = INT; 817: q->right->name[0] = '\0'; 818: q->right->lval = p->left->lval; 819: q->right->rval = 0; 820: 821: p->left->lval = 0; 822: p->left = q; 823: } 824: break; 825: 826: default: 827: cerror( "Bad address for hard ops" ); 828: /* NO RETURN */ 829: 830: } 831: } 832: 833: /* build comma op for args to function */ 834: q = talloc(); 835: q->op = CM; 836: q->rall = NOPREF; 837: q->type = INT; 838: q->left = p->left; 839: q->right = p->right; 840: p->op = CALL; 841: p->right = q; 842: 843: /* put function name in left node of call */ 844: p->left = q = talloc(); 845: q->op = ICON; 846: q->rall = NOPREF; 847: q->type = INCREF( FTN + p->type ); 848: strcpy( q->name, f->func ); 849: q->lval = 0; 850: q->rval = 0; 851: 852: return; 853: 854: } 855: 856: optim2( p ) register NODE *p; { 857: /* do local tree transformations and optimizations */ 858: 859: register NODE *r; 860: 861: switch( p->op ) { 862: 863: case AND: 864: /* commute L and R to eliminate compliments and constants */ 865: if( p->left->op==ICON || p->left->op==COMPL ) { 866: r = p->left; 867: p->left = p->right; 868: p->right = r; 869: } 870: case ASG AND: 871: /* change meaning of AND to ~R&L - bic on pdp11 */ 872: r = p->right; 873: if( r->op==ICON ) { /* compliment constant */ 874: r->lval = ~r->lval; 875: } 876: else if( r->op==COMPL ) { /* ~~A => A */ 877: r->op = FREE; 878: p->right = r->left; 879: } 880: else { /* insert complement node */ 881: p->right = talloc(); 882: p->right->op = COMPL; 883: p->right->rall = NOPREF; 884: p->right->type = r->type; 885: p->right->left = r; 886: p->right->right = NULL; 887: } 888: break; 889: 890: } 891: } 892: 893: myreader(p) register NODE *p; { 894: walkf( p, hardops ); /* convert ops to function calls */ 895: canon( p ); /* expands r-vals for fileds */ 896: walkf( p, optim2 ); 897: toff = 0; /* stack offset swindle */ 898: } 899: 900: special( p, shape ) register NODE *p; { 901: /* special shape matching routine */ 902: 903: switch( shape ) { 904: 905: case SCCON: 906: if( p->op == ICON && p->name[0]=='\0' && p->lval>= -128 && p->lval <=127 ) return( 1 ); 907: break; 908: 909: case SICON: 910: if( p->op == ICON && p->name[0]=='\0' && p->lval>= 0 && p->lval <=32767 ) return( 1 ); 911: break; 912: 913: default: 914: cerror( "bad special shape" ); 915: 916: } 917: 918: return( 0 ); 919: } 920: 921: # ifndef ONEPASS 922: main( argc, argv ) char *argv[]; { 923: return( mainp2( argc, argv ) ); 924: } 925: # endif