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