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