|
|
1.1 ! root 1: static char *sccsid ="%W% (Berkeley) %G%"; ! 2: # include "mfile2" ! 3: # include "ctype.h" ! 4: /* a lot of the machine dependent parts of the second pass */ ! 5: ! 6: # define BITMASK(n) ((1L<<n)-1) ! 7: ! 8: where(c){ ! 9: fprintf( stderr, "%s, line %d: ", filename, lineno ); ! 10: } ! 11: ! 12: lineid( l, fn ) char *fn; { ! 13: /* identify line l and file fn */ ! 14: printf( "# line %d, file %s\n", l, fn ); ! 15: } ! 16: ! 17: ! 18: eobl2(){ ! 19: OFFSZ spoff; /* offset from stack pointer */ ! 20: #ifdef FORT ! 21: spoff = maxoff; ! 22: if( spoff >= AUTOINIT ) spoff -= AUTOINIT; ! 23: spoff /= SZCHAR; ! 24: SETOFF(spoff,4); ! 25: #ifndef FLEXNAMES ! 26: printf( " .set .F%d,%ld\n", ftnno, spoff ); ! 27: #else ! 28: /* SHOULD BE L%d ... ftnno but must change pc/f77 */ ! 29: printf( " .set LF%d,%ld\n", ftnno, spoff ); ! 30: #endif ! 31: #else ! 32: extern int ftlab1, ftlab2; ! 33: ! 34: spoff = maxoff; ! 35: if( spoff >= AUTOINIT ) spoff -= AUTOINIT; ! 36: spoff /= SZCHAR; ! 37: SETOFF(spoff,4); ! 38: printf( "L%d:\n", ftlab1); ! 39: if( spoff!=0 ) ! 40: if( spoff < 64 ) ! 41: printf( " subl2 $%ld,sp\n", spoff); ! 42: else ! 43: printf( " movab -%ld(sp),sp\n", spoff); ! 44: printf( " jbr L%d\n", ftlab2); ! 45: #endif ! 46: maxargs = -1; ! 47: } ! 48: ! 49: struct hoptab { int opmask; char * opstring; } ioptab[] = { ! 50: ! 51: ASG PLUS, "add", ! 52: ASG MINUS, "sub", ! 53: ASG MUL, "mul", ! 54: ASG DIV, "div", ! 55: ASG OR, "bis", ! 56: ASG ER, "xor", ! 57: ASG AND, "bic", ! 58: PLUS, "add", ! 59: MINUS, "sub", ! 60: MUL, "mul", ! 61: DIV, "div", ! 62: OR, "bis", ! 63: ER, "xor", ! 64: AND, "bic", ! 65: -1, "" }; ! 66: ! 67: hopcode( f, o ){ ! 68: /* output the appropriate string from the above table */ ! 69: ! 70: register struct hoptab *q; ! 71: ! 72: for( q = ioptab; q->opmask>=0; ++q ){ ! 73: if( q->opmask == o ){ ! 74: printf( "%s", q->opstring ); ! 75: /* tbl ! 76: if( f == 'F' ) printf( "e" ); ! 77: else if( f == 'D' ) printf( "d" ); ! 78: tbl */ ! 79: /* tbl */ ! 80: switch( f ) { ! 81: case 'L': ! 82: case 'W': ! 83: case 'B': ! 84: case 'D': ! 85: case 'F': ! 86: printf("%c", tolower(f)); ! 87: break; ! 88: ! 89: } ! 90: /* tbl */ ! 91: return; ! 92: } ! 93: } ! 94: cerror( "no hoptab for %s", opst[o] ); ! 95: } ! 96: ! 97: char * ! 98: rnames[] = { /* keyed to register number tokens */ ! 99: ! 100: "r0", "r1", ! 101: "r2", "r3", "r4", "r5", ! 102: "r6", "r7", "r8", "r9", "r10", "r11", ! 103: "ap", "fp", "sp", "pc", ! 104: ! 105: }; ! 106: ! 107: int rstatus[] = { ! 108: SAREG|STAREG, SAREG|STAREG, ! 109: SAREG|STAREG, SAREG|STAREG, SAREG|STAREG, SAREG|STAREG, ! 110: SAREG, SAREG, SAREG, SAREG, SAREG, SAREG, ! 111: SAREG, SAREG, SAREG, SAREG, ! 112: ! 113: }; ! 114: ! 115: tlen(p) NODE *p; ! 116: { ! 117: switch(p->in.type) { ! 118: case CHAR: ! 119: case UCHAR: ! 120: return(1); ! 121: ! 122: case SHORT: ! 123: case USHORT: ! 124: return(2); ! 125: ! 126: case DOUBLE: ! 127: return(8); ! 128: ! 129: default: ! 130: return(4); ! 131: } ! 132: } ! 133: ! 134: mixtypes(p, q) NODE *p, *q; ! 135: { ! 136: register tp, tq; ! 137: ! 138: tp = p->in.type; ! 139: tq = q->in.type; ! 140: ! 141: return( (tp==FLOAT || tp==DOUBLE) != ! 142: (tq==FLOAT || tq==DOUBLE) ); ! 143: } ! 144: ! 145: prtype(n) NODE *n; ! 146: { ! 147: switch (n->in.type) ! 148: { ! 149: case DOUBLE: ! 150: printf("d"); ! 151: return; ! 152: ! 153: case FLOAT: ! 154: printf("f"); ! 155: return; ! 156: ! 157: case LONG: ! 158: case ULONG: ! 159: case INT: ! 160: case UNSIGNED: ! 161: printf("l"); ! 162: return; ! 163: ! 164: case SHORT: ! 165: case USHORT: ! 166: printf("w"); ! 167: return; ! 168: ! 169: case CHAR: ! 170: case UCHAR: ! 171: printf("b"); ! 172: return; ! 173: ! 174: default: ! 175: if ( !ISPTR( n->in.type ) ) cerror("zzzcode- bad type"); ! 176: else { ! 177: printf("l"); ! 178: return; ! 179: } ! 180: } ! 181: } ! 182: ! 183: zzzcode( p, c ) register NODE *p; { ! 184: register m; ! 185: CONSZ val; ! 186: switch( c ){ ! 187: ! 188: case 'N': /* logical ops, turned into 0-1 */ ! 189: /* use register given by register 1 */ ! 190: cbgen( 0, m=getlab(), 'I' ); ! 191: deflab( p->bn.label ); ! 192: printf( " clrl %s\n", rnames[getlr( p, '1' )->tn.rval] ); ! 193: deflab( m ); ! 194: return; ! 195: ! 196: case 'I': ! 197: case 'P': ! 198: cbgen( p->in.op, p->bn.label, c ); ! 199: return; ! 200: ! 201: case 'A': ! 202: { ! 203: register NODE *l, *r; ! 204: ! 205: if (xdebug) eprint(p, 0, &val, &val); ! 206: r = getlr(p, 'R'); ! 207: if (optype(p->in.op) == LTYPE || p->in.op == UNARY MUL) ! 208: { ! 209: l = resc; ! 210: l->in.type = (r->in.type==FLOAT || r->in.type==DOUBLE ? DOUBLE : INT); ! 211: } ! 212: else ! 213: l = getlr(p, 'L'); ! 214: if (r->in.op == ICON) ! 215: if(r->in.name[0] == '\0') ! 216: { ! 217: if (r->tn.lval == 0) ! 218: { ! 219: printf("clr"); ! 220: prtype(l); ! 221: printf(" "); ! 222: adrput(l); ! 223: return; ! 224: } ! 225: if (r->tn.lval < 0 && r->tn.lval >= -63) ! 226: { ! 227: printf("mneg"); ! 228: prtype(l); ! 229: r->tn.lval = -r->tn.lval; ! 230: goto ops; ! 231: } ! 232: r->in.type = (r->tn.lval < 0 ? ! 233: (r->tn.lval >= -128 ? CHAR ! 234: : (r->tn.lval >= -32768 ? SHORT ! 235: : INT )) : r->in.type); ! 236: r->in.type = (r->tn.lval >= 0 ? ! 237: (r->tn.lval <= 63 ? INT ! 238: : ( r->tn.lval <= 127 ? CHAR ! 239: : (r->tn.lval <= 255 ? UCHAR ! 240: : (r->tn.lval <= 32767 ? SHORT ! 241: : (r->tn.lval <= 65535 ? USHORT ! 242: : INT ))))) : r->in.type ); ! 243: } ! 244: else ! 245: { ! 246: printf("moval"); ! 247: printf(" "); ! 248: acon(r); ! 249: printf(","); ! 250: adrput(l); ! 251: return; ! 252: } ! 253: ! 254: if (l->in.op == REG && l->in.type != FLOAT && l->in.type != DOUBLE) ! 255: { ! 256: if( tlen(l) < tlen(r) ) ! 257: { ! 258: if (!mixtypes(l,r)) ! 259: { ! 260: !ISUNSIGNED(l->in.type)? ! 261: printf("cvt"): ! 262: printf("movz"); ! 263: prtype(l); ! 264: printf("l"); ! 265: goto ops; ! 266: } ! 267: else ! 268: { ! 269: printf("cvt"); ! 270: prtype(r); ! 271: prtype(l); ! 272: printf(" "); ! 273: adrput(r); ! 274: printf(","); ! 275: adrput(l); ! 276: printf("cvt"); ! 277: prtype(l); ! 278: printf("l"); ! 279: printf(" "); ! 280: adrput(l); ! 281: printf(","); ! 282: adrput(l); ! 283: return; ! 284: } ! 285: } ! 286: else ! 287: { ! 288: l->in.type = INT; ! 289: } ! 290: } ! 291: if (!mixtypes(l,r)) ! 292: { ! 293: if (tlen(l) == tlen(r)) ! 294: { ! 295: printf("mov"); ! 296: prtype(l); ! 297: goto ops; ! 298: } ! 299: else if (tlen(l) > tlen(r) && ISUNSIGNED(r->in.type)) ! 300: { ! 301: printf("movz"); ! 302: } ! 303: else ! 304: { ! 305: printf("cvt"); ! 306: } ! 307: } ! 308: else ! 309: { ! 310: printf("cvt"); ! 311: } ! 312: prtype(r); ! 313: prtype(l); ! 314: ops: ! 315: printf(" "); ! 316: adrput(r); ! 317: printf(","); ! 318: adrput(l); ! 319: return; ! 320: } ! 321: ! 322: case 'B': /* get oreg value in temp register for left shift */ ! 323: { ! 324: register NODE *r; ! 325: if (xdebug) eprint(p, 0, &val, &val); ! 326: r = p->in.right; ! 327: if( tlen(r) == sizeof(int) && r->in.type != FLOAT ) ! 328: printf("movl"); ! 329: else { ! 330: printf("cvt"); ! 331: prtype(r); ! 332: printf("l"); ! 333: } ! 334: return; ! 335: } ! 336: ! 337: case 'C': /* num words pushed on arg stack */ ! 338: { ! 339: extern int gc_numbytes; ! 340: extern int xdebug; ! 341: ! 342: if (xdebug) printf("->%d<-",gc_numbytes); ! 343: ! 344: printf("$%d", gc_numbytes/(SZLONG/SZCHAR) ); ! 345: return; ! 346: } ! 347: ! 348: case 'D': /* INCR and DECR */ ! 349: zzzcode(p->in.left, 'A'); ! 350: printf("\n "); ! 351: ! 352: case 'E': /* INCR and DECR, FOREFF */ ! 353: if (p->in.right->tn.lval == 1) ! 354: { ! 355: printf("%s", (p->in.op == INCR ? "inc" : "dec") ); ! 356: prtype(p->in.left); ! 357: printf(" "); ! 358: adrput(p->in.left); ! 359: return; ! 360: } ! 361: printf("%s", (p->in.op == INCR ? "add" : "sub") ); ! 362: prtype(p->in.left); ! 363: printf("2 "); ! 364: adrput(p->in.right); ! 365: printf(","); ! 366: adrput(p->in.left); ! 367: return; ! 368: ! 369: case 'F': /* register type of right operand */ ! 370: { ! 371: register NODE *n; ! 372: extern int xdebug; ! 373: register int ty; ! 374: ! 375: n = getlr( p, 'R' ); ! 376: ty = n->in.type; ! 377: ! 378: if (xdebug) printf("->%d<-", ty); ! 379: ! 380: if ( ty==DOUBLE) printf("d"); ! 381: else if ( ty==FLOAT ) printf("f"); ! 382: else printf("l"); ! 383: return; ! 384: } ! 385: ! 386: case 'L': /* type of left operand */ ! 387: case 'R': /* type of right operand */ ! 388: { ! 389: register NODE *n; ! 390: extern int xdebug; ! 391: ! 392: n = getlr ( p, c); ! 393: if (xdebug) printf("->%d<-", n->in.type); ! 394: ! 395: prtype(n); ! 396: return; ! 397: } ! 398: ! 399: case 'Z': /* complement mask for bit instr */ ! 400: printf("$%ld", ~p->in.right->tn.lval); ! 401: return; ! 402: ! 403: case 'U': /* 32 - n, for unsigned right shifts */ ! 404: printf("$%d", 32 - p->in.right->tn.lval ); ! 405: return; ! 406: ! 407: case 'T': /* rounded structure length for arguments */ ! 408: { ! 409: int size; ! 410: ! 411: size = p->stn.stsize; ! 412: SETOFF( size, 4); ! 413: printf("$%d", size); ! 414: return; ! 415: } ! 416: ! 417: case 'S': /* structure assignment */ ! 418: { ! 419: register NODE *l, *r; ! 420: register size; ! 421: ! 422: if( p->in.op == STASG ){ ! 423: l = p->in.left; ! 424: r = p->in.right; ! 425: ! 426: } ! 427: else if( p->in.op == STARG ){ /* store an arg into a temporary */ ! 428: l = getlr( p, '3' ); ! 429: r = p->in.left; ! 430: } ! 431: else cerror( "STASG bad" ); ! 432: ! 433: if( r->in.op == ICON ) r->in.op = NAME; ! 434: else if( r->in.op == REG ) r->in.op = OREG; ! 435: else if( r->in.op != OREG ) cerror( "STASG-r" ); ! 436: ! 437: size = p->stn.stsize; ! 438: ! 439: if( size <= 0 || size > 65535 ) ! 440: cerror("structure size <0=0 or >65535"); ! 441: ! 442: switch(size) { ! 443: case 1: ! 444: printf(" movb "); ! 445: break; ! 446: case 2: ! 447: printf(" movw "); ! 448: break; ! 449: case 4: ! 450: printf(" movl "); ! 451: break; ! 452: case 8: ! 453: printf(" movq "); ! 454: break; ! 455: default: ! 456: printf(" movc3 $%d,", size); ! 457: break; ! 458: } ! 459: adrput(r); ! 460: printf(","); ! 461: adrput(l); ! 462: printf("\n"); ! 463: ! 464: if( r->in.op == NAME ) r->in.op = ICON; ! 465: else if( r->in.op == OREG ) r->in.op = REG; ! 466: ! 467: } ! 468: break; ! 469: ! 470: default: ! 471: cerror( "illegal zzzcode" ); ! 472: } ! 473: } ! 474: ! 475: rmove( rt, rs, t ){ ! 476: printf( " %s %s,%s\n", ! 477: (t==FLOAT ? "movf" : (t==DOUBLE ? "movd" : "movl")), ! 478: rnames[rs], rnames[rt] ); ! 479: } ! 480: ! 481: struct respref ! 482: respref[] = { ! 483: INTAREG|INTBREG, INTAREG|INTBREG, ! 484: INAREG|INBREG, INAREG|INBREG|SOREG|STARREG|STARNM|SNAME|SCON, ! 485: INTEMP, INTEMP, ! 486: FORARG, FORARG, ! 487: INTEMP, INTAREG|INAREG|INTBREG|INBREG|SOREG|STARREG|STARNM, ! 488: 0, 0 }; ! 489: ! 490: setregs(){ /* set up temporary registers */ ! 491: fregs = 6; /* tbl- 6 free regs on VAX (0-5) */ ! 492: ; ! 493: } ! 494: ! 495: szty(t){ /* size, in registers, needed to hold thing of type t */ ! 496: return( (t==DOUBLE||t==FLOAT) ? 2 : 1 ); ! 497: } ! 498: ! 499: rewfld( p ) NODE *p; { ! 500: return(1); ! 501: } ! 502: ! 503: callreg(p) NODE *p; { ! 504: return( R0 ); ! 505: } ! 506: ! 507: base( p ) register NODE *p; { ! 508: register int o = p->in.op; ! 509: ! 510: if( (o==ICON && p->in.name[0] != '\0')) return( 100 ); /* ie no base reg */ ! 511: if( o==REG ) return( p->tn.rval ); ! 512: if( (o==PLUS || o==MINUS) && p->in.left->in.op == REG && p->in.right->in.op==ICON) ! 513: return( p->in.left->tn.rval ); ! 514: if( o==OREG && !R2TEST(p->tn.rval) && (p->in.type==INT || p->in.type==UNSIGNED || ISPTR(p->in.type)) ) ! 515: return( p->tn.rval + 0200*1 ); ! 516: if( o==INCR && p->in.left->in.op==REG ) return( p->in.left->tn.rval + 0200*2 ); ! 517: if( o==ASG MINUS && p->in.left->in.op==REG) return( p->in.left->tn.rval + 0200*4 ); ! 518: if( o==UNARY MUL && p->in.left->in.op==INCR && p->in.left->in.left->in.op==REG ! 519: && (p->in.type==INT || p->in.type==UNSIGNED || ISPTR(p->in.type)) ) ! 520: return( p->in.left->in.left->tn.rval + 0200*(1+2) ); ! 521: return( -1 ); ! 522: } ! 523: ! 524: offset( p, tyl ) register NODE *p; int tyl; { ! 525: ! 526: if( tyl==1 && p->in.op==REG && (p->in.type==INT || p->in.type==UNSIGNED) ) return( p->tn.rval ); ! 527: if( (p->in.op==LS && p->in.left->in.op==REG && (p->in.left->in.type==INT || p->in.left->in.type==UNSIGNED) && ! 528: (p->in.right->in.op==ICON && p->in.right->in.name[0]=='\0') ! 529: && (1<<p->in.right->tn.lval)==tyl)) ! 530: return( p->in.left->tn.rval ); ! 531: return( -1 ); ! 532: } ! 533: ! 534: makeor2( p, q, b, o) register NODE *p, *q; register int b, o; { ! 535: register NODE *t; ! 536: register int i; ! 537: NODE *f; ! 538: ! 539: p->in.op = OREG; ! 540: f = p->in.left; /* have to free this subtree later */ ! 541: ! 542: /* init base */ ! 543: switch (q->in.op) { ! 544: case ICON: ! 545: case REG: ! 546: case OREG: ! 547: t = q; ! 548: break; ! 549: ! 550: case MINUS: ! 551: q->in.right->tn.lval = -q->in.right->tn.lval; ! 552: case PLUS: ! 553: t = q->in.right; ! 554: break; ! 555: ! 556: case INCR: ! 557: case ASG MINUS: ! 558: t = q->in.left; ! 559: break; ! 560: ! 561: case UNARY MUL: ! 562: t = q->in.left->in.left; ! 563: break; ! 564: ! 565: default: ! 566: cerror("illegal makeor2"); ! 567: } ! 568: ! 569: p->tn.lval = t->tn.lval; ! 570: #ifndef FLEXNAMES ! 571: for(i=0; i<NCHNAM; ++i) ! 572: p->in.name[i] = t->in.name[i]; ! 573: #else ! 574: p->in.name = t->in.name; ! 575: #endif ! 576: ! 577: /* init offset */ ! 578: p->tn.rval = R2PACK( (b & 0177), o, (b>>7) ); ! 579: ! 580: tfree(f); ! 581: return; ! 582: } ! 583: ! 584: canaddr( p ) NODE *p; { ! 585: register int o = p->in.op; ! 586: ! 587: if( o==NAME || o==REG || o==ICON || o==OREG || (o==UNARY MUL && shumul(p->in.left)) ) return(1); ! 588: return(0); ! 589: } ! 590: ! 591: shltype( o, p ) register NODE *p; { ! 592: return( o== REG || o == NAME || o == ICON || o == OREG || ( o==UNARY MUL && shumul(p->in.left)) ); ! 593: } ! 594: ! 595: flshape( p ) register NODE *p; { ! 596: return( p->in.op == REG || p->in.op == NAME || p->in.op == ICON || ! 597: (p->in.op == OREG && (!R2TEST(p->tn.rval) || tlen(p) == 1)) ); ! 598: } ! 599: ! 600: shtemp( p ) register NODE *p; { ! 601: if( p->in.op == STARG ) p = p->in.left; ! 602: return( p->in.op==NAME || p->in.op ==ICON || p->in.op == OREG || (p->in.op==UNARY MUL && shumul(p->in.left)) ); ! 603: } ! 604: ! 605: shumul( p ) register NODE *p; { ! 606: register o; ! 607: extern int xdebug; ! 608: ! 609: if (xdebug) { ! 610: printf("\nshumul:op=%d,lop=%d,rop=%d", p->in.op, p->in.left->in.op, p->in.right->in.op); ! 611: printf(" prname=%s,plty=%d, prlval=%D\n", p->in.right->in.name, p->in.left->in.type, p->in.right->tn.lval); ! 612: } ! 613: ! 614: ! 615: o = p->in.op; ! 616: if( o == NAME || (o == OREG && !R2TEST(p->tn.rval)) || o == ICON ) return( STARNM ); ! 617: ! 618: if( ( o == INCR || o == ASG MINUS ) && ! 619: ( p->in.left->in.op == REG && p->in.right->in.op == ICON ) && ! 620: p->in.right->in.name[0] == '\0' ) ! 621: { ! 622: switch (p->in.left->in.type) ! 623: { ! 624: case CHAR|PTR: ! 625: case UCHAR|PTR: ! 626: o = 1; ! 627: break; ! 628: ! 629: case SHORT|PTR: ! 630: case USHORT|PTR: ! 631: o = 2; ! 632: break; ! 633: ! 634: case INT|PTR: ! 635: case UNSIGNED|PTR: ! 636: case LONG|PTR: ! 637: case ULONG|PTR: ! 638: case FLOAT|PTR: ! 639: o = 4; ! 640: break; ! 641: ! 642: case DOUBLE|PTR: ! 643: o = 8; ! 644: break; ! 645: ! 646: default: ! 647: if ( ISPTR(p->in.left->in.type) ) { ! 648: o = 4; ! 649: break; ! 650: } ! 651: else return(0); ! 652: } ! 653: return( p->in.right->tn.lval == o ? STARREG : 0); ! 654: } ! 655: ! 656: return( 0 ); ! 657: } ! 658: ! 659: adrcon( val ) CONSZ val; { ! 660: printf( "$" ); ! 661: printf( CONFMT, val ); ! 662: } ! 663: ! 664: conput( p ) register NODE *p; { ! 665: switch( p->in.op ){ ! 666: ! 667: case ICON: ! 668: acon( p ); ! 669: return; ! 670: ! 671: case REG: ! 672: printf( "%s", rnames[p->tn.rval] ); ! 673: return; ! 674: ! 675: default: ! 676: cerror( "illegal conput" ); ! 677: } ! 678: } ! 679: ! 680: insput( p ) register NODE *p; { ! 681: cerror( "insput" ); ! 682: } ! 683: ! 684: upput( p ) register NODE *p; { ! 685: cerror( "upput" ); ! 686: } ! 687: ! 688: adrput( p ) register NODE *p; { ! 689: register int r; ! 690: /* output an address, with offsets, from p */ ! 691: ! 692: if( p->in.op == FLD ){ ! 693: p = p->in.left; ! 694: } ! 695: switch( p->in.op ){ ! 696: ! 697: case NAME: ! 698: acon( p ); ! 699: return; ! 700: ! 701: case ICON: ! 702: /* addressable value of the constant */ ! 703: printf( "$" ); ! 704: acon( p ); ! 705: return; ! 706: ! 707: case REG: ! 708: printf( "%s", rnames[p->tn.rval] ); ! 709: return; ! 710: ! 711: case OREG: ! 712: r = p->tn.rval; ! 713: if( R2TEST(r) ){ /* double indexing */ ! 714: register int flags; ! 715: ! 716: flags = R2UPK3(r); ! 717: if( flags & 1 ) printf("*"); ! 718: if( flags & 4 ) printf("-"); ! 719: if( p->tn.lval != 0 || p->in.name[0] != '\0' ) acon(p); ! 720: if( R2UPK1(r) != 100) printf( "(%s)", rnames[R2UPK1(r)] ); ! 721: if( flags & 2 ) printf("+"); ! 722: printf( "[%s]", rnames[R2UPK2(r)] ); ! 723: return; ! 724: } ! 725: if( r == AP ){ /* in the argument region */ ! 726: if( p->tn.lval <= 0 || p->in.name[0] != '\0' ) werror( "bad arg temp" ); ! 727: printf( CONFMT, p->tn.lval ); ! 728: printf( "(ap)" ); ! 729: return; ! 730: } ! 731: if( p->tn.lval != 0 || p->in.name[0] != '\0') acon( p ); ! 732: printf( "(%s)", rnames[p->tn.rval] ); ! 733: return; ! 734: ! 735: case UNARY MUL: ! 736: /* STARNM or STARREG found */ ! 737: if( tshape(p, STARNM) ) { ! 738: printf( "*" ); ! 739: adrput( p->in.left); ! 740: } ! 741: else { /* STARREG - really auto inc or dec */ ! 742: register NODE *q; ! 743: ! 744: /* tbl ! 745: p = p->in.left; ! 746: p->in.left->in.op = OREG; ! 747: if( p->in.op == INCR ) { ! 748: adrput( p->in.left ); ! 749: printf( "+" ); ! 750: } ! 751: else { ! 752: printf( "-" ); ! 753: adrput( p->in.left ); ! 754: } ! 755: tbl */ ! 756: printf("%s(%s)%s", (p->in.left->in.op==INCR ? "" : "-"), ! 757: rnames[p->in.left->in.left->tn.rval], ! 758: (p->in.left->in.op==INCR ? "+" : "") ); ! 759: p->in.op = OREG; ! 760: p->tn.rval = p->in.left->in.left->tn.rval; ! 761: q = p->in.left; ! 762: p->tn.lval = (p->in.left->in.op == INCR ? -p->in.left->in.right->tn.lval : 0); ! 763: #ifndef FLEXNAMES ! 764: p->in.name[0] = '\0'; ! 765: #else ! 766: p->in.name = ""; ! 767: #endif ! 768: tfree(q); ! 769: } ! 770: return; ! 771: ! 772: default: ! 773: cerror( "illegal address" ); ! 774: return; ! 775: ! 776: } ! 777: ! 778: } ! 779: ! 780: acon( p ) register NODE *p; { /* print out a constant */ ! 781: ! 782: if( p->in.name[0] == '\0' ){ ! 783: printf( CONFMT, p->tn.lval); ! 784: } ! 785: else if( p->tn.lval == 0 ) { ! 786: #ifndef FLEXNAMES ! 787: printf( "%.8s", p->in.name ); ! 788: #else ! 789: printf( "%s", p->in.name ); ! 790: #endif ! 791: } ! 792: else { ! 793: #ifndef FLEXNAMES ! 794: printf( "%.8s+", p->in.name ); ! 795: #else ! 796: printf( "%s+", p->in.name ); ! 797: #endif ! 798: printf( CONFMT, p->tn.lval ); ! 799: } ! 800: } ! 801: ! 802: /* ! 803: aacon( p ) register NODE *p; { /* print out a constant */ ! 804: /* ! 805: ! 806: if( p->in.name[0] == '\0' ){ ! 807: printf( CONFMT, p->tn.lval); ! 808: return( 0 ); ! 809: } ! 810: else if( p->tn.lval == 0 ) { ! 811: #ifndef FLEXNAMES ! 812: printf( "$%.8s", p->in.name ); ! 813: #else ! 814: printf( "$%s", p->in.name ); ! 815: #endif ! 816: return( 1 ); ! 817: } ! 818: else { ! 819: printf( "$(" ); ! 820: printf( CONFMT, p->tn.lval ); ! 821: printf( "+" ); ! 822: #ifndef FLEXNAMES ! 823: printf( "%.8s)", p->in.name ); ! 824: #else ! 825: printf( "%s)", p->in.name ); ! 826: #endif ! 827: return(1); ! 828: } ! 829: } ! 830: */ ! 831: ! 832: genscall( p, cookie ) register NODE *p; { ! 833: /* structure valued call */ ! 834: return( gencall( p, cookie ) ); ! 835: } ! 836: ! 837: /* tbl */ ! 838: int gc_numbytes; ! 839: /* tbl */ ! 840: ! 841: gencall( p, cookie ) register NODE *p; { ! 842: /* generate the call given by p */ ! 843: register NODE *p1, *ptemp; ! 844: register temp, temp1; ! 845: register m; ! 846: ! 847: if( p->in.right ) temp = argsize( p->in.right ); ! 848: else temp = 0; ! 849: ! 850: if( p->in.op == STCALL || p->in.op == UNARY STCALL ){ ! 851: /* set aside room for structure return */ ! 852: ! 853: if( p->stn.stsize > temp ) temp1 = p->stn.stsize; ! 854: else temp1 = temp; ! 855: } ! 856: ! 857: if( temp > maxargs ) maxargs = temp; ! 858: SETOFF(temp1,4); ! 859: ! 860: if( p->in.right ){ /* make temp node, put offset in, and generate args */ ! 861: ptemp = talloc(); ! 862: ptemp->in.op = OREG; ! 863: ptemp->tn.lval = -1; ! 864: ptemp->tn.rval = SP; ! 865: #ifndef FLEXNAMES ! 866: ptemp->in.name[0] = '\0'; ! 867: #else ! 868: ptemp->in.name = ""; ! 869: #endif ! 870: ptemp->in.rall = NOPREF; ! 871: ptemp->in.su = 0; ! 872: genargs( p->in.right, ptemp ); ! 873: ptemp->in.op = FREE; ! 874: } ! 875: ! 876: p1 = p->in.left; ! 877: if( p1->in.op != ICON ){ ! 878: if( p1->in.op != REG ){ ! 879: if( p1->in.op != OREG || R2TEST(p1->tn.rval) ){ ! 880: if( p1->in.op != NAME ){ ! 881: order( p1, INAREG ); ! 882: } ! 883: } ! 884: } ! 885: } ! 886: ! 887: /* ! 888: if( p1->in.op == REG && p->tn.rval == R5 ){ ! 889: cerror( "call register overwrite" ); ! 890: } ! 891: */ ! 892: /* tbl ! 893: setup gc_numbytes so reference to ZC works */ ! 894: ! 895: gc_numbytes = temp; ! 896: /* tbl */ ! 897: ! 898: p->in.op = UNARY CALL; ! 899: m = match( p, INTAREG|INTBREG ); ! 900: /* tbl ! 901: switch( temp ) { ! 902: case 0: ! 903: break; ! 904: case 2: ! 905: printf( " tst (sp)+\n" ); ! 906: break; ! 907: case 4: ! 908: printf( " cmp (sp)+,(sp)+\n" ); ! 909: break; ! 910: default: ! 911: printf( " add $%d,sp\n", temp); ! 912: } ! 913: tbl */ ! 914: return(m != MDONE); ! 915: } ! 916: ! 917: /* tbl */ ! 918: char * ! 919: ccbranches[] = { ! 920: " jeql L%d\n", ! 921: " jneq L%d\n", ! 922: " jleq L%d\n", ! 923: " jlss L%d\n", ! 924: " jgeq L%d\n", ! 925: " jgtr L%d\n", ! 926: " jlequ L%d\n", ! 927: " jlssu L%d\n", ! 928: " jgequ L%d\n", ! 929: " jgtru L%d\n", ! 930: }; ! 931: /* tbl */ ! 932: ! 933: cbgen( o, lab, mode ) { /* printf conditional and unconditional branches */ ! 934: ! 935: /* tbl */ ! 936: if( o == 0 ) printf( " jbr L%d\n", lab ); ! 937: /* tbl */ ! 938: else { ! 939: if( o > UGT ) cerror( "bad conditional branch: %s", opst[o] ); ! 940: printf( ccbranches[o-EQ], lab ); ! 941: } ! 942: } ! 943: ! 944: nextcook( p, cookie ) NODE *p; { ! 945: /* we have failed to match p with cookie; try another */ ! 946: if( cookie == FORREW ) return( 0 ); /* hopeless! */ ! 947: if( !(cookie&(INTAREG|INTBREG)) ) return( INTAREG|INTBREG ); ! 948: if( !(cookie&INTEMP) && asgop(p->in.op) ) return( INTEMP|INAREG|INTAREG|INTBREG|INBREG ); ! 949: return( FORREW ); ! 950: } ! 951: ! 952: lastchance( p, cook ) NODE *p; { ! 953: /* forget it! */ ! 954: return(0); ! 955: } ! 956: ! 957: optim2( p ) register NODE *p; { ! 958: /* do local tree transformations and optimizations */ ! 959: ! 960: register NODE *r; ! 961: ! 962: switch( p->in.op ) { ! 963: ! 964: case AND: ! 965: /* commute L and R to eliminate compliments and constants */ ! 966: if( (p->in.left->in.op==ICON&&p->in.left->in.name[0]==0) || p->in.left->in.op==COMPL ) { ! 967: r = p->in.left; ! 968: p->in.left = p->in.right; ! 969: p->in.right = r; ! 970: } ! 971: case ASG AND: ! 972: /* change meaning of AND to ~R&L - bic on pdp11 */ ! 973: r = p->in.right; ! 974: if( r->in.op==ICON && r->in.name[0]==0 ) { /* compliment constant */ ! 975: r->tn.lval = ~r->tn.lval; ! 976: } ! 977: else if( r->in.op==COMPL ) { /* ~~A => A */ ! 978: r->in.op = FREE; ! 979: p->in.right = r->in.left; ! 980: } ! 981: else { /* insert complement node */ ! 982: p->in.right = talloc(); ! 983: p->in.right->in.op = COMPL; ! 984: p->in.right->in.rall = NOPREF; ! 985: p->in.right->in.type = r->in.type; ! 986: p->in.right->in.left = r; ! 987: p->in.right->in.right = NULL; ! 988: } ! 989: break; ! 990: ! 991: } ! 992: } ! 993: ! 994: NODE * addroreg(l) ! 995: /* OREG was built in clocal() ! 996: * for an auto or formal parameter ! 997: * now its address is being taken ! 998: * local code must unwind it ! 999: * back to PLUS/MINUS REG ICON ! 1000: * according to local conventions ! 1001: */ ! 1002: { ! 1003: cerror("address of OREG taken"); ! 1004: } ! 1005: ! 1006: ! 1007: ! 1008: # ifndef ONEPASS ! 1009: main( argc, argv ) char *argv[]; { ! 1010: return( mainp2( argc, argv ) ); ! 1011: } ! 1012: # endif ! 1013: ! 1014: ! 1015: /* added by jwf */ ! 1016: struct functbl { ! 1017: int fop; ! 1018: TWORD ftype; ! 1019: char *func; ! 1020: } opfunc[] = { ! 1021: DIV, TANY, "udiv", ! 1022: MOD, TANY, "urem", ! 1023: ASG DIV, TANY, "udiv", ! 1024: ASG MOD, TANY, "urem", ! 1025: 0, 0, 0 }; ! 1026: ! 1027: hardops(p) register NODE *p; { ! 1028: /* change hard to do operators into function calls. */ ! 1029: register NODE *q; ! 1030: register struct functbl *f; ! 1031: register o; ! 1032: register TWORD t; ! 1033: ! 1034: o = p->in.op; ! 1035: t = p->in.type; ! 1036: if( t!=UNSIGNED && t!=ULONG ) return; ! 1037: ! 1038: for( f=opfunc; f->fop; f++ ) { ! 1039: if( o==f->fop ) goto convert; ! 1040: } ! 1041: return; ! 1042: ! 1043: /* need to rewrite tree for ASG OP */ ! 1044: /* must change ASG OP to a simple OP */ ! 1045: convert: ! 1046: if( asgop( o ) ) { ! 1047: q = talloc(); ! 1048: switch( p->in.op ) { ! 1049: case ASG DIV: ! 1050: q->in.op = DIV; ! 1051: break; ! 1052: case ASG MOD: ! 1053: q->in.op = MOD; ! 1054: break; ! 1055: } ! 1056: q->in.rall = NOPREF; ! 1057: q->in.type = p->in.type; ! 1058: q->in.left = tcopy(p->in.left); ! 1059: q->in.right = p->in.right; ! 1060: p->in.op = ASSIGN; ! 1061: p->in.right = q; ! 1062: zappost(q->in.left); /* remove post-INCR(DECR) from new node */ ! 1063: fixpre(q->in.left); /* change pre-INCR(DECR) to +/- */ ! 1064: p = q; ! 1065: ! 1066: } ! 1067: ! 1068: /* build comma op for args to function */ ! 1069: q = talloc(); ! 1070: q->in.op = CM; ! 1071: q->in.rall = NOPREF; ! 1072: q->in.type = INT; ! 1073: q->in.left = p->in.left; ! 1074: q->in.right = p->in.right; ! 1075: p->in.op = CALL; ! 1076: p->in.right = q; ! 1077: ! 1078: /* put function name in left node of call */ ! 1079: p->in.left = q = talloc(); ! 1080: q->in.op = ICON; ! 1081: q->in.rall = NOPREF; ! 1082: q->in.type = INCREF( FTN + p->in.type ); ! 1083: #ifndef FLEXNAMES ! 1084: strcpy( q->in.name, f->func ); ! 1085: #else ! 1086: q->in.name = f->func; ! 1087: #endif ! 1088: q->tn.lval = 0; ! 1089: q->tn.rval = 0; ! 1090: ! 1091: return; ! 1092: ! 1093: } ! 1094: ! 1095: zappost(p) NODE *p; { ! 1096: /* look for ++ and -- operators and remove them */ ! 1097: ! 1098: register o, ty; ! 1099: register NODE *q; ! 1100: o = p->in.op; ! 1101: ty = optype( o ); ! 1102: ! 1103: switch( o ){ ! 1104: ! 1105: case INCR: ! 1106: case DECR: ! 1107: q = p->in.left; ! 1108: p->in.right->in.op = FREE; /* zap constant */ ! 1109: ncopy( p, q ); ! 1110: q->in.op = FREE; ! 1111: return; ! 1112: ! 1113: } ! 1114: ! 1115: if( ty == BITYPE ) zappost( p->in.right ); ! 1116: if( ty != LTYPE ) zappost( p->in.left ); ! 1117: } ! 1118: ! 1119: fixpre(p) NODE *p; { ! 1120: ! 1121: register o, ty; ! 1122: o = p->in.op; ! 1123: ty = optype( o ); ! 1124: ! 1125: switch( o ){ ! 1126: ! 1127: case ASG PLUS: ! 1128: p->in.op = PLUS; ! 1129: break; ! 1130: case ASG MINUS: ! 1131: p->in.op = MINUS; ! 1132: break; ! 1133: } ! 1134: ! 1135: if( ty == BITYPE ) fixpre( p->in.right ); ! 1136: if( ty != LTYPE ) fixpre( p->in.left ); ! 1137: } ! 1138: ! 1139: myreader(p) register NODE *p; { ! 1140: walkf( p, hardops ); /* convert ops to function calls */ ! 1141: canon( p ); /* expands r-vals for fileds */ ! 1142: walkf( p, optim2 ); ! 1143: /* jwf toff = 0; /* stack offset swindle */ ! 1144: } ! 1145: ! 1146:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.