# 2.11BSD#431 - /usr/src/lib/ccom/c11.c

##### Functions

    arlength          X
    branch            X
    breq              X
    cbranch           X
    collcon           X
    dcalc             X
    decref            X
    degree            X
    error             X
    geti              X
    getree            X
    incref            X
    isfloat           X
    ispow2            X
    label             X
    longrel           X
    notcompat         X
    oddreg            X
    pbase             X
    pname             X
    popstk            X
    pow2              X
    prins             X
    psoct             X
    pswitch           X
    sort              X
    strasg            X
    werror            X
    xdcalc            X
    xlongrel          X

##### Variables

    dirsw             X
    hashsw            X
    lrtab             X

##### Macros

    STKS              X

       1: /*
       2:  *  C compiler
       3:  */
       4:
       5: #include "c1.h"
       6:
       7: degree(t)
       8: register union tree *t;
       9: {
      10:     register union tree *t1;
      11:
      12:     if (t==NULL || t->t.op==0)
      13:         return(0);
      14:     if (t->t.op == CON)
      15:         return(-3);
      16:     if (t->t.op == AMPER)
      17:         return(-2);
      18:     if (t->t.op==ITOL) {
      19:         if ((t1 = isconstant(t)) && (t1->c.value>=0 || uns(t1)))
      20:             return(-2);
      21:         if (uns(t1 = t->t.tr1) && opdope[t1->t.op]&LEAF)
      22:             return(-1);
      23:     }
      24:     if ((opdope[t->t.op] & LEAF) != 0) {
      25:         if (t->t.type==CHAR || t->t.type==UNCHAR || t->t.type==FLOAT)
      26:             return(1);
      27:         return(0);
      28:     }
      29:     return(t->t.degree);
      30: }
      31:
      32: pname(p, flag)
      33: register union tree *p;
      34: {
      35:     register i;
      36:
      37: loop:
      38:     switch(p->t.op) {
      39:
      40:     case LCON:
      41:         printf("$%o", flag<=10? UNS(p->l.lvalue>>16):
      42:            UNS(p->l.lvalue));
      43:         return;
      44:
      45:     case SFCON:
      46:     case CON:
      47:         printf("$");
      48:         psoct(p->c.value);
      49:         return;
      50:
      51:     case FCON:
      52:         printf("L%d", (p->c.value>0? p->c.value: -p->c.value));
      53:         return;
      54:
      55:     case NAME:
      56:         i = p->n.offset;
      57:         if (flag>10)
      58:             i += 2;
      59:         if (i) {
      60:             psoct(i);
      61:             if (p->n.class!=OFFS)
      62:                 putchar('+');
      63:             if (p->n.class==REG)
      64:                 error("Illegal use of register");
      65:         }
      66:         switch(p->n.class) {
      67:
      68:         case SOFFS:
      69:         case XOFFS:
      70:             pbase(p);
      71:
      72:         case OFFS:
      73:             printf("(r%d)", p->n.regno);
      74:             return;
      75:
      76:         case EXTERN:
      77:         case STATIC:
      78:             pbase(p);
      79:             return;
      80:
      81:         case REG:
      82:             printf("r%d", p->n.nloc);
      83:             return;
      84:
      85:         }
      86:         error("Compiler error: pname");
      87:         return;
      88:
      89:     case AMPER:
      90:         putchar('$');
      91:         p = p->t.tr1;
      92:         if (p->t.op==NAME && p->n.class==REG)
      93:             error("Illegal use of register");
      94:         goto loop;
      95:
      96:     case AUTOI:
      97:         printf("(r%d)%s", p->n.nloc, flag==1?"":"+");
      98:         return;
      99:
     100:     case AUTOD:
     101:         printf("%s(r%d)", flag==2?"":"-", p->n.nloc);
     102:         return;
     103:
     104:     case STAR:
     105:         p = p->t.tr1;
     106:         putchar('*');
     107:         goto loop;
     108:
     109:     }
     110:     error("compiler error: bad pname");
     111: }
     112:
     113: pbase(p)
     114: register union tree *p;
     115: {
     116:
     117:     if (p->n.class==SOFFS || p->n.class==STATIC)
     118:         printf("L%d", p->n.nloc);
     119:     else
     120:         printf("%s", p->x.name);
     121: }
     122:
     123: xdcalc(p, nrleft)
     124: register union tree *p;
     125: {
     126:     register d;
     127:
     128:     if (p==NULL)
     129:         return(0);
     130:     d = dcalc(p, nrleft);
     131:     if (d<20 && (p->t.type==CHAR || p->t.type==UNCHAR)) {
     132:         if (nrleft>=1)
     133:             d = 20;
     134:         else
     135:             d = 24;
     136:     }
     137:     return(d);
     138: }
     139:
     140: dcalc(p, nrleft)
     141: register union tree *p;
     142: {
     143:     register union tree *p1;
     144:
     145:     if (p==NULL)
     146:         return(0);
     147:     switch (p->t.op) {
     148:
     149:     case NAME:
     150:         if (p->n.class==REG && p->n.type!=CHAR && p->n.type!=UNCHAR)
     151:             return(9);
     152:
     153:     case AMPER:
     154:     case FCON:
     155:     case LCON:
     156:     case AUTOI:
     157:     case AUTOD:
     158:         return(12);
     159:
     160:     case CON:
     161:     case SFCON:
     162:         if (p->c.value==0)
     163:             return(4);
     164:         if (p->c.value==1)
     165:             return(5);
     166:         if (p->c.value > 0)
     167:             return(8);
     168:         return(12);
     169:
     170:     case STAR:
     171:         p1 = p->t.tr1;
     172:         if (p1->t.op==NAME||p1->t.op==CON||p1->t.op==AUTOI||p1->t.op==AUTOD)
     173:             if (p->t.type!=LONG && p->t.type!=UNLONG)
     174:                 return(12);
     175:     }
     176:     if (p->t.type==LONG || p->t.type==UNLONG)
     177:         nrleft--;
     178:     return(p->t.degree <= nrleft? 20: 24);
     179: }
     180:
     181: notcompat(p, ast, deg, op)
     182: register union tree *p;
     183: {
     184:     unsigned register at, st;
     185:
     186:     at = p->t.type;
     187:     /*
     188: 	 * an e or n UNCHAR is to be considered an UNSIGNED,
     189: 	 * as long as it is not pointed to.
     190: 	 */
     191:     if (at==UNCHAR && deg<0100 && deg>=20)
     192:         at = UNSIGN;
     193:     st = ast;
     194:     if (st==0)      /* word, byte */
     195:         return(at!=CHAR && at!=INT && at!=UNSIGN && at<PTR);
     196:     if (st==1)      /* word */
     197:         return(at!=INT && at!=UNSIGN && at<PTR);
     198:     if (st==9 && (at&XTYPE))
     199:         return(0);
     200:     st -= 2;
     201:     if ((at&(~(TYPE+XTYPE))) != 0)
     202:         at = 020;
     203:     if ((at&(~TYPE)) != 0)
     204:         at = at&TYPE | 020;
     205:     if (st==FLOAT && at==DOUBLE)
     206:         at = FLOAT;
     207:     if (p->t.op==NAME && p->n.class==REG && op==ASSIGN && st==CHAR)
     208:         return(0);
     209:     return(st != at);
     210: }
     211:
     212: prins(op, c, itable, lbl)
     213: struct instab *itable;
     214: {
     215:     extern char jmijne[];
     216:     register struct instab  *insp;
     217:     register char   *ip;
     218:     register int    skip;
     219:
     220:     skip = 0;
     221:     for (insp = itable; insp->iop != 0; insp++) {
     222:         if (insp->iop == op) {
     223:             ip = c ? insp->str2: insp->str1;
     224:             if (!ip)
     225:                 break;
     226:             if (ip != jmijne) {
     227:                 printf(ip, lbl);
     228:             }
     229:             else {
     230:                 skip = isn++;
     231:                 printf(ip, skip);
     232:             }
     233:             return(skip);
     234:         }
     235:     }
     236:     error("No match' for op %d", op);
     237:     return(skip);
     238: }
     239:
     240: collcon(p)
     241: register union tree *p;
     242: {
     243:     register op;
     244:
     245:     if (p==NULL)
     246:         return(0);
     247:     if (p->t.op==STAR) {
     248:         if (p->t.type==LONG+PTR || p->t.type==UNLONG+PTR) /* avoid *x(r); *x+2(r) */
     249:             return(0);
     250:         p = p->t.tr1;
     251:     }
     252:     if (p->t.op==PLUS) {
     253:         op = p->t.tr2->t.op;
     254:         if (op==CON || op==AMPER)
     255:             return(1);
     256:     }
     257:     return(0);
     258: }
     259:
     260: isfloat(t)
     261: register union tree *t;
     262: {
     263:
     264:     if ((opdope[t->t.op]&RELAT)!=0)
     265:         t = t->t.tr1;
     266:     if (t->t.type==FLOAT || t->t.type==DOUBLE) {
     267:         nfloat = 1;
     268:         return('f');
     269:     }
     270:     return(0);
     271: }
     272:
     273: oddreg(t, reg)
     274: register union tree *t;
     275: register reg;
     276: {
     277:
     278:     if (!isfloat(t)) {
     279:         if (opdope[t->t.op]&RELAT) {
     280:             if (t->t.tr1->t.type==LONG || t->t.tr1->t.type==UNLONG)
     281:                 return((reg+1) & ~01);
     282:             return(reg);
     283:         }
     284:         switch(t->t.op) {
     285:         case ULLSHIFT:
     286:         case UASLSHL:
     287:         case LLSHIFT:
     288:         case ASLSHL:
     289:         case PTOI:
     290:             return((reg+1)&~01);
     291:
     292:         case DIVIDE:
     293:         case MOD:
     294:         case ASDIV:
     295:         case ASMOD:
     296:         case ULSH:
     297:         case ASULSH:
     298:             reg++;
     299:
     300:         case TIMES:
     301:         case ASTIMES:
     302:             return(reg|1);
     303:         }
     304:     }
     305:     return(reg);
     306: }
     307:
     308: arlength(t)
     309: {
     310:     if (t>=PTR)
     311:         return(2);
     312:     switch(t) {
     313:
     314:     case INT:
     315:     case CHAR:
     316:     case UNSIGN:
     317:     case UNCHAR:
     318:         return(2);
     319:
     320:     case UNLONG:
     321:     case LONG:
     322:         return(4);
     323:
     324:     case FLOAT:
     325:     case DOUBLE:
     326:         return(8);
     327:     }
     328:     error("botch: peculiar type %d", t);
     329:     return(1024);
     330: }
     331:
     332: /*
     333:  * Strings for switch code.
     334:  */
     335:
     336: /*
     337:  * Modified Memorial day May 80 to uniquely identify switch tables
     338:  * (as on Vax) so a shell script can optionally include them in RO code.
     339:  * This is useful in overlays to reduce the size of data space load.
     340:  * wfj 5/80
     341:  */
     342: char    dirsw[] = {"\
     343: cmp	r0,$%o\n\
     344: jhi	L%d\n\
     345: asl	r0\n\
     346: jmp	*L%d(r0)\n\
     347: \t.data\n\
     348: L%d:\
     349: " };
     350:
     351: char    hashsw[] = {"\
     352: mov	r0,r1\n\
     353: clr	r0\n\
     354: div	$%o,r0\n\
     355: asl	r1\n\
     356: jmp	*L%d(r1)\n\
     357: \t.data\n\
     358: L%d:\
     359: "};
     360:
     361: /*
     362:  * If the unsigned casts below won't compile,
     363:  * try using the calls to lrem and ldiv.
     364:  */
     365:
     366: pswitch(afp, alp, deflab)
     367: struct swtab *afp, *alp;
     368: {
     369:     int ncase, i, j, tabs, worst, best, range;
     370:     register struct swtab *swp, *fp, *lp;
     371:     int *poctab;
     372:
     373:     fp = afp;
     374:     lp = alp;
     375:     if (fp==lp) {
     376:         printf("jbr	L%d\n", deflab);
     377:         return;
     378:     }
     379:     isn++;
     380:     if (sort(fp, lp))
     381:         return;
     382:     ncase = lp-fp;
     383:     lp--;
     384:     range = lp->swval - fp->swval;
     385:     /* direct switch */
     386:     if (range>0 && range <= 3*ncase) {
     387:         if (fp->swval)
     388:             printf("sub	$%o,r0\n", UNS(fp->swval));
     389:         printf(dirsw, UNS(range), deflab, isn, isn);
     390:         isn++;
     391:         for (i=fp->swval; ; i++) {
     392:             if (i==fp->swval) {
     393:                 printf("L%d\n", fp->swlab);
     394:                 if (fp==lp)
     395:                     break;
     396:                 fp++;
     397:             } else
     398:                 printf("L%d\n", deflab);
     399:         }
     400:         printf(".text\n");
     401:         return;
     402:     }
     403:     /* simple switch */
     404:     if (ncase<10) {
     405:         for (fp = afp; fp<=lp; fp++)
     406:             breq(fp->swval, fp->swlab);
     407:         printf("jbr	L%d\n", deflab);
     408:         return;
     409:     }
     410:     /* hash switch */
     411:     best = 077777;
     412:     poctab = (int *)getblk(((ncase+2)/2) * sizeof(*poctab));
     413:     for (i=ncase/4; i<=ncase/2; i++) {
     414:         for (j=0; j<i; j++)
     415:             poctab[j] = 0;
     416:         for (swp=fp; swp<=lp; swp++)
     417:             /* lrem(0, swp->swval, i) */
     418:             poctab[(unsigned)swp->swval%i]++;
     419:         worst = 0;
     420:         for (j=0; j<i; j++)
     421:             if (poctab[j]>worst)
     422:                 worst = poctab[j];
     423:         if (i*worst < best) {
     424:             tabs = i;
     425:             best = i*worst;
     426:         }
     427:     }
     428:     i = isn++;
     429:     printf(hashsw, UNS(tabs), i, i);
     430:     isn++;
     431:     for (i=0; i<tabs; i++)
     432:         printf("L%d\n", isn+i);
     433:     printf(".text\n");
     434:     for (i=0; i<tabs; i++) {
     435:         printf("L%d:", isn++);
     436:         for (swp=fp; swp<=lp; swp++) {
     437:             /* lrem(0, swp->swval, tabs) */
     438:             if ((unsigned)swp->swval%tabs == i) {
     439:                 /* ldiv(0, swp->swval, tabs) */
     440:                 breq((int)((unsigned)swp->swval/tabs), swp->swlab);
     441:             }
     442:         }
     443:         printf("jbr	L%d\n", deflab);
     444:     }
     445: }
     446:
     447: breq(v, l)
     448: {
     449:     if (v==0)
     450:         printf("tst	r0\n");
     451:     else
     452:         printf("cmp	r0,$%o\n", UNS(v));
     453:     printf("jeq	L%d\n", l);
     454: }
     455:
     456: sort(afp, alp)
     457: struct swtab *afp, *alp;
     458: {
     459:     register struct swtab *cp, *fp, *lp;
     460:     int intch, t;
     461:
     462:     fp = afp;
     463:     lp = alp;
     464:     while (fp < --lp) {
     465:         intch = 0;
     466:         for (cp=fp; cp<lp; cp++) {
     467:             if (cp->swval == cp[1].swval) {
     468:                 error("Duplicate case (%d)", cp->swval);
     469:                 return(1);
     470:             }
     471:             if (cp->swval > cp[1].swval) {
     472:                 intch++;
     473:                 t = cp->swval;
     474:                 cp->swval = cp[1].swval;
     475:                 cp[1].swval = t;
     476:                 t = cp->swlab;
     477:                 cp->swlab = cp[1].swlab;
     478:                 cp[1].swlab = t;
     479:             }
     480:         }
     481:         if (intch==0)
     482:             break;
     483:     }
     484:     return(0);
     485: }
     486:
     487: ispow2(tree)
     488: register union tree *tree;
     489: {
     490:     register int d;
     491:
     492:     if (!isfloat(tree) && tree->t.tr2->t.op==CON) {
     493:         d = tree->t.tr2->c.value;
     494:         if (d>1 && (d&(d-1))==0)
     495:             return(d);
     496:     }
     497:     return(0);
     498: }
     499:
     500: union tree *
     501: pow2(tree)
     502: register union tree *tree;
     503: {
     504:     register int d, i;
     505:
     506:     if (d = ispow2(tree)) {
     507:         for (i=0; (d>>=1)!=0; i++);
     508:         tree->t.tr2->c.value = i;
     509:         switch (tree->t.op) {
     510:
     511:         case TIMES:
     512:             tree->t.op = LSHIFT;
     513:             break;
     514:
     515:         case ASTIMES:
     516:             tree->t.op = ASLSH;
     517:             break;
     518:
     519:         case PTOI:
     520:             if (i==1 && tree->t.tr1->t.op==MINUS && !isconstant(tree->t.tr1->t.tr2)) {
     521:                 tree->t.op = PTOI1;
     522:                 tree->t.tr1 = tnode(LTOI, INT, tree->t.tr1, TNULL);
     523:                 return(optim(tree));
     524:             }
     525:             tree->t.op = LLSHIFT;
     526:             tree->t.tr2->c.value = -i;
     527:             i = tree->t.type;
     528:             tree->t.type = LONG;
     529:             tree = tnode(LTOI, i, tree, TNULL);
     530:             break;
     531:
     532:         case DIVIDE:
     533:             tree->t.op = ULSH;
     534:             tree->t.tr2->c.value = -i;
     535:             break;
     536:
     537:         case ASDIV:
     538:             tree->t.op = ASULSH;
     539:             tree->t.tr2->c.value = -i;
     540:             break;
     541:
     542:         case MOD:
     543:             tree->t.op = AND;
     544:             tree->t.tr2->c.value = (1<<i)-1;
     545:             break;
     546:
     547:         case ASMOD:
     548:             tree->t.op = ASAND;
     549:             tree->t.tr2->c.value = (1<<i)-1;
     550:             break;
     551:
     552:         default:
     553:             error("pow2 botch");
     554:         }
     555:         tree = optim(tree);
     556:     }
     557:     return(tree);
     558: }
     559:
     560: cbranch(atree, lbl, cond, reg)
     561: union tree *atree;
     562: register lbl, reg;
     563: {
     564:     int l1, op;
     565:     register union tree *tree;
     566:
     567: again:
     568:     if ((tree=atree)==NULL)
     569:         return;
     570:     switch(tree->t.op) {
     571:
     572:     case LOGAND:
     573:         if (cond) {
     574:             cbranch(tree->t.tr1, l1=isn++, 0, reg);
     575:             cbranch(tree->t.tr2, lbl, 1, reg);
     576:             label(l1);
     577:         } else {
     578:             cbranch(tree->t.tr1, lbl, 0, reg);
     579:             cbranch(tree->t.tr2, lbl, 0, reg);
     580:         }
     581:         return;
     582:
     583:     case LOGOR:
     584:         if (cond) {
     585:             cbranch(tree->t.tr1, lbl, 1, reg);
     586:             cbranch(tree->t.tr2, lbl, 1, reg);
     587:         } else {
     588:             cbranch(tree->t.tr1, l1=isn++, 1, reg);
     589:             cbranch(tree->t.tr2, lbl, 0, reg);
     590:             label(l1);
     591:         }
     592:         return;
     593:
     594:     case EXCLA:
     595:         cbranch(tree->t.tr1, lbl, !cond, reg);
     596:         return;
     597:
     598:     case SEQNC:
     599:         rcexpr(tree->t.tr1, efftab, reg);
     600:         atree = tree->t.tr2;
     601:         goto again;
     602:
     603:     case ITOL:
     604:         tree = tree->t.tr1;
     605:         break;
     606:
     607:     case QUEST:
     608:         l1 = isn;
     609:         isn += 2;
     610:         cbranch(tree->t.tr1, l1, 0, reg);
     611:         cbranch(tree->t.tr2->t.tr1, lbl, cond, reg);
     612:         branch(l1+1, 0, 0);
     613:         label(l1);
     614:         cbranch(tree->t.tr2->t.tr2, lbl, cond, reg);
     615:         label(l1+1);
     616:         return;
     617:
     618:     }
     619:     op = tree->t.op;
     620:     if (opdope[op]&RELAT
     621:      && tree->t.tr1->t.op==ITOL && tree->t.tr2->t.op==ITOL
     622:      && uns(tree->t.tr1->t.tr1) == uns(tree->t.tr2->t.tr1)) {
     623:         tree->t.tr1 = tree->t.tr1->t.tr1;
     624:         tree->t.tr2 = tree->t.tr2->t.tr1;
     625:         if (op>=LESSEQ && op<=GREAT
     626:          && uns(tree->t.tr1))
     627:             tree->t.op = op = op+LESSEQP-LESSEQ;
     628:     }
     629:     if (tree->t.type==LONG || tree->t.type==UNLONG
     630:       || opdope[op]&RELAT&&(tree->t.tr1->t.type==LONG || tree->t.tr1->t.type==UNLONG)) {
     631:         longrel(tree, lbl, cond, reg);
     632:         return;
     633:     }
     634:     rcexpr(tree, cctab, reg);
     635:     op = tree->t.op;
     636:     if ((opdope[op]&RELAT)==0)
     637:         op = NEQUAL;
     638:     else {
     639:         l1 = tree->t.tr2->t.op;
     640:         if ((l1==CON || l1==SFCON) && tree->t.tr2->c.value==0)
     641:             op += 200;      /* special for ptr tests */
     642:         else
     643:             op = maprel[op-EQUAL];
     644:     }
     645:     if (isfloat(tree))
     646:         printf("cfcc\n");
     647:     branch(lbl, op, !cond);
     648: }
     649:
     650: branch(lbl, aop, c)
     651: {
     652:     register int    op,
     653:             skip;
     654:
     655:     if(op = aop) {
     656:         skip = prins(op, c, branchtab, lbl);
     657:     } else {
     658:         printf("jbr");
     659:         skip = 0;
     660:     }
     661:     if (skip)
     662:         printf("\tL%d\nL%d:", lbl, skip);
     663:     else
     664:         printf("\tL%d\n", lbl);
     665: }
     666:
     667: longrel(atree, lbl, cond, reg)
     668: union tree *atree;
     669: {
     670:     int xl1, xl2, xo, xz;
     671:     register int op, isrel;
     672:     register union tree *tree;
     673:
     674:     if (reg&01)
     675:         reg++;
     676:     reorder(&atree, cctab, reg);
     677:     tree = atree;
     678:     isrel = 0;
     679:     if (opdope[tree->t.op]&RELAT) {
     680:         isrel++;
     681:         op = tree->t.op;
     682:     } else
     683:         op = NEQUAL;
     684:     if (!cond)
     685:         op = notrel[op-EQUAL];
     686:     xl1 = xlab1;
     687:     xl2 = xlab2;
     688:     xo = xop;
     689:     xlab1 = lbl;
     690:     xlab2 = 0;
     691:     xop = op;
     692:     xz = xzero;
     693:     xzero = !isrel || (tree->t.tr2->t.op==ITOL && tree->t.tr2->t.tr1->t.op==CON
     694:         && tree->t.tr2->t.tr1->c.value==0);
     695:     if (tree->t.op==ANDN) {
     696:         tree->t.op = TAND;
     697:         tree->t.tr2 = optim(tnode(COMPL, LONG, tree->t.tr2, TNULL));
     698:     }
     699:     if (cexpr(tree, cctab, reg) < 0) {
     700:         reg = rcexpr(tree, regtab, reg);
     701:         printf("ashc	$0,r%d\n", reg);
     702:         branch(xlab1, op, 0);
     703:     }
     704:     xlab1 = xl1;
     705:     xlab2 = xl2;
     706:     xop = xo;
     707:     xzero = xz;
     708: }
     709:
     710: /*
     711:  * Tables for finding out how best to do long comparisons.
     712:  * First dimen is whether or not the comparison is with 0.
     713:  * Second is which test: e.g. a>b->
     714:  *	cmp	a,b
     715:  *	bgt	YES		(first)
     716:  *	blt	NO		(second)
     717:  *	cmp	a+2,b+2
     718:  *	bhi	YES		(third)
     719:  *  NO:	...
     720:  * Note some tests may not be needed.
     721:  *
     722:  * EQUAL = 60
     723:  * NEQUAL= 61
     724:  * LESSEQ= 62
     725:  * LESS  = 63
     726:  * GREATEQ=64
     727:  * GREAT  =65
     728:  * LESSEQP=66
     729:  * LESSP  =67
     730:  * GREATQP=68
     731:  * GREATP =69
     732:  *
     733:  * Third dimension (lrtab[][][x]) indexed by "x - EQUAL".
     734:  */
     735: char    lrtab[2][3][10] = {
     736:     0, NEQUAL, LESS, LESS, GREAT, GREAT, LESSP, LESSP, GREATP, GREATP,
     737:     NEQUAL, 0, GREAT, GREAT, LESS, LESS, GREATP, GREATP, LESSP, LESSP,
     738:     EQUAL,NEQUAL,LESSEQP,LESSP, GREATQP,GREATP,LESSEQP,LESSP,GREATQP,GREATP,
     739:
     740:     0, NEQUAL, LESS, LESS,  GREATEQ,GREAT, LESSP, LESSP, GREATQP, GREATP,
     741:     NEQUAL, 0, GREAT, 0, 0, LESS, GREATP, 0, 0, LESSP,
     742:     EQUAL,  NEQUAL, EQUAL,  0, 0, NEQUAL, EQUAL, 0, 0, NEQUAL,
     743: };
     744:
     745: xlongrel(f)
     746: {
     747:     register int op, bno;
     748:
     749:     op = xop;
     750:     if (f==0) {
     751:         if (bno = lrtab[xzero][0][op-EQUAL])
     752:             branch(xlab1, bno, 0);
     753:         if (bno = lrtab[xzero][1][op-EQUAL]) {
     754:             xlab2 = isn++;
     755:             branch(xlab2, bno, 0);
     756:         }
     757:         if (lrtab[xzero][2][op-EQUAL]==0)
     758:             return(1);
     759:     } else {
     760:         branch(xlab1, lrtab[xzero][2][op-EQUAL], 0);
     761:         if (xlab2)
     762:             label(xlab2);
     763:     }
     764:     return(0);
     765: }
     766:
     767: label(l)
     768: {
     769:     printf("L%d:", l);
     770: }
     771:
     772: popstk(a)
     773: {
     774:     switch(a) {
     775:
     776:     case 0:
     777:         return;
     778:
     779:     case 2:
     780:         printf("tst	(sp)+\n");
     781:         return;
     782:
     783:     case 4:
     784:         printf("cmp	(sp)+,(sp)+\n");
     785:         return;
     786:     }
     787:     printf("add	$%o,sp\n", UNS(a));
     788: }
     789:
     790: werror(s)
     791: char *s;
     792: {
     793:
     794:     fprintf(stderr, "%d: %s\n",line,s);
     795: }
     796:
     797: /* VARARGS1 */
     798: error(s, p1, p2, p3, p4, p5, p6)
     799: char *s;
     800: {
     801:
     802:     nerror++;
     803:     fprintf(stderr, "%d: ", line);
     804:     fprintf(stderr, s, p1, p2, p3, p4, p5, p6);
     805:     putc('\n', stderr);
     806: }
     807:
     808: psoct(an)
     809: {
     810:     register int n;
     811:     register char *sign;
     812:
     813:     sign = "";
     814:     if ((n = an) < 0) {
     815:         n = -n;
     816:         sign = "-";
     817:     }
     818:     printf("%s%o", sign, n);
     819: }
     820:
     821: /*
     822:  * Read in an intermediate file.
     823:  */
     824: #define STKS    100
     825: getree()
     826: {
     827:     union tree *expstack[STKS], **sp;
     828:     register union tree *tp;
     829:     register int t, op;
     830:     char s[80];     /* big for asm() stuff & long variable names */
     831:     struct swtab *swp;
     832:     long outloc;
     833:     int lbl, cond, lbl2, lbl3;
     834:     double atof();
     835:
     836:     curbase = funcbase;
     837:     sp = expstack;
     838:     for (;;) {
     839:         if (sp >= &expstack[STKS])
     840:             error("Stack overflow botch");
     841:         op = geti();
     842:         if ((op&0177400) != 0177000) {
     843:             error("Intermediate file error");
     844:             exit(1);
     845:         }
     846:         lbl = 0;
     847:         switch(op &= 0377) {
     848:
     849:     case SINIT:
     850:         printf("%o\n", UNS(geti()));
     851:         break;
     852:
     853:     case EOFC:
     854:         return;
     855:
     856:     case BDATA:
     857:         if (geti() == 1) {
     858:             printf(".byte ");
     859:             for (;;)  {
     860:                 printf("%o", UNS(geti()));
     861:                 if (geti() != 1)
     862:                     break;
     863:                 printf(",");
     864:             }
     865:             printf("\n");
     866:         }
     867:         break;
     868:
     869:     case PROG:
     870:         printf(".text\n");
     871:         break;
     872:
     873:     case DATA:
     874:         printf(".data\n");
     875:         break;
     876:
     877:     case BSS:
     878:         printf(".bss\n");
     879:         break;
     880:
     881:     case SYMDEF:
     882:         outname(s);
     883:         printf(".globl\t%s\n", s);
     884:         sfuncr.nloc = 0;
     885:         break;
     886:
     887:     case RETRN:
     888:         printf("jmp\tcret\n");
     889:         break;
     890:
     891:     case CSPACE:
     892:         outname(s);
     893:         printf(".comm\t%s,%o\n", s, UNS(geti()));
     894:         break;
     895:
     896:     case SSPACE:
     897:         printf(".=.+%o\n", UNS(t=geti()));
     898:         totspace += (unsigned)t;
     899:         break;
     900:
     901:     case EVEN:
     902:         printf(".even\n");
     903:         break;
     904:
     905:     case SAVE:
     906:         printf("jsr	r5,csv\n");
     907:         break;
     908:
     909:     case SETSTK:
     910:         t = geti();
     911:         if (t==2)
     912:             printf("tst	-(sp)\n");
     913:         else if (t != 0)
     914:             printf("sub	$%o,sp\n", UNS(t));
     915:         break;
     916:
     917:     case PROFIL:
     918:         t = geti();
     919:         outname(s);
     920:         printf("mov	$L%d,r0\njsr	pc,mcount\n", t);
     921:         printf(".data\nL%d:%s+1\n.text\n", t, s);
     922:         break;
     923:
     924:     case ASSEM:
     925:         outname(s);
     926:         printf("%s\n", s);
     927:         break;
     928:
     929:     case SNAME:
     930:         outname(s);
     931:         printf("~%s=L%d\n", s+1, geti());
     932:         break;
     933:
     934:     case ANAME:
     935:         outname(s);
     936:         printf("~%s=%o\n", s+1, UNS(geti()));
     937:         break;
     938:
     939:     case RNAME:
     940:         outname(s);
     941:         printf("~%s=r%d\n", s+1, geti());
     942:         break;
     943:
     944:     case SWIT:
     945:         t = geti();
     946:         line = geti();
     947:         curbase = funcbase;
     948:         while(swp=(struct swtab *)getblk(sizeof(*swp)), swp->swlab = geti())
     949:             swp->swval = geti();
     950:         pswitch((struct swtab *)funcbase, swp, t);
     951:         break;
     952:
     953:     case C3BRANCH:      /* for fortran [sic] */
     954:         lbl = geti();
     955:         lbl2 = geti();
     956:         lbl3 = geti();
     957:         goto xpr;
     958:
     959:     case CBRANCH:
     960:         lbl = geti();
     961:         cond = geti();
     962:
     963:     case EXPR:
     964:     xpr:
     965:         line = geti();
     966:         if (sp != &expstack[1]) {
     967:             error("Expression input botch");
     968:             exit(1);
     969:         }
     970:         --sp;
     971:         regpanic = 0;
     972:         if (setjmp(jmpbuf)) {
     973:             regpanic = 10;
     974:             fseek(stdout, outloc, 0);
     975:         }
     976:         nstack = 0;
     977:         panicposs = 0;
     978:         *sp = tp = optim(*sp);
     979:         if (regpanic==0 && panicposs)
     980:             outloc = ftell(stdout);
     981:         if (op==CBRANCH)
     982:             cbranch(tp, lbl, cond, 0);
     983:         else if (op==EXPR)
     984:             rcexpr(tp, efftab, 0);
     985:         else {
     986:             if (tp->t.type==LONG || tp->t.type==UNLONG) {
     987:                 rcexpr(tnode(RFORCE, tp->t.type, tp, TNULL), efftab, 0);
     988:                 printf("ashc	$0,r0\n");
     989:             } else {
     990:                 rcexpr(tp, cctab, 0);
     991:                 if (isfloat(tp))
     992:                     printf("cfcc\n");
     993:             }
     994:             printf("jgt	L%d\n", lbl3);
     995:             printf("jlt	L%d\njbr	L%d\n", lbl, lbl2);
     996:         }
     997:         curbase = funcbase;
     998:         break;
     999:
    1000:     case NAME:
    1001:         t = geti();
    1002:         if (t==EXTERN) {
    1003:             tp = getblk(sizeof(struct xtname));
    1004:             tp->t.type = geti();
    1005:             outname(s);
    1006:             tp->x.name = (char *)getblk(strlen(s) + 1);
    1007:             strcpy(tp->x.name, s);
    1008:         } else {
    1009:             tp = getblk(sizeof(struct tname));
    1010:             tp->t.type = geti();
    1011:             tp->n.nloc = geti();
    1012:         }
    1013:         tp->t.op = NAME;
    1014:         tp->n.class = t;
    1015:         tp->n.regno = 0;
    1016:         tp->n.offset = 0;
    1017:         *sp++ = tp;
    1018:         break;
    1019:
    1020:     case CON:
    1021:         t = geti();
    1022:         *sp++ = tconst(geti(), t);
    1023:         break;
    1024:
    1025:     case LCON:
    1026:         geti(); /* ignore type, assume long */
    1027:         t = geti();
    1028:         op = geti();
    1029:         if (t==0 && op>=0 || t == -1 && op<0) {
    1030:             *sp++ = tnode(ITOL, LONG, tconst(op, INT), TNULL);
    1031:             break;
    1032:         }
    1033:         tp = getblk(sizeof(struct lconst));
    1034:         tp->t.op = LCON;
    1035:         tp->t.type = LONG;
    1036:         tp->l.lvalue = ((long)t<<16) + UNS(op); /* nonportable */
    1037:         *sp++ = tp;
    1038:         break;
    1039:
    1040:     case FCON:
    1041:         t = geti();
    1042:         outname(s);
    1043:         tp = getblk(sizeof(struct ftconst));
    1044:         tp->t.op = FCON;
    1045:         tp->t.type = t;
    1046:         tp->f.value = isn++;
    1047:         tp->f.fvalue = atof(s);
    1048:         *sp++ = tp;
    1049:         break;
    1050:
    1051:     case FSEL:
    1052:         tp = tnode(FSEL, geti(), *--sp, TNULL);
    1053:         t = geti();
    1054:         tp->t.tr2 = tnode(COMMA, INT, tconst(geti(), INT), tconst(t, INT));
    1055:         if (tp->t.tr2->t.tr1->c.value==16)
    1056:             tp = paint(tp->t.tr1, tp->t.type);
    1057:         *sp++ = tp;
    1058:         break;
    1059:
    1060:     case STRASG:
    1061:         tp = getblk(sizeof(struct fasgn));
    1062:         tp->t.op = STRASG;
    1063:         tp->t.type = geti();
    1064:         tp->F.mask = geti();
    1065:         tp->t.tr1 = *--sp;
    1066:         tp->t.tr2 = NULL;
    1067:         *sp++ = tp;
    1068:         break;
    1069:
    1070:     case NULLOP:
    1071:         *sp++ = tnode(0, 0, TNULL, TNULL);
    1072:         break;
    1073:
    1074:     case LABEL:
    1075:         label(geti());
    1076:         break;
    1077:
    1078:     case NLABEL:
    1079:         outname(s);
    1080:         printf("%s:\n", s);
    1081:         break;
    1082:
    1083:     case RLABEL:
    1084:         outname(s);
    1085:         printf("%s:\n~~%s:\n", s, s+1);
    1086:         break;
    1087:
    1088:     case BRANCH:
    1089:         branch(geti(), 0, 0);
    1090:         break;
    1091:
    1092:     case SETREG:
    1093:         nreg = geti()-1;
    1094:         break;
    1095:
    1096:     default:
    1097:         if (opdope[op]&BINARY) {
    1098:             if (sp < &expstack[1]) {
    1099:                 error("Binary expression botch");
    1100:                 exit(1);
    1101:             }
    1102:             tp = *--sp;
    1103:             *sp++ = tnode(op, geti(), *--sp, tp);
    1104:         } else
    1105:             sp[-1] = tnode(op, geti(), sp[-1], TNULL);
    1106:         break;
    1107:     }
    1108:     }
    1109: }
    1110:
    1111: geti()
    1112: {
    1113:     register short i;
    1114:
    1115:     i = getchar() & 0xff;
    1116:     i |= (getchar() & 0xff) << 8;
    1117:     return(i);
    1118: }
    1119:
    1120: static
    1121: outname(s)
    1122: register char *s;
    1123: {
    1124:     register int c;
    1125:
    1126:     while (c = getchar())
    1127:         *s++ = c;
    1128:     *s++ = '\0';
    1129: }
    1130:
    1131: strasg(atp)
    1132: union tree *atp;
    1133: {
    1134:     register union tree *tp;
    1135:     register nwords, i;
    1136:
    1137:     nwords = atp->F.mask/sizeof(short);
    1138:     tp = atp->t.tr1;
    1139:     while (tp->t.op == SEQNC) {
    1140:         rcexpr(tp->t.tr1, efftab, 0);
    1141:         tp = tp->t.tr2;
    1142:     }
    1143:     if (tp->t.op != ASSIGN) {
    1144:         if (tp->t.op==RFORCE) { /* function return */
    1145:             if (sfuncr.nloc==0) {
    1146:                 sfuncr.nloc = isn++;
    1147:                 printf(".bss\nL%d:.=.+%o\n.text\n", sfuncr.nloc,
    1148:                     UNS(nwords*sizeof(short)));
    1149:             }
    1150:             atp->t.tr1 = tnode(ASSIGN, STRUCT, (union tree *)&sfuncr, tp->t.tr1);
    1151:             strasg(atp);
    1152:             printf("mov	$L%d,r0\n", sfuncr.nloc);
    1153:             return;
    1154:         }
    1155:         if (tp->t.op==CALL) {
    1156:             rcexpr(tp, efftab, 0);
    1157:             return;
    1158:         }
    1159:         error("Illegal structure operation");
    1160:         return;
    1161:     }
    1162:     tp->t.tr2 = strfunc(tp->t.tr2);
    1163:     if (nwords==1)
    1164:         paint(tp, INT);
    1165:     else if (nwords==sizeof(short))
    1166:         paint(tp, LONG);
    1167:     else {
    1168:         if (tp->t.tr1->t.op!=NAME && tp->t.tr1->t.op!=STAR
    1169:          || tp->t.tr2->t.op!=NAME && tp->t.tr2->t.op!=STAR) {
    1170:             error("unimplemented structure assignment");
    1171:             return;
    1172:         }
    1173:         tp->t.tr1 = tnode(AMPER, STRUCT+PTR, tp->t.tr1, TNULL);
    1174:         tp->t.tr2 = tnode(AMPER, STRUCT+PTR, tp->t.tr2, TNULL);
    1175:         tp->t.op = STRSET;
    1176:         tp->t.type = STRUCT+PTR;
    1177:         tp = optim(tp);
    1178:         rcexpr(tp, efftab, 0);
    1179:         if (nwords < 7) {
    1180:             for (i=0; i<nwords; i++)
    1181:                 printf("mov	(r1)+,(r0)+\n");
    1182:             return;
    1183:         }
    1184:         if (nreg<=1)
    1185:             printf("mov	r2,-(sp)\n");
    1186:         printf("mov	$%o,r2\n", UNS(nwords));
    1187:         printf("L%d:mov	(r1)+,(r0)+\ndec\tr2\njne\tL%d\n", isn, isn);
    1188:         isn++;
    1189:         if (nreg<=1)
    1190:             printf("mov	(sp)+,r2\n");
    1191:         return;
    1192:     }
    1193:     rcexpr(tp, efftab, 0);
    1194: }
    1195:
    1196: /*
    1197:  * Reduce the degree-of-reference by one.
    1198:  * e.g. turn "ptr-to-int" into "int".
    1199:  */
    1200: decref(t)
    1201: register t;
    1202: {
    1203:     if ((t & ~TYPE) == 0) {
    1204:         error("Illegal indirection");
    1205:         return(t);
    1206:     }
    1207:     return(((unsigned)t>>TYLEN) & ~TYPE | t&TYPE);
    1208: }
    1209:
    1210: /*
    1211:  * Increase the degree of reference by
    1212:  * one; e.g. turn "int" to "ptr-to-int".
    1213:  */
    1214: incref(t)
    1215: {
    1216:     return(((t&~TYPE)<<TYLEN) | (t&TYPE) | PTR);
    1217: }

