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