# 2.11BSD#431 - /usr/src/lib/c2/c21.c

##### Functions

    abs               X
    addsob            X
    adrlen            X
    alloc             X
    check             X
    clearreg          X
    compare           X
    decref            X
    dest              X
    dualop            X
    equop             X
    equstr            X
    findcon           X
    findrand          X
    fixupbr           X
    ilen              X
    isreg             X
    jumpsw            X
    movedat           X
    natural           X
    nonlab            X
    not_sp            X
    redunbr           X
    repladdr          X
    rmove             X
    savereg           X
    setcc             X
    setcon            X
    singop            X
    source            X
    toofar            X
    xnatural          X

##### Variables

    brtable           X

##### Macros

    round             X

       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

- in /usr/src/lib/c2/c20.c line 130

adrlen defined in line 521; used 2 times

- in line 517(2)

alloc defined in line 584; used 7 times

- in line 822
- in /usr/src/lib/c2/c2.h line 147
- in /usr/src/lib/c2/c20.c line 170, 188, 200, 378, 602

check defined in line 730; never used
clearreg defined in line 609; used 3 times

- in line 372, 379
- in /usr/src/lib/c2/c20.c line 124

compare defined in line 921; used 3 times

- in line 316-318(2), 895

decref defined in line 564; used 11 times

- in line 329, 898
- in /usr/src/lib/c2/c20.c line 483, 498, 511, 536, 547, 650, 673, 687, 722

dest defined in line 639; used 4 times

- in line 49, 155, 170, 211

dualop defined in line 686; used 10 times

- in line 26, 79, 117, 139, 166, 249, 269, 313, 516, 887

equop defined in line 541; used 2 times

- in /usr/src/lib/c2/c20.c line 573, 717

equstr defined in line 990; used 22 times

- in line 38, 80(2), 88, 113-119(4), 141, 253, 273(2), 280(2), 287, 293, 314, 653-655(2), 713, 916, 1038

findcon defined in line 905; used 5 times

- in line 318(2), 892-893(2)
- in /usr/src/lib/c2/c2.h line 143

findrand defined in line 708; used 4 times

- in line 27, 657, 776-779(2)

fixupbr defined in line 412; used 1 times

- in line 359

ilen defined in line 500; used 1 times

- in line 494

isreg defined in line 719; used 13 times

- in line 28, 47-48(2), 116-120(2), 135-140(2), 148, 171, 214, 470, 647, 914

jumpsw defined in line 434; used 1 times

- in /usr/src/lib/c2/c20.c line 129

movedat defined in line 811; used 1 times

- in /usr/src/lib/c2/c20.c line 118

natural defined in line 1018; used 6 times

- in line 140, 315(2), 982, 1010, 1036

nonlab defined in line 574; used 5 times

- in line 882
- in /usr/src/lib/c2/c2.h line 140
- in /usr/src/lib/c2/c20.c line 470, 482, 494

not_sp defined in line 1041; used 1 times

- in line 231

redunbr defined in line 873; used 1 times

- in line 376

repladdr defined in line 767; used 4 times

- in line 46, 168, 229, 302

rmove defined in line 8; used 1 times

- in /usr/src/lib/c2/c20.c line 128

savereg defined in line 619; used 6 times

- in line 52-57(3), 215, 311, 885

setcc defined in line 1004; used 6 times

- in line 61, 180, 221, 250, 261, 350

setcon defined in line 973; used 2 times

- in line 59, 217

singop defined in line 674; used 9 times

- in line 188, 209, 228, 234, 246-251(2), 310, 349, 884

source defined in line 746; used 7 times

- in line 60, 169, 230, 270-271(2), 626, 646

toofar defined in line 486; used 1 times

- in line 474

xnatural defined in line 1033; used 3 times

- in line 136-141(2), 190

#### Defined variables

brtable defined in line 396; used 1 times

- in line 427

#### Defined macros

round defined in line 590; used 1 times

- in line 591

Last modified: 1994-01-03 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2020 |