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