#### Defined functions

arlength defined in line 308; used 1 times

- in /usr/src/lib/ccom/c10.c line 1230

branch defined in line 650; used 7 times

- in line 612, 647, 702, 752-760(3), 1089

breq defined in line 447; used 2 times

- in line 406, 440

cbranch defined in line 560; used 13 times

- in line 574-579(4), 585-589(4), 595, 610-614(3), 982

collcon defined in line 240; used 2 times

- in /usr/src/lib/ccom/c10.c line 732, 818

dcalc defined in line 140; used 7 times

- in line 130
- in /usr/src/lib/ccom/c10.c line 118, 141, 840, 1169
- in /usr/src/lib/ccom/c12.c line 138, 738

decref defined in line 1200; never used
degree defined in line 7; used 22 times

- in line 29, 178
- in /usr/src/lib/ccom/c12.c line 130(2), 142-143(2), 176, 186-191(2), 292, 451, 587(2), 725, 733, 740-742(2), 759(2), 1101-1103(2), 1122

error defined in line 798; used 15 times

- in line 64, 86, 93, 110, 236, 328, 468, 553, 840-843(2), 967, 1099, 1159, 1170, 1204

geti defined in line 1111; used 42 times

- in line 841, 850, 857-861(3), 893-897(2), 910, 918, 931-965(13), 1001-1004(2), 1010-1011(2), 1021-1028(5), 1041, 1052-1054(3), 1063-1064(2), 1075, 1089-1093(2), 1103-1105(2)

