Annotation of coherent/b/bin/c/n1/out.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * The routines in this file perform code output.
                      3:  * That is, they walk down a selected tree,
                      4:  * expanding the code patterns and filling in the blanks.
                      5:  */
                      6: 
                      7: #ifdef   vax
                      8: #include "INC$LIB:cc1.h"
                      9: #else
                     10: #include "cc1.h"
                     11: #endif
                     12: 
                     13: /*
                     14:  * Code output.
                     15:  * All registers have been set up by selection.
                     16:  * A pointer to the selected macro has been stashed in the tree.
                     17:  * Walk down the tree, putting out the required code.
                     18:  * It would be nice if select and this guy could be one routine.
                     19:  */
                     20: output(tp, c, s, n)
                     21: register TREE *tp;
                     22: {
                     23:        register TREE *ap;
                     24:        register op;
                     25:        int lab0, lab1, rel;
                     26: 
                     27: again:
                     28: #if !TINY
                     29:        if (oflag > 1)
                     30:                snapf("output(%P, %C, %d, L%d); %A\n",
                     31:                        tp, c, s, n, tp->t_op);
                     32: #endif
                     33:        if ((op=tp->t_op) == COMMA) {
                     34:                output(tp->t_lp, MEFFECT, 0, 0);
                     35:                tp = tp->t_rp;
                     36:                goto again;
                     37:        }
                     38:        if (op == QUEST) {
                     39:                lab0 = newlab();
                     40:                lab1 = newlab();
                     41:                output(tp->t_lp, MFLOW, 0, lab0);
                     42:                ap = tp->t_rp;
                     43:                output(ap->t_lp, c, s, n);
                     44:                genubr(lab1);
                     45:                genlab(lab0);
                     46:                output(ap->t_rp, c, s, n);
                     47:                genlab(lab1);
                     48:                return;
                     49:        }
                     50:        if (c == MFLOW) {
                     51:                if (op == NOT) {
                     52:                        s = !s;
                     53:                        tp = tp->t_lp;
                     54:                        goto again;
                     55:                }
                     56:                if (op == LEAF) {
                     57:                        ap = tp->t_lp;
                     58:                        if (ap->t_op==ICON || ap->t_op==LCON) {
                     59:                                if ((grabnval(ap)!=0) == s)
                     60:                                        genubr(n);
                     61:                                return;
                     62:                        }
                     63:                }
                     64:                if (op==ANDAND || op==OROR) {
                     65:                        if ((op==OROR) == s) {
                     66:                                output(tp->t_lp, MFLOW, s, n);
                     67:                                output(tp->t_rp, MFLOW, s, n);
                     68:                                return;
                     69:                        }
                     70:                        lab0 = newlab();
                     71:                        output(tp->t_lp, MFLOW, !s, lab0);
                     72:                        output(tp->t_rp, MFLOW,  s, n);
                     73:                        genlab(lab0);
                     74:                        return;
                     75:                }
                     76:                rel = NE;
                     77:                if (isrelop(op)) {
                     78:                        rel = op;
                     79:                        if (isnval(tp->t_rp, 0)
                     80:                         && tp->t_lp->t_op != QUEST) {
                     81:                                if (rel == ULE)
                     82:                                        rel = EQ;
                     83:                                else if (rel == UGT)
                     84:                                        rel = NE;
                     85:                                tp = tp->t_lp;
                     86:                                ap = tp;
                     87:                                while ((op=ap->t_op) == COMMA)
                     88:                                        ap = ap->t_rp;
                     89:                                if (isrelop(op) || isflow(op)) {
                     90:                                        switch (rel) {
                     91:        
                     92:                                        case EQ:
                     93:                                        case LE:
                     94:                                        case ULE:
                     95:                                                s = !s;
                     96:                                        case NE:
                     97:                                        case GT:
                     98:                                        case UGT:
                     99:                                                goto again;
                    100:                                        }
                    101:                                }
                    102:                        }
                    103:                }
                    104:                if (s == 0)
                    105:                        rel = otherel[rel-EQ];
                    106:                while ((op=tp->t_op) == COMMA) {
                    107:                        output(tp->t_lp, MEFFECT, 0, 0);
                    108:                        tp = tp->t_rp;
                    109:                }
                    110:                c = MEQ + rel - EQ;
                    111:                if (op == QUEST)
                    112:                        goto again;
                    113:        }
                    114:        if (op == CALL) {
                    115:                outcall(tp, c, n);
                    116:                return;
                    117:        }
                    118:        if (op == FIXUP) {
                    119:                output(tp->t_lp, MRVALUE, 0, 0);
                    120:                tp->t_lp->t_op  = REG;
                    121:                tp->t_lp->t_reg = tp->t_lp->t_rreg;
                    122:                walk(tp, amd);
                    123:        }
                    124:        outtree(tp, c, n);
                    125: }
                    126: 
                    127: /*
                    128:  * This routine does the general cases of code output.
                    129:  * It generates code to output the subgoals,
                    130:  * then expands the code macro for this node.
                    131:  */
                    132: outtree(tp, cxt, lab)
                    133: register TREE *tp;
                    134: {
                    135:        register TREE   *lp, *rp;
                    136:        PAT             *patp;
                    137:        FLAG            lflag, rflag, lpflag, rpflag;
                    138:        TREE            *ap;
                    139:        int             op;             /* Tree operator */
                    140:        int             lab0, lab1;     /* Manufactured labels */
                    141:        unsigned char   *mp;            /* Macro pointer */
                    142:        int             c;              /* Current macro byte */
                    143:        int             false;          /* Conditional macro state */
                    144:        int             opcode;         /* Machine operation */
                    145:        int             opv;            /* Opcode size variant */
                    146:        int             naddr;          /* Number of addresses output */
                    147:        int             nse;            /* Side effect flag */
                    148:        int             star;           /* Indirection of computed address */
                    149:        int             npfx;           /* Number of prefix bytes */
                    150:        unsigned char   pfx[8];         /* Prefix bytes */
                    151:        int             label;          /* jump label */
                    152:        MASK            mask;           /* Bit field mask */
                    153:        TREE            node;           /* Automatic node */
                    154: 
                    155:        /*
                    156:         * Gather flags and types from the tree node.
                    157:         * If the left operand is a FIELD,
                    158:         * pull off the field and make up the appropriate mask.
                    159:         */
                    160: #if !TINY
                    161:        snapfix(&node);
                    162:        if (oflag > 1) {
                    163:                snapf("outtree(%P, %C, L%d);\n", tp, cxt, lab);
                    164:                if (oflag > 2)
                    165:                        snapf("%W%E%W", "Outtree", tp, NULL);
                    166:        }
                    167: #endif
                    168:        if ((patp=tp->t_patp) == NULL) {
                    169: #if    !TINY
                    170:                printf("tp = ");
                    171:                psnap((char *) tp);
                    172:                printf("\n");
                    173: #endif
                    174:                cbotch("no patp");
                    175:        }
                    176:        if ((lp=tp->t_lp)->t_op == FIELD) {
                    177:                mask = ((MASK)01<<lp->t_width) - 1;
                    178:                mask = mask << lp->t_base;
                    179:                lp = lp->t_lp;
                    180:        }
                    181:        lflag = lp->t_flag;
                    182:        lpflag = 0;
                    183:        if (patp->p_lflag != 0)
                    184:                lpflag = flagcache[patp->p_lflag-1];
                    185:        rflag = rpflag = 0;
                    186:        if ((rp=tp->t_rp) != NULL) {
                    187:                rflag = rp->t_flag;
                    188:                if (patp->p_rflag != 0)
                    189:                        rpflag = flagcache[patp->p_rflag-1];
                    190:        }
                    191:        /*
                    192:         * Perform output for any subgoals.
                    193:         * This code is similar to that in select,
                    194:         * but works in exactly the reverse order.
                    195:         */
                    196:        if (selmiss(lpflag, lflag)
                    197:        && islvadr(lpflag) && !isadr(lflag) && !isind(lflag))
                    198:                outofs(lp);
                    199:        if (selmiss(rpflag, rflag)
                    200:        && islvadr(rpflag) && !isadr(rflag) && !isind(rflag))
                    201:                outofs(rp);
                    202:        if (selmiss(lpflag, lflag) && isrvadr(lpflag) && !isadr(lflag)) {
                    203:                ap = lp;
                    204:                if (isofs(lflag))
                    205:                        ap = findoffs(lp);
                    206:                output(ap, MLVALUE, 0, 0);
                    207:                ap->t_op  = REG;
                    208:                ap->t_reg = ap->t_rreg;
                    209:                walk(lp, amd);
                    210:        }
                    211:        if (selmiss(rpflag, rflag) && isrvadr(rpflag) && !isadr(rflag)) {
                    212:                ap = rp;
                    213:                if (isofs(rflag))
                    214:                        ap = findoffs(rp);
                    215:                output(ap, MLVALUE, 0, 0);
                    216:                ap->t_op  = REG;
                    217:                ap->t_reg = ap->t_rreg;
                    218:                walk(rp, amd);
                    219:        }
                    220:        /* BUG - these are not reversed, but maybe another bug, too */
                    221:        if ((rpflag&T_TREG) != 0) {
                    222:                output(rp, MRVALUE, 0, 0);
                    223:                rp->t_op = REG;
                    224:                rp->t_reg = rp->t_rreg;
                    225:                amd(rp, NULL);
                    226:        }
                    227:        if ((lpflag&T_TREG) != 0) {
                    228:                output(lp, MRVALUE, 0, 0);
                    229:                lp->t_op = REG;
                    230:                lp->t_reg = lp->t_rreg;
                    231:                amd(lp, NULL);
                    232:        }
                    233:        if (isind(lflag))
                    234:                outofs(lp);
                    235:        if (isind(rflag))
                    236:                outofs(rp);
                    237:        /*
                    238:         * Expand the code macro.
                    239:         * Handle prefix bytes,
                    240:         * the no side effect flag byte,
                    241:         * the op variant prefix,
                    242:         * jumps to other parts of the table,
                    243:         * and conditional macros.
                    244:         */
                    245: #if    !TINY
                    246:        if (isvariant(VTPROF)) {
                    247:                bput(DLABEL);
                    248:                bput(DC_LINE);
                    249:                iput((ival_t)patp->p_fline);
                    250:                sput(namecache[patp->p_fname]);
                    251:                bput(DT_NONE);
                    252:                iput((ival_t)0);
                    253:        }
                    254: #endif
                    255:        op = tp->t_op;
                    256:        lab0 = lab1 = -1;
                    257:        false = naddr = opv = nse = npfx = star = 0;
                    258:        mp = patp->p_macro;
                    259:        while ((c = *mp++) != M_END) {
                    260:                /* Unsatisfied conditions ignore everything but goto's */
                    261:                if (false) {
                    262:                        if (c == M_ENDIF) {
                    263:                                false = 0;
                    264:                                continue;
                    265:                        }
                    266:                        if (c != M_JMP1 && c != M_JMPB && c != M_JMP2)
                    267:                                continue;
                    268:                }
                    269:                switch (c) {
                    270: 
                    271:                case M_JMP1:
                    272:                        label = mp[0];
                    273:                jump:
                    274:                        mp = macros + label;
                    275:                        continue;
                    276: 
                    277:                case M_JMPB:
                    278:                        label = ((char *)mp) - macros - 1 - mp[0];
                    279:                        goto jump;
                    280: 
                    281:                case M_JMP2:
                    282:                        label = mp[0] + (mp[1] << 8);
                    283:                        goto jump;
                    284: 
                    285:                case M_IFV:     /* Value context conditional */
                    286:                        false = (cxt!=MLVALUE && cxt!=MRVALUE);
                    287:                        continue;
                    288: 
                    289:                case M_IFE:     /* Effect context conditional */
                    290:                        false = (cxt != MEFFECT);
                    291:                        continue;
                    292: 
                    293:                case M_IFR:     /* Relational context condtional */
                    294:                        false = (cxt < MEQ);
                    295:                        continue;
                    296: 
                    297:                case M_ENDIF:   /* End of conditional */
                    298:                        continue;
                    299: 
                    300:                case M_TN:      /* Adjust the opcode according */
                    301:                case M_TL:      /* to the type of the base, left, */
                    302:                case M_TR:      /* or right node via maptype(...) */
                    303:                        opv = c;
                    304:                        continue;
                    305: 
                    306:                case M_OP0:     /* Use the opcode table to select */
                    307:                case M_OP1:     /* one of three variations of opcode */
                    308:                case M_OP2:
                    309:                        opcode = optab[op-MIOBASE][c-M_OP0];
                    310:                outop:
                    311:                        opcode = maptype(opv, opcode, tp);
                    312:                        bput(CODE);
                    313:                        bput(opcode);
                    314:                        naddr = opv = 0;
                    315:                        continue;
                    316: 
                    317:                case M_CALL:
                    318:                        outopcall(0);
                    319:                        continue;
                    320: 
                    321:                default:        /* This should be a machine opcode */
                    322:                        if (c < M_ORG) {
                    323:                                opcode = mapcode(c, tp);
                    324:                                goto outop;
                    325:                        }
                    326:                        cbotch("bad macro %d", c);
                    327:                        /* NOTREACHED */
                    328: 
                    329:                case M_NSE:     /* Set no side effect flag for genadr */
                    330:                        nse++;
                    331:                        continue;
                    332: 
                    333:                case M_HI:      /* Set part of address prefix for genadr */
                    334:                case M_LO:
                    335:                        pfx[npfx++] = c;
                    336:                        continue;
                    337: 
                    338:                case M_STAR:    /* Indicate indirection of address */
                    339:                        star += 1;
                    340:                        continue;
                    341: 
                    342:                case M_AN:      /* Output address form of base node */
                    343:                        ap = tp;
                    344:                outadr:
                    345:                        if (opv != 0) {
                    346:                                /* Add prefix bytes depending on type. */
                    347:                                mappfx(tp, opv, pfx, &npfx);
                    348:                                opv = 0;
                    349:                        }
                    350:                        if (star)
                    351:                                genstar(ap, nse, npfx, pfx);
                    352:                        else
                    353:                                genadr(ap, nse, npfx, pfx);
                    354:                        nse = npfx = star = 0;
                    355:                        naddr += 1;
                    356:                        continue;
                    357: 
                    358:                case M_AL:      /* Output address form of left node */
                    359:                        ap = lp;
                    360:                        goto outadr;
                    361: 
                    362:                case M_AR:      /* Output address form of right node */
                    363:                        ap = rp;
                    364:                        goto outadr;
                    365: 
                    366:                case M_R:       /* Output node register */
                    367:                        node.t_reg = tp->t_treg;
                    368:                        node.t_type = tp->t_type;
                    369:                outreg:
                    370:                        node.t_op  = REG;
                    371:                        ap = &node;
                    372:                        goto outadr;
                    373: 
                    374:                case M_RL:      /* Output left temp register */
                    375:                        node.t_reg = lp->t_rreg;
                    376:                        node.t_type = lp->t_type;
                    377:                        goto outreg;
                    378: 
                    379:                case M_RR:      /* Output right temp register */
                    380:                        node.t_reg = rp->t_rreg;
                    381:                        node.t_type = rp->t_type;
                    382:                        goto outreg;
                    383: 
                    384:                case M_REGNO:   /* Literal register from tables */
                    385:                        node.t_op  = REG;
                    386:                        node.t_reg = *mp++;
                    387:                        ap = &node;
                    388:                        goto outadr;
                    389: 
                    390:                case M_ICON:    /* Literal ival_t constant */
                    391:                        c = *mp++;
                    392:                        node.t_ival = ivalcache[c-1];
                    393:                outival:
                    394:                        node.t_op = ICON;
                    395:                        node.t_type = IVAL_T;
                    396:                        ap = &node;
                    397:                        goto outadr;
                    398: 
                    399:                case M_SIZE:    /* Size of block object */
                    400:                        node.t_ival = tp->t_size;
                    401:                        goto outival;
                    402: 
                    403:                case M_SSIZE:   /* Size of block object on stack */
                    404:                        node.t_ival = mapssize(tp->t_size);
                    405:                        goto outival;
                    406: 
                    407:                case M_LCON:    /* Literal lval_t constant */
                    408:                        c = *mp++;
                    409:                        node.t_lval = lvalcache[c-1];
                    410:                outlval:
                    411:                        node.t_op =   LCON;
                    412:                        node.t_type = LVAL_T;
                    413:                        ap = &node;
                    414:                        goto outadr;
                    415: 
                    416:                case M_EMASK:   /* Field extraction mask */
                    417:                        node.t_lval = (lval_t) mask;
                    418:                        goto outlval;
                    419: 
                    420:                case M_CMASK:   /* Field clear mask */
                    421:                        node.t_lval = (lval_t) ~mask;
                    422:                        goto outlval;
                    423: 
                    424:                case M_GID:     /* Literal global identifier */
                    425:                        c = *mp++;
                    426:                        node.t_op = GID;
                    427:                        node.t_sp = gidpool(gidcache[c-1]);
                    428:                        node.t_seg = SANY;
                    429:                        node.t_offs = 0;
                    430:                        ap = &node;
                    431:                        goto outadr;
                    432: 
                    433: #if BITS
                    434:                case M_BITL:    /* Bit number of left node */
                    435:                        node.t_ival = getbit(lp);
                    436:                        goto outival;
                    437: 
                    438:                case M_BITR:    /* Bit number of right node */
                    439:                        node.t_ival = getbit(rp);
                    440:                        goto outival;
                    441: #endif
                    442: 
                    443:                case M_TOS:     /* Generate top of stack address */
                    444:                        gentos(opcode, naddr++);
                    445:                        continue;
                    446: 
                    447:                case M_LAB0:    /* Generated label #0 */
                    448:                        if (lab0 < 0)
                    449:                                lab0 = newlab();
                    450:                        node.t_label = lab0;
                    451:                outlid:
                    452:                        node.t_op = LID;
                    453:                        node.t_seg = SANY;
                    454:                        node.t_offs = 0;
                    455:                        ap = &node;
                    456:                        goto outadr;
                    457: 
                    458:                case M_LAB1:    /* Generated label #1 */
                    459:                        if (lab1 < 0)
                    460:                                lab1 = newlab();
                    461:                        node.t_label = lab1;
                    462:                        goto outlid;
                    463: 
                    464:                case M_DLAB0:   /* Define label #0 */
                    465:                        if (lab0 < 0)
                    466:                                lab0 = newlab();
                    467:                        bput(LLABEL);
                    468:                        iput((ival_t)lab0);
                    469:                        continue;
                    470: 
                    471:                case M_DLAB1:   /* Define label #1 */
                    472:                        if (lab1 < 0)
                    473:                                lab1 = newlab();
                    474:                        bput(LLABEL);
                    475:                        iput((ival_t)lab1);
                    476:                        continue;
                    477: 
                    478:                case M_LAB:     /* The label associated with the tree */
                    479:                        node.t_label = lab;
                    480:                        goto outlid;
                    481: 
                    482:                case M_REL0:
                    483:                case M_REL1:
                    484:                        bput(CODE);
                    485:                        bput(optab[cxt-MEQ+EQ-MIOBASE][c-M_REL0]);
                    486:                        naddr = 0;
                    487:                        continue;
                    488: 
                    489: #if    LONGREL
                    490:                case M_LREL0:
                    491:                case M_LREL1:
                    492:                case M_LREL2:
                    493:                        bput(CODE);
                    494:                        opcode = cxt-MEQ+EQ;
                    495:                        if (c == M_LREL2) {
                    496:                                if (opcode>=GT && opcode<=LT)
                    497:                                        opcode += UGT-GT;
                    498:                                bput(optab[opcode-MIOBASE][0]);
                    499:                                naddr = 0;
                    500:                                continue;
                    501:                        }
                    502:                        if (c == M_LREL1)
                    503:                                opcode = fliprel[opcode-EQ];
                    504:                        bput(optab[opcode-MIOBASE][2]);
                    505:                        naddr = 0;
                    506:                        continue;
                    507: #endif
                    508: 
                    509:                }
                    510:        }
                    511: }
                    512: 
                    513: /*
                    514:  * Given a pointer to an offset type tree,
                    515:  * dig up the subtree that gets loaded into the base register
                    516:  * and make a recursive call to generate the code that does the load.
                    517:  */
                    518: outofs(tp)
                    519: TREE *tp;
                    520: {
                    521:        register TREE *ap;
                    522: 
                    523:        ap = findoffs(tp);
                    524:        output(ap, MLVALUE, 0, 0);
                    525:        ap->t_op  = REG;
                    526:        ap->t_reg = ap->t_rreg;
                    527:        walk(tp, amd);
                    528: }
                    529: 
                    530: #if BITS
                    531: /*
                    532:  * Figure out and output a bit number.
                    533:  * The argument must be flagged as a bit thing.
                    534:  */
                    535: getbit(tp)
                    536: register TREE *tp;
                    537: {
                    538:        register ival_t half;
                    539: 
                    540:        if ((tp->t_flag&(T_UOBS|T_LOBS|T_UOBC|T_LOBC)) == 0)
                    541:                cbotch("bad bit");
                    542:        {
                    543:                register op;
                    544: 
                    545:                while ((op=tp->t_op) == LEAF)
                    546:                        tp = tp->t_lp;
                    547:                if (op == ICON)
                    548:                        half = tp->t_ival;
                    549:                else if ((tp->t_flag&(T_UOBS|T_UOBC)) != 0)
                    550:                        half = upper(tp->t_lval);
                    551:                else
                    552:                        half = lower(tp->t_lval);
                    553:        }
                    554:        if ((tp->t_flag&(T_UOBC|T_LOBC)) != 0)
                    555:                half = ~half;
                    556:        {
                    557:                register bitnum;
                    558: 
                    559:                bitnum = 0;
                    560:                while ((half&01) == 0) {
                    561:                        half >>= 1;
                    562:                        ++bitnum;
                    563:                }
                    564:                return (bitnum);
                    565:        }
                    566: }
                    567: #endif

unix.superglobalmegacorp.com

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