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