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