|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)util2.c 1.1 86/02/03 Copyr 1985 Sun Micro"; ! 3: #endif ! 4: ! 5: /* ! 6: * Copyright (c) 1985 by Sun Microsystems, Inc. ! 7: */ ! 8: ! 9: #include "cpass2.h" ! 10: #include "ctype.h" ! 11: ! 12: /* ! 13: * garbage ripped out of local2.68, which was huge ! 14: */ ! 15: # ifdef FORT ! 16: int ftlab1, ftlab2; ! 17: # endif ! 18: /* a lot of the machine dependent parts of the second pass */ ! 19: #ifdef FORT ! 20: # define fltfun 0 ! 21: #else ! 22: extern int fltfun; ! 23: #endif ! 24: ! 25: #ifndef ONEPASS /* 2nd pass of (possibly) several compilers */ ! 26: char pcname[]= "pc0"; /* name passed by pc command */ ! 27: int pascal=0; /* = 1 if compiling pascal */ ! 28: #endif ! 29: ! 30: # define BITMASK(n) ((1L<<(n))-1) ! 31: ! 32: /* output forms for floating point constants */ ! 33: typedef enum { ! 34: F_hex, F_eformat, F_loworder, F_highorder ! 35: } Floatform; ! 36: ! 37: void adrput(); ! 38: static void fcon(); ! 39: static void dumpfcons(); ! 40: ! 41: void ! 42: print_d(value) ! 43: register int value; ! 44: { ! 45: char buffer[8]; ! 46: register char *p= buffer+8; ! 47: register int i= 0; ! 48: ! 49: if (value == 0) { ! 50: putchar('0'); ! 51: return; ! 52: } ! 53: if (value < 0) { ! 54: putchar('-'); ! 55: value= -value; ! 56: } ! 57: if (value <= 32767) { ! 58: register short v= value; ! 59: while (v != 0) { ! 60: *--p= (v % 10) + '0'; ! 61: v /= 10; ! 62: i++; ! 63: } ! 64: } else { ! 65: while (value != 0) { ! 66: *--p= (value % 10) + '0'; ! 67: value /= 10; ! 68: i++; ! 69: } ! 70: } ! 71: for(; i>0; i--) ! 72: putchar(*p++); ! 73: } ! 74: ! 75: void ! 76: print_x(value) ! 77: register unsigned value; ! 78: { ! 79: char buffer[8]; ! 80: register char *p= buffer+8; ! 81: register int i= 0; ! 82: ! 83: if (value == 0) { ! 84: putchar('0'); ! 85: return; ! 86: } ! 87: if ((int)value < 0) { ! 88: value = -value; ! 89: putchar('-'); ! 90: } ! 91: while (value != 0) { ! 92: *--p = "0123456789abcdef"[value & 0xf]; ! 93: value >>= 4; ! 94: i++; ! 95: } ! 96: putchar('0'); ! 97: putchar('x'); ! 98: fwrite(p, 1, i, stdout); ! 99: } ! 100: ! 101: void ! 102: print_str(s) ! 103: char *s; ! 104: { ! 105: fputs(s, stdout); ! 106: } ! 107: ! 108: void ! 109: print_str_nl(s) ! 110: char *s; ! 111: { ! 112: puts(s); ! 113: } ! 114: ! 115: void ! 116: print_str_d(s, d) ! 117: char *s; ! 118: int d; ! 119: { ! 120: fputs(s, stdout); ! 121: print_d(d); ! 122: } ! 123: ! 124: void ! 125: print_str_d_nl(s, d) ! 126: char *s; ! 127: int d; ! 128: { ! 129: fputs(s, stdout); ! 130: print_d(d); ! 131: putchar('\n'); ! 132: } ! 133: ! 134: void ! 135: print_str_str(s1, s2) ! 136: char *s1, *s2; ! 137: { ! 138: fputs(s1, stdout); ! 139: fputs(s2, stdout); ! 140: } ! 141: ! 142: void ! 143: print_str_str_nl(s1, s2) ! 144: char *s1, *s2; ! 145: { ! 146: fputs(s1, stdout); ! 147: puts(s2); ! 148: } ! 149: ! 150: void print_label(l) ! 151: int l; ! 152: { ! 153: putchar('L'); ! 154: print_d(l); ! 155: putchar(':'); ! 156: } ! 157: ! 158: where(c) ! 159: { ! 160: fprintf( stderr, "%s, line %d: ", filename, lineno ); ! 161: } ! 162: ! 163: lineid( l, fn ) ! 164: char *fn; ! 165: { ! 166: /* identify line l and file fn */ ! 167: printf( "| line %d, file %s\n", l, fn ); ! 168: } ! 169: ! 170: epr(p) ! 171: NODE *p; ! 172: { ! 173: extern fwalk(); ! 174: fwalk(p, eprint, 0); ! 175: } ! 176: ! 177: int usedregs; /* Flag word for registers used in current routine */ ! 178: int usedfpregs; /* Flag word for floating point registers */ ! 179: int toff, maxtoff; ! 180: ! 181: cntbits(i) ! 182: register int i; ! 183: { ! 184: register int j,ans; ! 185: ! 186: for (ans=0, j=0; i!=0 && j<16; j++) { ! 187: if (i&1) ans++; ! 188: i >>= 1 ; ! 189: } ! 190: return(ans); ! 191: } ! 192: ! 193: /* ! 194: * allocate storage for register save areas ! 195: * and generate routine epilogs. The d/a register ! 196: * save area is always the LAST section of an ! 197: * activation record. A label equated to its offset ! 198: * is used to create the activation record at runtime. ! 199: */ ! 200: eobl2() ! 201: { ! 202: OFFSZ regsave_off; /* a6-relative offset of areg/dreg save area */ ! 203: OFFSZ fp_regsave_off; /* a6-relative offset of fp reg save area */ ! 204: OFFSZ spoff; /* a6-relative offset of local vars/temps */ ! 205: ! 206: # ifndef FORT ! 207: extern int ftlab1, ftlab2; ! 208: # endif ! 209: ! 210: # ifdef FREETEMP ! 211: spoff = maxoff + maxtemp; ! 212: # else ! 213: spoff = maxoff; ! 214: # endif FREETEMP ! 215: ! 216: spoff /= SZCHAR; ! 217: SETOFF(spoff,sizeof(long)); ! 218: /* ! 219: * set masks for saving/restoring registers ! 220: */ ! 221: usedregs &= REGVARMASK; ! 222: usedfpregs &= FREGVARMASK; ! 223: /* ! 224: * allocate storage for register save areas ! 225: */ ! 226: fp_regsave_off = regsave_off = spoff; ! 227: if (use68881 && usedfpregs) { ! 228: fp_regsave_off += (SZEXTENDED/SZCHAR)*cntbits(usedfpregs); ! 229: regsave_off = fp_regsave_off; ! 230: } ! 231: if (usedregs) { ! 232: regsave_off += (SZLONG/SZCHAR)*cntbits(usedregs); ! 233: } ! 234: /* ! 235: * generate epilogue ! 236: */ ! 237: printf( "LE%d:\n",ftnno); ! 238: if (use68881 && usedfpregs) { ! 239: /* ! 240: * restore floating point registers. ! 241: */ ! 242: if (fp_regsave_off > 32767) { ! 243: /* long offset */ ! 244: if (use68020) { ! 245: printf(" fmovem a6@(-0x%x:l),#0x%x\n", ! 246: fp_regsave_off, usedfpregs); ! 247: } else { ! 248: /* ! 249: * 68881 but no 68020; I doubt this will ! 250: * ever happen, but just in case... ! 251: */ ! 252: printf(" movl #-0x%x,a0\n", ! 253: fp_regsave_off); ! 254: printf(" fmovem a6@(0,a0:l),#0x%x", ! 255: usedfpregs); ! 256: } ! 257: } else { ! 258: /* short offset */ ! 259: printf(" fmovem a6@(-0x%x),#0x%x\n", ! 260: fp_regsave_off, usedfpregs); ! 261: } ! 262: } /* usedfpregs */ ! 263: if (usedregs) { ! 264: /* ! 265: * restore data and address registers ! 266: */ ! 267: if (regsave_off > 32767) { ! 268: /* long offset */ ! 269: if (use68020) { ! 270: printf( " moveml a6@(-0x%x:l),#0x%x\n", ! 271: regsave_off, usedregs ); ! 272: } else { ! 273: printf(" movl #-0x%x,a0\n", ! 274: regsave_off); ! 275: printf(" moveml a6@(0,a0:l),#0x%x\n", ! 276: usedregs); ! 277: } ! 278: } else { ! 279: /* short offset */ ! 280: printf( " moveml a6@(-0x%x),#0x%x\n", ! 281: regsave_off, usedregs ); ! 282: } ! 283: } /* usedregs */ ! 284: printf( " unlk a6\n rts\n" ); ! 285: printf( " LF%d = %ld\n", ftnno, regsave_off ); ! 286: printf( " LS%d = 0x%x\n", ftnno, usedregs ); ! 287: printf( " LFF%d = %ld\n", ftnno, fp_regsave_off ); ! 288: printf( " LSS%d = 0x%x\n", ftnno, usedfpregs ); ! 289: # ifdef FREETEMP ! 290: printf(" LT%d = 0x%x\n", ftnno, ! 291: cntbits(usedregs)*(SZINT/SZCHAR)); ! 292: # endif ! 293: # ifdef STACKPROBE ! 294: printf(" LP%d = 0x%x\n", ftnno, maxtoff+8 ); ! 295: # endif ! 296: maxtoff = 0; ! 297: usedregs = 0; ! 298: usedfpregs = 0; ! 299: dumpfcons(); ! 300: } ! 301: ! 302: struct hoptab { int opmask; char * opstring; } ioptab[] = { ! 303: ! 304: ASG PLUS, "add", ! 305: ASG MINUS, "sub", ! 306: ASG OR, "or", ! 307: ASG AND, "and", ! 308: ASG ER, "eor", ! 309: ASG MUL, "mul", ! 310: ASG DIV, "div", ! 311: ASG MOD, "div", ! 312: ASG LS, "sl", ! 313: ASG RS, "sr", ! 314: -1, "" }; ! 315: ! 316: hopcode( f, o ) ! 317: { ! 318: /* output the appropriate string from the above table */ ! 319: ! 320: register struct hoptab *q; ! 321: ! 322: for( q = ioptab; q->opmask>=0; ++q ){ ! 323: if( q->opmask == o ){ ! 324: if( f == 'F') putchar('f'); ! 325: printf(q->opstring); ! 326: return; ! 327: } ! 328: } ! 329: cerror( "no hoptab for %s", opst[o] ); ! 330: } ! 331: ! 332: char * ! 333: rnames[] = { /* keyed to register number tokens */ ! 334: "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", ! 335: "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp", ! 336: "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7" ! 337: }; ! 338: ! 339: int rstatus[] = { ! 340: SAREG|STAREG, SAREG|STAREG, ! 341: SAREG|STAREG, SAREG|STAREG, ! 342: SAREG|STAREG, SAREG|STAREG, ! 343: SAREG|STAREG, SAREG|STAREG, ! 344: ! 345: SBREG|STBREG, SBREG|STBREG, ! 346: SBREG|STBREG, SBREG|STBREG, ! 347: SBREG|STBREG, SBREG|STBREG, ! 348: SBREG, SBREG, ! 349: ! 350: SCREG|STCREG, SCREG|STCREG, ! 351: SCREG|STCREG, SCREG|STCREG, ! 352: SCREG|STCREG, SCREG|STCREG, ! 353: SCREG|STCREG, SCREG|STCREG, ! 354: }; ! 355: ! 356: tlen(p) NODE *p; ! 357: { ! 358: switch(p->in.type) { ! 359: case CHAR: ! 360: case UCHAR: ! 361: return(SZCHAR/SZCHAR); ! 362: ! 363: case SHORT: ! 364: case USHORT: ! 365: return(SZSHORT/SZCHAR); ! 366: ! 367: case DOUBLE: ! 368: return(SZDOUBLE/SZCHAR); ! 369: ! 370: default: ! 371: return(SZINT/SZCHAR); ! 372: } ! 373: } ! 374: ! 375: ! 376: rmove( rt, rs, t ) ! 377: register int rt,rs; ! 378: { ! 379: int fsrce, fdest; ! 380: ! 381: fsrce = iscreg(rs); ! 382: fdest = iscreg(rt); ! 383: if (!fsrce && !fdest) { ! 384: /* ! 385: * neither source nor dest is on the coprocessor ! 386: */ ! 387: if ( t==DOUBLE ){ ! 388: printf(" movl %s,%s\n movl %s,%s\n", ! 389: rnames[rs], rnames[rt], ! 390: rnames[rs+1], rnames[rt+1]); ! 391: markused(rs+1); ! 392: markused(rt+1); ! 393: } else { ! 394: /* the most common case */ ! 395: printf(" movl %s,%s\n", ! 396: rnames[rs], rnames[rt] ); ! 397: } ! 398: } else if (fsrce && !fdest) { ! 399: /* ! 400: * source is on coprocessor, dest isn't ! 401: */ ! 402: if (t == DOUBLE) { ! 403: /* royal pain; must use memory */ ! 404: printf(" fmoved %s,sp@-\n", rnames[rs]); ! 405: printf(" movl sp@+,%s\n", rnames[rt]); ! 406: printf(" movl sp@+,%s\n", rnames[rt+1]); ! 407: markused(rt+1); ! 408: } else { ! 409: /* t == FLOAT */ ! 410: printf(" fmoves %s,%s\n", ! 411: rnames[rs], rnames[rt]); ! 412: } ! 413: } else if (!fsrce && fdest) { ! 414: /* ! 415: * source isn't on coprocessor, dest is ! 416: */ ! 417: if (t == DOUBLE) { ! 418: /* royal pain; must use memory */ ! 419: printf(" movl %s,sp@-\n", rnames[rs+1]); ! 420: printf(" movl %s,sp@-\n", rnames[rs]); ! 421: printf(" fmoved sp@+,%s\n", rnames[rt]); ! 422: markused(rs+1); ! 423: } else { ! 424: /* t == FLOAT */ ! 425: printf(" fmoves %s,%s\n", ! 426: rnames[rs], rnames[rt]); ! 427: } ! 428: } else { ! 429: /* ! 430: * both regs are on the coprocessor ! 431: */ ! 432: printf(" fmovex %s,%s\n", rnames[rs], rnames[rt]); ! 433: } ! 434: markused(rs); ! 435: markused(rt); ! 436: } ! 437: ! 438: struct respref ! 439: respref[] = { ! 440: INCREG|INTCREG, INCREG|INTCREG, ! 441: INTAREG|INTBREG,INTAREG|INTBREG, ! 442: INAREG|INBREG, INAREG|INBREG, ! 443: INAREG|INBREG, SZERO, ! 444: INAREG|INBREG, SOREG|STARREG|STARNM|SNAME|SCON, ! 445: INTEMP, INTEMP, ! 446: FORARG, FORARG, ! 447: INTAREG, SOREG|SNAME|SAREG|SBREG, ! 448: 0, 0 }; ! 449: ! 450: #ifdef FORT ! 451: /* ! 452: * save register variables. ! 453: * Use labels since we don't know ! 454: * which ones are being used until ! 455: * the end of the function. ! 456: */ ! 457: saveregs() ! 458: { ! 459: printf(" link a6,#0\n"); ! 460: printf(" addl #-LF%d,sp\n", ftnno); ! 461: printf(" moveml #LS%d,sp@\n",ftnno); ! 462: if (use68881) { ! 463: /* ! 464: * save floating registers used for variables ! 465: */ ! 466: if (use68020) { ! 467: printf(" fmovem #LSS%d,a6@(-LFF%d:l)\n", ! 468: ftnno, ftnno); ! 469: } else { ! 470: /* 68881 without 68020; unlikely combination */ ! 471: printf(" movl #-LFF%d,a0\n", ftnno); ! 472: printf(" fmovem #LSS%d,a6@(0,a0:l)\n", ftnno); ! 473: } ! 474: } ! 475: } ! 476: #endif FORT ! 477: ! 478: ! 479: /* ! 480: * Set up temporary registers. ! 481: * Use any left over from register ! 482: * variable allocation for scratch. ! 483: */ ! 484: ! 485: setregs() ! 486: { ! 487: register i; ! 488: int nextdreg; ! 489: int nextareg; ! 490: int nextfreg; ! 491: ! 492: extern int skybase; ! 493: ! 494: nextdreg = NEXTD(maxtreg); ! 495: nextareg = NEXTA(maxtreg); ! 496: nextfreg = NEXTF(maxtreg); ! 497: ! 498: # ifdef FORT ! 499: /* reg reserved by iropt for __skybase */ ! 500: skybase = SKYBASE(maxtreg); ! 501: if (nextdreg == D0) ! 502: nextdreg = MAX_DVAR; ! 503: if (nextareg == A0) ! 504: nextareg = MAX_AVAR; ! 505: if (nextfreg == FP0) ! 506: nextfreg = MAX_FVAR; ! 507: # endif FORT ! 508: ! 509: # ifdef FREETEMP ! 510: tmpoff = 0; /* we number temp regsters differently here */ ! 511: # endif ! 512: ! 513: for( i=MIN_DVAR; i<=MAX_DVAR; i++ ){ ! 514: rstatus[i] = i <= nextdreg ? SAREG|STAREG : SAREG; ! 515: # ifdef FORT ! 516: if (i > nextdreg) ! 517: markused(i); ! 518: # endif ! 519: } ! 520: for( i=MIN_AVAR; i<=MAX_AVAR; i++ ){ ! 521: rstatus[i] = i <= nextareg ? SBREG|STBREG : SBREG; ! 522: # ifdef FORT ! 523: if (i > nextareg) ! 524: markused(i); ! 525: # endif ! 526: } ! 527: for( i=MIN_FVAR; i<=MAX_FVAR; i++ ){ ! 528: rstatus[i] = i <= nextfreg ? SCREG|STCREG : SCREG; ! 529: # ifdef FORT ! 530: if (i > nextfreg) ! 531: markused(i); ! 532: # endif ! 533: } ! 534: ! 535: fregs.d = (nextdreg - D0) + 1; ! 536: fregs.a = (nextareg - A0) + 1; ! 537: fregs.f = (nextfreg - FP0) + 1; ! 538: ! 539: if( xdebug ){ ! 540: /* -x changes number of free regs to 2, -xx to 3, etc. */ ! 541: if( (xdebug+1) < fregs.f ) fregs.f = xdebug+1; ! 542: } ! 543: } ! 544: ! 545: shltype( o, p ) ! 546: register o; ! 547: NODE *p; ! 548: { ! 549: return( o== REG || o == NAME || o == ICON || o == OREG || o == FCON ! 550: || ( o==UNARY MUL && shumul(p->in.left)) ); ! 551: } ! 552: ! 553: flshape( p ) register NODE *p; ! 554: { ! 555: register o = p->in.op; ! 556: if( o==NAME || o==REG || o==ICON || o==OREG ) return( 1 ); ! 557: return( o==UNARY MUL && shumul(p->in.left)==STARNM ); ! 558: } ! 559: ! 560: shtemp( p ) register NODE *p; ! 561: { ! 562: if( p->in.op == UNARY MUL ) p = p->in.left; ! 563: if( p->in.op == REG ) ! 564: return( !istreg( p->tn.rval ) ); ! 565: if( p->in.op == OREG && !R2TEST(p->tn.rval) ) ! 566: return( !istreg( p->tn.rval ) ); ! 567: return( p->in.op == NAME || p->in.op == ICON ); ! 568: } ! 569: ! 570: spsz( t, v ) TWORD t; CONSZ v; ! 571: { ! 572: ! 573: /* is v the size to increment something of type t */ ! 574: ! 575: if( !ISPTR(t) ) return( 0 ); ! 576: t = DECREF(t); ! 577: ! 578: if( ISPTR(t) ) return( v == (SZPOINT/SZCHAR) ); ! 579: ! 580: switch( t ){ ! 581: ! 582: case UCHAR: ! 583: case CHAR: ! 584: return( v == 1 ); ! 585: ! 586: case SHORT: ! 587: case USHORT: ! 588: return( v == (SZSHORT/SZCHAR) ); ! 589: ! 590: case INT: ! 591: case UNSIGNED: ! 592: case FLOAT: ! 593: return( v == (SZINT/SZCHAR) ); ! 594: ! 595: case DOUBLE: ! 596: return( v == (SZDOUBLE/SZCHAR) ); ! 597: } ! 598: ! 599: return( 0 ); ! 600: } ! 601: ! 602: indexreg( p ) register NODE *p; ! 603: { ! 604: if( p->in.op == REG && p->tn.rval >= A0 && p->tn.rval <= SP ) return(1); ! 605: return(0); ! 606: } ! 607: ! 608: shumul( p ) register NODE *p; ! 609: { ! 610: register o; ! 611: extern int xdebug; ! 612: ! 613: if (xdebug) { ! 614: printf("\nshumul:op=%d, ", p->in.op); ! 615: switch (optype(p->in.op)){ ! 616: case BITYPE: ! 617: printf( " rop=%d, rname=%s, rlval=%D", ! 618: p->in.right->in.op, p->in.right->in.name, ! 619: p->in.right->tn.lval); ! 620: /* fall through */ ! 621: default: ! 622: printf( "lop=%d, plty=%d ", ! 623: p->in.left->in.op, p->in.left->in.type ); ! 624: case LTYPE: ; /* do nothing */ ! 625: } ! 626: putchar('\n'); ! 627: } ! 628: ! 629: ! 630: o = p->in.op; ! 631: if( indexreg(p) ) ! 632: return( STARNM ); ! 633: ! 634: if( o == INCR && indexreg(p->in.left) && p->in.right->in.op == ICON && ! 635: p->in.right->in.name[0] == '\0' && ! 636: spsz( p->in.left->in.type, p->in.right->tn.lval ) ) ! 637: return( STARREG ); ! 638: if( o == ASG MINUS && indexreg(p->in.left) && p->in.right->in.op == ICON && ! 639: p->in.right->in.name[0] == '\0' && ! 640: spsz( p->in.left->in.type, p->in.right->tn.lval ) ) ! 641: return( STARREG ); ! 642: ! 643: return( 0 ); ! 644: } ! 645: ! 646: adrcon( val ) CONSZ val; ! 647: { ! 648: printf( CONFMT, val ); ! 649: } ! 650: ! 651: /* put out a floating e-format constant */ ! 652: ! 653: floatimmed(p) ! 654: NODE *p; ! 655: { ! 656: putchar('#'); ! 657: fcon( p, F_eformat ); ! 658: } ! 659: ! 660: conput( p ) register NODE *p; ! 661: { ! 662: switch( p->in.op ){ ! 663: case FCON: ! 664: fcon( p, F_hex ); ! 665: return; ! 666: ! 667: case ICON: ! 668: acon( p ); ! 669: return; ! 670: ! 671: default: ! 672: cerror( "illegal conput" ); ! 673: } ! 674: } ! 675: ! 676: /* ! 677: * put out an explicit length qualifier. This simplifies ! 678: * handling of offsets in the 68020 assembler somewhat. ! 679: */ ! 680: offsize(p) ! 681: register NODE *p; ! 682: { ! 683: if ( p->tn.name[0] != '\0' || p->tn.lval > 32767 ! 684: || p->tn.lval < -32768 ) { ! 685: printf(":l"); ! 686: } ! 687: } ! 688: ! 689: oregput(p) ! 690: register NODE *p; ! 691: { ! 692: register r; ! 693: ! 694: r = p->tn.rval; ! 695: if (R2TEST(r)) { ! 696: /* ! 697: * double indexing ! 698: */ ! 699: if (use68020) { ! 700: /* ! 701: * For 68020, R2UPK3 encodes the following data: ! 702: * int shortx:1; short index ! 703: * int ibit:1; memory indirect mode (ignored) ! 704: * int scale:4; scale factor (1,2,4,8) ! 705: */ ! 706: register flags; ! 707: int base, index, scale, shortx, indirect; ! 708: ! 709: base = R2UPK1(r); ! 710: index = R2UPK2(r); ! 711: markused(base); ! 712: markused(index); ! 713: flags = R2UPK3(r); ! 714: R2UPKFLGS(flags,shortx,indirect,scale); ! 715: /* ! 716: * print base register and displacement (if any) ! 717: */ ! 718: printf(rnames[base]); ! 719: printf("@("); ! 720: acon(p); /* base displacement */ ! 721: offsize(p); /* size of displacement */ ! 722: putchar(','); ! 723: /* ! 724: * print index register and scale factor. For now, ! 725: * we assume all indices have been long-extended. ! 726: */ ! 727: printf(rnames[index]); ! 728: putchar(':'); ! 729: putchar(shortx? 'w' : 'l'); ! 730: switch(scale) { ! 731: case 0: ! 732: case 1: ! 733: break; ! 734: case 2: ! 735: case 4: ! 736: case 8: ! 737: printf(":%d",scale); ! 738: break; ! 739: default: ! 740: cerror("illegal scale factor (%d)", scale); ! 741: /*NOTREACHED*/ ! 742: } ! 743: putchar(')'); ! 744: } /* use68020 */ ! 745: else { ! 746: /* ! 747: * For the 68010, R2UPK3 encodes only whether ! 748: * a short index is used. ! 749: */ ! 750: int base, index, flags, shortx, ignored; ! 751: base = R2UPK1(p->tn.rval); ! 752: index = R2UPK2(p->tn.rval); ! 753: flags = R2UPK3(p->tn.rval); ! 754: R2UPKFLGS(flags,shortx,ignored,ignored); ! 755: printf( "%s@(%d,%s:%c)", ! 756: rnames[base], /* breg */ ! 757: p->tn.lval, /* disp */ ! 758: rnames[index], /* xreg */ ! 759: shortx ? 'w' : 'l' ); /* xlen */ ! 760: markused(base); ! 761: markused(index); ! 762: } ! 763: } ! 764: else { ! 765: int base = R2UPK2(p->tn.rval); ! 766: markused(base); ! 767: printf( rnames[base] ); ! 768: putchar('@'); ! 769: if( p->tn.lval != 0 || p->in.name[0] != '\0' ) { ! 770: putchar('('); ! 771: acon( p ); ! 772: if (use68020) offsize( p ); ! 773: putchar(')'); ! 774: } /* if */ ! 775: } /* else */ ! 776: } /* oregput */ ! 777: ! 778: void ! 779: upput( p ) register NODE *p; ! 780: { ! 781: /* output the address of the second word in the ! 782: pair pointed to by p (for LONGs)*/ ! 783: CONSZ save; ! 784: int r; ! 785: ! 786: if( p->in.op == FLD ){ ! 787: p = p->in.left; ! 788: } ! 789: ! 790: save = p->tn.lval; ! 791: switch( p->in.op ){ ! 792: ! 793: case NAME: ! 794: p->tn.lval += SZINT/SZCHAR; ! 795: acon( p ); ! 796: break; ! 797: ! 798: case FCON: ! 799: fcon( p, F_loworder ); ! 800: break; ! 801: ! 802: case ICON: ! 803: /* addressable value of the constant */ ! 804: p->tn.lval &= BITMASK(SZINT); ! 805: putchar('#'); ! 806: acon( p ); ! 807: break; ! 808: ! 809: case REG: ! 810: r = p->tn.rval+1; ! 811: if (r >= FP0) { ! 812: cerror("illegal floating register pair"); ! 813: } ! 814: print_str(rnames[r] ); ! 815: markused(r); ! 816: break; ! 817: ! 818: case OREG: ! 819: p->tn.lval += SZINT/SZCHAR; ! 820: if( R2UPK2(p->tn.rval) == A6 ){ /* in the argument region */ ! 821: if( p->in.name[0] != '\0' ) werror( "bad arg temp" ); ! 822: } ! 823: #ifdef FREETEMP ! 824: else if( R2UPK2(p->tn.rval) == SP ){ /* in the temp region */ ! 825: if( p->in.name[0] != '\0' ) werror( "bad arg temp" ); ! 826: printf( "sp@(LT%d+0x%x)", ftnno, toff+p->tn.lval); ! 827: p->tn.lval = save; ! 828: return; ! 829: } ! 830: #endif FREETEMP ! 831: oregput(p); ! 832: break; ! 833: ! 834: case UNARY MUL: ! 835: if (p->in.left->in.op==INCR){ ! 836: /* rewrite a-la adrput */ ! 837: NODE *q, *l; int i; ! 838: l = p->in.left; ! 839: q = l->in.left; ! 840: p->in.op = OREG; ! 841: p->in.rall = q->in.rall; ! 842: p->tn.lval = q->tn.lval; ! 843: p->tn.rval = q->tn.rval; ! 844: #ifndef FLEXNAMES ! 845: for( i=0; i<NCHNAM; i++ ) ! 846: p->in.name[i] = q->in.name[i]; ! 847: #else ! 848: p->in.name = q->in.name; ! 849: #endif ! 850: adrput( p ); ! 851: putchar('+'); ! 852: p->tn.lval -= l->in.right->tn.lval; ! 853: tfree( l ); ! 854: } else if ( tshape(p, STARNM) ) { ! 855: adrput( p->in.left ); ! 856: print_str("@(4)"); ! 857: } else { ! 858: /* p->in.left->in.op==ASG MINUS */ ! 859: /* just put and let adrput rewrite -- VERY carefully */ ! 860: adrput( p->in.left->in.left ); ! 861: print_str( "@-"); ! 862: } ! 863: break; ! 864: ! 865: default: ! 866: cerror( "illegal upper address" ); ! 867: break; ! 868: ! 869: } ! 870: p->tn.lval = save; ! 871: } ! 872: ! 873: void ! 874: adrput( p ) register NODE *p; ! 875: { ! 876: /* the 68k code saves lval and restores after the switch */ ! 877: register int r; ! 878: /* output an address, with offsets, from p */ ! 879: ! 880: if( p->in.op == FLD ){ ! 881: p = p->in.left; ! 882: } ! 883: switch( p->in.op ){ ! 884: ! 885: case NAME: ! 886: acon( p ); ! 887: return; ! 888: ! 889: case FCON: ! 890: /* ! 891: * put out floating constant in hex. ! 892: * Do not use in coprocessor instructions; ! 893: * use floatimmed(p) instead. ! 894: */ ! 895: if (p->in.type == FLOAT) { ! 896: putchar('#'); ! 897: fcon( p, F_hex ); ! 898: } else { ! 899: fcon( p, F_highorder ); ! 900: } ! 901: return; ! 902: ! 903: case ICON: ! 904: /* addressable value of the constant */ ! 905: putchar('#'); ! 906: acon( p ); ! 907: return; ! 908: ! 909: case REG: ! 910: r = p->tn.rval; ! 911: print_str(rnames[r] ); ! 912: markused(r); ! 913: return; ! 914: ! 915: case OREG: ! 916: if( R2UPK2(p->tn.rval) == A6 ){ /* in the argument region */ ! 917: if( p->in.name[0] != '\0' ) werror( "bad arg temp" ); ! 918: } ! 919: #ifdef FREETEMP ! 920: else if( R2UPK2(p->tn.rval) == SP ){ /* in the temp region */ ! 921: if( p->in.name[0] != '\0' ) werror( "bad arg temp" ); ! 922: printf( "sp@(LT%d+%d)", ftnno, toff+p->tn.lval); ! 923: return; ! 924: } ! 925: #endif FREETEMP ! 926: oregput(p); ! 927: break; ! 928: ! 929: case UNARY MUL: ! 930: /* STARNM or STARREG found */ ! 931: if( tshape(p, STARNM) ) { ! 932: adrput( p->in.left); ! 933: putchar('@'); ! 934: } ! 935: else { /* STARREG - really auto inc or dec */ ! 936: /* turn into OREG so replacement node will ! 937: reflect the value of the expression */ ! 938: register i; ! 939: register NODE *q, *l; ! 940: ! 941: l = p->in.left; ! 942: q = l->in.left; ! 943: if (p->in.type==DOUBLE ) ! 944: if (l->in.op==INCR){ ! 945: /* just do it and let upput rewrite */ ! 946: adrput( q ); ! 947: print_str( "@+"); ! 948: return; ! 949: } ! 950: /* else fall through and we rewrite -- VERY carefully */ ! 951: p->in.op = OREG; ! 952: p->in.rall = q->in.rall; ! 953: p->tn.lval = q->tn.lval; ! 954: p->tn.rval = q->tn.rval; ! 955: #ifndef FLEXNAMES ! 956: for( i=0; i<NCHNAM; i++ ) ! 957: p->in.name[i] = q->in.name[i]; ! 958: #else ! 959: p->in.name = q->in.name; ! 960: #endif ! 961: if( l->in.op == INCR ) { ! 962: adrput( p ); ! 963: putchar('+'); ! 964: p->tn.lval -= l->in.right->tn.lval; ! 965: } else { ! 966: /* l->in.op == ASG MINUS */ ! 967: adrput( p ); ! 968: putchar('-'); ! 969: } ! 970: tfree( l ); ! 971: } ! 972: return; ! 973: ! 974: case SCONV: ! 975: adrput(p->in.left); /* kludge for SFLOAT_SRCE */ ! 976: break; ! 977: ! 978: default: ! 979: cerror( "illegal address" ); ! 980: return; ! 981: ! 982: } ! 983: ! 984: } ! 985: ! 986: acon( p ) register NODE *p; ! 987: { /* print out a constant */ ! 988: ! 989: if( p->in.name[0] == '\0' ){ ! 990: print_x(p->tn.lval); ! 991: } ! 992: else if( p->tn.lval == 0 ) { ! 993: #ifndef FLEXNAMES ! 994: printf( "%.8s", p->in.name ); ! 995: #else ! 996: print_str(p->in.name ); ! 997: #endif ! 998: } ! 999: else { ! 1000: #ifndef FLEXNAMES ! 1001: printf( "%.8s+", p->in.name ); ! 1002: #else ! 1003: print_str(p->in.name ); putchar('+'); ! 1004: #endif ! 1005: print_x(p->tn.lval ); ! 1006: } ! 1007: } ! 1008: ! 1009: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ ! 1010: ! 1011: /* ! 1012: * fcon(p, form): output a floating point constant in one of several forms ! 1013: */ ! 1014: ! 1015: static int fgetlab(); ! 1016: ! 1017: static char floatfmt[] = "0r%.9e"; ! 1018: static char doublefmt[] = "0r%.17e"; ! 1019: ! 1020: static void ! 1021: fcon( p, form ) ! 1022: register NODE *p; ! 1023: Floatform form; ! 1024: { ! 1025: float x; ! 1026: long *lp; ! 1027: ! 1028: switch(form) { ! 1029: case F_highorder: ! 1030: /* ! 1031: * put out a reference to the highorder word of a ! 1032: * double constant from the pool ! 1033: */ ! 1034: printf("L%d", fgetlab(p)); ! 1035: return; ! 1036: case F_loworder: ! 1037: /* ! 1038: * put out a reference to the loworder word of a ! 1039: * double constant from the pool ! 1040: */ ! 1041: printf("L%d+4", fgetlab(p)); ! 1042: return; ! 1043: case F_eformat: ! 1044: /* ! 1045: * put out a constant in e-floating point format; ! 1046: * for coprocessor instructions. ! 1047: */ ! 1048: if (p->in.type == FLOAT) { ! 1049: printf(floatfmt, p->fpn.dval); ! 1050: } else { ! 1051: printf(doublefmt, p->fpn.dval); ! 1052: } ! 1053: return; ! 1054: case F_hex: ! 1055: /* ! 1056: * put out the constant as one or two hex words; ! 1057: * for initialization. ! 1058: */ ! 1059: if (p->in.type == FLOAT) { ! 1060: float x = p->fpn.dval; ! 1061: lp = (long*)&x; ! 1062: printf("0x%x", lp[0]); ! 1063: } else { ! 1064: lp = (long*)&p->fpn.dval; ! 1065: printf("0x%x,0x%x", lp[0], lp[1]); ! 1066: } ! 1067: return; ! 1068: } ! 1069: } ! 1070: ! 1071: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ ! 1072: ! 1073: /* ! 1074: * floating point constant pool -- a data structure that ! 1075: * associates floating point constants with labels ! 1076: */ ! 1077: ! 1078: struct floatcon { ! 1079: int conlab; ! 1080: TWORD contype; ! 1081: double conval; ! 1082: struct floatcon *left, *right; ! 1083: }; ! 1084: ! 1085: static struct floatcon *fconpool; /* the search tree */ ! 1086: static struct floatcon *newfloatcon(); /* floatcon storage allocator */ ! 1087: static int fconlookup(); /* search routine */ ! 1088: ! 1089: /* ! 1090: * search for, and create if necessary, ! 1091: * a label in the floating point constant pool ! 1092: */ ! 1093: ! 1094: static int ! 1095: fgetlab(p) ! 1096: NODE *p; ! 1097: { ! 1098: return(fconlookup(&fconpool, p)); ! 1099: } ! 1100: ! 1101: static int ! 1102: fconlookup(fpp, p) ! 1103: struct floatcon **fpp; ! 1104: NODE *p; ! 1105: { ! 1106: struct floatcon *fp = *fpp; ! 1107: if (fp == NULL) { ! 1108: *fpp = fp = newfloatcon(); ! 1109: fp->conval = p->fpn.dval; ! 1110: fp->contype = p->fpn.type; ! 1111: fp->conlab = getlab(); ! 1112: fp->left = NULL; ! 1113: fp->right = NULL; ! 1114: return(fp->conlab); ! 1115: } else if (fp->conval == p->fpn.dval) { ! 1116: return(fp->conlab); ! 1117: } else if (fp->conval < p->fpn.dval) { ! 1118: return(fconlookup(&fp->left, p)); ! 1119: } else { ! 1120: return(fconlookup(&fp->right,p)); ! 1121: } ! 1122: } ! 1123: ! 1124: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ ! 1125: ! 1126: /* ! 1127: * storage allocation for the floating point constant pool ! 1128: */ ! 1129: ! 1130: #define FCONSEGSIZ 256 ! 1131: struct fconseg { ! 1132: struct fconseg *nextseg; ! 1133: struct floatcon *nextcon; ! 1134: struct floatcon storage[FCONSEGSIZ]; ! 1135: }; ! 1136: ! 1137: static struct fconseg *curseg = NULL; ! 1138: ! 1139: /* ! 1140: * allocate storage for a ! 1141: * labeled floating point constant ! 1142: */ ! 1143: static struct floatcon * ! 1144: newfloatcon() ! 1145: { ! 1146: struct fconseg *newseg; ! 1147: ! 1148: if (curseg == NULL ! 1149: || curseg->nextcon == curseg->storage+FCONSEGSIZ) { ! 1150: newseg = (struct fconseg*)malloc(sizeof(struct fconseg)); ! 1151: newseg->nextseg = curseg; ! 1152: curseg = newseg; ! 1153: curseg->nextcon = curseg->storage; ! 1154: } ! 1155: return(curseg->nextcon++); ! 1156: } ! 1157: ! 1158: /* ! 1159: * emit the floating point constant ! 1160: * pool to the output stream ! 1161: */ ! 1162: static void ! 1163: dumpfcons() ! 1164: { ! 1165: register struct floatcon *fp,*nextfree; ! 1166: struct fconseg *segp, *temp; ! 1167: long *lp; ! 1168: ! 1169: segp = curseg; ! 1170: while(segp != NULL) { ! 1171: nextfree = segp->nextcon; ! 1172: for (fp = segp->storage; fp < nextfree; fp++) { ! 1173: printf("L%d: .long ", fp->conlab); ! 1174: if (fp->contype == FLOAT) { ! 1175: float x = fp->conval; ! 1176: lp = (long*)&x; ! 1177: printf("0x%lx", lp[0]); ! 1178: } else { ! 1179: lp = (long*)&fp->conval; ! 1180: printf("0x%lx,0x%lx", lp[0], lp[1]); ! 1181: } ! 1182: putchar('\n'); ! 1183: } ! 1184: temp = segp->nextseg; ! 1185: free(segp); ! 1186: segp = temp; ! 1187: } ! 1188: curseg = NULL; ! 1189: fconpool = NULL; ! 1190: } ! 1191: ! 1192: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ ! 1193: ! 1194: genscall( p, cookie ) register NODE *p; ! 1195: { ! 1196: /* structure valued call */ ! 1197: return( gencall( p, cookie ) ); ! 1198: } ! 1199: ! 1200: gencall( p, cookie ) register NODE *p; ! 1201: { ! 1202: /* generate the call given by p */ ! 1203: register args; ! 1204: register m; ! 1205: ! 1206: if( p->in.right ) args = argsize( p->in.right ); ! 1207: else args = 0; ! 1208: ! 1209: if( p->in.right ){ /* generate args */ ! 1210: int residue = args % (SZLONG/SZCHAR); ! 1211: if (residue) { ! 1212: /* ! 1213: * pad the argument list out to an ! 1214: * even number of longwords. This is ! 1215: * the wrong way to do it, but doing ! 1216: * it right isn't backwards compatible. ! 1217: */ ! 1218: printf(" subqw #0x%x,sp\n", residue); ! 1219: } ! 1220: genargs( p->in.right ); ! 1221: } ! 1222: ! 1223: if( !shltype( p->in.left->in.op, p->in.left ) ) { ! 1224: order( p->in.left, INBREG|SOREG ); ! 1225: } ! 1226: ! 1227: p->in.op = UNARY CALL; ! 1228: m = match( p, INTAREG|INTBREG ); ! 1229: popargs( args ); ! 1230: return(m != MDONE); ! 1231: } ! 1232: ! 1233: popargs( size ) register size; ! 1234: { ! 1235: /* pop arguments from stack */ ! 1236: ! 1237: if (size==0) return; ! 1238: /* ! 1239: * round size up to a multiple of sizeof(long), ! 1240: * to compensate for the hack in gencall() above. ! 1241: */ ! 1242: SETOFF(size, (SZLONG/SZCHAR)); ! 1243: toff -= size; ! 1244: /* huh? if( toff == 0 && size >= 2 ) size -= 2; */ ! 1245: if (size <=8 ) ! 1246: printf( " addqw #0x%x,sp\n", size); ! 1247: else if (size <(1<<15)) ! 1248: printf( " lea sp@(0x%x),sp\n", size); ! 1249: else ! 1250: printf( " addl #0x%x,sp\n", size); ! 1251: } ! 1252: ! 1253: ! 1254: nextcook( p, cookie ) ! 1255: NODE *p; ! 1256: register cookie; ! 1257: { ! 1258: /* we have failed to match p with cookie; try another */ ! 1259: if ( cookie == FORREW ) return( 0 ); /* hopeless! */ ! 1260: if ( cookie & (INCREG|INTCREG) ) return (INTAREG); ! 1261: if ( !(cookie&(INTAREG|INTBREG|INTCREG)) ) ! 1262: return( INTAREG|INTBREG|INTCREG ); ! 1263: if ( !(cookie&INTEMP) && asgop(p->in.op) ) ! 1264: return( INTEMP|INAREG|INTAREG|INTBREG|INBREG); ! 1265: if ( !(cookie&(INTAREG|INAREG)) && p->in.op == CHK ) ! 1266: return(INTAREG|INAREG); ! 1267: return ( FORREW ); ! 1268: } ! 1269: ! 1270: lastchance( p, cook ) NODE *p; ! 1271: { ! 1272: /* forget it! */ ! 1273: return(0); ! 1274: } ! 1275: ! 1276: ! 1277: NODE * addroreg(l) ! 1278: /* ! 1279: * OREG was built in clocal() ! 1280: * for an auto or formal parameter ! 1281: * now its address is being taken ! 1282: * local code must unwind it ! 1283: * back to PLUS/MINUS REG ICON ! 1284: * according to local conventions ! 1285: */ ! 1286: { ! 1287: cerror("address of OREG taken"); ! 1288: } ! 1289: ! 1290: ! 1291: ! 1292: # ifndef ONEPASS ! 1293: main( argc, argv ) char *argv[]; ! 1294: { ! 1295: int v; ! 1296: if ( strcmp(argv[0],pcname) == 0 ) ! 1297: pascal = 1; ! 1298: v = mainp2( argc, argv ); ! 1299: floatnote(); ! 1300: exit( v ); ! 1301: } ! 1302: # endif ! 1303: ! 1304: /* return 1 if node is a SCONV from short to int */ ! 1305: isconv( p, t1, t2 ) ! 1306: register NODE *p; ! 1307: TWORD t1, t2; ! 1308: { ! 1309: register v; ! 1310: if ( p->in.op==SCONV && (p->in.type==INT || p->in.type==UNSIGNED) && ! 1311: ((v=p->in.left->in.type)==t1 || v == t2)) ! 1312: return( 1 ); ! 1313: return( 0 ); ! 1314: } ! 1315: ! 1316: ! 1317: ! 1318: myreader(p) register NODE *p; ! 1319: { ! 1320: #ifdef FORT ! 1321: void unoptim2(); ! 1322: if (!pascal) { ! 1323: unoptim2(p); ! 1324: } ! 1325: #endif FORT ! 1326: optim2(p); ! 1327: canon( p ); /* expands r-vals for fields */ ! 1328: toff = 0; /* stack offset swindle */ ! 1329: #ifdef FREETEMP ! 1330: tmpoff = 0; /* we number temp regsters differently here */ ! 1331: #endif ! 1332: } ! 1333: ! 1334: ! 1335: special( p, shape ) register NODE *p; ! 1336: { ! 1337: /* special shape matching routine */ ! 1338: ! 1339: switch (shape){ ! 1340: case SPEC_FLD: ! 1341: /* do-it-yourself multi-level matching */ ! 1342: if (tshape(p,SFLD)) ! 1343: switch( p->in.left->tn.op){ ! 1344: case OREG: ! 1345: /* if (R2TEST(p->in.left->tn.rval)) return 0; */ ! 1346: case REG: ! 1347: case ICON: ! 1348: case NAME: ! 1349: return(1); ! 1350: } ! 1351: return 0; ! 1352: ! 1353: case SPEC_FLT: ! 1354: /* depends on phase of moon */ ! 1355: if (usesky) ! 1356: return tshape(p,SCON|SAREG|STAREG|SBREG|SOREG|SNAME|STARREG); ! 1357: else ! 1358: return tshape(p,SAREG|STAREG) && (p->tn.rval==D0 || p->tn.rval==D1); ! 1359: case SPEC_DFLT: ! 1360: /* likewise */ ! 1361: if (usesky) ! 1362: return tshape(p,SCON|SAREG|STAREG|SBREG|SOREG|SNAME|STARREG); ! 1363: else ! 1364: return tshape(p,SCON| SOREG|SNAME|STARREG); ! 1365: ! 1366: case SFLOAT_SRCE: ! 1367: /* source operand of 68881 floating point instruction */ ! 1368: if (p->in.op == SCONV) { ! 1369: /* ! 1370: * the 68881 converts signed integral types into ! 1371: * (extended) floating point format ! 1372: */ ! 1373: p = p->in.left; ! 1374: switch(p->in.type) { ! 1375: case CHAR: ! 1376: case SHORT: ! 1377: case INT: ! 1378: case LONG: ! 1379: case FLOAT: ! 1380: /* d-registers, constants, and memory are all ok */ ! 1381: return tshape(p, ! 1382: SCON|SCREG|STCREG|SAREG|STAREG|SOREG|SNAME|STARNM|STARREG); ! 1383: case DOUBLE: ! 1384: /* can't deal with register pairs */ ! 1385: return tshape(p, ! 1386: SCON|SCREG|STCREG|SOREG|SNAME|STARNM|STARREG); ! 1387: default: ! 1388: return(0); ! 1389: } ! 1390: } ! 1391: if (p->in.type == FLOAT) { ! 1392: /* d-regs, f-registers, or memory */ ! 1393: return tshape(p, ! 1394: SCON|SCREG|STCREG|SAREG|STAREG|SOREG|SNAME|STARNM|STARREG); ! 1395: } ! 1396: /* type == DOUBLE: f-registers or memory only */ ! 1397: return tshape(p, SCON|SCREG|STCREG|SOREG|SNAME|STARNM|STARREG); ! 1398: ! 1399: case SPEC_PVT: ! 1400: /* right subtree of x + y*z ; an idiom from matrix computations */ ! 1401: if (!usesky) return 0; ! 1402: if (p->in.op != MUL) return 0; ! 1403: if (tshape(p->in.left,SCON|SAREG|STAREG|SBREG|SOREG|SNAME|STARREG)){ ! 1404: return tshape(p->in.right, ! 1405: SCON|SAREG|STAREG|SBREG|SOREG|SNAME|STARREG); ! 1406: } ! 1407: return 0; ! 1408: ! 1409: case SSOREG: ! 1410: /* someday soon, this will be useful */ ! 1411: return ( p->in.op == OREG && !R2TEST(p->tn.rval) ); ! 1412: ! 1413: case SBASE: ! 1414: /* half of a double-oreg */ ! 1415: return ( p->in.op == PLUS ! 1416: && p->in.left->in.op == REG && isbreg(p->in.left->tn.rval) ! 1417: && (p=p->in.right)->in.op == ICON && p->tn.name[0] == '\0' ! 1418: && p->tn.lval >= -127 && p->tn.lval <= 127 ); ! 1419: ! 1420: case SXREG: ! 1421: /* the other half */ ! 1422: if ( p->in.op==SCONV ! 1423: && (p->in.type == INT || p->in.type == UNSIGNED) ! 1424: && p->in.left->in.type == SHORT ) ! 1425: p = p->in.left; ! 1426: return ( p->in.op == REG ); ! 1427: ! 1428: case SNONPOW2: ! 1429: /* ! 1430: * constant, NOT a power of 2. This is a kludge to enable ! 1431: * us to match a template for ASG MOD on the 68020. The ! 1432: * semantics of the DIVSLL instruction make it impossible ! 1433: * to return a remainder in the lhs of <reg> %= <ea>, unless ! 1434: * an extra instruction is generated. Returning the result ! 1435: * in RESC1 makes the extra instruction unnecessary. ! 1436: */ ! 1437: return( p->in.op == ICON && (p->tn.lval & p->tn.lval-1) ); ! 1438: ! 1439: case SAUTOINC: ! 1440: return( p->in.op == UNARY MUL ! 1441: && p->in.left->in.op == INCR ! 1442: && shumul(p->in.left) == STARREG ); ! 1443: ! 1444: /* ! 1445: * CHK bounds pair with constant lower bound of 0 ! 1446: */ ! 1447: case SZEROLB: ! 1448: return( p->in.op == CM ! 1449: && p->in.left->in.op == ICON ! 1450: && p->in.left->tn.name == NULL ! 1451: && p->in.left->tn.lval == 0 ); ! 1452: ! 1453: case SFZERO: ! 1454: return( p->in.op == FCON && p->fpn.dval == 0.0 ); ! 1455: ! 1456: } ! 1457: ! 1458: if(p->tn.op != ICON || p->in.name[0] != '\0') return (0); ! 1459: switch( shape ) { ! 1460: case SCCON: ! 1461: return( p->tn.lval>= -128 && p->tn.lval <=127 ); ! 1462: case SICON: ! 1463: return( p->tn.lval>= 0 && p->tn.lval <=32767 ); ! 1464: case SSCON: ! 1465: return( p->tn.lval>= -32768 && p->tn.lval <=32767 ); ! 1466: case S8CON: ! 1467: return( p->tn.lval>= 1 && p->tn.lval <=8 ); ! 1468: default: ! 1469: cerror( "bad special shape" ); ! 1470: } ! 1471: ! 1472: return( 0 ); ! 1473: } ! 1474: ! 1475: # ifdef MULTILEVEL ! 1476: # include "mldec.h" ! 1477: ! 1478: struct ml_node mltree[] ={ ! 1479: ! 1480: DEFINCDEC, INCR, 0, ! 1481: INCR, SANY, TANY, ! 1482: OPANY, SAREG|STAREG, TANY, ! 1483: OPANY, SCON, TANY, ! 1484: ! 1485: DEFINCDEC, ASG MINUS, 0, ! 1486: ASG MINUS, SANY, TANY, ! 1487: REG, SANY, TANY, ! 1488: ICON, SANY, TANY, ! 1489: ! 1490: TSOREG, 1, 0, ! 1491: UNARY MUL, SANY, TANY, ! 1492: REG, SANY, TANY, ! 1493: ! 1494: TSOREG, 2, 0, ! 1495: UNARY MUL, SANY, TANY, ! 1496: PLUS, SANY, TANY, ! 1497: REG, SANY, TANY, ! 1498: ICON, SANY, TCHAR|TUCHAR|TSHORT|TUSHORT|TINT|TUNSIGNED|TPOINT, ! 1499: ! 1500: TSOREG, 2, 0, ! 1501: UNARY MUL, SANY, TANY, ! 1502: MINUS, SANY, TANY, ! 1503: REG, SANY, TANY, ! 1504: ICON, SANY, TCHAR|TUCHAR|TSHORT|TUSHORT|TINT|TUNSIGNED|TPOINT, ! 1505: 0,0,0}; ! 1506: # endif ! 1507: ! 1508: #ifdef FREETEMP ! 1509: extern unsigned offsz; ! 1510: ! 1511: freetemp( k ) ! 1512: { ! 1513: /* allocate k integers worth of temp space */ ! 1514: /* we also make the convention that, if the number of words is more than 1, ! 1515: /* it must be aligned for storing doubles... */ ! 1516: /* allocate temps forwards from sp+(saved registers) */ ! 1517: ! 1518: int t; ! 1519: ! 1520: if( k>1 ){ ! 1521: SETOFF( tmpoff, ALDOUBLE ); ! 1522: } ! 1523: t = tmpoff; ! 1524: tmpoff += k*SZINT; ! 1525: if( tmpoff >= offsz ) ! 1526: cerror( "stack overflow" ); ! 1527: if( tmpoff > maxtemp ) maxtemp = tmpoff ; ! 1528: return(t); ! 1529: ! 1530: } ! 1531: #endif FREETEMP ! 1532: ! 1533: #ifdef FORT ! 1534: void ! 1535: unoptim2( p ) register NODE *p; ! 1536: { ! 1537: /* FORTRAN thinks we can do double operations on float operands */ ! 1538: NODE * double_conv(); ! 1539: switch( optype(p->in.op)){ ! 1540: case BITYPE: ! 1541: unoptim2(p->in.left); ! 1542: unoptim2(p->in.right); ! 1543: if (p->in.type == DOUBLE){ ! 1544: switch (p->in.op) { ! 1545: case QUEST: ! 1546: case CM: ! 1547: case COMOP: ! 1548: case CALL: ! 1549: return; ! 1550: } ! 1551: if (p->in.right->in.type != DOUBLE) ! 1552: p->in.right = double_conv(p->in.right); ! 1553: if (p->in.left->in.type != DOUBLE) ! 1554: p->in.left = double_conv(p->in.left); ! 1555: return; ! 1556: } ! 1557: if ( logop(p->in.op) ){ ! 1558: if (p->in.left->in.type==DOUBLE && p->in.right->in.type != DOUBLE) ! 1559: p->in.right = double_conv(p->in.right); ! 1560: if (p->in.right->in.type==DOUBLE && p->in.left->in.type != DOUBLE) ! 1561: p->in.left = double_conv(p->in.left); ! 1562: } ! 1563: return; ! 1564: case UTYPE: ! 1565: unoptim2(p->in.left); ! 1566: if (p->in.type == DOUBLE ){ ! 1567: switch( p->in.op ){ ! 1568: case UNARY MUL: ! 1569: case UNARY CALL: ! 1570: case SCONV: ! 1571: return; ! 1572: } ! 1573: if (p->in.left->in.type != DOUBLE) ! 1574: p->in.left = double_conv(p->in.left); ! 1575: } ! 1576: return; ! 1577: case LTYPE: return; ! 1578: } ! 1579: } ! 1580: #endif FORT ! 1581:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.