|
|
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: for (i=uses+NREG; i>uses;) *--i=0; ! 378: useacc = 0; ! 379: } ! 380: ! 381: clearreg() { ! 382: register char **i; ! 383: for (i=regs+NREG+1; i>regs;){ **--i=0; **i=0; } ! 384: conloc[0] = 0; ccloc[0] = 0; ! 385: } ! 386: ! 387: savereg(ai, s, type) ! 388: register char *s; ! 389: { ! 390: register char *p, *sp; ! 391: ! 392: sp = p = regs[ai]; ! 393: /* if any indexing, must be parameter or local */ ! 394: /* indirection (as in "*-4(fp)") is ok, however */ ! 395: *p++ = type; ! 396: if (*s=='*' || *s=='$') ! 397: *p++ = *s++; ! 398: if (natural(s)) ! 399: strcpy(p, s); ! 400: else {*sp = 0; return;} ! 401: } ! 402: ! 403: dest(s,type, ccflg) ! 404: register char *s; ! 405: { ! 406: register int i; ! 407: ! 408: if ((i = isreg(s)) >= 0) { ! 409: *(short *)(regs[i]) = 0; /* if register destination, that reg is a goner */ ! 410: if (DOUBLE==(type&0xF) || DOUBLE==((type>>4)&0xF) || type==QUAD) ! 411: *(short *)(regs[i+1]) = 0; ! 412: } ! 413: for (i=NREG; --i>=0;) ! 414: if (regs[i][1]=='*' && equstr(s, regs[i]+2)) ! 415: *(short *)(regs[i]) = 0; /* previous indirection through destination is invalid */ ! 416: while ((i = findrand(s,0)) >= 0) /* previous values of destination are invalid */ ! 417: *(short *)(regs[i]) = 0; ! 418: ! 419: if (!natural(s)) {/* wild store, everything except constants vanishes */ ! 420: for (i=NREG; --i>=0;) if (regs[i][1] != '$') *(short *)(regs[i]) = 0; ! 421: conloc[0] = 0; ccloc[0] = 0; ! 422: } else { ! 423: if(ccflg)setcc(s,type); /* natural destinations set condition codes */ ! 424: if (equstr(s, conloc)) ! 425: conloc[0] = 0; ! 426: } ! 427: } ! 428: ! 429: splitrand(p) struct node *p; { ! 430: /* separate operands at commas, set up 'regs' and 'lastrand' */ ! 431: register char *p1, *p2; register char **preg; ! 432: ! 433: preg=regs+RT1; ! 434: if (p1=p->code) while (*p1) { ! 435: lastrand=p2= *preg++; ! 436: while (*p1) if (','==(*p2++= *p1++)) {--p2; break;} ! 437: *p2=0; ! 438: } ! 439: while (preg<(regs+RT1+5)) *(*preg++)=0; ! 440: } ! 441: ! 442: compat(have, want) ! 443: register int have, want; ! 444: { ! 445: register int hsrc, hdst; ! 446: extern int bitsize[]; ! 447: ! 448: if (0==(want &= 0xF)) return(1); /* anything satisfies a wildcard want */ ! 449: hsrc=have&0xF; if (0==(hdst=((have>>4)&0xF)) || hdst>=OP2) hdst=hsrc; ! 450: if (want>=QUAD) ! 451: return(bitsize[hdst]==bitsize[want] && bitsize[hsrc]==bitsize[want]); ! 452: return(hsrc==want && hdst>=want && hdst<QUAD); ! 453: } ! 454: ! 455: equtype(t1,t2) {return(compat(t1,t2) && compat(t2,t1));} ! 456: ! 457: findrand(as, type) ! 458: char *as; ! 459: { ! 460: register char **i; ! 461: for (i = regs+NREG; --i>=regs;) { ! 462: if (**i && equstr(*i+1, as) && compat(**i,type)) ! 463: return(i-regs); ! 464: } ! 465: return(-1); ! 466: } ! 467: ! 468: isreg(s) ! 469: register char *s; ! 470: { ! 471: if (*s++!='r' || !isdigit(*s++)) return(-1); ! 472: if (*s==0) return(*--s-'0'); ! 473: if (*(s-1)=='1' && isdigit(*s++) && *s==0) return(10+*--s-'0'); ! 474: return(-1); ! 475: } ! 476: ! 477: /* ! 478: check() ! 479: { ! 480: register struct node *p, *lp; ! 481: ! 482: lp = &first; ! 483: for (p=first.forw; p!=0; p = p->forw) { ! 484: if (p->back != lp) ! 485: abort(-1); ! 486: lp = p; ! 487: } ! 488: } ! 489: */ ! 490: ! 491: newcode(p) struct node *p; { ! 492: register char *p1,*p2,**preg; ! 493: ! 494: preg=regs+RT1; p2=line; ! 495: while (*(p1= *preg++)) {while (*p2++= *p1++); *(p2-1)=',';} ! 496: *--p2=0; ! 497: p->code=copy(line); ! 498: } ! 499: ! 500: repladdr(p) ! 501: struct node *p; ! 502: { ! 503: register int r; ! 504: register char *p1; ! 505: register char **preg; ! 506: register int nrepl; ! 507: ! 508: preg=regs+RT1; nrepl=0; ! 509: while (lastrand!=(p1= *preg++)) ! 510: if (0<=(r=findrand(p1,p->subop))) { ! 511: *p1++='r'; if (r>9) {*p1++='1'; r -= 10;} *p1++=r+'0'; *p1=0; ! 512: nchange++; nrepl++; nsaddr++; ! 513: } ! 514: if (nrepl) newcode(p); ! 515: } ! 516: ! 517: /* conditional branches which are never/always taken */ ! 518: reduncbr(p) ! 519: register struct node *p; ! 520: { ! 521: register struct node *p1; ! 522: register char *ap1, *ap2; ! 523: ! 524: p1 = p->back; ! 525: if (p1->op==CMP) { ! 526: splitrand(p1); ! 527: ap1 = findcon(regs[RT1], p1->subop); ! 528: ap2 = findcon(regs[RT2], p1->subop); ! 529: } else { ! 530: if(!ccloc[0]) ! 531: return; ! 532: ap1 = findcon(ccloc+1, ccloc[0]); ! 533: ap2 = "$0"; ! 534: } ! 535: switch (compare(p->subop, ap1, ap2)) { ! 536: case 0: /* branch never taken */ ! 537: delnode(p); ! 538: nredunj++; ! 539: nchange++; ! 540: decref(p->ref); ! 541: if(p->forw->op!=CBR && (p1->op==TST || p1->op==CMP)) { ! 542: delnode(p1); ! 543: nrtst++; ! 544: } ! 545: break; ! 546: case 1: /* branch always taken */ ! 547: p->op = JBR; ! 548: p->subop = 0; ! 549: p->pop = 0; ! 550: nchange++; ! 551: if(nonlab(p->ref)->op!=CBR && (p1->op==TST || p1->op==CMP)) { ! 552: delnode(p1); ! 553: nrtst++; ! 554: } ! 555: } ! 556: } ! 557: ! 558: /* a jump to a redundant compare (start of a 'for') */ ! 559: redunbr(p) ! 560: register struct node *p; ! 561: { ! 562: register struct node *p1; ! 563: register char *ap1, *ap2; ! 564: ! 565: if ((p1 = p->ref) == 0) ! 566: return; ! 567: p1 = nonlab(p1); ! 568: if (p1->op==TST || p1->op==CMP) ! 569: splitrand(p1); ! 570: else ! 571: return; ! 572: if (p1->forw->op==CBR) { ! 573: ap1 = findcon(regs[RT1], p1->subop); ! 574: if (p1->op==TST) ! 575: ap2 = "$0"; ! 576: else ! 577: ap2 = findcon(regs[RT2], p1->subop); ! 578: p1 = p1->forw; ! 579: if (compare(p1->subop, ap1, ap2) > 0) { ! 580: nredunj++; ! 581: nchange++; ! 582: decref(p->ref); ! 583: p->ref = p1->ref; ! 584: p->labno = p1->labno; ! 585: #ifdef COPYCODE ! 586: if (p->labno == 0) ! 587: p->code = p1->code; ! 588: if (p->ref) ! 589: #endif ! 590: p->ref->refc++; ! 591: } ! 592: } else if (p1->op==TST && equstr(regs[RT1],ccloc+1) && ! 593: equtype(ccloc[0],p1->subop)) { ! 594: p1=insertl(p1->forw); decref(p->ref); p->ref=p1; ! 595: nrtst++; nchange++; ! 596: } ! 597: } ! 598: ! 599: char * ! 600: findcon(p, type) ! 601: register char *p; ! 602: { ! 603: register int r; ! 604: ! 605: if (*p=='$') ! 606: return(p); ! 607: if ((r = isreg(p)) >= 0 && compat(regs[r][0],type)) ! 608: return(regs[r]+1); ! 609: if (equstr(p, conloc) && equtype(conloc[0], type)) ! 610: return(conval+1); ! 611: return(p); ! 612: } ! 613: ! 614: /* compare constants: 0 - branch taken; 1 - not taken; -1 - don't know */ ! 615: compare(op, acp1, acp2) ! 616: char *acp1, *acp2; ! 617: { ! 618: register char *cp1, *cp2; ! 619: register int n1, n2, sign; ! 620: ! 621: cp1 = acp1; ! 622: cp2 = acp2; ! 623: if (*cp1++ != '$' || *cp2++ != '$') ! 624: return(-1); ! 625: n1 = 0; sign=1; if (*cp1=='-') {++cp1; sign= -1;} ! 626: while (isdigit(*cp1)) {n1 *= 10; n1 += *cp1++ - '0';} ! 627: n1 *= sign; ! 628: n2 = 0; sign=1; if (*cp2=='-') {++cp2; sign= -1;} ! 629: while (isdigit(*cp2)) {n2 *= 10; n2 += *cp2++ - '0';} ! 630: n2 *= sign; ! 631: if (*cp1=='+') ! 632: cp1++; ! 633: if (*cp2=='+') ! 634: cp2++; ! 635: do { ! 636: if (*cp1++ != *cp2) ! 637: return(-1); ! 638: } while (*cp2++); ! 639: switch(op) { ! 640: ! 641: case JEQ: ! 642: return(n1 == n2); ! 643: case JNE: ! 644: return(n1 != n2); ! 645: case JLE: ! 646: return(n1 <= n2); ! 647: case JGE: ! 648: return(n1 >= n2); ! 649: case JLT: ! 650: return(n1 < n2); ! 651: case JGT: ! 652: return(n1 > n2); ! 653: case JLO: ! 654: return((unsigned)n1 < (unsigned)n2); ! 655: case JHI: ! 656: return((unsigned)n1 > (unsigned)n2); ! 657: case JLOS: ! 658: return((unsigned)n1 <= (unsigned)n2); ! 659: case JHIS: ! 660: return((unsigned)n1 >= (unsigned)n2); ! 661: } ! 662: return(-1); ! 663: } ! 664: ! 665: setcon(cv, cl, type) ! 666: register char *cv, *cl; ! 667: { ! 668: register char *p; ! 669: ! 670: if (*cv != '$') ! 671: return; ! 672: if (!natural(cl)) ! 673: return; ! 674: p = conloc; ! 675: while (*p++ = *cl++); ! 676: p = conval; ! 677: *p++ = type; ! 678: while (*p++ = *cv++); ! 679: } ! 680: ! 681: setcc(ap,type) ! 682: char *ap; ! 683: { ! 684: register char *p, *p1; ! 685: ! 686: p = ap; ! 687: if (!natural(p)) { ! 688: ccloc[0] = 0; ! 689: return; ! 690: } ! 691: p1 = ccloc; ! 692: *p1++ = type; ! 693: while (*p1++ = *p++); ! 694: } ! 695: ! 696: indexa(p) register char *p; {/* 1-> uses [r] addressing mode; 0->doesn't */ ! 697: while (*p) if (*p++=='[') return(1); ! 698: return(0); ! 699: } ! 700: ! 701: natural(p) ! 702: register char *p; ! 703: {/* 1->simple local, parameter, global, or register; 0->otherwise */ ! 704: ! 705: if (*p=='*' || *p=='(' || *p=='$') ! 706: return(0); ! 707: while (*p++); ! 708: p--; ! 709: if (*--p==']' || *p==')' && ! 710: !(*(p-2)=='f' || fortflg && (*--p=='1' || *p=='2') && *--p=='1')) ! 711: return(0); ! 712: return(1); ! 713: } ! 714: ! 715: /* ! 716: ** Tell if an argument is most likely static. ! 717: */ ! 718: ! 719: isstatic(cp) ! 720: register char *cp; ! 721: { ! 722: if (*cp == '_' || *cp == 'L') ! 723: return (1); ! 724: return (0); ! 725: } ! 726: ! 727: ! 728: checkaobdisp(p) ! 729: register struct node *p; ! 730: { ! 731: register struct node *q; ! 732: register int i; ! 733: ! 734: ! 735: if (!aobflag) return(1); ! 736: /* backward search */ ! 737: i = 0; ! 738: q = p; ! 739: while (i++ < MAXAOBDISP && ((q= q->back) !=&first)) ! 740: { ! 741: if (p->ref == q) ! 742: return(1); ! 743: } ! 744: ! 745: /* forward search */ ! 746: i = 0; ! 747: q = p; ! 748: while (i++ < MAXAOBDISP && ((q= q->forw) !=0)) ! 749: { ! 750: if (p->ref == q) ! 751: return(1); ! 752: } ! 753: return(0); ! 754: } ! 755: ! 756: ! 757: struct intleavetab intltab[] = { ! 758: ADDF, FLOAT, 1, ! 759: ADDF, DOUBLE, 1, ! 760: SUBF, FLOAT, 1, ! 761: SUBF, DOUBLE, 1, ! 762: MULF, FLOAT, 1, ! 763: MULF, DOUBLE, 1, ! 764: DIVF, FLOAT, 1, ! 765: DIVF, DOUBLE, 1, ! 766: SINF, FLOAT, 1, ! 767: COSF, FLOAT, 1, ! 768: ATANF, FLOAT, 1, ! 769: LOGF, FLOAT, 1, ! 770: SQRTF, FLOAT, 1, ! 771: EXPF, FLOAT, 1, ! 772: LDF, FLOAT, 0, ! 773: LDF, DOUBLE, 0, ! 774: LNF, FLOAT, 0, ! 775: LNF, DOUBLE, 0, ! 776: STF, FLOAT, 0, ! 777: CMPF, FLOAT, 0, ! 778: CMPF, DOUBLE, 0, ! 779: CMPF2, FLOAT, 0, ! 780: TSTF, FLOAT, 0, ! 781: TSTF, DOUBLE, 0, ! 782: PUSHD, DOUBLE, 0, ! 783: CVLF, U(LONG,FLOAT), 0, ! 784: CVFL, U(FLOAT,LONG), 0, ! 785: LDFD, U(FLOAT,DOUBLE),0, ! 786: CVDF, U(DOUBLE,FLOAT),0, ! 787: NEGF, FLOAT, 0, ! 788: NIL, 0, 0}; ! 789: ! 790: interleave() ! 791: { ! 792: register struct node *p, *p1; ! 793: ! 794: register struct intleavetab *t; ! 795: register int r; ! 796: int count; ! 797: for (p= first.forw; p!=0; p = p->forw){ ! 798: count = 0; ! 799: for (t =intltab; t->op != NIL; t++){ ! 800: if (t->op == p->op && t->subop == p->subop){ ! 801: count = t->intleavect; ! 802: break; ! 803: } ! 804: } ! 805: if (count < 1) continue; ! 806: p1 = p->forw; ! 807: clearuse(); ! 808: clearreg(); ! 809: while ((p1 != 0) && (p1->op != CBR) && ! 810: (p1->subop == FLOAT || p1->subop == DOUBLE || ! 811: ((p1->subop&0xF0)==DOUBLE<<4) || ((p1->subop&0xF)==DOUBLE )|| ! 812: ((p1->subop&0xF0)==FLOAT<<4) || (p1->subop&0xF)==FLOAT)) ! 813: { ! 814: if (((r = isreg(p1->code)) >= 0)){ ! 815: setuse(r,p1); ! 816: if ((p1->subop == DOUBLE) || ((p->subop&0xF0)==DOUBLE<<4) || ! 817: ((p->subop&0xF)==DOUBLE)) ! 818: setuse(r+1,p1); ! 819: } ! 820: else checkreg(p1,p1->code); ! 821: p1 = p1->forw; ! 822: ! 823: } ! 824: if (p1 == 0) return; ! 825: if (!(sideeffect(p, p1))) ! 826: insertblk(p,p1); ! 827: } ! 828: ! 829: } ! 830: ! 831: ! 832: insertblk(p, p1) ! 833: struct node *p, *p1; ! 834: { ! 835: p1->back->forw = p1->forw; ! 836: p1->forw->back = p1->back; ! 837: p1->forw = p->forw; ! 838: p->forw->back = p1; ! 839: p->forw = p1; ! 840: p1->back = p; ! 841: } ! 842: ! 843: OpCode termop[] = { ! 844: JBR, CBR, JMP, LABEL, DLABEL, EROU, JSW, TST, CMP, BIT, ! 845: CALLF, CALLS, CASE, AOBLEQ, AOBLSS, CMPF, CMPF2, TSTF, MOVBLK, MFPR, ! 846: MTPR, PROBE, MOVO, TEXT, DATA, BSS, ALIGN, END, LGEN, SET, ! 847: LCOMM, COMM, NIL ! 848: }; ! 849: ! 850: sideeffect(p,p1) ! 851: struct node *p, *p1; ! 852: { ! 853: register struct node *q; ! 854: register int r; ! 855: register OpCode *t; ! 856: register char *cp; ! 857: int i; ! 858: ! 859: if (p1->op == NIL) return(1); /* special instructions */ ! 860: ! 861: for (t = termop; *t!=NIL; t++){ ! 862: if (*t == p1->op) return(1); ! 863: } ! 864: if ((p1->forw != NULL) && (p1->forw->op == CBR)) ! 865: return(1); ! 866: splitrand(p1); ! 867: r = isreg(lastrand); ! 868: if (lastuse(r) && r >= 0 ) return(1); ! 869: if ((p1->op == EDIV) && (r = isreg(regs[RT3]) >= 0) && ! 870: (lastuse(r))) return(1); ! 871: ! 872: for (q = p1->back ; q!=p; q=q->back) ! 873: { ! 874: if ((p1->op == PUSH || p1->op == PUSHA) && ! 875: (q->op == PUSHD || q->op == PUSH || q->op == PUSHA)) ! 876: return(1); /* keep args in order */ ! 877: if (((i = strlen(q->code)) >= 5 && /* cvdl -(sp); pushl r0*/ ! 878: (strcmp(q->code+i-5,"-(sp)") == 0 )) || ! 879: (strcmp(lastrand,"-(sp)") == 0)) return(1); ! 880: if (equstr(q->code, lastrand)) ! 881: return(1); ! 882: if (q->op == STF || q->op == CVFL || q->op == CVLF) ! 883: { ! 884: if (equstr(q->code, regs[RT1])) return(1); ! 885: if (has3ops(p1) || p1->op == EMUL || p1->op == EDIV) ! 886: if (equstr(q->code, regs[RT2])) ! 887: return(1); ! 888: /* handle the case std -56(fp) pushl -60(fp) pushl ! 889: -56(fp); ! 890: */ ! 891: if ((p1->forw != NULL) && (q->op == STF) && ! 892: (q->subop == DOUBLE)){ ! 893: if (!strncmp(q->code,p1->forw->code,strlen(q->code))) ! 894: return(1); ! 895: } ! 896: } ! 897: } ! 898: return(0); ! 899: } ! 900: checkreg(p,s) ! 901: struct node *p; ! 902: char *s; ! 903: { ! 904: char *cp2; ! 905: register int r; ! 906: /* check for (r),[r] */ ! 907: do if (*s=='(' || *s=='[') {/* get register number */ ! 908: char t; ! 909: cp2= ++s; while (*++s!=')' && *s!=']'); t= *s; *s=0; ! 910: if ((r=isreg(cp2)) >= 0) ! 911: setuse(r,p); ! 912: *s=t; ! 913: } while (*++s); ! 914: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.