getree defined in line 825; used 2 times

- in /usr/src/lib/ccom/c10.c line 62, 80

incref defined in line 1214; never used
isfloat defined in line 260; used 12 times

- in line 278, 492, 645, 991
- in /usr/src/lib/ccom/c10.c line 410, 619, 680, 971, 1228, 1370
- in /usr/src/lib/ccom/c12.c line 664, 1083

ispow2 defined in line 487; used 5 times

- in line 506
- in /usr/src/lib/ccom/c10.c line 979, 1010
- in /usr/src/lib/ccom/c12.c line 205, 758

label defined in line 767; used 6 times

- in line 576, 590, 613-615(2), 762, 1075

longrel defined in line 667; used 1 times

- in line 631

notcompat defined in line 181; used 2 times

- in /usr/src/lib/ccom/c10.c line 150, 156

oddreg defined in line 273; used 2 times

- in /usr/src/lib/ccom/c10.c line 508, 756

outname defined in line 1120; used 11 times

- in line 882, 892, 919, 925-940(4), 1005, 1042, 1079-1084(2)

pbase defined in line 113; used 2 times

- in line 70, 78

pname defined in line 32; used 3 times

- in /usr/src/lib/ccom/c10.c line 648, 827, 1288

popstk defined in line 772; used 1 times

