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