Annotation of researchv10no/cmd/PDP11/11c/c11.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.