- in /usr/src/lib/ccom/c10.c line 330

pow2 defined in line 500; used 4 times

- in /usr/src/lib/ccom/c1.h line 153
- in /usr/src/lib/ccom/c10.c line 376, 981
- in /usr/src/lib/ccom/c12.c line 206

prins defined in line 212; used 2 times

- in line 656
- in /usr/src/lib/ccom/c10.c line 657

psoct defined in line 808; used 3 times

- in line 48, 60
- in /usr/src/lib/ccom/c10.c line 825

pswitch defined in line 366; used 1 times

- in line 950

sort defined in line 456; used 1 times

- in line 380

strasg defined in line 1131; used 2 times

- in line 1151
- in /usr/src/lib/ccom/c10.c line 237

werror defined in line 790; never used
xdcalc defined in line 123; used 4 times

- in /usr/src/lib/ccom/c10.c line 158, 759-760(2), 991

xlongrel defined in line 745; used 1 times

- in /usr/src/lib/ccom/c10.c line 897

#### Defined variables

dirsw defined in line 342; used 1 times

- in line 389

hashsw defined in line 351; used 1 times

- in line 429

lrtab defined in line 735; used 4 times

- in line 751-760(4)

#### Defined macros

STKS defined in line 824; used 2 times

- in line 827, 839

Last modified: 1993-06-03 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 3342 |