Annotation of researchv10no/cmd/PDP11/11c/c11.c, revision 1.1.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.