1: #
   2: /*
   3:  * C object code improver-- second part
   4:  */
   5: 
   6: #include "c2.h"
   7: 
   8: rmove()
   9: {
  10:     register struct node *p;
  11:     register int r;
  12:     register  r1, flt;
  13: 
  14:     for (p=first.forw; p!=0; p = p->forw) {
  15:     flt = 0;
  16:     switch (p->op) {
  17: 
  18:     case MOVF:
  19:     case MOVFO:
  20:     case MOVOF:
  21:         flt = NREG;
  22: 
  23:     case MOV:
  24:         if (p->subop==BYTE)
  25:             goto dble;
  26:         dualop(p);
  27:         if ((r = findrand(regs[RT1], flt)) >= 0) {
  28:             if (r == flt+isreg(regs[RT2]) && p->forw->op!=CBR
  29:                && p->forw->op!=SXT
  30:                && p->forw->op!=CFCC) {
  31:                 p->forw->back = p->back;
  32:                 p->back->forw = p->forw;
  33:                 redunm++;
  34:                 nchange++;
  35:                 continue;
  36:             }
  37:         }
  38:         if (equstr(regs[RT1], "$0")) {
  39:             p->op = CLR;
  40:             strcpy(regs[RT1], regs[RT2]);
  41:             regs[RT2][0] = 0;
  42:             p->code = copy(1, regs[RT1]);
  43:             nchange++;
  44:             goto sngl;
  45:         }
  46:         repladdr(p, 0, flt);
  47:         r = isreg(regs[RT1]);
  48:         r1 = isreg(regs[RT2]);
  49:         dest(regs[RT2], flt);
  50:         if (r >= 0)
  51:             if (r1 >= 0)
  52:                 savereg(r1+flt, regs[r+flt]);
  53:             else
  54:                 savereg(r+flt, regs[RT2]);
  55:         else
  56:             if (r1 >= 0)
  57:                 savereg(r1+flt, regs[RT1]);
  58:             else
  59:                 setcon(regs[RT1], regs[RT2]);
  60:         source(regs[RT1]);
  61:         setcc(regs[RT2]);
  62:         continue;
  63: 
  64:     case ADDF:
  65:     case SUBF:
  66:     case DIVF:
  67:     case MULF:
  68:         flt = NREG;
  69:         goto dble;
  70: 
  71:     case ADD:
  72:     case SUB:
  73:     case BIC:
  74:     case BIS:
  75:     case MUL:
  76:     case DIV:
  77:     case ASH:
  78:     dble:
  79:         dualop(p);
  80:         if (p->op==BIC && (equstr(regs[RT1], "$-1") || equstr(regs[RT1], "$177777"))) {
  81:             p->op = CLR;
  82:             strcpy(regs[RT1], regs[RT2]);
  83:             regs[RT2][0] = 0;
  84:             p->code = copy(1, regs[RT1]);
  85:             nchange++;
  86:             goto sngl;
  87:         }
  88:         if ((p->op==BIC || p->op==BIS) && equstr(regs[RT1], "$0")) {
  89:             if (p->forw->op!=CBR) {
  90:                 p->back->forw = p->forw;
  91:                 p->forw->back = p->back;
  92:                 nchange++;
  93:                 continue;
  94:             }
  95:         }
  96: /*
  97:  * the next block of code looks for the sequences (which extract the
  98:  * high byte of a word or the low byte respectively):
  99:  *	ash $-10,r
 100:  *	bic $-400,r
 101:  * or
 102:  *	mov natural,r
 103:  *	bic $-400,r
 104:  * and transforms them into:
 105:  *	clrb r
 106:  *	swab r
 107:  * or
 108:  *	clr r
 109:  *	bisb natural,r
 110:  * These constructs occur often enough in the kernel (dealing with major/minor
 111:  * device numbers, etc) it's worth a little extra work at compile time.
 112: */
 113:         if (p->op == BIC && (equstr(regs[RT1],"$-400") ||
 114:              equstr(regs[RT1],"$-177400"))) {
 115:             if (p->back->op == ASH) {
 116:                 r = isreg(regs[RT2]);
 117:                 dualop(p->back);
 118:                 if ((equstr(regs[RT1], "$-10") ||
 119:                      equstr(regs[RT1], "$177770")) &&
 120:                     r == isreg(regs[RT2])) {
 121:                     strcpy(regs[RT1], regs[RT2]);
 122:                     regs[RT2][0] = 0;
 123:                     p->back->op = CLR;
 124:                     p->back->subop = BYTE;
 125:                     p->back->code = copy(1, regs[RT1]);
 126:                     p->op = SWAB;
 127:                     p->code = copy(1, regs[RT1]);
 128:                     nchange++;
 129:                     goto sngl;
 130:                 }
 131:             }
 132:             else if (p->back->op == MOV && p->forw->op != CBR) {
 133:                 char temp[50];
 134: 
 135:                 r = isreg(regs[RT2]);
 136:                 if (r < 0 && !xnatural(regs[RT2]))
 137:                     goto out;
 138:                 strcpy(temp, regs[RT2]);
 139:                 dualop(p->back);
 140:                 if (isreg(regs[RT2]) == r && natural(regs[RT1])) {
 141:                     if (r < 0 && (!xnatural(regs[RT2]) || !equstr(temp, regs[RT2])))
 142:                     goto out;
 143: /*
 144:  * XXX - the sequence "movb rN,rN; bic $-400,rN" can not be transformed
 145:  * because the 'clr' would lose all information about 'rN'.  The best that can
 146:  * be done is to remove the 'movb' instruction and leave the 'bic'.
 147: */
 148:                     if (isreg(regs[RT1]) == r && r >= 0) {
 149:                         p = p->back;
 150:                         p->forw->back = p->back;
 151:                         p->back->forw = p->forw;
 152:                         nchange++;
 153:                         continue;
 154:                     }
 155:                     dest(regs[RT1], flt);
 156:                     p->back->op = CLR;
 157:                     p->back->subop = 0;
 158:                     p->back->code = copy(1, regs[RT2]);
 159:                     p->op = BIS;
 160:                     p->subop = BYTE;
 161:                     strcat(regs[RT1], ",");
 162:                     p->code = copy(2, regs[RT1], regs[RT2]);
 163:                     nchange++;
 164:                 }
 165:             }
 166: out:        dualop(p);  /* restore banged up parsed operands */
 167:         }
 168:         repladdr(p, 0, flt);
 169:         source(regs[RT1]);
 170:         dest(regs[RT2], flt);
 171:         if (p->op==DIV && (r = isreg(regs[RT2]))>=0)
 172:             regs[r|1][0] = 0;
 173:         switch  (p->op)
 174:             {
 175:             case    ADD:
 176:             case    SUB:
 177:             case    BIC:
 178:             case    BIS:
 179:             case    ASH:
 180:                 setcc(regs[RT2]);
 181:                 break;
 182:             default:
 183:                 ccloc[0] = 0;
 184:             }
 185:         continue;
 186: 
 187:     case SXT:
 188:         singop(p);
 189:         if (p->forw->op == CLR && p->forw->subop != BYTE &&
 190:             xnatural(regs[RT1]) && !strcmp(p->code, p->forw->code)){
 191:             p->forw->back = p->back;
 192:             p->back->forw = p->forw;
 193:             nchange++;
 194:             continue;
 195:         }
 196:         goto sngl;
 197:     case CLRF:
 198:     case NEGF:
 199:         flt = NREG;
 200: 
 201:     case CLR:
 202:     case COM:
 203:     case INC:
 204:     case DEC:
 205:     case NEG:
 206:     case ASR:
 207:     case ASL:
 208:     case SWAB:
 209:         singop(p);
 210:     sngl:
 211:         dest(regs[RT1], flt);
 212:         if (p->op==CLR && flt==0)
 213:             {
 214:             if ((r = isreg(regs[RT1])) >= 0)
 215:                 savereg(r, "$0");
 216:             else
 217:                 setcon("$0", regs[RT1]);
 218:             ccloc[0] = 0;
 219:             }
 220:         else
 221:             setcc(regs[RT1]);
 222:         continue;
 223: 
 224:     case TSTF:
 225:         flt = NREG;
 226: 
 227:     case TST:
 228:         singop(p);
 229:         repladdr(p, 0, flt);
 230:         source(regs[RT1]);
 231:         if (p->back->op == TST && !flt && not_sp(regs[RT1])) {
 232:             char rt1[MAXCPS + 2];
 233:             strcpy(rt1, regs[RT1]);
 234:             singop(p->back);
 235:             if (!strcmp("(sp)+", regs[RT1])) {
 236:                 p->back->subop = p->subop;
 237:                 p->back->forw = p->forw;
 238:                 p->forw->back = p->back;
 239:                 p = p->back;
 240:                 p->op = MOV;
 241:                 p->code = copy(2, rt1, ",(sp)+");
 242:                 nrtst++;
 243:                 nchange++;
 244:                 continue;
 245:             }
 246:         singop(p);
 247:         }
 248:         if (p->back->op == MOV && p->back->subop == BYTE) {
 249:             dualop(p->back);
 250:             setcc(regs[RT2]);
 251:             singop(p);
 252:         }
 253:         if (equstr(regs[RT1], ccloc) && p->subop == p->back->subop) {
 254:             p->back->forw = p->forw;
 255:             p->forw->back = p->back;
 256:             p = p->back;
 257:             nrtst++;
 258:             nchange++;
 259:         }
 260:         else
 261:             setcc(regs[RT1]); /* XXX - double TST in a row */
 262:         continue;
 263: 
 264:     case CMPF:
 265:         flt = NREG;
 266: 
 267:     case CMP:
 268:     case BIT:
 269:         dualop(p);
 270:         source(regs[RT1]);
 271:         source(regs[RT2]);
 272:         if(p->op==BIT) {
 273:             if (equstr(regs[RT1], "$-1") || equstr(regs[RT1], "$177777")) {
 274:                 p->op = TST;
 275:                 strcpy(regs[RT1], regs[RT2]);
 276:                 regs[RT2][0] = 0;
 277:                 p->code = copy(1, regs[RT1]);
 278:                 nchange++;
 279:                 nsaddr++;
 280:             } else if (equstr(regs[RT2], "$-1") || equstr(regs[RT2], "$177777")) {
 281:                 p->op = TST;
 282:                 regs[RT2][0] = 0;
 283:                 p->code = copy(1, regs[RT1]);
 284:                 nchange++;
 285:                 nsaddr++;
 286:             }
 287:             if (equstr(regs[RT1], "$0")) {
 288:                 p->op = TST;
 289:                 regs[RT2][0] = 0;
 290:                 p->code = copy(1, regs[RT1]);
 291:                 nchange++;
 292:                 nsaddr++;
 293:             } else if (equstr(regs[RT2], "$0")) {
 294:                 p->op = TST;
 295:                 strcpy(regs[RT1], regs[RT2]);
 296:                 regs[RT2][0] = 0;
 297:                 p->code = copy(1, regs[RT1]);
 298:                 nchange++;
 299:                 nsaddr++;
 300:             }
 301:         }
 302:         repladdr(p, 1, flt);
 303:         ccloc[0] = 0;
 304:         continue;
 305: 
 306:     case CBR:
 307:         r = -1;
 308:         if (p->back->op==TST || p->back->op==CMP) {
 309:             if (p->back->op==TST) {
 310:                 singop(p->back);
 311:                 savereg(RT2, "$0");
 312:             } else
 313:                 dualop(p->back);
 314:             if (equstr(regs[RT1], regs[RT2])
 315:              && natural(regs[RT1]) && natural(regs[RT2]))
 316:                 r = compare(p->subop, "$1", "$1");
 317:             else
 318:                 r = compare(p->subop, findcon(RT1), findcon(RT2));
 319:             if (r==0) {
 320:                 if (p->forw->op==CBR
 321:                   || p->forw->op==SXT
 322:                   || p->forw->op==CFCC) {
 323:                     p->back->forw = p->forw;
 324:                     p->forw->back = p->back;
 325:                 } else {
 326:                     p->back->back->forw = p->forw;
 327:                     p->forw->back = p->back->back;
 328:                 }
 329:                 decref(p->ref);
 330:                 p = p->back->back;
 331:                 nchange++;
 332:             } else if (r>0) {
 333:                 p->op = JBR;
 334:                 p->subop = 0;
 335:                 p->back->back->forw = p;
 336:                 p->back = p->back->back;
 337:                 p = p->back;
 338:                 nchange++;
 339:             }
 340: /*
 341:  * If the instruction prior to the conditional branch was a 'tst' then
 342:  * save the condition code status.  The C construct:
 343:  * 		if (x)
 344:  *		   if (x > 0)
 345:  * generates "tst _x; jeq ...; tst _x; jmi ...;jeq ...".  The code below removes
 346:  * the second "tst _x", leaving "tst _x; jeq ...;jmi ...; jeq ...".
 347: */
 348:             if (p->back->op == TST) {
 349:                 singop(p->back);
 350:                 setcc(regs[RT1]);
 351:                 break;
 352:             }
 353:         }
 354: /*
 355:  * If the previous instruction was also a conditional branch then
 356:  * attempt to merge the two into a single branch.
 357: */
 358:         if (p->back->op == CBR)
 359:             fixupbr(p);
 360:     case CFCC:
 361:         ccloc[0] = 0;
 362:         continue;
 363: 
 364: /*
 365:  * Unrecognized (unparsed) instructions, assignments (~foo=r2), and
 366:  * data arrive here.  In order to prevent throwing away information
 367:  * about register contents just because a local assignment is done
 368:  * we check for the first character being a tilde.
 369: */
 370:     case 0:
 371:         if (p->code[0] != '~')
 372:             clearreg();
 373:         continue;
 374: 
 375:     case JBR:
 376:         redunbr(p);
 377: 
 378:     default:
 379:         clearreg();
 380:     }
 381:     }
 382: }
 383: 
 384: /*
 385:  * This table is used to convert two branches to the same label after a
 386:  * 'tst' (which clears the C and V condition codes) into a single branch.
 387:  * Entries which translate to JBR could eventually cause the 'tst' instruction
 388:  * to be eliminated as well, but that can wait for now.  There are unused or
 389:  * impossible combinations ('tst' followed by 'jlo' for example.  since
 390:  * 'tst' clears C it makes little sense to 'jlo/bcs') in the table, it
 391:  * would have cost more in code to remove them than the entries themselves.
 392:  *
 393:  * Example:  "tst _x; jmi L3; jeq L3".  Find the row for 'jmi', then look
 394:  * at the column for 'jeq', the resulting "opcode" is 'jle'.
 395: */
 396:     char    brtable[12][12] = {
 397:     /* jeq  jne  jle  jge  jlt  jgt  jlo  jhi  jlos jhis jpl  jmi */
 398: /* jeq */ {JEQ ,JBR ,JLE ,JGE ,JLE ,JGE ,JEQ ,JBR ,JEQ ,JBR ,JGE ,JLE},
 399: /* jne */ {JBR ,JNE ,JBR ,JBR ,JNE ,JNE ,JNE ,JNE ,JBR ,JBR ,JBR ,JNE},
 400: /* jle */ {JLE ,JBR ,JLE ,JBR ,JLE ,JBR ,JLE ,JBR ,JLE ,JBR ,JBR ,JLE},
 401: /* jge */ {JGE ,JBR ,JBR ,JGE ,JBR ,JGE ,JGE ,JBR ,JGE ,JBR ,JGE ,JBR},
 402: /* jlt */ {JLE ,JNE ,JLE ,JBR ,JLT ,JNE ,JLT ,JBR ,JLE ,JBR ,JBR ,JLT},
 403: /* jgt */ {JGE ,JNE ,JBR ,JGE ,JNE ,JGT ,JGT ,JGT ,JBR ,JGE ,JGE ,JNE},
 404: /* jlo */ {JEQ ,JNE ,JLE ,JGE ,JLT ,JGT ,JLO ,JHI ,JLOS,JHIS,JPL ,JMI},
 405: /* jhi */ {JBR ,JNE ,JBR ,JBR ,JNE ,JNE ,JNE ,JNE ,JBR ,JBR ,JBR ,JNE},
 406: /* jlos*/ {JEQ ,JBR ,JLE ,JGE ,JLE ,JGE ,JLE ,JBR ,JEQ ,JBR ,JGE ,JLE},
 407: /* jhis*/ {JBR ,JBR ,JBR ,JBR ,JBR ,JBR ,JBR ,JBR ,JBR ,JBR ,JBR ,JBR},
 408: /* jpl */ {JGE ,JBR ,JBR ,JGE ,JBR ,JGE ,JGE ,JBR ,JGE ,JBR ,JGE ,JBR},
 409: /* jmi */ {JLE ,JNE ,JLE ,JBR ,JLT ,JNE ,JLT ,JNE ,JLE ,JLT ,JBR ,JLT}
 410:       };
 411: 
 412: fixupbr(p)
 413:     register struct node *p;
 414: {
 415:     register struct node *p1, *p2;
 416:     int op;
 417: 
 418:     p1 = p->back;
 419:     p2 = p1->back;
 420:     if (p->labno != p1->labno)
 421:         return;
 422:     if (p2->op != TST) {
 423:         if (p2->op == CBR && p2->back->op == TST)
 424:             goto ok;
 425:         return;
 426:     }
 427: ok: p->subop = brtable[p->subop][p1->subop];
 428:     nchange++;
 429:     nredunj++;
 430:     p2->forw = p;
 431:     p->back = p1->back;
 432:     }
 433: 
 434: jumpsw()
 435: {
 436:     register struct node *p, *p1;
 437:     register t;
 438:     register struct node *tp;
 439:     int nj;
 440: 
 441:     t = 0;
 442:     nj = 0;
 443:     for (p=first.forw; p!=0; p = p->forw)
 444:         p->refc = ++t;
 445:     for (p=first.forw; p!=0; p = p1) {
 446:         p1 = p->forw;
 447:         if (p->op == CBR && p1->op==JBR && p->ref && p1->ref
 448:          && abs(p->refc - p->ref->refc) > abs(p1->refc - p1->ref->refc)) {
 449:             if (p->ref==p1->ref)
 450:                 continue;
 451:             p->subop = revbr[p->subop];
 452:             tp = p1->ref;
 453:             p1->ref = p->ref;
 454:             p->ref = tp;
 455:             t = p1->labno;
 456:             p1->labno = p->labno;
 457:             p->labno = t;
 458:             nrevbr++;
 459:             nj++;
 460:         }
 461:     }
 462:     return(nj);
 463: }
 464: 
 465: addsob()
 466: {
 467:     register struct node *p, *p1;
 468: 
 469:     for (p = &first; (p1 = p->forw)!=0; p = p1) {
 470:         if (p->op==DEC && isreg(p->code)>=0
 471:          && p1->op==CBR && p1->subop==JNE) {
 472:             if (p->refc < p1->ref->refc)
 473:                 continue;
 474:             if (toofar(p1))
 475:                 continue;
 476:             p->labno = p1->labno;
 477:             p->op = SOB;
 478:             p->subop = 0;
 479:             p1->forw->back = p;
 480:             p->forw = p1->forw;
 481:             nsob++;
 482:         }
 483:     }
 484: }
 485: 
 486: toofar(p)
 487: struct node *p;
 488: {
 489:     register struct node *p1;
 490:     int len;
 491: 
 492:     len = 0;
 493:     for (p1 = p->ref; p1 && p1!=p; p1 = p1->forw)
 494:         len += ilen(p1);
 495:     if (len < 128)
 496:         return(0);
 497:     return(1);
 498: }
 499: 
 500: ilen(p)
 501: register struct node *p;
 502: {
 503: 
 504:     switch (p->op) {
 505:     case LABEL:
 506:     case DLABEL:
 507:     case TEXT:
 508:     case EROU:
 509:     case EVEN:
 510:         return(0);
 511: 
 512:     case CBR:
 513:         return(6);
 514: 
 515:     default:
 516:         dualop(p);
 517:         return(2 + adrlen(regs[RT1]) + adrlen(regs[RT2]));
 518:     }
 519: }
 520: 
 521: adrlen(s)
 522: register char *s;
 523: {
 524:     if (*s == 0)
 525:         return(0);
 526:     if (*s=='r')
 527:         return(0);
 528:     if (*s=='(' && *(s+1)=='r')
 529:         return(0);
 530:     if (*s=='-' && *(s+1)=='(')
 531:         return(0);
 532:     return(2);
 533: }
 534: 
 535: abs(x)
 536: register int x;
 537: {
 538:     return(x<0? -x: x);
 539: }
 540: 
 541: equop(ap1, p2)
 542: struct node *ap1, *p2;
 543: {
 544:     register char *cp1, *cp2;
 545:     register struct node *p1;
 546: 
 547:     p1 = ap1;
 548:     if (p1->op!=p2->op || p1->subop!=p2->subop)
 549:         return(0);
 550:     if (p1->op>0 && p1->op<MOV)
 551:         return(0);
 552:     cp1 = p1->code;
 553:     cp2 = p2->code;
 554:     if (cp1==0 && cp2==0)
 555:         return(1);
 556:     if (cp1==0 || cp2==0)
 557:         return(0);
 558:     while (*cp1 == *cp2++)
 559:         if (*cp1++ == 0)
 560:             return(1);
 561:     return(0);
 562: }
 563: 
 564: decref(p)
 565: register struct node *p;
 566: {
 567:     if (--p->refc <= 0) {
 568:         nrlab++;
 569:         p->back->forw = p->forw;
 570:         p->forw->back = p->back;
 571:     }
 572: }
 573: 
 574: struct node *
 575: nonlab(p)
 576: register struct node *p;
 577: {
 578:     CHECK(10);
 579:     while (p && p->op==LABEL)
 580:         p = p->forw;
 581:     return(p);
 582: }
 583: 
 584: char *
 585: alloc(n)
 586: register n;
 587: {
 588:     register char *p;
 589: 
 590: #define round(a,b) ((((a)+(b)-1)/(b))*(b))
 591:     n=round(n,sizeof(char *));
 592:     if (alasta+n < alastr) {
 593:         p = alasta;
 594:         alasta += n;
 595:         return(p);
 596:     }
 597:     if (lasta+n >= lastr) {
 598:         if (sbrk(2000) == (char *)-1) {
 599:             fprintf(stderr, "C Optimizer: out of space\n");
 600:             exit(1);
 601:         }
 602:         lastr += 2000;
 603:     }
 604:     p = lasta;
 605:     lasta += n;
 606:     return(p);
 607: }
 608: 
 609: clearreg()
 610: {
 611:     register int i;
 612: 
 613:     for (i=0; i<2*NREG; i++)
 614:         regs[i][0] = '\0';
 615:     conloc[0] = 0;
 616:     ccloc[0] = 0;
 617: }
 618: 
 619: savereg(ai, as)
 620: char *as;
 621: {
 622:     register char *p, *s, *sp;
 623: 
 624:     sp = p = regs[ai];
 625:     s = as;
 626:     if (source(s))
 627:         return;
 628:     while (*p++ = *s) {
 629:         if (s[0]=='(' && s[1]=='r' && s[2]<'5') {
 630:             *sp = 0;
 631:             return;
 632:         }
 633:         if (*s++ == ',')
 634:             break;
 635:     }
 636:     *--p = '\0';
 637: }
 638: 
 639: dest(as, flt)
 640: char *as;
 641: {
 642:     register char *s;
 643:     register int i;
 644: 
 645:     s = as;
 646:     source(s);
 647:     if ((i = isreg(s)) >= 0)
 648:         regs[i+flt][0] = 0;
 649: /* v7orig:
 650:  *	for (i=0; i<NREG+NREG; i++)
 651:  */
 652:     for (i=flt; i<flt+NREG; i++)
 653:         if (*regs[i]=='*' && equstr(s, regs[i]+1))
 654:             regs[i][0] = 0;
 655:     if (equstr(s, conloc))
 656:         conloc[0] = '\0';
 657:     while ((i = findrand(s, flt)) >= 0)
 658:         regs[i][0] = 0;
 659:     while (*s) {
 660:         if ((*s=='(' && (*(s+1)!='r' || *(s+2)!='5')) || *s++=='*') {
 661: /* v7.orig:
 662:  *			for (i=0; i<NREG+NREG; i++) {
 663:  */
 664:             for (i=flt; i<flt+NREG; i++) {
 665:                 if (regs[i][0] != '$')
 666:                     regs[i][0] = 0;
 667:                 conloc[0] = 0;
 668:             }
 669:             return;
 670:         }
 671:     }
 672: }
 673: 
 674: singop(ap)
 675: struct node *ap;
 676: {
 677:     register char *p1, *p2;
 678: 
 679:     p1 = ap->code;
 680:     p2 = regs[RT1];
 681:     while (*p2++ = *p1++);
 682:     regs[RT2][0] = 0;
 683: }
 684: 
 685: 
 686: dualop(ap)
 687: struct node *ap;
 688: {
 689:     register char *p1, *p2;
 690:     register struct node *p;
 691: 
 692:     p = ap;
 693:     p1 = p->code;
 694:     p2 = regs[RT1];
 695:     while (*p1 && *p1!=',')
 696:         *p2++ = *p1++;
 697:     *p2++ = 0;
 698:     p2 = regs[RT2];
 699:     *p2 = 0;
 700:     if (*p1++ !=',')
 701:         return;
 702:     while (*p1==' ' || *p1=='\t')
 703:         p1++;
 704:     while (*p2++ = *p1++)
 705:         ;
 706: }
 707: 
 708: findrand(as, flt)
 709: char *as;
 710: {
 711:     register int i;
 712:     for (i = flt; i<NREG+flt; i++) {
 713:         if (equstr(regs[i], as))
 714:             return(i);
 715:     }
 716:     return(-1);
 717: }
 718: 
 719: isreg(as)
 720: char *as;
 721: {
 722:     register char *s;
 723: 
 724:     s = as;
 725:     if (s[0]=='r' && s[1]>='0' && s[1]<='4' && s[2]==0)
 726:         return(s[1]-'0');
 727:     return(-1);
 728: }
 729: 
 730: check()
 731: {
 732:     register struct node *p, *lp;
 733:     register count;
 734: 
 735:     lp = &first;
 736:     count = 0;
 737:     for (p=first.forw; p!=0; p = p->forw) {
 738:         if (++count > 10000)
 739:             abort(0);
 740:         if (p->back != lp)
 741:             abort(1);
 742:         lp = p;
 743:     }
 744: }
 745: 
 746: source(ap)
 747: char *ap;
 748: {
 749:     register char *p1, *p2;
 750: 
 751:     p1 = ap;
 752:     p2 = p1;
 753:     if (*p1==0)
 754:         return(0);
 755:     while (*p2++);
 756:     if (*p1=='-' && *(p1+1)=='('
 757:      || *p1=='*' && *(p1+1)=='-' && *(p1+2)=='('
 758:      || *(p2-2)=='+') {
 759:         while (*p1 && *p1++!='r');
 760:         if (*p1>='0' && *p1<='4')
 761:             regs[*p1 - '0'][0] = 0;
 762:         return(1);
 763:     }
 764:     return(0);
 765: }
 766: 
 767: repladdr(p, f, flt)
 768: struct node *p;
 769: {
 770:     register r;
 771:     int r1;
 772:     register char *p1, *p2;
 773:     static char rt1[50], rt2[50];
 774: 
 775:     if (f)
 776:         r1 = findrand(regs[RT2], flt);
 777:     else
 778:         r1 = -1;
 779:     r = findrand(regs[RT1], flt);
 780:     if (r1 >= NREG)
 781:         r1 -= NREG;
 782:     if (r >= NREG)
 783:         r -= NREG;
 784:     if (r>=0 || r1>=0) {
 785:         p2 = regs[RT1];
 786:         for (p1 = rt1; *p1++ = *p2++;);
 787:         if (regs[RT2][0]) {
 788:             p1 = rt2;
 789:             *p1++ = ',';
 790:             for (p2 = regs[RT2]; *p1++ = *p2++;);
 791:         } else
 792:             rt2[0] = 0;
 793:         if (r>=0) {
 794:             rt1[0] = 'r';
 795:             rt1[1] = r + '0';
 796:             rt1[2] = 0;
 797:             nsaddr++;
 798:             nchange++;
 799:         }
 800:         if (r1>=0) {
 801:             rt2[1] = 'r';
 802:             rt2[2] = r1 + '0';
 803:             rt2[3] = 0;
 804:             nsaddr++;
 805:             nchange++;
 806:         }
 807:         p->code = copy(2, rt1, rt2);
 808:     }
 809: }
 810: 
 811: movedat()
 812: {
 813:     register struct node *p1, *p2;
 814:     struct node *p3;
 815:     register seg;
 816:     struct node data;
 817:     struct node *datp;
 818: 
 819:     if (first.forw == 0)
 820:         return;
 821:     if (lastseg != TEXT && lastseg != -1) {
 822:         p1 = (struct node *)alloc(sizeof(first));
 823:         p1->op = lastseg;
 824:         p1->subop = 0;
 825:         p1->code = NULL;
 826:         p1->forw = first.forw;
 827:         p1->back = &first;
 828:         first.forw->back = p1;
 829:         first.forw = p1;
 830:     }
 831:     datp = &data;
 832:     for (p1 = first.forw; p1!=0; p1 = p1->forw) {
 833:         if (p1->op == DATA) {
 834:             p2 = p1->forw;
 835:             while (p2 && p2->op!=TEXT)
 836:                 p2 = p2->forw;
 837:             if (p2==0)
 838:                 break;
 839:             p3 = p1->back;
 840:             p1->back->forw = p2->forw;
 841:             p2->forw->back = p3;
 842:             p2->forw = 0;
 843:             datp->forw = p1;
 844:             p1->back = datp;
 845:             p1 = p3;
 846:             datp = p2;
 847:         }
 848:     }
 849:     if (data.forw) {
 850:         datp->forw = first.forw;
 851:         first.forw->back = datp;
 852:         data.forw->back = &first;
 853:         first.forw = data.forw;
 854:     }
 855:     seg = lastseg;
 856:     for (p1 = first.forw; p1!=0; p1 = p1->forw) {
 857:         if (p1->op==TEXT||p1->op==DATA||p1->op==BSS) {
 858:             if (p2 = p1->forw) {
 859:                 if (p2->op==TEXT||p2->op==DATA||p2->op==BSS)
 860:                     p1->op  = p2->op;
 861:             }
 862:             if (p1->op == seg || p1->forw&&p1->forw->op==seg) {
 863:                 p1->back->forw = p1->forw;
 864:                 p1->forw->back = p1->back;
 865:                 p1 = p1->back;
 866:                 continue;
 867:             }
 868:             seg = p1->op;
 869:         }
 870:     }
 871: }
 872: 
 873: redunbr(p)
 874: register struct node *p;
 875: {
 876:     register struct node *p1;
 877:     register char *ap1;
 878:     char *ap2;
 879: 
 880:     if ((p1 = p->ref) == 0)
 881:         return;
 882:     p1 = nonlab(p1);
 883:     if (p1->op==TST) {
 884:         singop(p1);
 885:         savereg(RT2, "$0");
 886:     } else if (p1->op==CMP)
 887:         dualop(p1);
 888:     else
 889:         return;
 890:     if (p1->forw->op!=CBR)
 891:         return;
 892:     ap1 = findcon(RT1);
 893:     ap2 = findcon(RT2);
 894:     p1 = p1->forw;
 895:     if (compare(p1->subop, ap1, ap2)>0) {
 896:         nredunj++;
 897:         nchange++;
 898:         decref(p->ref);
 899:         p->ref = p1->ref;
 900:         p->labno = p1->labno;
 901:         p->ref->refc++;
 902:     }
 903: }
 904: 
 905: char *
 906: findcon(i)
 907: {
 908:     register char *p;
 909:     register r;
 910: 
 911:     p = regs[i];
 912:     if (*p=='$')
 913:         return(p);
 914:     if ((r = isreg(p)) >= 0)
 915:         return(regs[r]);
 916:     if (equstr(p, conloc))
 917:         return(conval);
 918:     return(p);
 919: }
 920: 
 921: compare(oper, cp1, cp2)
 922: register char *cp1, *cp2;
 923: {
 924:     register unsigned n1, n2;
 925: 
 926:     if (*cp1++ != '$' || *cp2++ != '$')
 927:         return(-1);
 928:     n1 = 0;
 929:     while (*cp2 >= '0' && *cp2 <= '7') {
 930:         n1 <<= 3;
 931:         n1 += *cp2++ - '0';
 932:     }
 933:     n2 = n1;
 934:     n1 = 0;
 935:     while (*cp1 >= '0' && *cp1 <= '7') {
 936:         n1 <<= 3;
 937:         n1 += *cp1++ - '0';
 938:     }
 939:     if (*cp1=='+')
 940:         cp1++;
 941:     if (*cp2=='+')
 942:         cp2++;
 943:     do {
 944:         if (*cp1++ != *cp2)
 945:             return(-1);
 946:     } while (*cp2++);
 947:     switch(oper) {
 948: 
 949:     case JEQ:
 950:         return(n1 == n2);
 951:     case JNE:
 952:         return(n1 != n2);
 953:     case JLE:
 954:         return((int)n1 <= (int)n2);
 955:     case JGE:
 956:         return((int)n1 >= (int)n2);
 957:     case JLT:
 958:         return((int)n1 < (int)n2);
 959:     case JGT:
 960:         return((int)n1 > (int)n2);
 961:     case JLO:
 962:         return(n1 < n2);
 963:     case JHI:
 964:         return(n1 > n2);
 965:     case JLOS:
 966:         return(n1 <= n2);
 967:     case JHIS:
 968:         return(n1 >= n2);
 969:     }
 970:     return(-1);
 971: }
 972: 
 973: setcon(ar1, ar2)
 974: char *ar1, *ar2;
 975: {
 976:     register char *cl, *cv, *p;
 977: 
 978:     cl = ar2;
 979:     cv = ar1;
 980:     if (*cv != '$')
 981:         return;
 982:     if (!natural(cl))
 983:         return;
 984:     p = conloc;
 985:     while (*p++ = *cl++);
 986:     p = conval;
 987:     while (*p++ = *cv++);
 988: }
 989: 
 990: equstr(ap1, ap2)
 991: char *ap1, *ap2;
 992: {
 993:     register char *p1, *p2;
 994: 
 995:     p1 = ap1;
 996:     p2 = ap2;
 997:     do {
 998:         if (*p1++ != *p2)
 999:             return(0);
1000:     } while (*p2++);
1001:     return(1);
1002: }
1003: 
1004: setcc(ap)
1005: char *ap;
1006: {
1007:     register char *p, *p1;
1008: 
1009:     p = ap;
1010:     if (!natural(p)) {
1011:         ccloc[0] = 0;
1012:         return;
1013:     }
1014:     p1 = ccloc;
1015:     while (*p1++ = *p++);
1016: }
1017: 
1018: natural(ap)
1019: char *ap;
1020: {
1021:     register char *p;
1022: 
1023:     p = ap;
1024:     if (*p=='*' || *p=='(' || *p=='-'&&*(p+1)=='(')
1025:         return(0);
1026:     while (*p++);
1027:     p--;
1028:     if (*--p == '+' || *p ==')' && *--p != '5')
1029:         return(0);
1030:     return(1);
1031: }
1032: 
1033: xnatural(ap)
1034:     char *ap;
1035: {
1036:     if (natural(ap))
1037:         return(1);
1038:     return(equstr("(sp)", ap));
1039: }
1040: 
1041: not_sp(ap)
1042:     register char *ap;
1043: {
1044:     char c;
1045: 
1046:     while (c = *ap++)
1047:         if (c == '(') return(*ap == 's' && ap[1] == 'p');
1048:     return(1);
1049: }

