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