|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "%W% (Berkeley/CCI) %G%"; ! 3: #endif ! 4: ! 5: /* ! 6: * C object code improver-- third part ! 7: */ ! 8: ! 9: #include "c2.h" ! 10: #include <stdio.h> ! 11: #include <ctype.h> ! 12: ! 13: rmove() ! 14: { ! 15: register struct node *p; ! 16: register int r, r1; ! 17: ! 18: clearreg(); ! 19: for (p=first.forw; p!=0; p = p->forw) { ! 20: if (debug) { ! 21: printf("Regs: "); ! 22: for (r=0; r<=NREG; r++) ! 23: if (regs[r][0]) { ! 24: r1=regs[r][0]; ! 25: printf("%d: %d%d %s\n", r, r1&0xF, r1>>4, regs[r]+1); ! 26: } ! 27: printf("-\n"); ! 28: } ! 29: switch (p->op) { ! 30: ! 31: case CVT: ! 32: case MOVZ: ! 33: splitrand(p); ! 34: repladdr(p); ! 35: r = isreg(regs[RT1]); ! 36: r1 = isreg(regs[RT2]); ! 37: dest(regs[RT2],p->subop, 1); ! 38: if (r>=0 && r1>=0) { ! 39: p->op = MOV; p->subop = LONG; ! 40: p->pop = 0; ! 41: nchange++; ! 42: goto case_mov; ! 43: } ! 44: if(p->op == CVT) { ! 45: if (r1>=0) savereg(r1, regs[RT1], p->subop); ! 46: } else ! 47: ccloc[0] = 0; ! 48: break; ! 49: ! 50: case MOV: ! 51: case_mov: ! 52: splitrand(p); ! 53: if ((r = findrand(regs[RT1],p->subop)) >= 0) { ! 54: if (r == isreg(regs[RT2])) ! 55: if(p->forw->op!=CBR) { ! 56: delnode(p); redunm++; nchange++; break; ! 57: } else { ! 58: p->op=TST; p->pop=0; ! 59: while(*p->code++ != ','); ! 60: redunm++; nchange++; ! 61: goto case_tst; ! 62: } ! 63: } ! 64: repladdr(p); ! 65: r = isreg(regs[RT1]); ! 66: r1 = isreg(regs[RT2]); ! 67: dest(regs[RT2],p->subop, 1); ! 68: if ((regs[ACC][0]) && equstr(regs[RT2],regs[ACC]+1)) ! 69: *(short *)(regs[ACC]) = 0; ! 70: if (r>=0) { ! 71: if (r1>=0) { ! 72: if (r == r1 && p->forw->op!=CBR) { ! 73: delnode(p); redunm++; nchange++; ! 74: break; ! 75: } ! 76: if(regs[r][0]) ! 77: savereg(r1, regs[r]+1, p->subop); ! 78: } else ! 79: savereg(r, regs[RT2], p->subop); ! 80: } else if (r1>=0) ! 81: savereg(r1, regs[RT1], p->subop); ! 82: else ! 83: setcon(regs[RT1], regs[RT2], p->subop); ! 84: break; ! 85: ! 86: /* .rx,.wx or .rx,.rx,.wx */ ! 87: case ADD: ! 88: case SUB: ! 89: case AND: ! 90: case OR: ! 91: case XOR: ! 92: case MUL: ! 93: case DIV: ! 94: #ifdef EMOD ! 95: case EDIV: ! 96: case EMOD: ! 97: #endif EMOD ! 98: case SHAL: ! 99: case SHAR: ! 100: case SHL: ! 101: case SHR: ! 102: case ADDA: ! 103: case SUBA: ! 104: /* .rx,.wx */ ! 105: case MFPR: ! 106: case COM: ! 107: case NEG: ! 108: splitrand(p); ! 109: repladdr(p); ! 110: dest(lastrand,p->subop, p->op!=ADDA && p->op!=SUBA); ! 111: break; ! 112: ! 113: /* .mx or .wx */ ! 114: case STF: ! 115: if(equstr(p->code, regs[ACC]+1) && p->subop==regs[ACC][0]) { ! 116: delnode(p); ! 117: nst++; nchange++; break; ! 118: } ! 119: savereg(ACC, p->code, p->subop); ! 120: case INC: ! 121: case DEC: ! 122: case CVFL: ! 123: dest(p->code,p->subop, 1); ! 124: break; ! 125: ! 126: case CLR: ! 127: dest(p->code,p->subop, 1); ! 128: if ((regs[ACC][0]) && equstr(p->code,regs[ACC]+1)) ! 129: *(short *)(regs[ACC]) = 0; ! 130: if ((r = isreg(p->code)) < 0) ! 131: setcon("$0", p->code, p->subop); ! 132: else ! 133: savereg(r, "$0", p->subop); ! 134: break; ! 135: ! 136: /* .rx */ ! 137: case LDF: ! 138: if(equstr(p->code, regs[ACC]+1) && p->subop==regs[ACC][0]) { ! 139: delnode(p); ! 140: nld++; nchange++; break; ! 141: } ! 142: savereg(ACC, p->code, p->subop); ! 143: goto case_tst; ! 144: case LNF: ! 145: if(equstr(p->code, regs[ACC]+1) && p->subop==regs[ACC][0]) { ! 146: p->op = NEGF; p->pop = 0; p->code = 0; ! 147: regs[ACC][0] = 0; ! 148: break; ! 149: } ! 150: case CVLF: ! 151: case LDFD: ! 152: case ADDF: ! 153: case SUBF: ! 154: case MULF: ! 155: case DIVF: ! 156: regs[ACC][0] = 0; ! 157: case TST: ! 158: case_tst: ! 159: case PUSH: ! 160: splitrand(p); ! 161: lastrand=regs[RT1+1]; /* fool repladdr into doing 1 operand */ ! 162: repladdr(p); ! 163: lastrand=regs[RT1]; ! 164: if (p->op==TST && equstr(lastrand, ccloc+1) ! 165: && ((0xf&(ccloc[0]>>4))==p->subop || equtype(ccloc[0],p->subop))) { ! 166: delnode(p); nrtst++; nchange++; break; ! 167: } ! 168: if (p->op==PUSH && p->subop!=LONG && ! 169: (isreg(lastrand)>=0 || *lastrand=='$')) { ! 170: p->subop = LONG; ! 171: p->pop = 0; ! 172: nchange++; ! 173: } ! 174: if (p->op==TST || p->op==PUSH) ! 175: setcc(lastrand,p->subop); ! 176: break; ! 177: ! 178: /* .rx,.rx,.rx */ ! 179: case PROBE: ! 180: case CASE: ! 181: /* .rx,.rx */ ! 182: case MTPR: ! 183: case CALLS: ! 184: case CALLF: ! 185: case CMP: ! 186: case BIT: ! 187: case CMPF: ! 188: case CMPF2: ! 189: splitrand(p); ! 190: /* fool repladdr into doing right number of operands */ ! 191: lastrand=byondrd(p); ! 192: if (p->op==CALLF || p->op==CALLS) clearreg(); ! 193: else repladdr(p); ! 194: case TSTF: ! 195: ccloc[0]=0; ! 196: case PUSHD: ! 197: break; ! 198: ! 199: /* acc only */ ! 200: case CVDF: ! 201: case NEGF: ! 202: case SINF: ! 203: case COSF: ! 204: case ATANF: ! 205: case LOGF: ! 206: case SQRTF: ! 207: case EXPF: ! 208: regs[ACC][0] = 0; ! 209: break; ! 210: ! 211: #ifndef EMOD ! 212: /* .rx,.rx,.wx,.wx */ ! 213: case EDIV: ! 214: splitrand(p); ! 215: lastrand = regs[RT3]; ! 216: repladdr(p); ! 217: dest(regs[RT3], p->subop, 1); ! 218: dest(regs[RT4], p->subop, 0); ! 219: break; ! 220: #endif EMOD ! 221: ! 222: /* .rx,.rx,.rx,wx */ ! 223: case EMUL: ! 224: splitrand(p); ! 225: lastrand = regs[RT4]; ! 226: repladdr(p); ! 227: dest(regs[RT4],QUAD, 1); /* fourth operand is a quad */ ! 228: break; ! 229: case CBR: ! 230: if (p->subop>=JBC) { ! 231: splitrand(p); ! 232: lastrand=regs[RT3]; /* 2 operands can be optimized */ ! 233: repladdr(p); ! 234: ccloc[0] = 0; ! 235: } else ! 236: reduncbr(p); ! 237: break; ! 238: ! 239: case JBR: ! 240: redunbr(p); ! 241: ! 242: default: ! 243: clearreg(); ! 244: } ! 245: } ! 246: } ! 247: ! 248: jumpsw() ! 249: { ! 250: register struct node *p, *p1, *pt; ! 251: register int t, nj; ! 252: ! 253: t = 0; ! 254: nj = 0; ! 255: for (p=first.forw; p!=0; p = p->forw) ! 256: p->seq = ++t; ! 257: for (p=first.forw; p!=0; p = p1) { ! 258: p1 = p->forw; ! 259: if (p->op == CBR && p1->op==JBR && p->ref && p1->ref ! 260: && abs(p->seq - p->ref->seq) > abs(p1->seq - p1->ref->seq)) { ! 261: if (p->ref==p1->ref) ! 262: continue; ! 263: p->subop = revbr[p->subop]; ! 264: p->pop=0; ! 265: pt = p1->ref; ! 266: p1->ref = p->ref; ! 267: p->ref = pt; ! 268: t = p1->labno; ! 269: p1->labno = p->labno; ! 270: p->labno = t; ! 271: #ifdef COPYCODE ! 272: if (p->labno == 0) { ! 273: pt = (struct node *)p1->code; p1->code = p->code; p->code = (char *)pt; ! 274: } ! 275: #endif ! 276: nrevbr++; ! 277: nj++; ! 278: } ! 279: } ! 280: return(nj); ! 281: } ! 282: ! 283: addaob() ! 284: { ! 285: register struct node *p, *p1, *p2, *p3; ! 286: ! 287: for (p = &first; (p1 = p->forw)!=0; p = p1) { ! 288: if (p->op==INC && p->subop==LONG) { ! 289: if (p1->op==LABEL && p1->refc==1 && p1->forw->op==CMP && p1->forw->subop==LONG ! 290: && (p2=p1->forw->forw)->op==CBR && p2->subop==JLE ! 291: && (p3=p2->ref->back)->op==JBR && p3->subop==0 && p3->ref==p1 ! 292: && p3->forw->op==LABEL && p3->forw==p2->ref) { ! 293: /* change INC LAB: CMP to LAB: INC CMP */ ! 294: p->back->forw=p1; p1->back=p->back; ! 295: p->forw=p1->forw; p1->forw->back=p; ! 296: p->back=p1; p1->forw=p; ! 297: p1=p->forw; ! 298: /* adjust beginning value by 1 */ ! 299: p2=alloc(sizeof first); p2->op = DEC; p2->subop = LONG; ! 300: p2->pop=0; ! 301: p2->forw=p3; p2->back=p3->back; p3->back->forw=p2; ! 302: p3->back=p2; p2->code=p->code; p2->labno=0; ! 303: } ! 304: if (p1->op==CMP && p1->subop==LONG && ! 305: (p2=p1->forw)->op==CBR && p2->forw->op!=CBR) { ! 306: register char *cp1,*cp2; ! 307: splitrand(p1); if (!equstr(p->code,regs[RT1])) continue; ! 308: if ((p2->subop==JLE || p2->subop==JLT) && ! 309: checkaobdisp(p2)){ ! 310: if (p2->subop==JLE) p->op = AOBLEQ; else p->op = AOBLSS; p->subop = 0; ! 311: cp2=regs[RT1]; cp1=regs[RT2]; while (*cp2++= *cp1++); /* limit */ ! 312: cp2=regs[RT2]; cp1=p->code; while (*cp2++= *cp1++); /* index */ ! 313: p->pop=0; newcode(p); ! 314: p->labno = p2->labno; delnode(p2); delnode(p1); naob++; ! 315: } ! 316: } ! 317: } ! 318: } ! 319: } ! 320: ! 321: ispow2(n) register long n; {/* -1 -> no; else -> log to base 2 */ ! 322: register int log; ! 323: if (n==0 || n&(n-1)) return(-1); log=0; ! 324: for (;;) {n >>= 1; if (n==0) return(log); ++log; if (n== -1) return(log);} ! 325: } ! 326: ! 327: equop(p1, p2) ! 328: register struct node *p1, *p2; ! 329: { ! 330: register char *cp1, *cp2; ! 331: ! 332: if (p1->op != p2->op || p1->subop != p2->subop) ! 333: return(0); ! 334: if (p1->op != NIL && ord(p1->op) < ord(MOV)) ! 335: return(0); ! 336: if (p1->op==MOVA && p1->labno!=p2->labno) return(0); ! 337: cp1 = p1->code; ! 338: cp2 = p2->code; ! 339: if (cp1==0 && cp2==0) ! 340: return(1); ! 341: if (cp1==0 || cp2==0) ! 342: return(0); ! 343: while (*cp1 == *cp2++) ! 344: if (*cp1++ == 0) ! 345: return(1); ! 346: return(0); ! 347: } ! 348: ! 349: delnode(p) register struct node *p; { ! 350: p->back->forw = p->forw; ! 351: p->forw->back = p->back; ! 352: } ! 353: ! 354: decref(p) ! 355: register struct node *p; ! 356: { ! 357: if (p && --p->refc <= 0) { ! 358: nrlab++; nchange++; ! 359: delnode(p); ! 360: } ! 361: } ! 362: ! 363: struct node * ! 364: nonlab(ap) ! 365: struct node *ap; ! 366: { ! 367: register struct node *p; ! 368: ! 369: p = ap; ! 370: while (p && p->op==LABEL) ! 371: p = p->forw; ! 372: return(p); ! 373: } ! 374: ! 375: clearuse() { ! 376: register struct node **i; ! 377: register short *p; ! 378: for (i=uses+NREG; i>uses;) *--i=0; ! 379: useacc = 0; ! 380: for (p=usecnt+NUSE; p>usecnt;) *--p=0; ! 381: } ! 382: ! 383: clearreg() { ! 384: register char **i; ! 385: for (i=regs+NREG+1; i>regs;){ **--i=0; **i=0; } ! 386: conloc[0] = 0; ccloc[0] = 0; ! 387: } ! 388: ! 389: savereg(ai, s, type) ! 390: register char *s; ! 391: { ! 392: register char *p, *sp; ! 393: ! 394: sp = p = regs[ai]; ! 395: /* if any indexing, must be parameter or local */ ! 396: /* indirection (as in "*-4(fp)") is ok, however */ ! 397: *p++ = type; ! 398: if (*s=='*' || *s=='$') ! 399: *p++ = *s++; ! 400: if (natural(s)) ! 401: strcpy(p, s); ! 402: else {*sp = 0; return;} ! 403: } ! 404: ! 405: dest(s,type, ccflg) ! 406: register char *s; ! 407: { ! 408: register int i; ! 409: ! 410: if ((i = isreg(s)) >= 0) { ! 411: *(short *)(regs[i]) = 0; /* if register destination, that reg is a goner */ ! 412: if (DOUBLE==(type&0xF) || DOUBLE==((type>>4)&0xF) || type==QUAD) ! 413: *(short *)(regs[i+1]) = 0; ! 414: } ! 415: for (i=NREG; --i>=0;) ! 416: if (regs[i][1]=='*' && equstr(s, regs[i]+2)) ! 417: *(short *)(regs[i]) = 0; /* previous indirection through destination is invalid */ ! 418: while ((i = findrand(s,0)) >= 0) /* previous values of destination are invalid */ ! 419: *(short *)(regs[i]) = 0; ! 420: ! 421: if (!natural(s)) {/* wild store, everything except constants vanishes */ ! 422: for (i=NREG; --i>=0;) if (regs[i][1] != '$') *(short *)(regs[i]) = 0; ! 423: conloc[0] = 0; ccloc[0] = 0; ! 424: } else { ! 425: if(ccflg)setcc(s,type); /* natural destinations set condition codes */ ! 426: if (equstr(s, conloc)) ! 427: conloc[0] = 0; ! 428: } ! 429: } ! 430: ! 431: splitrand(p) struct node *p; { ! 432: /* separate operands at commas, set up 'regs' and 'lastrand' */ ! 433: register char *p1, *p2; register char **preg; ! 434: ! 435: preg=regs+RT1; ! 436: if (p1=p->code) while (*p1) { ! 437: lastrand=p2= *preg++; ! 438: while (*p1) if (','==(*p2++= *p1++)) {--p2; break;} ! 439: *p2=0; ! 440: } ! 441: while (preg<(regs+RT1+5)) *(*preg++)=0; ! 442: } ! 443: ! 444: compat(have, want) ! 445: register int have, want; ! 446: { ! 447: register int hsrc, hdst; ! 448: extern int bitsize[]; ! 449: ! 450: if (0==(want &= 0xF)) return(1); /* anything satisfies a wildcard want */ ! 451: hsrc=have&0xF; if (0==(hdst=((have>>4)&0xF)) || hdst>=OP2) hdst=hsrc; ! 452: if (want>=QUAD) ! 453: return(bitsize[hdst]==bitsize[want] && bitsize[hsrc]==bitsize[want]); ! 454: return(hsrc==want && hdst>=want && hdst<QUAD); ! 455: } ! 456: ! 457: equtype(t1,t2) {return(compat(t1,t2) && compat(t2,t1));} ! 458: ! 459: findrand(as, type) ! 460: char *as; ! 461: { ! 462: register char **i; ! 463: for (i = regs+NREG; --i>=regs;) { ! 464: if (**i && equstr(*i+1, as) && compat(**i,type)) ! 465: return(i-regs); ! 466: } ! 467: return(-1); ! 468: } ! 469: ! 470: isreg(s) ! 471: register char *s; ! 472: { ! 473: if (*s++!='r' || !isdigit(*s++)) return(-1); ! 474: if (*s==0) return(*--s-'0'); ! 475: if (*(s-1)=='1' && isdigit(*s++) && *s==0) return(10+*--s-'0'); ! 476: return(-1); ! 477: } ! 478: ! 479: /* ! 480: check() ! 481: { ! 482: register struct node *p, *lp; ! 483: ! 484: lp = &first; ! 485: for (p=first.forw; p!=0; p = p->forw) { ! 486: if (p->back != lp) ! 487: abort(-1); ! 488: lp = p; ! 489: } ! 490: } ! 491: */ ! 492: ! 493: newcode(p) struct node *p; { ! 494: register char *p1,*p2,**preg; ! 495: ! 496: preg=regs+RT1; p2=line; ! 497: while (*(p1= *preg++)) {while (*p2++= *p1++); *(p2-1)=',';} ! 498: *--p2=0; ! 499: p->code=copy(line); ! 500: } ! 501: ! 502: repladdr(p) ! 503: struct node *p; ! 504: { ! 505: register int r; ! 506: register char *p1; ! 507: register char **preg; ! 508: register int nrepl; ! 509: ! 510: preg=regs+RT1; nrepl=0; ! 511: while (lastrand!=(p1= *preg++)) ! 512: if (0<=(r=findrand(p1,p->subop))) { ! 513: *p1++='r'; if (r>9) {*p1++='1'; r -= 10;} *p1++=r+'0'; *p1=0; ! 514: nchange++; nrepl++; nsaddr++; ! 515: } ! 516: if (nrepl) newcode(p); ! 517: } ! 518: ! 519: /* conditional branches which are never/always taken */ ! 520: reduncbr(p) ! 521: register struct node *p; ! 522: { ! 523: register struct node *p1; ! 524: register char *ap1, *ap2; ! 525: ! 526: p1 = p->back; ! 527: if (p1->op==CMP) { ! 528: splitrand(p1); ! 529: ap1 = findcon(regs[RT1], p1->subop); ! 530: ap2 = findcon(regs[RT2], p1->subop); ! 531: } else { ! 532: if(!ccloc[0]) ! 533: return; ! 534: ap1 = findcon(ccloc+1, ccloc[0]); ! 535: ap2 = "$0"; ! 536: } ! 537: switch (compare(p->subop, ap1, ap2)) { ! 538: case 0: /* branch never taken */ ! 539: delnode(p); ! 540: nredunj++; ! 541: nchange++; ! 542: decref(p->ref); ! 543: if(p->forw->op!=CBR && (p1->op==TST || p1->op==CMP)) { ! 544: delnode(p1); ! 545: nrtst++; ! 546: } ! 547: break; ! 548: case 1: /* branch always taken */ ! 549: p->op = JBR; ! 550: p->subop = 0; ! 551: p->pop = 0; ! 552: nchange++; ! 553: if(nonlab(p->ref)->op!=CBR && (p1->op==TST || p1->op==CMP)) { ! 554: delnode(p1); ! 555: nrtst++; ! 556: } ! 557: } ! 558: } ! 559: ! 560: /* a jump to a redundant compare (start of a 'for') */ ! 561: redunbr(p) ! 562: register struct node *p; ! 563: { ! 564: register struct node *p1; ! 565: register char *ap1, *ap2; ! 566: ! 567: if ((p1 = p->ref) == 0) ! 568: return; ! 569: p1 = nonlab(p1); ! 570: if (p1->op==TST || p1->op==CMP) ! 571: splitrand(p1); ! 572: else ! 573: return; ! 574: if (p1->forw->op==CBR) { ! 575: ap1 = findcon(regs[RT1], p1->subop); ! 576: if (p1->op==TST) ! 577: ap2 = "$0"; ! 578: else ! 579: ap2 = findcon(regs[RT2], p1->subop); ! 580: p1 = p1->forw; ! 581: if (compare(p1->subop, ap1, ap2) > 0) { ! 582: nredunj++; ! 583: nchange++; ! 584: decref(p->ref); ! 585: p->ref = p1->ref; ! 586: p->labno = p1->labno; ! 587: #ifdef COPYCODE ! 588: if (p->labno == 0) ! 589: p->code = p1->code; ! 590: if (p->ref) ! 591: #endif ! 592: p->ref->refc++; ! 593: } ! 594: } else if (p1->op==TST && equstr(regs[RT1],ccloc+1) && ! 595: equtype(ccloc[0],p1->subop)) { ! 596: p1=insertl(p1->forw); decref(p->ref); p->ref=p1; ! 597: nrtst++; nchange++; ! 598: } ! 599: } ! 600: ! 601: char * ! 602: findcon(p, type) ! 603: register char *p; ! 604: { ! 605: register int r; ! 606: ! 607: if (*p=='$') ! 608: return(p); ! 609: if ((r = isreg(p)) >= 0 && compat(regs[r][0],type)) ! 610: return(regs[r]+1); ! 611: if (equstr(p, conloc) && equtype(conloc[0], type)) ! 612: return(conval+1); ! 613: return(p); ! 614: } ! 615: ! 616: /* compare constants: 0 - branch taken; 1 - not taken; -1 - don't know */ ! 617: compare(op, acp1, acp2) ! 618: char *acp1, *acp2; ! 619: { ! 620: register char *cp1, *cp2; ! 621: register int n1, n2, sign; ! 622: ! 623: cp1 = acp1; ! 624: cp2 = acp2; ! 625: if (*cp1++ != '$' || *cp2++ != '$') ! 626: return(-1); ! 627: n1 = 0; sign=1; if (*cp1=='-') {++cp1; sign= -1;} ! 628: while (isdigit(*cp1)) {n1 *= 10; n1 += *cp1++ - '0';} ! 629: n1 *= sign; ! 630: n2 = 0; sign=1; if (*cp2=='-') {++cp2; sign= -1;} ! 631: while (isdigit(*cp2)) {n2 *= 10; n2 += *cp2++ - '0';} ! 632: n2 *= sign; ! 633: if (*cp1=='+') ! 634: cp1++; ! 635: if (*cp2=='+') ! 636: cp2++; ! 637: do { ! 638: if (*cp1++ != *cp2) ! 639: return(-1); ! 640: } while (*cp2++); ! 641: switch(op) { ! 642: ! 643: case JEQ: ! 644: return(n1 == n2); ! 645: case JNE: ! 646: return(n1 != n2); ! 647: case JLE: ! 648: return(n1 <= n2); ! 649: case JGE: ! 650: return(n1 >= n2); ! 651: case JLT: ! 652: return(n1 < n2); ! 653: case JGT: ! 654: return(n1 > n2); ! 655: case JLO: ! 656: return((unsigned)n1 < (unsigned)n2); ! 657: case JHI: ! 658: return((unsigned)n1 > (unsigned)n2); ! 659: case JLOS: ! 660: return((unsigned)n1 <= (unsigned)n2); ! 661: case JHIS: ! 662: return((unsigned)n1 >= (unsigned)n2); ! 663: } ! 664: return(-1); ! 665: } ! 666: ! 667: setcon(cv, cl, type) ! 668: register char *cv, *cl; ! 669: { ! 670: register char *p; ! 671: ! 672: if (*cv != '$') ! 673: return; ! 674: if (!natural(cl)) ! 675: return; ! 676: p = conloc; ! 677: while (*p++ = *cl++); ! 678: p = conval; ! 679: *p++ = type; ! 680: while (*p++ = *cv++); ! 681: } ! 682: ! 683: setcc(ap,type) ! 684: char *ap; ! 685: { ! 686: register char *p, *p1; ! 687: ! 688: p = ap; ! 689: if (!natural(p)) { ! 690: ccloc[0] = 0; ! 691: return; ! 692: } ! 693: p1 = ccloc; ! 694: *p1++ = type; ! 695: while (*p1++ = *p++); ! 696: } ! 697: ! 698: indexa(p) register char *p; {/* 1-> uses [r] addressing mode; 0->doesn't */ ! 699: while (*p) if (*p++=='[') return(1); ! 700: return(0); ! 701: } ! 702: ! 703: natural(p) ! 704: register char *p; ! 705: {/* 1->simple local, parameter, global, or register; 0->otherwise */ ! 706: ! 707: if (*p=='*' || *p=='(' || *p=='$') ! 708: return(0); ! 709: while (*p++); ! 710: p--; ! 711: if (*--p==']' || *p==')' && ! 712: !(*(p-2)=='f' || fortflg && (*--p=='1' || *p=='2') && *--p=='1')) ! 713: return(0); ! 714: return(1); ! 715: } ! 716: ! 717: /* ! 718: ** Tell if an argument is most likely static. ! 719: */ ! 720: ! 721: isstatic(cp) ! 722: register char *cp; ! 723: { ! 724: if (*cp == '_' || *cp == 'L') ! 725: return (1); ! 726: return (0); ! 727: } ! 728: ! 729: ! 730: checkaobdisp(p) ! 731: register struct node *p; ! 732: { ! 733: register struct node *q; ! 734: register int i; ! 735: ! 736: ! 737: if (!aobflag) return(1); ! 738: /* backward search */ ! 739: i = 0; ! 740: q = p; ! 741: while (i++ < MAXAOBDISP && ((q= q->back) !=&first)) ! 742: { ! 743: if (p->ref == q) ! 744: return(1); ! 745: } ! 746: ! 747: /* forward search */ ! 748: i = 0; ! 749: q = p; ! 750: while (i++ < MAXAOBDISP && ((q= q->forw) !=0)) ! 751: { ! 752: if (p->ref == q) ! 753: return(1); ! 754: } ! 755: return(0); ! 756: } ! 757: ! 758: ! 759: struct intleavetab intltab[] = { ! 760: ADDF, FLOAT, 1, ! 761: ADDF, DOUBLE, 1, ! 762: SUBF, FLOAT, 1, ! 763: SUBF, DOUBLE, 1, ! 764: MULF, FLOAT, 1, ! 765: MULF, DOUBLE, 1, ! 766: DIVF, FLOAT, 1, ! 767: DIVF, DOUBLE, 1, ! 768: SINF, FLOAT, 1, ! 769: COSF, FLOAT, 1, ! 770: ATANF, FLOAT, 1, ! 771: LOGF, FLOAT, 1, ! 772: SQRTF, FLOAT, 1, ! 773: EXPF, FLOAT, 1, ! 774: LDF, FLOAT, 0, ! 775: LDF, DOUBLE, 0, ! 776: LNF, FLOAT, 0, ! 777: LNF, DOUBLE, 0, ! 778: STF, FLOAT, 0, ! 779: CMPF, FLOAT, 0, ! 780: CMPF, DOUBLE, 0, ! 781: CMPF2, FLOAT, 0, ! 782: TSTF, FLOAT, 0, ! 783: TSTF, DOUBLE, 0, ! 784: PUSHD, DOUBLE, 0, ! 785: CVLF, U(LONG,FLOAT), 0, ! 786: CVFL, U(FLOAT,LONG), 0, ! 787: LDFD, U(FLOAT,DOUBLE),0, ! 788: CVDF, U(DOUBLE,FLOAT),0, ! 789: NEGF, FLOAT, 0, ! 790: NIL, 0, 0}; ! 791: ! 792: interleave() ! 793: { ! 794: register struct node *p, *p1; ! 795: ! 796: register struct intleavetab *t; ! 797: register int r; ! 798: int count; ! 799: for (p= first.forw; p!=0; p = p->forw){ ! 800: count = 0; ! 801: for (t =intltab; t->op != NIL; t++){ ! 802: if (t->op == p->op && t->subop == p->subop){ ! 803: count = t->intleavect; ! 804: break; ! 805: } ! 806: } ! 807: if (count < 1) continue; ! 808: p1 = p->forw; ! 809: clearuse(); ! 810: clearreg(); ! 811: while ((p1 != 0) && (p1->op != CBR) && ! 812: (p1->subop == FLOAT || p1->subop == DOUBLE || ! 813: ((p1->subop&0xF0)==DOUBLE<<4) || ((p1->subop&0xF)==DOUBLE )|| ! 814: ((p1->subop&0xF0)==FLOAT<<4) || (p1->subop&0xF)==FLOAT)) ! 815: { ! 816: if (((r = isreg(p1->code)) >= 0)){ ! 817: uses[r] = p1; ! 818: if ((p1->subop == DOUBLE) || ((p->subop&0xF0)==DOUBLE<<4) || ! 819: ((p->subop&0xF)==DOUBLE)) ! 820: uses[r+1] = p1; ! 821: } ! 822: else checkreg(p1,p1->code); ! 823: p1 = p1->forw; ! 824: ! 825: } ! 826: if (p1 == 0) return; ! 827: if (!(sideeffect(p, p1))) ! 828: insertblk(p,p1); ! 829: } ! 830: ! 831: } ! 832: ! 833: ! 834: insertblk(p, p1) ! 835: struct node *p, *p1; ! 836: { ! 837: p1->back->forw = p1->forw; ! 838: p1->forw->back = p1->back; ! 839: p1->forw = p->forw; ! 840: p->forw->back = p1; ! 841: p->forw = p1; ! 842: p1->back = p; ! 843: } ! 844: ! 845: OpCode termop[] = { ! 846: JBR, CBR, JMP, LABEL, DLABEL, EROU, JSW, TST, CMP, BIT, ! 847: CALLF, CALLS, CASE, AOBLEQ, AOBLSS, CMPF, CMPF2, TSTF, MOVBLK, MFPR, ! 848: MTPR, PROBE, MOVO, TEXT, DATA, BSS, ALIGN, END, LGEN, SET, ! 849: LCOMM, COMM, NIL ! 850: }; ! 851: ! 852: sideeffect(p,p1) ! 853: struct node *p, *p1; ! 854: { ! 855: register struct node *q; ! 856: register int r; ! 857: register OpCode *t; ! 858: register char *cp; ! 859: int i; ! 860: ! 861: if (p1->op == NIL) return(1); /* special instructions */ ! 862: ! 863: for (t = termop; *t!=NIL; t++){ ! 864: if (*t == p1->op) return(1); ! 865: } ! 866: if ((p1->forw != NULL) && (p1->forw->op == CBR)) ! 867: return(1); ! 868: splitrand(p1); ! 869: r = isreg(lastrand); ! 870: if (uses[r] && r >= 0 ) return(1); ! 871: if ((p1->op == EDIV) && (r = isreg(regs[RT3]) >= 0) && ! 872: (uses[r])) return(1); ! 873: ! 874: for (q = p1->back ; q!=p; q=q->back) ! 875: { ! 876: if ((p1->op == PUSH || p1->op == PUSHA) && ! 877: (q->op == PUSHD || q->op == PUSH || q->op == PUSHA)) ! 878: return(1); /* keep args in order */ ! 879: if (((i = strlen(q->code)) >= 5 && /* cvdl -(sp); pushl r0*/ ! 880: (strcmp(q->code+i-5,"-(sp)") == 0 )) || ! 881: (strcmp(lastrand,"-(sp)") == 0)) return(1); ! 882: if (equstr(q->code, lastrand)) ! 883: return(1); ! 884: if (q->op == STF || q->op == CVFL || q->op == CVLF) ! 885: { ! 886: if (equstr(q->code, regs[RT1])) return(1); ! 887: if (has3ops(p1) || p1->op == EMUL || p1->op == EDIV) ! 888: if (equstr(q->code, regs[RT2])) ! 889: return(1); ! 890: /* handle the case std -56(fp) pushl -60(fp) pushl ! 891: -56(fp); ! 892: */ ! 893: if ((p1->forw != NULL) && (q->op == STF) && ! 894: (q->subop == DOUBLE)){ ! 895: if (!strncmp(q->code,p1->forw->code,strlen(q->code))) ! 896: return(1); ! 897: } ! 898: } ! 899: } ! 900: return(0); ! 901: } ! 902: checkreg(p,s) ! 903: struct node *p; ! 904: char *s; ! 905: { ! 906: char *cp2; ! 907: register int r; ! 908: /* check for (r),[r] */ ! 909: do if (*s=='(' || *s=='[') {/* get register number */ ! 910: char t; ! 911: cp2= ++s; while (*++s!=')' && *s!=']'); t= *s; *s=0; ! 912: if ((r=isreg(cp2)) >= 0) { ! 913: uses[r]=p; ! 914: } ! 915: *s=t; ! 916: } while (*++s); ! 917: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.