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