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