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