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

1.1     ! root        1: #
        !             2: /*
        !             3: 
        !             4:                C compiler, part 2
        !             5: 
        !             6: 
        !             7: */
        !             8: 
        !             9: #include "c1.h"
        !            10: 
        !            11: #define        dbprint(op)     /* */
        !            12: #ifdef DEBUG
        !            13: #define        dbprint(op)     printf("        / %s", opntab[op])
        !            14: #endif
        !            15: 
        !            16: char   maprel[] = {    EQUAL, NEQUAL, GREATEQ, GREAT, LESSEQ,
        !            17:                        LESS, GREATQP, GREATP, LESSEQP, LESSP
        !            18: };
        !            19: 
        !            20: char   notrel[] = {    NEQUAL, EQUAL, GREAT, GREATEQ, LESS,
        !            21:                        LESSEQ, GREATP, GREATQP, LESSP, LESSEQP
        !            22: };
        !            23: 
        !            24: struct tconst czero = { CON, INT, 0};
        !            25: struct tconst cone  = { CON, INT, 1};
        !            26: 
        !            27: struct tname sfuncr = { NAME, STRUCT, STATIC, 0, 0, 0 };
        !            28: 
        !            29: struct table   *cregtab;
        !            30: 
        !            31: int    nreg    = 3;
        !            32: int    isn     = 10000;
        !            33: 
        !            34: main(argc, argv)
        !            35: char *argv[];
        !            36: {
        !            37: 
        !            38:        if (argc<4) {
        !            39:                error("Arg count");
        !            40:                exit(1);
        !            41:        }
        !            42:        if (freopen(argv[1], "r", stdin)==NULL) {
        !            43:                error("Missing temp file");
        !            44:                exit(1);
        !            45:        }
        !            46:        if ((freopen(argv[3], "w", stdout)) == NULL) {
        !            47:                error("Can't create %s", argv[3]);
        !            48:                exit(1);
        !            49:        }
        !            50:        funcbase = curbase = coremax = sbrk(0);
        !            51:        getree();
        !            52:        /*
        !            53:         * If any floating-point instructions
        !            54:         * were used, generate a reference that
        !            55:         * pulls in the floating-point part of printf.
        !            56:         */
        !            57:        if (nfloat)
        !            58:                printf(".globl  fltused\n");
        !            59:        /*
        !            60:         * tack on the string file.
        !            61:         */
        !            62:        printf(".globl\n.data\n");
        !            63:        if (*argv[2] != '-') {
        !            64:                if (freopen(argv[2], "r", stdin)==NULL) {
        !            65:                        error("Missing temp file");
        !            66:                        exit(1);
        !            67:                }
        !            68:                getree();
        !            69:        }
        !            70:        if (totspace >= (unsigned)56000) {
        !            71:                error("Warning: possibly too much data");
        !            72:                nerror--;
        !            73:        }
        !            74:        exit(nerror!=0);
        !            75: }
        !            76: 
        !            77: /*
        !            78:  * Given a tree, a code table, and a
        !            79:  * count of available registers, find the code table
        !            80:  * for the appropriate operator such that the operands
        !            81:  * are of the right type and the number of registers
        !            82:  * required is not too large.
        !            83:  * Return a ptr to the table entry or 0 if none found.
        !            84:  */
        !            85: struct optab *
        !            86: match(tree, table, nrleft, nocvt)
        !            87: union tree *tree;
        !            88: struct table *table;
        !            89: {
        !            90: #define        NOCVL   1
        !            91: #define        NOCVR   2
        !            92:        int op, d1, d2, dope;
        !            93:        union tree *p2;
        !            94:        register union tree *p1;
        !            95:        register struct optab *opt;
        !            96: 
        !            97:        if (tree==NULL)
        !            98:                return(NULL);
        !            99:        if (table==lsptab)
        !           100:                table = sptab;
        !           101:        if ((op = tree->t.op)==0)
        !           102:                return(0);
        !           103:        dope = opdope[op];
        !           104:        if ((dope&LEAF) == 0)
        !           105:                p1 = tree->t.tr1;
        !           106:        else
        !           107:                p1 = tree;
        !           108:        d1 = dcalc(p1, nrleft);
        !           109:        if ((dope&BINARY)!=0) {
        !           110:                p2 = tree->t.tr2;
        !           111:                /*
        !           112:                 * If a subtree starts off with a conversion operator,
        !           113:                 * try for a match with the conversion eliminated.
        !           114:                 * E.g. int = double can be done without generating
        !           115:                 * the converted int in a register by
        !           116:                 * movf double,fr0; movfi fr0,int .
        !           117:                 */
        !           118:                if (opdope[p2->t.op]&CNVRT && (nocvt&NOCVR)==0
        !           119:                         && (opdope[p2->t.tr1->t.op]&CNVRT)==0) {
        !           120:                        tree->t.tr2 = p2->t.tr1;
        !           121:                        if (opt = match(tree, table, nrleft, NOCVL))
        !           122:                                return(opt);
        !           123:                        tree->t.tr2 = p2;
        !           124:                } else if (opdope[p1->t.op]&CNVRT && (nocvt&NOCVL)==0
        !           125:                 && (opdope[p1->t.tr1->t.op]&CNVRT)==0) {
        !           126:                        tree->t.tr1 = p1->t.tr1;
        !           127:                        if (opt = match(tree, table, nrleft, NOCVR))
        !           128:                                return(opt);
        !           129:                        tree->t.tr1 = p1;
        !           130:                }
        !           131:                d2 = dcalc(p2, nrleft);
        !           132:        }
        !           133:        for (; table->tabop!=op; table++)
        !           134:                if (table->tabop==0)
        !           135:                        return(0);
        !           136:        for (opt = table->tabp; opt->tabdeg1!=0; opt++) {
        !           137:                if (d1 > (opt->tabdeg1&077)
        !           138:                 || (opt->tabdeg1 >= 0100 && (p1->t.op != STAR)))
        !           139:                        continue;
        !           140:                if (notcompat(p1, opt->tabtyp1, opt->tabdeg1, op))
        !           141:                        continue;
        !           142:                if ((opdope[op]&BINARY)!=0 && p2!=0) {
        !           143:                        if (d2 > (opt->tabdeg2&077)
        !           144:                         || (opt->tabdeg2 >= 0100) && (p2->t.op != STAR) )
        !           145:                                continue;
        !           146:                        if (notcompat(p2,opt->tabtyp2, opt->tabdeg2, 0))
        !           147:                                continue;
        !           148:                        if ((opt->tabdeg2&077)==20 && xdcalc(p2,nrleft)>20)
        !           149:                                continue;
        !           150:                }
        !           151:                return(opt);
        !           152:        }
        !           153:        return(0);
        !           154: }
        !           155: 
        !           156: /*
        !           157:  * Given a tree, a code table, and a register,
        !           158:  * produce code to evaluate the tree with the appropriate table.
        !           159:  * Registers reg and upcan be used.
        !           160:  * If there is a value, it is desired that it appear in reg.
        !           161:  * The routine returns the register in which the value actually appears.
        !           162:  * This routine must work or there is an error.
        !           163:  * If the table called for is cctab, sptab, or efftab,
        !           164:  * and tree can't be done using the called-for table,
        !           165:  * another try is made.
        !           166:  * If the tree can't be compiled using cctab, regtab is
        !           167:  * used and a "tst" instruction is produced.
        !           168:  * If the tree can't be compiled using sptab,
        !           169:  * regtab is used and the register is pushed on the stack.
        !           170:  * If the tree can't be compiled using efftab,
        !           171:  * just use regtab.
        !           172:  * Regtab must succeed or an "op not found" error results.
        !           173:  *
        !           174:  * A number of special cases are recognized, and
        !           175:  * there is an interaction with the optimizer routines.
        !           176:  */
        !           177: rcexpr(atree, atable, reg)
        !           178: union tree *atree;
        !           179: struct table *atable;
        !           180: {
        !           181:        register r;
        !           182:        int modf, nargs, recurf;
        !           183:        register union tree *tree;
        !           184:        register struct table *table;
        !           185: 
        !           186:        table = atable;
        !           187:        recurf = 0;
        !           188:        if (reg<0) {
        !           189:                recurf++;
        !           190:                reg = ~reg;
        !           191:                if (reg>=020) {
        !           192:                        reg -= 020;
        !           193:                        recurf++;
        !           194:                }
        !           195:        }
        !           196: again:
        !           197:        if((tree=atree)==0)
        !           198:                return(0);
        !           199:        if (tree->t.type==VOID) {
        !           200:                if (table!=efftab)
        !           201:                        error("Illegal use of void");
        !           202:                tree->t.type = INT;
        !           203:        }
        !           204:        if (opdope[tree->t.op]&RELAT && tree->t.tr2->t.op==CON
        !           205:            && tree->t.tr2->c.value==0
        !           206:            && table==cctab)
        !           207:                tree = atree = tree->t.tr1;
        !           208:        /*
        !           209:         * fieldselect(...) : in efftab mode,
        !           210:         * ignore the select, otherwise
        !           211:         * do the shift and mask.
        !           212:         */
        !           213:        if (tree->t.op == FSELT) {
        !           214:                if (table==efftab)
        !           215:                        atree = tree = tree->t.tr1;
        !           216:                else {
        !           217:                        tree->t.op = FSEL;
        !           218:                        atree = tree = optim(tree);
        !           219:                }
        !           220:        }
        !           221:        switch (tree->t.op)  {
        !           222: 
        !           223:        /*
        !           224:         * Structure assignments
        !           225:         */
        !           226:        case STRASG:
        !           227:                strasg(tree);
        !           228:                return(0);
        !           229: 
        !           230:        /*
        !           231:         * An initializing expression
        !           232:         */
        !           233:        case INIT:
        !           234:                tree = optim(tree);
        !           235:                doinit(tree->t.type, tree->t.tr1);
        !           236:                return(0);
        !           237: 
        !           238:        /*
        !           239:         * Put the value of an expression in r0,
        !           240:         * for a switch or a return
        !           241:         */
        !           242:        case RFORCE:
        !           243:                tree = tree->t.tr1;
        !           244:                if((r=rcexpr(tree, regtab, reg)) != 0)
        !           245:                        movreg(r, 0, tree);
        !           246:                return(0);
        !           247: 
        !           248:        /*
        !           249:         * sequential execution
        !           250:         */
        !           251:        case SEQNC:
        !           252:                r = nstack;
        !           253:                rcexpr(tree->t.tr1, efftab, reg);
        !           254:                nstack = r;
        !           255:                atree = tree = tree->t.tr2;
        !           256:                goto again;
        !           257: 
        !           258:        /*
        !           259:         * In the generated &~ operator,
        !           260:         * fiddle things so a PDP-11 "bit"
        !           261:         * instruction will be produced when cctab is used.
        !           262:         */
        !           263:        case ANDN:
        !           264:                if (table==cctab) {
        !           265:                        tree->t.op = TAND;
        !           266:                        tree->t.tr2 = optim(tnode(COMPL, tree->t.type, tree->t.tr2, TNULL));
        !           267:                }
        !           268:                break;
        !           269: 
        !           270:        /*
        !           271:         * Handle a subroutine call. It has to be done
        !           272:         * here because if cexpr got called twice, the
        !           273:         * arguments might be compiled twice.
        !           274:         * There is also some fiddling so the
        !           275:         * first argument, in favorable circumstances,
        !           276:         * goes to (sp) instead of -(sp), reducing
        !           277:         * the amount of stack-popping.
        !           278:         */
        !           279:        case CALL:
        !           280:                r = 0;
        !           281:                nargs = 0;
        !           282:                modf = 0;
        !           283:                if (tree->t.tr1->t.op!=NAME || tree->t.tr1->n.class!=EXTERN) {
        !           284:                        nargs++;
        !           285:                        nstack++;
        !           286:                }
        !           287:                tree = tree->t.tr2;
        !           288:                if(tree->t.op) {
        !           289:                        while (tree->t.op==COMMA) {
        !           290:                                r += comarg(tree->t.tr2, &modf);
        !           291:                                tree = tree->t.tr1;
        !           292:                                nargs++;
        !           293:                        }
        !           294:                        r += comarg(tree, &modf);
        !           295:                        nargs++;
        !           296:                }
        !           297:                tree = atree;
        !           298:                tree->t.op = CALL2;
        !           299:                if (modf && tree->t.tr1->t.op==NAME
        !           300:                   && tree->t.tr1->n.class==EXTERN)
        !           301:                        tree->t.op = CALL1;
        !           302:                if (cexpr(tree, regtab, reg)<0)
        !           303:                        error("compiler botch: call");
        !           304:                popstk(r);
        !           305:                nstack -= nargs;
        !           306:                if (table==efftab || table==regtab)
        !           307:                        return(0);
        !           308:                r = 0;
        !           309:                goto fixup;
        !           310: 
        !           311:        /*
        !           312:         * Longs need special treatment.
        !           313:         */
        !           314:        case ASLSH:
        !           315:        case LSHIFT:
        !           316:                if (tree->t.type==LONG) {
        !           317:                        if (tree->t.tr2->t.op==ITOL)
        !           318:                                tree->t.tr2 = tree->t.tr2->t.tr1;
        !           319:                        else
        !           320:                                tree->t.tr2 = optim(tnode(LTOI,INT,tree->t.tr2,TNULL));
        !           321:                        if (tree->t.op==ASLSH)
        !           322:                                tree->t.op = ASLSHL;
        !           323:                        else
        !           324:                                tree->t.op = LLSHIFT;
        !           325:                }
        !           326:                break;
        !           327: 
        !           328:        /*
        !           329:         * Try to change * to shift.
        !           330:         */
        !           331:        case TIMES:
        !           332:        case ASTIMES:
        !           333:                tree = pow2(tree);
        !           334:        }
        !           335:        /*
        !           336:         * Try to find postfix ++ and -- operators that can be
        !           337:         * pulled out and done after the rest of the expression
        !           338:         */
        !           339:        if (table!=cctab && table!=cregtab && recurf<2
        !           340:         && (opdope[tree->t.op]&LEAF)==0) {
        !           341:                if (r=delay(&atree, table, reg)) {
        !           342:                        tree = atree;
        !           343:                        table = efftab;
        !           344:                        reg = r-1;
        !           345:                }
        !           346:        }
        !           347:        /*
        !           348:         * Basically, try to reorder the computation
        !           349:         * so  reg = x+y  is done as  reg = x; reg += y
        !           350:         */
        !           351:        if (recurf==0 && reorder(&atree, table, reg)) {
        !           352:                if (table==cctab && atree->t.op==NAME)
        !           353:                        return(reg);
        !           354:        }
        !           355:        tree = atree;
        !           356:        if (table==efftab && tree->t.op==NAME)
        !           357:                return(reg);
        !           358:        if ((r=cexpr(tree, table, reg))>=0) {
        !           359:                if (table==cregtab && (tree->t.op==INCAFT
        !           360:                    || tree->t.op==DECAFT || tree->t.op==TIMES))
        !           361:                        goto fixup;
        !           362:                return(r);
        !           363:        }
        !           364:        if (table!=regtab && (table!=cctab||(opdope[tree->t.op]&RELAT)==0)) {
        !           365:                if((r=cexpr(tree, regtab, reg))>=0) {
        !           366:        fixup:
        !           367:                        modf = isfloat(tree);
        !           368:                        dbprint(tree->t.op);
        !           369:                        if (table==sptab || table==lsptab) {
        !           370:                                if (tree->t.type==LONG) {
        !           371:                                        printf("mov\tr%d,-(sp)\n",r+1);
        !           372:                                        nstack++;
        !           373:                                }
        !           374:                                printf("mov%s   r%d,%s(sp)\n", modf=='f'?"f":"", r,
        !           375:                                        table==sptab? "-":"");
        !           376:                                nstack++;
        !           377:                        }
        !           378:                        if (table==cctab || table==cregtab)
        !           379:                                printf("tst%s   r%d\n", modf=='f'?"f":"", r);
        !           380:                        return(r);
        !           381:                }
        !           382:        }
        !           383:        /*
        !           384:         * Special grace for unsigned chars as right operands
        !           385:         */
        !           386:        if (opdope[tree->t.op]&BINARY && tree->t.tr2->t.type==UNCHAR) {
        !           387:                tree->t.tr2 = tnode(LOAD, UNSIGN, tree->t.tr2, TNULL);
        !           388:                return(rcexpr(tree, table, reg));
        !           389:        }
        !           390:        /*
        !           391:         * There's a last chance for this operator
        !           392:         */
        !           393:        if (tree->t.op==LTOI) {
        !           394:                r = rcexpr(tree->t.tr1, regtab, reg);
        !           395:                if (r >= 0) {
        !           396:                        r++;
        !           397:                        goto fixup;
        !           398:                }
        !           399:        }
        !           400:        if (tree->t.type == STRUCT)
        !           401:                error("Illegal operation on structure");
        !           402:        else if (tree->t.op>0 && tree->t.op<RFORCE && opntab[tree->t.op])
        !           403:                error("No code table for op: %s", opntab[tree->t.op]);
        !           404:        else
        !           405:                error("No code table for op %d", tree->t.op);
        !           406:        return(reg);
        !           407: }
        !           408: 
        !           409: /*
        !           410:  * Try to compile the tree with the code table using
        !           411:  * registers areg and up.  If successful,
        !           412:  * return the register where the value actually ended up.
        !           413:  * If unsuccessful, return -1.
        !           414:  *
        !           415:  * Most of the work is the macro-expansion of the
        !           416:  * code table.
        !           417:  */
        !           418: cexpr(tree, table, areg)
        !           419: register union tree *tree;
        !           420: struct table *table;
        !           421: {
        !           422:        int c, r;
        !           423:        register union tree *p, *p1;
        !           424:        struct table *ctable;
        !           425:        union tree *p2;
        !           426:        char *string;
        !           427:        int reg, reg1, rreg, flag, opd;
        !           428:        struct optab *opt;
        !           429: 
        !           430:        reg = areg;
        !           431:        p1 = tree->t.tr2;
        !           432:        c = tree->t.op;
        !           433:        opd = opdope[c];
        !           434:        /*
        !           435:         * When the value of a relational or a logical expression is
        !           436:         * desired, more work must be done.
        !           437:         */
        !           438:        if ((opd&RELAT||c==LOGAND||c==LOGOR||c==EXCLA) && table!=cctab) {
        !           439:                cbranch(tree, c=isn++, 1, reg);
        !           440:                rcexpr((union tree *)&czero, table, reg);
        !           441:                branch(isn, 0, 0);
        !           442:                label(c);
        !           443:                rcexpr((union tree *)&cone, table, reg);
        !           444:                label(isn++);
        !           445:                return(reg);
        !           446:        }
        !           447:        if(c==QUEST) {
        !           448:                if (table==cctab)
        !           449:                        return(-1);
        !           450:                cbranch(tree->t.tr1, c=isn++, 0, reg);
        !           451:                flag = nstack;
        !           452:                rreg = rcexpr(p1->t.tr1, table, reg);
        !           453:                nstack = flag;
        !           454:                branch(r=isn++, 0, 0);
        !           455:                label(c);
        !           456:                reg = rcexpr(p1->t.tr2, table, rreg);
        !           457:                if (rreg!=reg)
        !           458:                        movreg(reg, rreg, tree->t.tr2);
        !           459:                label(r);
        !           460:                return(rreg);
        !           461:        }
        !           462:        reg = oddreg(tree, reg);
        !           463:        reg1 = reg+1;
        !           464:        /*
        !           465:         * long values take 2 registers.
        !           466:         */
        !           467:        if ((tree->t.type==LONG||opd&RELAT&&tree->t.tr1->t.type==LONG)
        !           468:           && tree->t.op!=ITOL)
        !           469:                reg1++;
        !           470:        /*
        !           471:         * Leaves of the expression tree
        !           472:         */
        !           473:        if ((r = chkleaf(tree, table, reg)) >= 0)
        !           474:                return(r);
        !           475:        /*
        !           476:         * x + (-1) is better done as x-1.
        !           477:         */
        !           478:        if (tree->t.op==PLUS||tree->t.op==ASPLUS) {
        !           479:                if ((p1=tree->t.tr2)->t.op==CON && p1->c.value==-1) {
        !           480:                        p1->c.value = -p1->c.value;
        !           481:                        tree->t.op += (MINUS-PLUS);
        !           482:                }
        !           483:        }
        !           484:        /*
        !           485:         * Because of a peculiarity of the PDP11 table
        !           486:         * char = *intreg++ and *--intreg cannot go through.
        !           487:         */
        !           488:        if (tree->t.tr2 && (tree->t.tr2->t.op==AUTOI||tree->t.tr2->t.op==AUTOD)
        !           489:         && (tree->t.tr1->t.type==CHAR || tree->t.tr1->t.type==UNCHAR)
        !           490:         && tree->t.tr2->t.type!=CHAR && tree->t.tr2->t.type!=UNCHAR)
        !           491:                tree->t.tr2 = tnode(LOAD, tree->t.tr2->t.type, tree->t.tr2, TNULL);
        !           492:        if (table==cregtab)
        !           493:                table = regtab;
        !           494:        /*
        !           495:         * The following peculiar code depends on the fact that
        !           496:         * if you just want the codition codes set, efftab
        !           497:         * will generate the right code unless the operator is
        !           498:         * a shift or
        !           499:         * postfix ++ or --. Unravelled, if the table is
        !           500:         * cctab and the operator is not special, try first
        !           501:         * for efftab;  if the table isn't, if the operator is,
        !           502:         * or the first match fails, try to match
        !           503:         * with the table actually asked for.
        !           504:         */
        !           505:        /*
        !           506:         * Account for longs and oddregs; below is really
        !           507:         * r = nreg - reg - (reg-areg) - (reg1-reg-1);
        !           508:         */
        !           509:        r = nreg - reg + areg - reg1 + 1;
        !           510:        if (table!=cctab || c==INCAFT || c==DECAFT || tree->t.type==LONG
        !           511:         || c==ASRSH || c==ASLSH || c==ASULSH || tree->t.tr1->t.type==UNCHAR
        !           512:         || (opt = match(tree, efftab, r, 0)) == 0)
        !           513:                if ((opt=match(tree, table, r, 0))==0)
        !           514:                        return(-1);
        !           515:        string = opt->tabstring;
        !           516:        p1 = tree->t.tr1;
        !           517:        if (p1->t.op==FCON && p1->f.value>0) {
        !           518: /* nonportable */
        !           519:                printf(".data\nL%d:%o;%o;%o;%o\n.text\n", p1->f.value,
        !           520:                        ((unsigned short *)&(p1->f.fvalue))[0],
        !           521:                        ((unsigned short *)&(p1->f.fvalue))[1],
        !           522:                        ((unsigned short *)&(p1->f.fvalue))[2],
        !           523:                        ((unsigned short *)&(p1->f.fvalue))[3] );
        !           524:                p1->c.value = -p1->c.value;
        !           525:        }
        !           526:        p2 = 0;
        !           527:        if (opdope[tree->t.op]&BINARY) {
        !           528:                p2 = tree->t.tr2;
        !           529:                if (p2->t.op==FCON && p2->f.value>0) {
        !           530: /* nonportable */
        !           531:                        printf(".data\nL%d:%o;%o;%o;%o\n.text\n", p2->f.value,
        !           532:                                ((unsigned short *)&(p2->f.fvalue))[0],
        !           533:                                ((unsigned short *)&(p2->f.fvalue))[1],
        !           534:                                ((unsigned short *)&(p2->f.fvalue))[2],
        !           535:                                ((unsigned short *)&(p2->f.fvalue))[3] );
        !           536:                        p2->f.value = -p2->f.value;
        !           537:                }
        !           538:        }
        !           539: loop:
        !           540:        /*
        !           541:         * The 0200 bit asks for a tab.
        !           542:         */
        !           543:        if ((c = *string++) & 0200) {
        !           544:                c &= 0177;
        !           545:                putchar('\t');
        !           546:        }
        !           547:        switch (c) {
        !           548: 
        !           549:        case '\n':
        !           550:                dbprint(tree->t.op);
        !           551:                break;
        !           552: 
        !           553:        case '\0':
        !           554:                if (!isfloat(tree))
        !           555:                        if (tree->t.op==DIVIDE||tree->t.op==ASDIV)
        !           556:                                reg--;
        !           557:                if (table==regtab && (opdope[tree->t.op]&ASSGOP)) {
        !           558:                        if (tree->t.tr1->t.type==CHAR)
        !           559:                                printf("movb    r%d,r%d\n", reg, reg);
        !           560:                }
        !           561:                return(reg);
        !           562: 
        !           563:        /* A1 */
        !           564:        case 'A':
        !           565:                p = p1;
        !           566:                goto adr;
        !           567: 
        !           568:        /* A2 */
        !           569:        case 'B':
        !           570:                p = p2;
        !           571:                goto adr;
        !           572: 
        !           573:        adr:
        !           574:                c = 0;
        !           575:                while (*string=='\'') {
        !           576:                        c++;
        !           577:                        string++;
        !           578:                }
        !           579:                if (*string=='+') {
        !           580:                        c = 100;
        !           581:                        string++;
        !           582:                }
        !           583:                pname(p, c);
        !           584:                goto loop;
        !           585: 
        !           586:        /* I */
        !           587:        case 'M':
        !           588:                if ((c = *string)=='\'')
        !           589:                        string++;
        !           590:                else
        !           591:                        c = 0;
        !           592:                prins(tree->t.op, c, instab);
        !           593:                goto loop;
        !           594: 
        !           595:        /* B1 */
        !           596:        case 'C':
        !           597:                if ((opd&LEAF) != 0)
        !           598:                        p = tree;
        !           599:                else
        !           600:                        p = p1;
        !           601:                goto pbyte;
        !           602: 
        !           603:        /* BF */
        !           604:        case 'P':
        !           605:                p = tree;
        !           606:                goto pb1;
        !           607: 
        !           608:        /* B2 */
        !           609:        case 'D':
        !           610:                p = p2;
        !           611:        pbyte:
        !           612:                if (p->t.type==CHAR || p->t.type==UNCHAR)
        !           613:                        putchar('b');
        !           614:        pb1:
        !           615:                if (isfloat(p))
        !           616:                        putchar('f');
        !           617:                goto loop;
        !           618: 
        !           619:        /* BE */
        !           620:        case 'L':
        !           621:                if (p1->t.type==CHAR || p2->t.type==CHAR
        !           622:                 || p1->t.type==UNCHAR || p2->t.type==UNCHAR)
        !           623:                        putchar('b');
        !           624:                p = tree;
        !           625:                goto pb1;
        !           626: 
        !           627:        /* F */
        !           628:        case 'G':
        !           629:                p = p1;
        !           630:                flag = 01;
        !           631:                goto subtre;
        !           632: 
        !           633:        /* S */
        !           634:        case 'K':
        !           635:                p = p2;
        !           636:                flag = 02;
        !           637:                goto subtre;
        !           638: 
        !           639:        /* H */
        !           640:        case 'H':
        !           641:                p = tree;
        !           642:                flag = 04;
        !           643: 
        !           644:        subtre:
        !           645:                ctable = regtab;
        !           646:                if (flag&04)
        !           647:                        ctable = cregtab;
        !           648:                c = *string++ - 'A';
        !           649:                if (*string=='!') {
        !           650:                        string++;
        !           651:                        c |= 020;       /* force right register */
        !           652:                }
        !           653:                if (*string=='?') {
        !           654:                        string++;
        !           655:                        c |= 040;       /* force condition codes */
        !           656:                }
        !           657:                if ((c&02)!=0)
        !           658:                        ctable = sptab;
        !           659:                if ((c&04)!=0)
        !           660:                        ctable = cctab;
        !           661:                if ((flag&01) && ctable==regtab && (c&01)==0
        !           662:                  && ((c&040)||tree->t.op==DIVIDE||tree->t.op==MOD
        !           663:                   || tree->t.op==ASDIV||tree->t.op==ASMOD||tree->t.op==ITOL))
        !           664:                        ctable = cregtab;
        !           665:                if ((c&01)!=0) {
        !           666:                        p = p->t.tr1;
        !           667:                        if(collcon(p) && ctable!=sptab) {
        !           668:                                if (p->t.op==STAR)
        !           669:                                        p = p->t.tr1;
        !           670:                                p = p->t.tr1;
        !           671:                        }
        !           672:                }
        !           673:                if (table==lsptab && ctable==sptab)
        !           674:                        ctable = lsptab;
        !           675:                if (c&010)
        !           676:                        r = reg1;
        !           677:                else
        !           678:                        if (opdope[p->t.op]&LEAF || p->t.degree < 2)
        !           679:                                r = reg;
        !           680:                        else
        !           681:                                r = areg;
        !           682:                rreg = rcexpr(p, ctable, r);
        !           683:                if (ctable!=regtab && ctable!=cregtab)
        !           684:                        goto loop;
        !           685:                if (c&010) {
        !           686:                        if (c&020 && rreg!=reg1)
        !           687:                                movreg(rreg, reg1, p);
        !           688:                        else
        !           689:                                reg1 = rreg;
        !           690:                } else if (rreg!=reg)
        !           691:                        if ((c&020)==0 && oddreg(tree, 0)==0 && tree->t.type!=LONG
        !           692:                        && (flag&04
        !           693:                          || flag&01&&xdcalc(p2,nreg-rreg-1)<=(opt->tabdeg2&077)
        !           694:                          || flag&02&&xdcalc(p1,nreg-rreg-1)<=(opt->tabdeg1&077))) {
        !           695:                                reg = rreg;
        !           696:                                reg1 = rreg+1;
        !           697:                        } else
        !           698:                                movreg(rreg, reg, p);
        !           699:                goto loop;
        !           700: 
        !           701:        /* R */
        !           702:        case 'I':
        !           703:                r = reg;
        !           704:                if (*string=='-') {
        !           705:                        string++;
        !           706:                        r--;
        !           707:                }
        !           708:                goto preg;
        !           709: 
        !           710:        /* R1 */
        !           711:        case 'J':
        !           712:                r = reg1;
        !           713:        preg:
        !           714:                if (*string=='+') {
        !           715:                        string++;
        !           716:                        r++;
        !           717:                }
        !           718:                if (r>nreg || r>=4 && tree->t.type==DOUBLE) {
        !           719:                        if (regpanic)
        !           720:                                error("Register overflow: simplify expression");
        !           721:                        else
        !           722:                                longjmp(jmpbuf, 1);
        !           723:                }
        !           724:                printf("r%d", r);
        !           725:                goto loop;
        !           726: 
        !           727:        case '-':               /* check -(sp) */
        !           728:                if (*string=='(') {
        !           729:                        nstack++;
        !           730:                        if (table!=lsptab)
        !           731:                                putchar('-');
        !           732:                        goto loop;
        !           733:                }
        !           734:                break;
        !           735: 
        !           736:        case ')':               /* check (sp)+ */
        !           737:                putchar(')');
        !           738:                if (*string=='+')
        !           739:                        nstack--;
        !           740:                goto loop;
        !           741: 
        !           742:        /* #1 */
        !           743:        case '#':
        !           744:                p = p1->t.tr1;
        !           745:                goto nmbr;
        !           746: 
        !           747:        /* #2 */
        !           748:        case '"':
        !           749:                p = p2->t.tr1;
        !           750: 
        !           751:        nmbr:
        !           752:                if(collcon(p)) {
        !           753:                        if (p->t.op==STAR) {
        !           754:                                printf("*");
        !           755:                                p = p->t.tr1;
        !           756:                        }
        !           757:                        if ((p = p->t.tr2)->t.op == CON) {
        !           758:                                if (p->c.value)
        !           759:                                        psoct(p->c.value);
        !           760:                        } else if (p->t.op==AMPER)
        !           761:                                pname(p->t.tr1, 0);
        !           762:                }
        !           763:                goto loop;
        !           764: 
        !           765:        /*
        !           766:         * Certain adjustments for / %
        !           767:         */
        !           768:        case 'T':
        !           769:                c = reg-1;
        !           770:                if (uns(p1) || uns(p2)) {
        !           771:                        printf("clr     r%d\n", c);
        !           772:                        goto loop;
        !           773:                }
        !           774:                if (dcalc(p1, 5)>12 && !match(p1, cctab, 10, 0))
        !           775:                        printf("tst     r%d\n", reg);
        !           776:                printf("sxt     r%d\n", c);
        !           777:                goto loop;
        !           778: 
        !           779:        case 'V':       /* adc sbc, clr, or sxt as required for longs */
        !           780:                switch(tree->t.op) {
        !           781:                case PLUS:
        !           782:                case ASPLUS:
        !           783:                case INCBEF:
        !           784:                case INCAFT:
        !           785:                        printf("adc");
        !           786:                        break;
        !           787: 
        !           788:                case MINUS:
        !           789:                case ASMINUS:
        !           790:                case NEG:
        !           791:                case DECBEF:
        !           792:                case DECAFT:
        !           793:                        printf("sbc");
        !           794:                        break;
        !           795: 
        !           796:                case ASSIGN:
        !           797:                        p = tree->t.tr2;
        !           798:                        goto lcasev;
        !           799: 
        !           800:                case ASDIV:
        !           801:                case ASMOD:
        !           802:                case ASULSH:
        !           803:                        p = tree->t.tr1;
        !           804:                lcasev:
        !           805:                        if (p->t.type!=LONG) {
        !           806:                                if (uns(p) || uns(tree->t.tr2))
        !           807:                                        printf("clr");
        !           808:                                else
        !           809:                                        printf("sxt");
        !           810:                                goto loop;
        !           811:                        }
        !           812:                default:
        !           813:                        while ((c = *string++)!='\n' && c!='\0');
        !           814:                        break;
        !           815:                }
        !           816:                goto loop;
        !           817: 
        !           818:        /*
        !           819:         * Mask used in field assignments
        !           820:         */
        !           821:        case 'Z':
        !           822:                printf("$%o", UNS(tree->F.mask));
        !           823:                goto loop;
        !           824: 
        !           825:        /*
        !           826:         * Relational on long values.
        !           827:         * Might bug out early. E.g.,
        !           828:         * (long<0) can be determined with only 1 test.
        !           829:         */
        !           830:        case 'X':
        !           831:                if (xlongrel(*string++ - '0'))
        !           832:                        return(reg);
        !           833:                goto loop;
        !           834:        }
        !           835:        putchar(c);
        !           836:        goto loop;
        !           837: }
        !           838: 
        !           839: /*
        !           840:  * This routine just calls sreorder (below)
        !           841:  * on the subtrees and then on the tree itself.
        !           842:  * It returns non-zero if anything changed.
        !           843:  */
        !           844: reorder(treep, table, reg)
        !           845: union tree **treep;
        !           846: struct table *table;
        !           847: {
        !           848:        register r, o;
        !           849:        register union tree *p;
        !           850: 
        !           851:        p = *treep;
        !           852:        o = p->t.op;
        !           853:        if (opdope[o]&LEAF||o==LOGOR||o==LOGAND||o==SEQNC||o==QUEST||o==COLON)
        !           854:                return(0);
        !           855:        while(sreorder(&p->t.tr1, regtab, reg, 1))
        !           856:                ;
        !           857:        if (opdope[o]&BINARY) 
        !           858:                while(sreorder(&p->t.tr2, regtab, reg, 1))
        !           859:                        ;
        !           860:        r = 0;
        !           861:        if (table!=cctab)
        !           862:        while (sreorder(treep, table, reg, 0))
        !           863:                r++;
        !           864:        *treep = optim(*treep);
        !           865:        return(r);
        !           866: }
        !           867: 
        !           868: /*
        !           869:  * Basically this routine carries out two kinds of optimization.
        !           870:  * First, it observes that "x + (reg = y)" where actually
        !           871:  * the = is any assignment op is better done as "reg=y; x+reg".
        !           872:  * In this case rcexpr is called to do the first part and the
        !           873:  * tree is modified so the name of the register
        !           874:  * replaces the assignment.
        !           875:  * Moreover, expressions like "reg = x+y" are best done as
        !           876:  * "reg = x; reg += y" (so long as "reg" and "y" are not the same!).
        !           877:  */
        !           878: sreorder(treep, table, reg, recurf)
        !           879: union tree **treep;
        !           880: struct table *table;
        !           881: {
        !           882:        register union tree *p, *p1;
        !           883: 
        !           884:        p = *treep;
        !           885:        if (opdope[p->t.op]&LEAF)
        !           886:                return(0);
        !           887:        if (p->t.op==PLUS && recurf)
        !           888:                if (reorder(&p->t.tr2, table, reg))
        !           889:                        *treep = p = optim(p);
        !           890:        if ((p1 = p->t.tr1)==TNULL)
        !           891:                return(0);
        !           892:        if (p->t.op==STAR || p->t.op==PLUS) {
        !           893:                if (recurf && reorder(&p->t.tr1, table, reg)) {
        !           894:                        *treep = p = optim(p);
        !           895:                        if (opdope[p->t.op]&LEAF)
        !           896:                                return(0);
        !           897:                }
        !           898:                p1 = p->t.tr1;
        !           899:        }
        !           900:        if (p1->t.op==NAME) switch(p->t.op) {
        !           901:                case ASLSH:
        !           902:                case ASRSH:
        !           903:                case ASSIGN:
        !           904:                        if (p1->n.class != REG || p1->n.type==CHAR
        !           905:                          || isfloat(p->t.tr2))
        !           906:                                return(0);
        !           907:                        if (p->t.op==ASSIGN) switch (p->t.tr2->t.op) {
        !           908:                        case RSHIFT:
        !           909:                                if (p->t.type==UNSIGN)
        !           910:                                        return(0);
        !           911:                                goto caseGEN;
        !           912:                        case TIMES:
        !           913:                                if (!ispow2(p->t.tr2))
        !           914:                                        break;
        !           915:                                p->t.tr2 = pow2(p->t.tr2);
        !           916:                        case PLUS:
        !           917:                        case MINUS:
        !           918:                        case AND:
        !           919:                        case ANDN:
        !           920:                        case OR:
        !           921:                        case EXOR:
        !           922:                        case LSHIFT:
        !           923:                        caseGEN:
        !           924:                                p1 = p->t.tr2->t.tr2;
        !           925:                                if (xdcalc(p1, 16) > 12
        !           926:                                 || p1->t.op==NAME
        !           927:                                 &&(p1->n.nloc==p->t.tr1->n.nloc
        !           928:                                  || p1->n.regno==p->t.tr1->n.nloc))
        !           929:                                        return(0);
        !           930:                                p1 = p->t.tr2;
        !           931:                                p->t.tr2 = p1->t.tr1;
        !           932:                                if (p1->t.tr1->t.op!=NAME
        !           933:                                 || p1->t.tr1->n.class!=REG
        !           934:                                 || p1->t.tr1->n.nloc!=p->t.tr1->n.nloc)
        !           935:                                        rcexpr(p, efftab, reg);
        !           936:                                p->t.tr2 = p1->t.tr2;
        !           937:                                p->t.op = p1->t.op + ASPLUS - PLUS;
        !           938:                                *treep = p;
        !           939:                                return(1);
        !           940:                        }
        !           941:                        goto OK;
        !           942: 
        !           943:                case ASTIMES:
        !           944:                        if (!ispow2(p))
        !           945:                                return(0);
        !           946:                case ASPLUS:
        !           947:                case ASMINUS:
        !           948:                case ASAND:
        !           949:                case ASANDN:
        !           950:                case ASOR:
        !           951:                case ASXOR:
        !           952:                case INCBEF:
        !           953:                case DECBEF:
        !           954:                OK:
        !           955:                        if (table==cctab||table==cregtab)
        !           956:                                reg += 020;
        !           957:                        rcexpr(optim(p), efftab, ~reg);
        !           958:                        *treep = p1;
        !           959:                        return(1);
        !           960:        }
        !           961:        return(0);
        !           962: }
        !           963: 
        !           964: /*
        !           965:  * Delay handles postfix ++ and -- 
        !           966:  * It observes that "x + y++" is better
        !           967:  * treated as "x + y; y++".
        !           968:  * If the operator is ++ or -- itself,
        !           969:  * it calls rcexpr to load the operand, letting
        !           970:  * the calling instance of rcexpr to do the
        !           971:  * ++ using efftab.
        !           972:  * Otherwise it uses sdelay to search for inc/dec
        !           973:  * among the operands.
        !           974:  */
        !           975: delay(treep, table, reg)
        !           976: union tree **treep;
        !           977: struct table *table;
        !           978: {
        !           979:        register union tree *p, *p1;
        !           980:        register r;
        !           981: 
        !           982:        p = *treep;
        !           983:        if ((p->t.op==INCAFT||p->t.op==DECAFT)
        !           984:         && p->t.tr1->t.op==NAME) {
        !           985:                return(1+rcexpr(paint(p->t.tr1, p->t.type), table, reg));
        !           986:        }
        !           987:        p1 = 0;
        !           988:        if (opdope[p->t.op]&BINARY) {
        !           989:                if (p->t.op==LOGAND || p->t.op==LOGOR
        !           990:                 || p->t.op==QUEST || p->t.op==COLON || p->t.op==SEQNC)
        !           991:                        return(0);
        !           992:                }
        !           993:                p1 = sdelay(&p->t.tr2);
        !           994:        if (p1==0)
        !           995:                p1 = sdelay(&p->t.tr1);
        !           996:        if (p1) {
        !           997:                r = rcexpr(optim(p), table, reg);
        !           998:                *treep = p1;
        !           999:                return(r+1);
        !          1000:        }
        !          1001:        return(0);
        !          1002: }
        !          1003: 
        !          1004: union tree *
        !          1005: sdelay(ap)
        !          1006: union tree **ap;
        !          1007: {
        !          1008:        register union tree *p, *p1;
        !          1009: 
        !          1010:        if ((p = *ap)==TNULL)
        !          1011:                return(TNULL);
        !          1012:        if ((p->t.op==INCAFT||p->t.op==DECAFT) && p->t.tr1->t.op==NAME) {
        !          1013:                *ap = paint(ncopy(p->t.tr1), p->t.type);
        !          1014:                return(p);
        !          1015:        }
        !          1016:        if (p->t.op==STAR || p->t.op==PLUS)
        !          1017:                if (p1=sdelay(&p->t.tr1))
        !          1018:                        return(p1);
        !          1019:        if (p->t.op==PLUS)
        !          1020:                return(sdelay(&p->t.tr2));
        !          1021:        return(0);
        !          1022: }
        !          1023: 
        !          1024: /*
        !          1025:  * Propagate possible implicit type-changing operation
        !          1026:  */
        !          1027: union tree *
        !          1028: paint(tp, type)
        !          1029: register union tree *tp;
        !          1030: register type;
        !          1031: {
        !          1032: 
        !          1033:        if (tp->t.type==type)
        !          1034:                return(tp);
        !          1035:        if (tp->t.type==CHAR && type==INT)
        !          1036:                return(tp);
        !          1037:        if (tp->t.type==CHAR || tp->t.type==UNCHAR)
        !          1038:                return(optim(tnode(LOAD, type, tp, TNULL)));
        !          1039:        tp->t.type = type;
        !          1040:        if (tp->t.op==AMPER && type&XTYPE)
        !          1041:                tp->t.tr1 = paint(tp->t.tr1, decref(type));
        !          1042:        else if (tp->t.op==STAR)
        !          1043:                tp->t.tr1 = paint(tp->t.tr1, incref(type));
        !          1044:        else if (tp->t.op==ASSIGN) {
        !          1045:                paint(tp->t.tr1, type);
        !          1046:                paint(tp->t.tr2, type);
        !          1047:        }
        !          1048:        return(tp);
        !          1049: }
        !          1050: 
        !          1051: /*
        !          1052:  * Copy a tree node for a register variable.
        !          1053:  * Used by sdelay because if *reg-- is turned
        !          1054:  * into *reg; reg-- the *reg will in turn
        !          1055:  * be changed to some offset class, accidentally
        !          1056:  * modifying the reg--.
        !          1057:  */
        !          1058: union tree *
        !          1059: ncopy(p)
        !          1060: register union tree *p;
        !          1061: {
        !          1062:        register union tree *q;
        !          1063: 
        !          1064:        q = getblk(sizeof(struct xtname));
        !          1065:        q->n.op = p->n.op;
        !          1066:        q->n.type = p->n.type;
        !          1067:        q->n.class = p->n.class;
        !          1068:        q->n.regno = p->n.regno;
        !          1069:        q->n.offset = p->n.offset;
        !          1070:        if (q->n.class==EXTERN || q->n.class==XOFFS)
        !          1071:                strncpy(q->x.name, p->x.name, NCPS);
        !          1072:        else
        !          1073:                q->n.nloc = p->n.nloc;
        !          1074:        return(q);
        !          1075: }
        !          1076: 
        !          1077: /*
        !          1078:  * If the tree can be immediately loaded into a register,
        !          1079:  * produce code to do so and return success.
        !          1080:  */
        !          1081: chkleaf(tree, table, reg)
        !          1082: register union tree *tree;
        !          1083: struct table *table;
        !          1084: {
        !          1085:        struct tnode lbuf;
        !          1086: 
        !          1087:        if (tree->t.op!=STAR && dcalc(tree, nreg-reg) > 12)
        !          1088:                return(-1);
        !          1089:        lbuf.op = LOAD;
        !          1090:        lbuf.type = tree->t.type;
        !          1091:        lbuf.degree = tree->t.degree;
        !          1092:        lbuf.tr1 = tree;
        !          1093:        return(rcexpr((union tree *)&lbuf, table, reg));
        !          1094: }
        !          1095: 
        !          1096: /*
        !          1097:  * Compile a function argument.
        !          1098:  * If the stack is currently empty, put it in (sp)
        !          1099:  * rather than -(sp); this will save a pop.
        !          1100:  * Return the number of bytes pushed,
        !          1101:  * for future popping.
        !          1102:  */
        !          1103: comarg(tree, flagp)
        !          1104: register union tree *tree;
        !          1105: int *flagp;
        !          1106: {
        !          1107:        register retval;
        !          1108:        int i;
        !          1109:        int size;
        !          1110: 
        !          1111:        if (tree->t.op==STRASG) {
        !          1112:                size = tree->F.mask;
        !          1113:                tree = tree->t.tr1;
        !          1114:                tree = strfunc(tree);
        !          1115:                if (size <= sizeof(short)) {
        !          1116:                        paint(tree, INT);
        !          1117:                        goto normal;
        !          1118:                }
        !          1119:                if (size <= sizeof(long)) {
        !          1120:                        paint(tree, LONG);
        !          1121:                        goto normal;
        !          1122:                }
        !          1123:                if (tree->t.op!=NAME && tree->t.op!=STAR) {
        !          1124:                        error("Unimplemented structure assignment");
        !          1125:                        return(0);
        !          1126:                }
        !          1127:                tree = tnode(AMPER, STRUCT+PTR, tree, TNULL);
        !          1128:                tree = tnode(PLUS, STRUCT+PTR, tree, tconst(size, INT));
        !          1129:                tree = optim(tree);
        !          1130:                retval = rcexpr(tree, regtab, 0);
        !          1131:                size >>= 1;
        !          1132:                if (size <= 5) {
        !          1133:                        for (i=0; i<size; i++)
        !          1134:                                printf("mov     -(r%d),-(sp)\n", retval);
        !          1135:                } else {
        !          1136:                        if (retval!=0)
        !          1137:                                printf("mov     r%d,r0\n", retval);
        !          1138:                        printf("mov     $%o,r1\n", UNS(size));
        !          1139:                        printf("L%d:mov -(r0),-(sp)\ndec\tr1\njne\tL%d\n", isn, isn);
        !          1140:                        isn++;
        !          1141:                }
        !          1142:                nstack++;
        !          1143:                return(size*2);
        !          1144:        }
        !          1145: normal:
        !          1146:        if (nstack || isfloat(tree) || tree->t.type==LONG) {
        !          1147:                rcexpr(tree, sptab, 0);
        !          1148:                retval = arlength(tree->t.type);
        !          1149:        } else {
        !          1150:                (*flagp)++;
        !          1151:                rcexpr(tree, lsptab, 0);
        !          1152:                retval = 0;
        !          1153:        }
        !          1154:        return(retval);
        !          1155: }
        !          1156: 
        !          1157: union tree *
        !          1158: strfunc(tp)
        !          1159: register union tree *tp;
        !          1160: {
        !          1161:        if (tp->t.op != CALL)
        !          1162:                return(tp);
        !          1163:        paint(tp, STRUCT+PTR);
        !          1164:        return(tnode(STAR, STRUCT, tp, TNULL));
        !          1165: }
        !          1166: 
        !          1167: /*
        !          1168:  * Compile an initializing expression
        !          1169:  */
        !          1170: doinit(type, tree)
        !          1171: register type;
        !          1172: register union tree *tree;
        !          1173: {
        !          1174:        float sfval;
        !          1175:        double fval;
        !          1176:        long lval;
        !          1177: 
        !          1178:        if (type==CHAR || type==UNCHAR) {
        !          1179:                printf(".byte ");
        !          1180:                if (tree->t.type&XTYPE)
        !          1181:                        goto illinit;
        !          1182:                type = INT;
        !          1183:        }
        !          1184:        if (type&XTYPE)
        !          1185:                type = INT;
        !          1186:        switch (type) {
        !          1187:        case INT:
        !          1188:        case UNSIGN:
        !          1189:                if (tree->t.op==FTOI) {
        !          1190:                        if (tree->t.tr1->t.op!=FCON && tree->t.tr1->t.op!=SFCON)
        !          1191:                                goto illinit;
        !          1192:                        tree = tree->t.tr1;
        !          1193:                        tree->c.value = tree->f.fvalue;
        !          1194:                        tree->t.op = CON;
        !          1195:                } else if (tree->t.op==LTOI) {
        !          1196:                        if (tree->t.tr1->t.op!=LCON)
        !          1197:                                goto illinit;
        !          1198:                        tree = tree->t.tr1;
        !          1199:                        lval = tree->l.lvalue;
        !          1200:                        tree->t.op = CON;
        !          1201:                        tree->c.value = lval;
        !          1202:                }
        !          1203:                if (tree->t.op == CON)
        !          1204:                        printf("%o\n", UNS(tree->c.value));
        !          1205:                else if (tree->t.op==AMPER) {
        !          1206:                        pname(tree->t.tr1, 0);
        !          1207:                        putchar('\n');
        !          1208:                } else
        !          1209:                        goto illinit;
        !          1210:                return;
        !          1211: 
        !          1212:        case DOUBLE:
        !          1213:        case FLOAT:
        !          1214:                if (tree->t.op==ITOF) {
        !          1215:                        if (tree->t.tr1->t.op==CON) {
        !          1216:                                fval = tree->t.tr1->c.value;
        !          1217:                        } else
        !          1218:                                goto illinit;
        !          1219:                } else if (tree->t.op==FCON || tree->t.op==SFCON)
        !          1220:                        fval = tree->f.fvalue;
        !          1221:                else if (tree->t.op==LTOF) {
        !          1222:                        if (tree->t.tr1->t.op!=LCON)
        !          1223:                                goto illinit;
        !          1224:                        fval = tree->t.tr1->l.lvalue;
        !          1225:                } else
        !          1226:                        goto illinit;
        !          1227:                if (type==FLOAT) {
        !          1228:                        sfval = fval;
        !          1229: /* nonportable */
        !          1230:                        printf("%o; %o\n",
        !          1231:                                ((unsigned short *)&sfval)[0],
        !          1232:                                ((unsigned short *)&sfval)[1] );
        !          1233:                } else
        !          1234:                        printf("%o; %o; %o; %o\n",
        !          1235:                                ((unsigned short *)&fval)[0],
        !          1236:                                ((unsigned short *)&fval)[1],
        !          1237:                                ((unsigned short *)&fval)[2],
        !          1238:                                ((unsigned short *)&fval)[3] );
        !          1239:                return;
        !          1240: 
        !          1241:        case LONG:
        !          1242:                if (tree->t.op==FTOL) {
        !          1243:                        tree = tree->t.tr1;
        !          1244:                        if (tree->t.op==SFCON)
        !          1245:                                tree->t.op = FCON;
        !          1246:                        if (tree->t.op!= FCON)
        !          1247:                                goto illinit;
        !          1248:                        lval = tree->f.fvalue;
        !          1249:                } else if (tree->t.op==ITOL) {
        !          1250:                        if (tree->t.tr1->t.op != CON)
        !          1251:                                goto illinit;
        !          1252:                        if (uns(tree->t.tr1))
        !          1253:                                lval = (unsigned)tree->t.tr1->c.value;
        !          1254:                        else
        !          1255:                                lval = tree->t.tr1->c.value;
        !          1256:                } else if (tree->t.op==LCON)
        !          1257:                        lval = tree->l.lvalue;
        !          1258:                else
        !          1259:                        goto illinit;
        !          1260: /* nonportable */
        !          1261:                printf("%o; %o\n", UNS((lval>>16)), UNS(lval));
        !          1262:                return;
        !          1263:        }
        !          1264: illinit:
        !          1265:        error("Illegal initialization");
        !          1266: }
        !          1267: 
        !          1268: movreg(r0, r1, tree)
        !          1269: union tree *tree;
        !          1270: {
        !          1271:        register char *s;
        !          1272:        char c;
        !          1273: 
        !          1274:        if (r0==r1)
        !          1275:                return;
        !          1276:        if (tree->t.type==LONG) {
        !          1277:                if (r0>=nreg || r1>=nreg) {
        !          1278:                        error("register overflow: compiler error");
        !          1279:                }
        !          1280:                s = "mov        r%d,r%d\nmov    r%d,r%d\n";
        !          1281:                if (r0 < r1)
        !          1282:                        printf(s, r0+1,r1+1,r0,r1);
        !          1283:                else
        !          1284:                        printf(s, r0,r1,r0+1,r1+1);
        !          1285:                return;
        !          1286:        }
        !          1287:        c = isfloat(tree);
        !          1288:        printf("mov%.1s r%d,r%d\n", &c, r0, r1);
        !          1289: }

unix.superglobalmegacorp.com

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