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