|
|
1.1 ! root 1: /* ! 2: * C object code improver ! 3: */ ! 4: ! 5: #include "c2.h" ! 6: ! 7: struct optab optab[] = { ! 8: "jbr", JBR, ! 9: "jeq", CBR | JEQ<<8, ! 10: "jne", CBR | JNE<<8, ! 11: "jle", CBR | JLE<<8, ! 12: "jge", CBR | JGE<<8, ! 13: "jlt", CBR | JLT<<8, ! 14: "jgt", CBR | JGT<<8, ! 15: "jlo", CBR | JLO<<8, ! 16: "jhi", CBR | JHI<<8, ! 17: "jlos", CBR | JLOS<<8, ! 18: "jhis", CBR | JHIS<<8, ! 19: "jmp", JMP, ! 20: ".globl",EROU, ! 21: "mov", MOV, ! 22: "clr", CLR, ! 23: "com", COM, ! 24: "inc", INC, ! 25: "dec", DEC, ! 26: "neg", NEG, ! 27: "tst", TST, ! 28: "asr", ASR, ! 29: "asl", ASL, ! 30: "sxt", SXT, ! 31: "cmp", CMP, ! 32: "add", ADD, ! 33: "sub", SUB, ! 34: "bit", BIT, ! 35: "bic", BIC, ! 36: "bis", BIS, ! 37: "mul", MUL, ! 38: "ash", ASH, ! 39: "xor", XOR, ! 40: ".text",TEXT, ! 41: ".data",DATA, ! 42: ".bss", BSS, ! 43: ".even",EVEN, ! 44: "movf", MOVF, ! 45: "movof",MOVOF, ! 46: "movfo",MOVFO, ! 47: "addf", ADDF, ! 48: "subf", SUBF, ! 49: "divf", DIVF, ! 50: "mulf", MULF, ! 51: "clrf", CLRF, ! 52: "cmpf", CMPF, ! 53: "negf", NEGF, ! 54: "tstf", TSTF, ! 55: "cfcc", CFCC, ! 56: "sob", SOB, ! 57: "jsr", JSR, ! 58: ".end", END, ! 59: 0, 0}; ! 60: ! 61: char revbr[] = { JNE, JEQ, JGT, JLT, JGE, JLE, JHIS, JLOS, JHI, JLO }; ! 62: int isn = 20000; ! 63: int lastseg = -1; ! 64: ! 65: #define NSTK 5000 ! 66: ! 67: main(argc, argv) ! 68: char **argv; ! 69: { ! 70: register int niter, maxiter, isend; ! 71: extern end; ! 72: int nflag; ! 73: char stspace[NSTK]; ! 74: ! 75: if (argc>1 && argv[1][0]=='+') { ! 76: argc--; ! 77: argv++; ! 78: debug++; ! 79: } ! 80: nflag = 0; ! 81: if (argc>1 && argv[1][0]=='-') { ! 82: argc--; ! 83: argv++; ! 84: nflag++; ! 85: } ! 86: if (argc>1) { ! 87: if (freopen(argv[1], "r", stdin) == NULL) { ! 88: fprintf(stderr, "C2: can't find %s\n", argv[1]); ! 89: exit(1); ! 90: } ! 91: } ! 92: if (argc>2) { ! 93: if (freopen(argv[2], "w", stdout) == NULL) { ! 94: fprintf(stderr, "C2: can't create %s\n", argv[2]); ! 95: exit(1); ! 96: } ! 97: } ! 98: lasta = firstr = lastr = sbrk(sizeof(char *)); ! 99: maxiter = 0; ! 100: opsetup(); ! 101: do { ! 102: alasta = stspace; ! 103: alastr = &stspace[NSTK]; ! 104: isend = input(); ! 105: movedat(); ! 106: niter = 0; ! 107: do { ! 108: refcount(); ! 109: do { ! 110: iterate(); ! 111: clearreg(); ! 112: niter++; ! 113: } while (nchange); ! 114: comjump(); ! 115: rmove(); ! 116: } while (nchange || jumpsw()); ! 117: addsob(); ! 118: output(); ! 119: if (niter > maxiter) ! 120: maxiter = niter; ! 121: lasta = firstr; ! 122: } while (isend); ! 123: if (nflag) { ! 124: fprintf(stderr, "%d iterations\n", maxiter); ! 125: fprintf(stderr, "%d jumps to jumps\n", nbrbr); ! 126: fprintf(stderr, "%d inst. after jumps\n", iaftbr); ! 127: fprintf(stderr, "%d jumps to .+2\n", njp1); ! 128: fprintf(stderr, "%d redundant labels\n", nrlab); ! 129: fprintf(stderr, "%d cross-jumps\n", nxjump); ! 130: fprintf(stderr, "%d code motions\n", ncmot); ! 131: fprintf(stderr, "%d branches reversed\n", nrevbr); ! 132: fprintf(stderr, "%d redundant moves\n", redunm); ! 133: fprintf(stderr, "%d simplified addresses\n", nsaddr); ! 134: fprintf(stderr, "%d loops inverted\n", loopiv); ! 135: fprintf(stderr, "%d redundant jumps\n", nredunj); ! 136: fprintf(stderr, "%d common seqs before jmp's\n", ncomj); ! 137: fprintf(stderr, "%d skips over jumps\n", nskip); ! 138: fprintf(stderr, "%d sob's added\n", nsob); ! 139: fprintf(stderr, "%d redundant tst's\n", nrtst); ! 140: fprintf(stderr, "%d literals eliminated\n", nlit); ! 141: fprintf(stderr, "%dK core\n", (((int)lastr+01777)>>10)&077); ! 142: } ! 143: exit(0); ! 144: } ! 145: ! 146: input() ! 147: { ! 148: register struct node *p, *lastp; ! 149: register int oper; ! 150: ! 151: lastp = &first; ! 152: for (;;) { ! 153: oper = getline(); ! 154: switch (oper&0377) { ! 155: ! 156: case LABEL: ! 157: p = (struct node *)alloc(sizeof first); ! 158: if (line[0] == 'L') { ! 159: p->op = LABEL; ! 160: p->subop = 0; ! 161: p->labno = getnum(line+1); ! 162: p->code = 0; ! 163: } else { ! 164: p->op = DLABEL; ! 165: p->subop = 0; ! 166: p->labno = 0; ! 167: p->code = copy(1, line); ! 168: } ! 169: break; ! 170: ! 171: case JBR: ! 172: case CBR: ! 173: case JMP: ! 174: case JSW: ! 175: p = (struct node *)alloc(sizeof first); ! 176: p->op = oper&0377; ! 177: p->subop = oper>>8; ! 178: if (*curlp=='L' && (p->labno = getnum(curlp+1))) ! 179: p->code = 0; ! 180: else { ! 181: p->labno = 0; ! 182: p->code = copy(1, curlp); ! 183: } ! 184: break; ! 185: ! 186: default: ! 187: p = (struct node *)alloc(sizeof first); ! 188: p->op = oper&0377; ! 189: p->subop = oper>>8; ! 190: p->labno = 0; ! 191: p->code = copy(1, curlp); ! 192: break; ! 193: ! 194: } ! 195: p->forw = 0; ! 196: p->back = lastp; ! 197: lastp->forw = p; ! 198: lastp = p; ! 199: p->ref = 0; ! 200: if (oper==EROU) ! 201: return(1); ! 202: if (oper==END) ! 203: return(0); ! 204: } ! 205: } ! 206: ! 207: getline() ! 208: { ! 209: register char *lp; ! 210: register c; ! 211: ! 212: lp = line; ! 213: while ((c = getchar())==' ' || c=='\t') ! 214: ; ! 215: do { ! 216: if (c==':') { ! 217: *lp++ = 0; ! 218: return(LABEL); ! 219: } ! 220: if (c=='\n') { ! 221: *lp++ = 0; ! 222: return(oplook()); ! 223: } ! 224: if (lp >= &line[LSIZE-2]) { ! 225: fprintf(stderr, "C2: Sorry, input line too long\n"); ! 226: exit(1); ! 227: } ! 228: *lp++ = c; ! 229: } while ((c = getchar()) != EOF); ! 230: *lp++ = 0; ! 231: return(END); ! 232: } ! 233: ! 234: getnum(ap) ! 235: char *ap; ! 236: { ! 237: register char *p; ! 238: register n, c; ! 239: ! 240: p = ap; ! 241: n = 0; ! 242: while ((c = *p++) >= '0' && c <= '9') ! 243: n = n*10 + c - '0'; ! 244: if (*--p != 0) ! 245: return(0); ! 246: return(n); ! 247: } ! 248: ! 249: output() ! 250: { ! 251: register struct node *t; ! 252: register struct optab *oper; ! 253: register int byte; ! 254: ! 255: t = &first; ! 256: while (t = t->forw) switch (t->op) { ! 257: ! 258: case END: ! 259: return; ! 260: ! 261: case LABEL: ! 262: printf("L%d:", t->labno); ! 263: continue; ! 264: ! 265: case DLABEL: ! 266: printf("%s:", t->code); ! 267: continue; ! 268: ! 269: case TEXT: ! 270: case DATA: ! 271: case BSS: ! 272: lastseg = t->op; ! 273: ! 274: default: ! 275: if ((byte = t->subop) == BYTE) ! 276: t->subop = 0; ! 277: for (oper = optab; oper->opstring!=0; oper++) ! 278: if ((oper->opcode&0377) == t->op ! 279: && (oper->opcode>>8) == t->subop) { ! 280: printf("%s", oper->opstring); ! 281: if (byte==BYTE) ! 282: printf("b"); ! 283: break; ! 284: } ! 285: if (t->code) { ! 286: reducelit(t); ! 287: printf("\t%s\n", t->code); ! 288: } else if (t->op==JBR || t->op==CBR) ! 289: printf("\tL%d\n", t->labno); ! 290: else ! 291: printf("\n"); ! 292: continue; ! 293: ! 294: case JSW: ! 295: printf("L%d\n", t->labno); ! 296: continue; ! 297: ! 298: case SOB: ! 299: printf("sob %s", t->code); ! 300: if (t->labno) ! 301: printf(",L%d", t->labno); ! 302: printf("\n"); ! 303: continue; ! 304: ! 305: case 0: ! 306: if (t->code) ! 307: printf("%s", t->code); ! 308: printf("\n"); ! 309: continue; ! 310: } ! 311: } ! 312: ! 313: /* ! 314: * Notice addresses of the form ! 315: * $xx,xx(r) ! 316: * and replace them with (pc),xx(r) ! 317: * -- Thanx and a tip of the Hatlo hat to Bliss-11. ! 318: */ ! 319: reducelit(at) ! 320: struct node *at; ! 321: { ! 322: register char *c1, *c2; ! 323: char *c2s; ! 324: register struct node *t; ! 325: ! 326: t = at; ! 327: if (*t->code != '$') ! 328: return; ! 329: c1 = t->code; ! 330: while (*c1 != ',') ! 331: if (*c1++ == '\0') ! 332: return; ! 333: c2s = c1; ! 334: c1++; ! 335: if (*c1=='*') ! 336: c1++; ! 337: c2 = t->code+1; ! 338: while (*c1++ == *c2++); ! 339: if (*--c1!='(' || *--c2!=',') ! 340: return; ! 341: t->code = copy(2, "(pc)", c2s); ! 342: nlit++; ! 343: } ! 344: ! 345: char * ! 346: copy(na, ap) ! 347: char *ap; ! 348: { ! 349: register char *p, *np; ! 350: char *onp; ! 351: register n; ! 352: ! 353: p = ap; ! 354: n = 0; ! 355: if (*p==0) ! 356: return(0); ! 357: do ! 358: n++; ! 359: while (*p++); ! 360: if (na>1) { ! 361: p = (&ap)[1]; ! 362: while (*p++) ! 363: n++; ! 364: } ! 365: onp = np = alloc(n); ! 366: p = ap; ! 367: while (*np++ = *p++) ! 368: ; ! 369: if (na>1) { ! 370: p = (&ap)[1]; ! 371: np--; ! 372: while (*np++ = *p++); ! 373: } ! 374: return(onp); ! 375: } ! 376: ! 377: opsetup() ! 378: { ! 379: register struct optab *optp, **ophp; ! 380: register char *p; ! 381: ! 382: for (optp = optab; p = optp->opstring; optp++) { ! 383: ophp = &ophash[(((p[0]<<3)+(p[1]<<1)+p[2])&077777) % OPHS]; ! 384: while (*ophp++) ! 385: if (ophp > &ophash[OPHS]) ! 386: ophp = ophash; ! 387: *--ophp = optp; ! 388: } ! 389: } ! 390: ! 391: oplook() ! 392: { ! 393: register struct optab *optp; ! 394: register char *lp, *np; ! 395: static char tmpop[32]; ! 396: struct optab **ophp; ! 397: ! 398: if (line[0]=='\0') { ! 399: curlp = line; ! 400: return(0); ! 401: } ! 402: np = tmpop; ! 403: for (lp = line; *lp && *lp!=' ' && *lp!='\t';) ! 404: *np++ = *lp++; ! 405: *np++ = 0; ! 406: while (*lp=='\t' || *lp==' ') ! 407: lp++; ! 408: curlp = lp; ! 409: ophp = &ophash[(((tmpop[0]<<3)+(tmpop[1]<<1)+tmpop[2])&077777) % OPHS]; ! 410: while (optp = *ophp) { ! 411: np = optp->opstring; ! 412: lp = tmpop; ! 413: while (*lp == *np++) ! 414: if (*lp++ == 0) ! 415: return(optp->opcode); ! 416: if (*lp++=='b' && *lp++==0 && *--np==0) ! 417: return(optp->opcode + (BYTE<<8)); ! 418: ophp++; ! 419: if (ophp >= &ophash[OPHS]) ! 420: ophp = ophash; ! 421: } ! 422: if (line[0]=='L') { ! 423: lp = &line[1]; ! 424: while (*lp) ! 425: if (*lp<'0' || *lp++>'9') ! 426: return(0); ! 427: curlp = line; ! 428: return(JSW); ! 429: } ! 430: curlp = line; ! 431: return(0); ! 432: } ! 433: ! 434: refcount() ! 435: { ! 436: register struct node *p, *lp; ! 437: static struct node *labhash[LABHS]; ! 438: register struct node **hp, *tp; ! 439: ! 440: for (hp = labhash; hp < &labhash[LABHS];) ! 441: *hp++ = 0; ! 442: for (p = first.forw; p!=0; p = p->forw) ! 443: if (p->op==LABEL) { ! 444: labhash[p->labno % LABHS] = p; ! 445: p->refc = 0; ! 446: } ! 447: for (p = first.forw; p!=0; p = p->forw) { ! 448: if (p->op==JBR || p->op==CBR || p->op==JSW) { ! 449: p->ref = 0; ! 450: lp = labhash[p->labno % LABHS]; ! 451: if (lp==0 || p->labno!=lp->labno) ! 452: for (lp = first.forw; lp!=0; lp = lp->forw) { ! 453: if (lp->op==LABEL && p->labno==lp->labno) ! 454: break; ! 455: } ! 456: if (lp) { ! 457: tp = nonlab(lp)->back; ! 458: if (tp!=lp) { ! 459: p->labno = tp->labno; ! 460: lp = tp; ! 461: } ! 462: p->ref = lp; ! 463: lp->refc++; ! 464: } ! 465: } ! 466: } ! 467: for (p = first.forw; p!=0; p = p->forw) ! 468: if (p->op==LABEL && p->refc==0 ! 469: && (lp = nonlab(p))->op && lp->op!=JSW) ! 470: decref(p); ! 471: } ! 472: ! 473: iterate() ! 474: { ! 475: register struct node *p, *rp, *p1; ! 476: ! 477: nchange = 0; ! 478: for (p = first.forw; p!=0; p = p->forw) { ! 479: CHECK(0); ! 480: if ((p->op==JBR||p->op==CBR||p->op==JSW) && p->ref) { ! 481: rp = nonlab(p->ref); ! 482: if (rp->op==JBR && rp->labno && p->labno!=rp->labno) { ! 483: nbrbr++; ! 484: p->labno = rp->labno; ! 485: decref(p->ref); ! 486: rp->ref->refc++; ! 487: p->ref = rp->ref; ! 488: CHECK(1); ! 489: nchange++; ! 490: } ! 491: } ! 492: if (p->op==CBR && (p1 = p->forw)->op==JBR) { ! 493: rp = p->ref; ! 494: do ! 495: rp = rp->back; ! 496: while (rp->op==LABEL); ! 497: if (rp==p1) { ! 498: decref(p->ref); ! 499: p->ref = p1->ref; ! 500: p->labno = p1->labno; ! 501: p1->forw->back = p; ! 502: p->forw = p1->forw; ! 503: p->subop = revbr[p->subop]; ! 504: nchange++; ! 505: CHECK(2); ! 506: nskip++; ! 507: } ! 508: } ! 509: if (p->op==JBR || p->op==JMP) { ! 510: while (p->forw && p->forw->op!=LABEL ! 511: && p->forw->op!=DLABEL ! 512: && p->forw->op!=EROU && p->forw->op!=END ! 513: && p->forw->op!=0 && p->forw->op!=DATA) { ! 514: nchange++; ! 515: iaftbr++; ! 516: if (p->forw->ref) ! 517: decref(p->forw->ref); ! 518: p->forw = p->forw->forw; ! 519: p->forw->back = p; ! 520: CHECK(3); ! 521: } ! 522: rp = p->forw; ! 523: while (rp && rp->op==LABEL) { ! 524: if (p->ref == rp) { ! 525: p->back->forw = p->forw; ! 526: p->forw->back = p->back; ! 527: p = p->back; ! 528: decref(rp); ! 529: nchange++; ! 530: CHECK(4); ! 531: njp1++; ! 532: break; ! 533: } ! 534: rp = rp->forw; ! 535: } ! 536: } ! 537: if (p->op==JBR || p->op==JMP) { ! 538: xjump(p); ! 539: p = codemove(p); ! 540: } ! 541: } ! 542: } ! 543: ! 544: xjump(p1) ! 545: register struct node *p1; ! 546: { ! 547: register struct node *p2, *p3; ! 548: ! 549: if ((p2 = p1->ref)==0) ! 550: return; ! 551: for (;;) { ! 552: while ((p1 = p1->back) && p1->op==LABEL); ! 553: while ((p2 = p2->back) && p2->op==LABEL); ! 554: if (!equop(p1, p2) || p1==p2) ! 555: return; ! 556: p3 = insertl(p2); ! 557: p1->op = JBR; ! 558: p1->subop = 0; ! 559: p1->ref = p3; ! 560: p1->labno = p3->labno; ! 561: p1->code = 0; ! 562: nxjump++; ! 563: CHECK(5); ! 564: nchange++; ! 565: } ! 566: } ! 567: ! 568: struct node * ! 569: insertl(oldp) ! 570: register struct node *oldp; ! 571: { ! 572: register struct node *lp; ! 573: ! 574: if (oldp->op == LABEL) { ! 575: oldp->refc++; ! 576: return(oldp); ! 577: } ! 578: if (oldp->back->op == LABEL) { ! 579: oldp = oldp->back; ! 580: oldp->refc++; ! 581: return(oldp); ! 582: } ! 583: lp = (struct node *)alloc(sizeof first); ! 584: lp->op = LABEL; ! 585: lp->subop = 0; ! 586: lp->labno = isn++; ! 587: lp->ref = 0; ! 588: lp->code = 0; ! 589: lp->refc = 1; ! 590: lp->back = oldp->back; ! 591: lp->forw = oldp; ! 592: oldp->back->forw = lp; ! 593: oldp->back = lp; ! 594: CHECK(6); ! 595: return(lp); ! 596: } ! 597: ! 598: struct node * ! 599: codemove(p) ! 600: struct node *p; ! 601: { ! 602: register struct node *p1, *p2, *p3; ! 603: struct node *t, *tl; ! 604: int n; ! 605: ! 606: p1 = p; ! 607: if (p1->op!=JBR || (p2 = p1->ref)==0) ! 608: return(p1); ! 609: while (p2->op == LABEL) ! 610: if ((p2 = p2->back) == 0) ! 611: return(p1); ! 612: if (p2->op!=JBR && p2->op!=JMP) ! 613: goto ivloop; ! 614: if (p1==p2) ! 615: return(p1); ! 616: p2 = p2->forw; ! 617: p3 = p1->ref; ! 618: while (p3) { ! 619: if (p3->op==JBR || p3->op==JMP) { ! 620: if (p1==p3 || p1->forw==p3 || p1->back==p3) ! 621: return(p1); ! 622: ncmot++; ! 623: nchange++; ! 624: CHECK(70); ! 625: p1->back->forw = p2; ! 626: p1->forw->back = p3; ! 627: p2->back->forw = p3->forw; ! 628: p3->forw->back = p2->back; ! 629: p2->back = p1->back; ! 630: p3->forw = p1->forw; ! 631: decref(p1->ref); ! 632: CHECK(7); ! 633: return(p2); ! 634: } else ! 635: p3 = p3->forw; ! 636: } ! 637: return(p1); ! 638: ivloop: ! 639: if (p1->forw->op!=LABEL) ! 640: return(p1); ! 641: p3 = p2 = p2->forw; ! 642: n = 16; ! 643: do { ! 644: if ((p3 = p3->forw) == 0 || p3==p1 || --n==0) ! 645: return(p1); ! 646: } while (p3->op!=CBR || p3->labno!=p1->forw->labno); ! 647: do ! 648: if ((p1 = p1->back) == 0) ! 649: return(p); ! 650: while (p1!=p3); ! 651: p1 = p; ! 652: tl = insertl(p1); ! 653: p3->subop = revbr[p3->subop]; ! 654: decref(p3->ref); ! 655: p2->back->forw = p1; ! 656: p3->forw->back = p1; ! 657: p1->back->forw = p2; ! 658: p1->forw->back = p3; ! 659: t = p1->back; ! 660: p1->back = p2->back; ! 661: p2->back = t; ! 662: t = p1->forw; ! 663: p1->forw = p3->forw; ! 664: p3->forw = t; ! 665: p2 = insertl(p1->forw); ! 666: p3->labno = p2->labno; ! 667: p3->ref = p2; ! 668: decref(tl); ! 669: if (tl->refc<=0) ! 670: nrlab--; ! 671: loopiv++; ! 672: nchange++; ! 673: CHECK(8); ! 674: return(p3); ! 675: } ! 676: ! 677: comjump() ! 678: { ! 679: register struct node *p1, *p2, *p3; ! 680: ! 681: for (p1 = first.forw; p1!=0; p1 = p1->forw) ! 682: if (p1->op==JBR && (p2 = p1->ref) && p2->refc > 1) ! 683: for (p3 = p1->forw; p3!=0; p3 = p3->forw) ! 684: if (p3->op==JBR && p3->ref == p2) ! 685: backjmp(p1, p3); ! 686: } ! 687: ! 688: backjmp(ap1, ap2) ! 689: struct node *ap1, *ap2; ! 690: { ! 691: register struct node *p1, *p2, *p3; ! 692: ! 693: p1 = ap1; ! 694: p2 = ap2; ! 695: for(;;) { ! 696: while ((p1 = p1->back) && p1->op==LABEL); ! 697: p2 = p2->back; ! 698: if (equop(p1, p2)) { ! 699: p3 = insertl(p1); ! 700: p2->back->forw = p2->forw; ! 701: p2->forw->back = p2->back; ! 702: p2 = p2->forw; ! 703: decref(p2->ref); ! 704: p2->labno = p3->labno; ! 705: p2->ref = p3; ! 706: nchange++; ! 707: ncomj++; ! 708: CHECK(9); ! 709: } else ! 710: return; ! 711: } ! 712: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.