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