Annotation of coherent/b/bin/c/n1/out.c, revision 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.