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

Defined functions

backjmp defined in line 673; used 1 times
codemove defined in line 588; used 2 times
comjump defined in line 662; used 1 times
copy defined in line 342; used 12 times
getline defined in line 204; used 1 times
getnum defined in line 231; used 2 times
input defined in line 143; used 1 times
insertl defined in line 559; used 5 times
iterate defined in line 470; used 1 times
main defined in line 67; never used
oplook defined in line 388; used 1 times
opsetup defined in line 374; used 1 times
  • in line 99
output defined in line 246; used 1 times
reducelit defined in line 316; used 1 times
refcount defined in line 431; used 1 times
xjump defined in line 536; used 1 times

Defined variables

isn defined in line 64; used 1 times
lastseg defined in line 65; used 1 times
optab defined in line 9; used 2 times
revbr defined in line 63; used 2 times
sccsid defined in line 1; never used
Last modified: 1981-07-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1638
Valid CSS Valid XHTML 1.0 Strict