1: # 2: /* 3: * C object code improver-- second part 4: */ 5: 6: #include "c2h.c" 7: 8: rmove() 9: { 10: register struct node *p; 11: register char *cp; 12: register int r; 13: int r1, flt; 14: 15: for (p=first.forw; p!=0; p = p->forw) { 16: if (debug) { 17: for (r=0; r<2*NREG; r++) 18: if (regs[r][0]) 19: printf("%d: %s\n", r, regs[r]); 20: printf("-\n"); 21: } 22: flt = 0; 23: switch (p->op) { 24: 25: case MOVF: 26: case MOVFO: 27: case MOVOF: 28: flt = NREG; 29: 30: case MOV: 31: if (p->subop==BYTE) 32: goto badmov; 33: dualop(p); 34: if ((r = findrand(regs[RT1], flt)) >= 0) { 35: if (r == flt+isreg(regs[RT2]) && p->forw->op!=CBR) { 36: p->forw->back = p->back; 37: p->back->forw = p->forw; 38: redunm++; 39: continue; 40: } 41: } 42: repladdr(p, 0, flt); 43: r = isreg(regs[RT1]); 44: r1 = isreg(regs[RT2]); 45: dest(regs[RT2], flt); 46: if (r >= 0) 47: if (r1 >= 0) 48: savereg(r1+flt, regs[r+flt]); 49: else 50: savereg(r+flt, regs[RT2]); 51: else 52: if (r1 >= 0) 53: savereg(r1+flt, regs[RT1]); 54: else 55: setcon(regs[RT1], regs[RT2]); 56: source(regs[RT1]); 57: setcc(regs[RT2]); 58: continue; 59: 60: case ADDF: 61: case SUBF: 62: case DIVF: 63: case MULF: 64: flt = NREG; 65: 66: case ADD: 67: case SUB: 68: case BIC: 69: case BIS: 70: case MUL: 71: case DIV: 72: case ASH: 73: badmov: 74: dualop(p); 75: repladdr(p, 0, flt); 76: source(regs[RT1]); 77: dest(regs[RT2], flt); 78: if (p->op==DIV && (r = isreg(regs[RT2])>=0)) 79: regs[r+1][0] = 0; 80: ccloc[0] = 0; 81: continue; 82: 83: case CLRF: 84: case NEGF: 85: flt = NREG; 86: 87: case CLR: 88: case COM: 89: case INC: 90: case DEC: 91: case NEG: 92: case ASR: 93: case ASL: 94: case SXT: 95: singop(p); 96: dest(regs[RT1], flt); 97: if (p->op==CLR && flt==0) 98: if ((r = isreg(regs[RT1])) >= 0) 99: savereg(r, "$0"); 100: else 101: setcon("$0", regs[RT1]); 102: setcc(regs[RT1]); 103: continue; 104: 105: case TSTF: 106: flt = NREG; 107: 108: case TST: 109: singop(p); 110: repladdr(p, 0, flt); 111: source(regs[RT1]); 112: if (equstr(regs[RT1], ccloc)) { 113: p->back->forw = p->forw; 114: p->forw->back = p->back; 115: p = p->back; 116: nrtst++; 117: nchange++; 118: } 119: continue; 120: 121: case CMPF: 122: flt = NREG; 123: 124: case CMP: 125: case BIT: 126: dualop(p); 127: source(regs[RT1]); 128: source(regs[RT2]); 129: repladdr(p, 1, flt); 130: ccloc[0] = 0; 131: continue; 132: 133: case CBR: 134: case CFCC: 135: ccloc[0] = 0; 136: continue; 137: 138: case JBR: 139: redunbr(p); 140: 141: default: 142: clearreg(); 143: } 144: } 145: } 146: 147: jumpsw() 148: { 149: register struct node *p, *p1; 150: register t; 151: int nj; 152: 153: t = 0; 154: nj = 0; 155: for (p=first.forw; p!=0; p = p->forw) 156: p->refc = ++t; 157: for (p=first.forw; p!=0; p = p1) { 158: p1 = p->forw; 159: if (p->op == CBR && p1->op==JBR && p->ref && p1->ref 160: && abs(p->refc - p->ref->refc) > abs(p1->refc - p1->ref->refc)) { 161: p->subop = revbr[p->subop]; 162: t = p1->ref; 163: p1->ref = p->ref; 164: p->ref = t; 165: t = p1->labno; 166: p1->labno = p->labno; 167: p->labno = t; 168: nrevbr++; 169: nj++; 170: } 171: } 172: return(nj); 173: } 174: 175: addsob() 176: { 177: register struct node *p, *p1; 178: 179: for (p = &first; (p1 = p->forw)!=0; p = p1) { 180: if (p->op==DEC && isreg(p->code)>=0 181: && p1->combop==(CBR|JNE<<8)) { 182: if (p->refc < p1->ref->refc) 183: continue; 184: if (p->refc - p1->ref->refc > 50) 185: continue; 186: p->labno = p1->labno; 187: p->combop = SOB; 188: p1->forw->back = p; 189: p->forw = p1->forw; 190: nsob++; 191: } 192: } 193: } 194: 195: abs(x) 196: { 197: return(x<0? -x: x); 198: } 199: 200: equop(ap1, p2) 201: struct node *ap1, *p2; 202: { 203: register char *cp1, *cp2; 204: register struct node *p1; 205: 206: p1 = ap1; 207: if (p1->combop != p2->combop) 208: return(0); 209: if (p1->op>0 && p1->op<MOV) 210: return(0); 211: cp1 = p1->code; 212: cp2 = p2->code; 213: if (cp1==0 && cp2==0) 214: return(1); 215: if (cp1==0 || cp2==0) 216: return(0); 217: while (*cp1 == *cp2++) 218: if (*cp1++ == 0) 219: return(1); 220: return(0); 221: } 222: 223: decref(ap) 224: { 225: register struct node *p; 226: 227: p = ap; 228: if (--p->refc <= 0) { 229: nrlab++; 230: p->back->forw = p->forw; 231: p->forw->back = p->back; 232: } 233: } 234: 235: nonlab(ap) 236: struct node *ap; 237: { 238: register struct node *p; 239: 240: p = ap; 241: while (p && p->op==LABEL) 242: p = p->forw; 243: return(p); 244: } 245: 246: alloc(an) 247: { 248: register int n; 249: register char *p; 250: 251: n = an; 252: n++; 253: n =& ~01; 254: if (lasta+n >= lastr) { 255: if (sbrk(2000) == -1) { 256: write(2, "Optimizer: out of space\n", 14); 257: exit(1); 258: } 259: lastr =+ 2000; 260: } 261: p = lasta; 262: lasta =+ n; 263: return(p); 264: } 265: 266: clearreg() 267: { 268: register int i; 269: 270: for (i=0; i<2*NREG; i++) 271: regs[i][0] = '\0'; 272: conloc[0] = 0; 273: ccloc[0] = 0; 274: } 275: 276: savereg(ai, as) 277: char *as; 278: { 279: register char *p, *s, *sp; 280: 281: sp = p = regs[ai]; 282: s = as; 283: if (source(s)) 284: return; 285: while (*p++ = *s) { 286: if (s[0]=='(' && s[1]=='r' && s[2]<'5') { 287: *sp = 0; 288: return; 289: } 290: if (*s++ == ',') 291: break; 292: } 293: *--p = '\0'; 294: } 295: 296: dest(as, flt) 297: char *as; 298: { 299: register char *s; 300: register int i; 301: 302: s = as; 303: if ((i = isreg(s)) >= 0) 304: regs[i+flt][0] = 0; 305: while ((i = findrand(s, flt)) >= 0) 306: regs[i][0] = 0; 307: while (*s) { 308: if ((*s=='(' && (*(s+1)!='r' || *(s+2)!='5')) || *s++=='*') { 309: for (i=flt; i<flt+NREG; i++) { 310: if (regs[i][0] != '$') 311: regs[i][0] = 0; 312: conloc[0] = 0; 313: } 314: return; 315: } 316: } 317: } 318: 319: singop(ap) 320: struct node *ap; 321: { 322: register char *p1, *p2; 323: 324: p1 = ap->code; 325: p2 = regs[RT1]; 326: while (*p2++ = *p1++); 327: regs[RT2][0] = 0; 328: } 329: 330: 331: dualop(ap) 332: struct node *ap; 333: { 334: register char *p1, *p2; 335: register struct node *p; 336: 337: p = ap; 338: p1 = p->code; 339: p2 = regs[RT1]; 340: while (*p1 && *p1!=',') 341: *p2++ = *p1++; 342: *p2++ = 0; 343: p2 = regs[RT2]; 344: *p2 = 0; 345: if (*p1++ !=',') 346: return; 347: while (*p2++ = *p1++); 348: } 349: 350: findrand(as, flt) 351: char *as; 352: { 353: register int i; 354: for (i = flt; i<NREG+flt; i++) { 355: if (equstr(regs[i], as)) 356: return(i); 357: } 358: return(-1); 359: } 360: 361: isreg(as) 362: char *as; 363: { 364: register char *s; 365: 366: s = as; 367: if (s[0]=='r' && s[1]>='0' && s[1]<='4' && s[2]==0) 368: return(s[1]-'0'); 369: return(-1); 370: } 371: 372: check() 373: { 374: register struct node *p, *lp; 375: 376: lp = &first; 377: for (p=first.forw; p!=0; p = p->forw) { 378: if (p->back != lp) 379: abort(); 380: lp = p; 381: } 382: } 383: 384: source(ap) 385: char *ap; 386: { 387: register char *p1, *p2; 388: 389: p1 = ap; 390: p2 = p1; 391: if (*p1==0) 392: return(0); 393: while (*p2++); 394: if (*p1=='-' && *(p1+1)=='(' 395: || *p1=='*' && *(p1+1)=='-' && *(p1+2)=='(' 396: || *(p2-2)=='+') { 397: while (*p1 && *p1++!='r'); 398: if (*p1>='0' && *p1<='4') 399: regs[*p1 - '0'][0] = 0; 400: return(1); 401: } 402: return(0); 403: } 404: 405: repladdr(p, f, flt) 406: struct node *p; 407: { 408: register r; 409: int r1; 410: register char *p1, *p2; 411: static char rt1[50], rt2[50]; 412: 413: if (f) 414: r1 = findrand(regs[RT2], flt); 415: else 416: r1 = -1; 417: r = findrand(regs[RT1], flt); 418: if (r1 >= NREG) 419: r1 =- NREG; 420: if (r >= NREG) 421: r =- NREG; 422: if (r>=0 || r1>=0) { 423: p2 = regs[RT1]; 424: for (p1 = rt1; *p1++ = *p2++;); 425: if (regs[RT2][0]) { 426: p1 = rt2; 427: *p1++ = ','; 428: for (p2 = regs[RT2]; *p1++ = *p2++;); 429: } else 430: rt2[0] = 0; 431: if (r>=0) { 432: rt1[0] = 'r'; 433: rt1[1] = r + '0'; 434: rt1[2] = 0; 435: nsaddr++; 436: } 437: if (r1>=0) { 438: rt2[1] = 'r'; 439: rt2[2] = r1 + '0'; 440: rt2[3] = 0; 441: nsaddr++; 442: } 443: p->code = copy(rt1, rt2); 444: } 445: } 446: 447: movedat() 448: { 449: register struct node *p1, *p2; 450: struct node *p3; 451: register seg; 452: struct node data; 453: struct node *datp; 454: 455: if (first.forw == 0) 456: return; 457: datp = &data; 458: for (p1 = first.forw; p1!=0; p1 = p1->forw) { 459: if (p1->op == DATA) { 460: p2 = p1->forw; 461: while (p2 && p2->op!=TEXT) 462: p2 = p2->forw; 463: if (p2==0) 464: break; 465: p3 = p1->back; 466: p1->back->forw = p2->forw; 467: p2->forw->back = p3; 468: p2->forw = 0; 469: datp->forw = p1; 470: p1->back = datp; 471: p1 = p3; 472: datp = p2; 473: } 474: } 475: if (data.forw) { 476: datp->forw = first.forw; 477: first.forw->back = datp; 478: data.forw->back = &first; 479: first.forw = data.forw; 480: } 481: seg = -1; 482: for (p1 = first.forw; p1!=0; p1 = p1->forw) { 483: if (p1->op==TEXT||p1->op==DATA||p1->op==BSS) { 484: if (p1->op == seg || p1->forw&&p1->forw->op==seg) { 485: p1->back->forw = p1->forw; 486: p1->forw->back = p1->back; 487: p1 = p1->back; 488: continue; 489: } 490: seg = p1->op; 491: } 492: } 493: } 494: 495: redunbr(ap) 496: struct node *ap; 497: { 498: register struct node *p, *p1; 499: register char *ap1; 500: char *ap2; 501: 502: if ((p1 = p->ref) == 0) 503: return; 504: p1 = nonlab(p1); 505: if (p1->op==TST) { 506: singop(p1); 507: savereg(RT2, "$0"); 508: } else if (p1->op==CMP) 509: dualop(p1); 510: else 511: return; 512: if (p1->forw->op!=CBR) 513: return; 514: ap1 = findcon(RT1); 515: ap2 = findcon(RT2); 516: p1 = p1->forw; 517: if (compare(p1->subop, ap1, ap2)) { 518: nredunj++; 519: nchange++; 520: decref(p->ref); 521: p->ref = p1->ref; 522: p->labno = p1->labno; 523: p->ref->refc++; 524: } 525: } 526: 527: findcon(i) 528: { 529: register char *p; 530: register r; 531: 532: p = regs[i]; 533: if (*p=='$') 534: return(p); 535: if ((r = isreg(p)) >= 0) 536: return(regs[r]); 537: if (equstr(p, conloc)) 538: return(conval); 539: return(p); 540: } 541: 542: compare(op, acp1, acp2) 543: char *acp1, *acp2; 544: { 545: register char *cp1, *cp2; 546: register n1; 547: int n2; 548: struct { int i;}; 549: 550: cp1 = acp1; 551: cp2 = acp2; 552: if (*cp1++ != '$' || *cp2++ != '$') 553: return(0); 554: n1 = 0; 555: while (*cp2 >= '0' && *cp2 <= '7') { 556: n1 =<< 3; 557: n1 =+ *cp2++ - '0'; 558: } 559: n2 = n1; 560: n1 = 0; 561: while (*cp1 >= '0' && *cp1 <= '7') { 562: n1 =<< 3; 563: n1 =+ *cp1++ - '0'; 564: } 565: if (*cp1=='+') 566: cp1++; 567: if (*cp2=='+') 568: cp2++; 569: do { 570: if (*cp1++ != *cp2) 571: return(0); 572: } while (*cp2++); 573: cp1 = n1; 574: cp2 = n2; 575: switch(op) { 576: 577: case JEQ: 578: return(cp1 == cp2); 579: case JNE: 580: return(cp1 != cp2); 581: case JLE: 582: return(cp1.i <= cp2.i); 583: case JGE: 584: return(cp1.i >= cp2.i); 585: case JLT: 586: return(cp1.i < cp2.i); 587: case JGT: 588: return(cp1.i > cp2.i); 589: case JLO: 590: return(cp1 < cp2); 591: case JHI: 592: return(cp1 > cp2); 593: case JLOS: 594: return(cp1 <= cp2); 595: case JHIS: 596: return(cp1 >= cp2); 597: } 598: return(0); 599: } 600: 601: setcon(ar1, ar2) 602: char *ar1, *ar2; 603: { 604: register char *cl, *cv, *p; 605: 606: cl = ar2; 607: cv = ar1; 608: if (*cv != '$') 609: return; 610: if (!natural(cl)) 611: return; 612: p = conloc; 613: while (*p++ = *cl++); 614: p = conval; 615: while (*p++ = *cv++); 616: } 617: 618: equstr(ap1, ap2) 619: char *ap1, *ap2; 620: { 621: char *p1, *p2; 622: 623: p1 = ap1; 624: p2 = ap2; 625: do { 626: if (*p1++ != *p2) 627: return(0); 628: } while (*p2++); 629: return(1); 630: } 631: 632: setcc(ap) 633: char *ap; 634: { 635: register char *p, *p1; 636: 637: p = ap; 638: if (!natural(p)) { 639: ccloc[0] = 0; 640: return; 641: } 642: p1 = ccloc; 643: while (*p1++ = *p++); 644: } 645: 646: natural(ap) 647: char *ap; 648: { 649: register char *p; 650: 651: p = ap; 652: if (*p=='*' || *p=='(' || *p=='-'&&*(p+1)=='(') 653: return(0); 654: while (*p++); 655: p--; 656: if (*--p == '+' || *p ==')' && *--p != '5') 657: return(0); 658: return(1); 659: }