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

Defined functions

backjmp defined in line 672; used 1 times
codemove defined in line 587; used 2 times
comjump defined in line 661; used 1 times
copy defined in line 341; used 12 times
getline defined in line 203; used 1 times
getnum defined in line 230; used 2 times
input defined in line 142; used 1 times
insertl defined in line 558; used 5 times
iterate defined in line 469; used 1 times
main defined in line 66; never used
oplook defined in line 387; used 1 times
opsetup defined in line 373; used 1 times
  • in line 98
output defined in line 245; used 1 times
reducelit defined in line 315; used 1 times
refcount defined in line 430; used 1 times
xjump defined in line 535; used 1 times

Defined variables

isn defined in line 63; used 1 times
lastseg defined in line 64; used 1 times
optab defined in line 8; used 2 times
revbr defined in line 62; used 2 times
Last modified: 1979-05-03
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1646
Valid CSS Valid XHTML 1.0 Strict