Defined functions

abs defined in line 535; used 2 times
  • in line 448(2)
addsob defined in line 465; used 1 times
adrlen defined in line 521; used 2 times
  • in line 517(2)
alloc defined in line 584; used 7 times
check defined in line 730; never used
clearreg defined in line 609; used 3 times
compare defined in line 921; used 3 times
decref defined in line 564; used 11 times
dest defined in line 639; used 4 times
dualop defined in line 686; used 10 times
equop defined in line 541; used 2 times
equstr defined in line 990; used 22 times
findcon defined in line 905; used 5 times
findrand defined in line 708; used 4 times
fixupbr defined in line 412; used 1 times
ilen defined in line 500; used 1 times
isreg defined in line 719; used 13 times
jumpsw defined in line 434; used 1 times
movedat defined in line 811; used 1 times
natural defined in line 1018; used 6 times
nonlab defined in line 574; used 5 times
not_sp defined in line 1041; used 1 times
redunbr defined in line 873; used 1 times
repladdr defined in line 767; used 4 times
rmove defined in line 8; used 1 times
savereg defined in line 619; used 6 times
setcc defined in line 1004; used 6 times
setcon defined in line 973; used 2 times
singop defined in line 674; used 9 times
source defined in line 746; used 7 times
toofar defined in line 486; used 1 times
xnatural defined in line 1033; used 3 times

Defined variables

brtable defined in line 396; used 1 times

Defined macros

round defined in line 590; used 1 times
Last modified: 1994-01-03
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4063
Valid CSS Valid XHTML 1.0 Strict