Annotation of researchv10no/cmd/ccom/vax/genaux.c, revision 1.1

1.1     ! root        1: #include "gencode.h"
        !             2: #define NDNUM 800
        !             3: mnod myt[NDNUM];
        !             4: extern mnod *svq;
        !             5: int ntree;
        !             6: char *regnames[] = {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8",
        !             7:        "r9", "r10", "r11", "r12", "r13", "r14", "r15"};
        !             8: char *frameptr = "fp";
        !             9: char *argptr = "ap";
        !            10: #define CHARCHAR 'b'
        !            11: #define SHORTCHAR 'w'
        !            12: #define LONGCHAR 'l'
        !            13: #define FLOATCHAR 'f'
        !            14: #define DOUBLECHAR 'd'
        !            15: 
        !            16: mnod *
        !            17: gimmemnod()
        !            18: {      mnod *p;
        !            19:        p = myt + ntree++;
        !            20:        if(ntree > NDNUM)
        !            21:                cerror("out of temporary trees");
        !            22:        return(p);
        !            23: }
        !            24: 
        !            25: mnod *
        !            26: tempnode(p, flag)
        !            27: mnod *p;
        !            28: {      mnod *x, *q;
        !            29:        int n;
        !            30:        extern int minrvar;
        !            31:        if(p->op == Conv)
        !            32:                q = p;  /* Conv to double of float, versus (CMP double double) */
        !            33:        else
        !            34:                q = (flag & RIGHT)? p->right: p->left;
        !            35:        x = gimmemnod();
        !            36:        x->type = q->type;
        !            37:        n = incrsize(q) == 8? 2: 1;
        !            38:        if(!(flag & ASADDR) && regvar >= REGVAR - 1 + n) {
        !            39:                x->op = Reg;
        !            40:                x->rval = regvar + 1 - n;
        !            41:                x->lval = 1;    /* SCRATCH marker !!!!! */
        !            42:                regvar -= n;
        !            43:                if(minrvar > regvar)
        !            44:                        minrvar = regvar;       /* in case current routine recursive */
        !            45:                return(x);
        !            46:        }
        !            47:        x->op = Auto;
        !            48:        x->lval = gimmetemp(n);
        !            49:        /* scratch marker? */
        !            50:        return(x);
        !            51: }
        !            52: ret
        !            53: alloctmp(p)
        !            54: mnod *p;
        !            55: {      ret s;
        !            56:        sprintf(buf, "%d(%s)", gimmetemp(incrsize(p) == 8? 2: 1), frameptr);
        !            57:        done(s, CANINDIR|SCRATCH, 0);
        !            58: }
        !            59: 
        !            60: ret
        !            61: allocreg(p, regmask)
        !            62: mnod *p;
        !            63: {      int i, n;
        !            64:        ret s;
        !            65:        mnod *x;
        !            66:        if(p->type == Tdouble)
        !            67:                n = 2;
        !            68:        else
        !            69:                n = 1;
        !            70:        for(i = 0; i < REGVAR; i++) {
        !            71:                if(!(regmask & (1 << i)))
        !            72:                        continue;
        !            73:                if(n == 2 & !(regmask & (1 << (1+i))))
        !            74:                        continue;
        !            75:                sprintx(buf, "%s", regnames[i]);
        !            76:                regmask = (1 << i);
        !            77:                if(n == 2)
        !            78:                        regmask |= (1 << (i+1));
        !            79:                done(s, SCRATCH|ISREG, regmask);
        !            80:        }
        !            81:        x = tempnode(p, 0);
        !            82:        if(x->op == Reg) {
        !            83:                sprintx(buf, "%s", regnames[x->rval]);
        !            84:                done(s, SCRATCH|ISREG, 0);
        !            85:        }
        !            86:        sprintx(buf, "%d(%s)", x->lval, frameptr);
        !            87:        done(s, SCRATCH|CANINDIR, 0);
        !            88: }
        !            89: 
        !            90: isfloat(p)
        !            91: mnod *p;
        !            92: {
        !            93:        return(p->type == Tfloat || p->type == Tdouble);
        !            94: }
        !            95: 
        !            96: childtype(p)
        !            97: mnod *p;
        !            98: {
        !            99:        return(type(p->left));
        !           100: }
        !           101: 
        !           102: char typearr[] = {LONGCHAR, CHARCHAR, CHARCHAR, SHORTCHAR, SHORTCHAR,
        !           103:        LONGCHAR, LONGCHAR, LONGCHAR, LONGCHAR,
        !           104:        FLOATCHAR, DOUBLECHAR, '?', '?'};
        !           105: type(p)
        !           106: mnod *p;
        !           107: {
        !           108:        return(typearr[p->type]);
        !           109: }
        !           110: 
        !           111: int shiftarr[] = {2, 0, 0, 1, 1, 2, 2, 2, 2, 2, 3, -99, 0};
        !           112: shiftsize(p)
        !           113: mnod *p;
        !           114: {
        !           115:        return(shiftarr[p->type]);
        !           116: }      
        !           117: 
        !           118: int incrarr[] = {4, 1, 1, 2, 2, 4, 4, 4, 4, 4, 8, -99, 0};
        !           119: incrsize(p)
        !           120: mnod *p;
        !           121: {
        !           122:        return(incrarr[p->type]);
        !           123: }
        !           124: 
        !           125: int unsarr[] = {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0};        
        !           126: isunsigned(p)
        !           127: mnod *p;
        !           128: {
        !           129:        return(unsarr[p->type]);
        !           130: }
        !           131: 
        !           132: mnod *
        !           133: copymnod(p)
        !           134: mnod *p;
        !           135: {      mnod *a, *b, *c;
        !           136:        c = gimmemnod();
        !           137:        switch(p->op) {
        !           138:        case Andeq: case And: case Cmp: case Comop: case Decr: 
        !           139:        case Diveq: case Div: case Xoreq: case Xor:
        !           140:        case Incr: case Lseq: case Ls: case Minuseq: case Minus:
        !           141:        case Modeq: case Mod: case Muleq: case Mul: case Oreq:
        !           142:        case Or: case Pluseq: case Plus: case Rseq: case Rs:
        !           143:        case Asg: case Cm:
        !           144:        case Call: case Stcall:
        !           145:        case Stasg:
        !           146:                a = copymnod(p->left);
        !           147:                b = copymnod(p->right);
        !           148:                *c = *p;
        !           149:                c->left = a;
        !           150:                c->right = b;
        !           151:                return(c);
        !           152:        case Compl: case Conv: case Genbr: case Genlab:
        !           153:        case Genubr: case Star: case Addr: case Ucall:
        !           154:        case Uminus: case Ustcall: case Init: case Funarg:
        !           155:        case Fld:case Starg:
        !           156:                a = copymnod(p->left);
        !           157:                *c = *p;
        !           158:                c->left = a;
        !           159:                return(c);
        !           160:        case Auto: case Reg: case Name: case Param: case Icon:
        !           161:        case Snode: case Rnode: case Qnode:
        !           162:                *c = *p;
        !           163:                return(c);
        !           164:        default:
        !           165:                cerror("unk mnod in copymnod");
        !           166:        }
        !           167: }
        !           168: 
        !           169: /* rewrit A op B into (T = A, T) op B or A op (T = B, T) */
        !           170: totemp(p, flag)
        !           171: mnod *p;
        !           172: {      mnod *a, *b, *c;
        !           173:        a = gimmemnod();
        !           174:        b = tempnode(p, flag);
        !           175:        c = gimmemnod();
        !           176:        if(flag & LEFT)
        !           177:                *a = *p->left;
        !           178:        else
        !           179:                *a = *p->right;
        !           180:        a->op = Asg;
        !           181:        a->left = b;
        !           182:        if(flag & LEFT)
        !           183:                a->right = p->left;
        !           184:        else
        !           185:                a->right = p->right;
        !           186:        c->op = Comop;
        !           187:        c->left = a;
        !           188:        c->right = b;
        !           189:        c->type = a->type;
        !           190:        if(flag & LEFT)
        !           191:                p->left = c;
        !           192:        else
        !           193:                p->right = c;
        !           194: }
        !           195: 
        !           196: funargs(p, regmask)
        !           197: mnod *p;
        !           198: {      ret s, t;
        !           199:        int i;
        !           200:        switch(p->op) {
        !           201:        case Cm:        /* order depends on way stack grows */
        !           202: #ifdef LTORARGS
        !           203:                i = funargs(p->left, regmask);
        !           204:                i |= funargs(p->right, regmask);
        !           205: #else
        !           206:                i = funargs(p->right, regmask);
        !           207:                i |= funargs(p->left, regmask);
        !           208: #endif
        !           209:                return(i);
        !           210:        case Funarg:
        !           211:                t = tostack();
        !           212:                s = doit(p->left, VALUE|TOSTACK, t, regmask);
        !           213:                return(s.flag & FAIL);
        !           214:        case Starg:
        !           215:                /* this has to have same cases as STASG */
        !           216:                if(regmask != REGMASK)
        !           217:                        return(FAILX);
        !           218:                s = doit(p->left, (ASADDR|VALUE|FSTASG), 0, regmask);
        !           219:                /* this generates expensive code for small structures */
        !           220:                i = p->stsize / 8;
        !           221:                if(p->left->op == Stasg) {
        !           222:                        if(i != 4 && i != 8) {
        !           223:                                pr("#\tsubl2\t$%d,sp\n", i);
        !           224:                                pr("#\tsubl2\t$%d,r3\n", i);
        !           225:                                pr("#\tmovc3\t$%d,(r3),(sp)\n", p->stsize/8);
        !           226:                                return(0);
        !           227:                        }
        !           228:                }
        !           229:                if(i == 4)
        !           230:                        pr("#\tpushl\t%s\n", str(s));
        !           231:                else if(i == 8)
        !           232:                        pr("#\tmovq\t%s,-(sp)\n", str(s));
        !           233:                else {
        !           234:                        pr("#\tsubl2\t$%d,sp\n", i);
        !           235:                        pr("#\tmovc3\t$%d,%s,(sp)\n", p->stsize/8, str(s));
        !           236:                }
        !           237:                return(s.flag & FAIL);
        !           238:        }
        !           239: }
        !           240: ret
        !           241: specialreg(p, regmask)
        !           242: mnod *p;
        !           243: {      ret s;
        !           244:        int n, i;
        !           245:        n = p->type == Tdouble? 2: 1;
        !           246:        i = 1;
        !           247:        if(n == 2)
        !           248:                i = 3;
        !           249:        sprintx(buf, "%s", regnames[0]);
        !           250:        if(i & ~regmask)
        !           251:                pr("#\specialreg not free\n");
        !           252:        done(s, SCRATCH|ISREG, i);
        !           253: }
        !           254: /* these guys rewrite a1 = a2 = ... an = x
        !           255:  * as t = x; an = t; an-1 = an */
        !           256: mnod *
        !           257: fromtemp(p, temp)
        !           258: mnod *p, *temp;
        !           259: {      mnod *q;
        !           260:        q = gimmemnod();
        !           261:        *q = *p;
        !           262:        q->left = p;
        !           263:        q->op = Asg;
        !           264:        q->right = temp;
        !           265:        return(q);
        !           266: }
        !           267: 
        !           268: mnod *
        !           269: to(p, temp)
        !           270: mnod *p, *temp;
        !           271: {      mnod *q;
        !           272:        q = gimmemnod();
        !           273:        *q = *p;
        !           274:        q->right = p;
        !           275:        q->op = Asg;
        !           276:        q->left = temp;
        !           277:        return(q);
        !           278: }
        !           279: 
        !           280: mnod *
        !           281: commnod(a, p)
        !           282: mnod *a, *p;
        !           283: {      mnod *q;
        !           284:        q = gimmemnod();
        !           285:        *q = *p;
        !           286:        q->op = Comop;
        !           287:        q->right = p;
        !           288:        q->left = a;
        !           289:        return(q);
        !           290: }
        !           291: 
        !           292: asgwrite(p)
        !           293: mnod *p;
        !           294: {      mnod *q, *a, *temp;
        !           295:        debugpr("#REWRITEasgwrite ");
        !           296:        temp = tempnode(p, 0);
        !           297:        a = fromtemp(p->left, temp);
        !           298:        for(q = p->right; q->op == Asg; q = q->right)
        !           299:                a = commnod(fromtemp(q->left, temp), a);
        !           300:        a = commnod(to(q, temp), a);
        !           301:        *p = *a;
        !           302: }
        !           303: 
        !           304: lsconv(p)
        !           305: mnod *p;
        !           306: {      mnod *lft, *right;
        !           307:        debugpr("#REWRITElsconv ");
        !           308:        lft = gimmemnod();
        !           309:        right = gimmemnod();
        !           310:        lft->op = right->op = Conv;
        !           311:        lft->type = right->type = Tlong;
        !           312:        lft->left = p->left;
        !           313:        right->left = p->right;
        !           314:        if(p->left->op != Icon) /* Icon are longs anyway (see RS) */
        !           315:                p->left = lft;
        !           316:        p->right = right;
        !           317: }
        !           318: /* only some ops have to be rewritten (addb and addl are the same at the bottom) */
        !           319: rewriteasgop(p)
        !           320: mnod *p;
        !           321: {      mnod *a, *newop;
        !           322:        if(p->left->op != Conv)
        !           323:                return(0);
        !           324:        if(p->left->left->op == Star)
        !           325:                longjmp(back, awfulstar(p));
        !           326:        debugpr("#REWRITE rewriteasgop ");
        !           327:        newop = gimmemnod();
        !           328:        *newop = *p;
        !           329:        switch(p->op) {
        !           330:        case Diveq:
        !           331:                newop->op = Div;
        !           332:                break;
        !           333:        case Lseq:
        !           334:                newop->op = Ls;
        !           335:                break;
        !           336:        case Modeq:
        !           337:                newop->op = Mod;
        !           338:                break;
        !           339:        case Rseq:
        !           340:                newop->op = Rs;
        !           341:                break;
        !           342:        case Pluseq:
        !           343:                if(!isfloat(p->left))
        !           344:                        return(0);
        !           345:                newop->op = Plus;
        !           346:                break;
        !           347:        case Minuseq:
        !           348:                if(!isfloat(p->left))
        !           349:                        return(0);
        !           350:                newop->op = Minus;
        !           351:                break;
        !           352:        case Muleq:
        !           353:                if(!isfloat(p->left))
        !           354:                        return(0);
        !           355:                newop->op = Mul;
        !           356:                break;
        !           357: 
        !           358:        default:
        !           359:                cerror("codegen: rewriting asgop");
        !           360:        }
        !           361:        a = gimmemnod();
        !           362:        *a = *p->left->left;
        !           363:        p->op = Asg;
        !           364:        p->left = a;
        !           365:        p->right = newop;
        !           366:        return(1);
        !           367: }
        !           368: 
        !           369: rewriteconv(p) /* uns to float or double */
        !           370: mnod *p;
        !           371: {      mnod *a;
        !           372:        debugpr("#REWRITEconv ");
        !           373:        a = gimmemnod();
        !           374:        *a = *p;
        !           375:        a->type = Tlong;
        !           376:        p->left = a;
        !           377: }
        !           378: 
        !           379: /* =(FLD(*(A)),B) -> ,(=(T,A), =(FLD(*(T)),B) */
        !           380: fldstar(p)
        !           381: mnod *p;
        !           382: {      mnod *A, *B, *T, *newtop;
        !           383:        debugpr("#REWRITE fldstar ");write(2, "fldstar\n", 8);
        !           384:        A = p->left->left->left;
        !           385:        B = p->right;
        !           386:        T = tempnode(A, 0);
        !           387:        newtop = gimmemnod();
        !           388:        newtop->op = Comop;
        !           389:        newtop->type = p->type;
        !           390:        newtop->left = gimmemnod();
        !           391:        newtop->left->op = Asg;
        !           392:        newtop->left->type = A->type;
        !           393:        newtop->left->left = T;
        !           394:        newtop->left->right = A;
        !           395:        newtop->right = gimmemnod();
        !           396:        *newtop->right = *p;
        !           397:        p->left->left->left = T;
        !           398:        *p = *newtop;
        !           399: }
        !           400: 
        !           401: mediumstar(p)
        !           402: mnod *p;
        !           403: {      mnod *newtop, *tmp, *x, *y;
        !           404:        debugpr("#REWRITE mediumstar ");
        !           405:        newtop = gimmemnod();
        !           406:        newtop->op = Comop;
        !           407:        newtop->type = p->type;
        !           408:        x = gimmemnod();
        !           409:        x->op = Asg;
        !           410:        x->type = Tpoint;
        !           411:        x->right = p->left->left;
        !           412:        newtop->left = x;
        !           413:        tmp = tempnode(newtop, 0);
        !           414:        tmp->type = Tpoint;
        !           415:        x->left = tmp;
        !           416:        y = gimmemnod();
        !           417:        y->op = Comop;
        !           418:        y->type = p->type;
        !           419:        x = gimmemnod();
        !           420:        *x = *p;
        !           421:        newtop->right = y;
        !           422:        y->left = x;
        !           423:        y->right = x->left;
        !           424:        x->left->left = tmp;
        !           425:        *p = *newtop;
        !           426:        return(1);
        !           427: }
        !           428: 
        !           429: awfulstar(p)
        !           430: mnod *p;
        !           431: {      mnod *newtop, *doleft, *x, *op, *equals;
        !           432:        debugpr("#REWRITE awfulstar ");
        !           433:        newtop = gimmemnod();
        !           434:        newtop->op = Comop;
        !           435:        newtop->type = p->type;
        !           436:        doleft = gimmemnod();
        !           437:        doleft->op = Asg;
        !           438:        doleft->type = Tpoint;
        !           439:        doleft->right = p->left->left->left;
        !           440:        x = tempnode(doleft, RIGHT);
        !           441:        doleft->left = x;
        !           442:        op = gimmemnod();
        !           443:        *op = *p;
        !           444:        op->op += 1;    /* cheap hack */
        !           445:        op->left->left->left = x;       /* so it's a dag, but x is harmless */
        !           446:        equals = gimmemnod();
        !           447:        *equals = *p;
        !           448:        equals->right = op;
        !           449:        equals->left = p->left->left;
        !           450:        equals->op = Asg;
        !           451:        *p = *newtop;
        !           452:        p->left = doleft;
        !           453:        p->right = equals;
        !           454:        return(1);
        !           455: }
        !           456: rewritefld(p)
        !           457: mnod *p;
        !           458: {      mnod *q, *tmp, *left, *comop;
        !           459:        debugpr("#REWRITEfld ");
        !           460:        if((q = p->left->left)->op != Star) {
        !           461:                rewfld(p);
        !           462:                return;
        !           463:        }
        !           464:        q = q->left;
        !           465:        tmp = tempnode(q, 0);
        !           466:        left = gimmemnod();
        !           467:        left->type = q->type;
        !           468:        left->op = Asg;
        !           469:        left->left = tmp;
        !           470:        left->right = gimmemnod();
        !           471:        left->right = copymnod(q);
        !           472:        *q = *tmp;
        !           473:        comop = gimmemnod();
        !           474:        comop->op = Comop;
        !           475:        comop->left = left;
        !           476:        comop->right = copymnod(p);
        !           477:        *p = *comop;
        !           478:        rewfld(p->right);
        !           479:        longjmp(back, 1);
        !           480: }
        !           481: rewfld(p)
        !           482: mnod *p;
        !           483: {      mnod *x, *y, *z;
        !           484:        x = gimmemnod();
        !           485:        *x = *copymnod(p);
        !           486:        y = gimmemnod();
        !           487:        *y = *copymnod(p);
        !           488:        z = gimmemnod();
        !           489:        *z = *p;
        !           490:        z->left = x;
        !           491:        x->op = Asg;
        !           492:        x->right = y;
        !           493:        if(p->op == Decr || p->op == Minuseq)
        !           494:                z->op = Plus;
        !           495:        else
        !           496:                z->op = Minus;
        !           497:        if(p->op == Decr)
        !           498:                y->op = Minus;
        !           499:        else if(p->op == Incr)
        !           500:                y->op = Plus;
        !           501:        else
        !           502:                y->op += 1;     /* cheap hack */
        !           503:        if(p->op == Decr || p->op == Incr)
        !           504:                *p = *z;
        !           505:        else
        !           506:                *p = *x;
        !           507: }
        !           508: /* not int = (...? int exprs) have a bogus tree */
        !           509: extracheck(p)
        !           510: mnod *p;
        !           511: {      mnod *a;
        !           512:        if(p->right->op != Genlab && p->right->op != Comop)
        !           513:                return;
        !           514:        debugpr("#REWRITE extracheck ");
        !           515:        a = gimmemnod();
        !           516:        *a = *p;
        !           517:        a->left = p->right;
        !           518:        a->op = Conv;
        !           519:        p->right = a;
        !           520: }
        !           521: 
        !           522: starasg(p)
        !           523: mnod *p;
        !           524: {      mnod *tmp, *asg, *x;
        !           525:        debugpr("#REWRITE starasg ");
        !           526:        tmp = tempnode(p->left->left, 0);
        !           527:        x = gimmemnod();
        !           528:        *x = *p;
        !           529:        asg = gimmemnod();
        !           530:        *asg = *p->left->left;
        !           531:        asg->op = Asg;
        !           532:        asg->left = tmp;
        !           533:        asg->right = p->left->left;
        !           534:        x->left->left = tmp;
        !           535:        p->op = Comop;
        !           536:        p->left = asg;
        !           537:        p->right = x;
        !           538: }
        !           539: /* *A op= B => (T=A, *T op= B) if T has Incr or Asg */
        !           540: fixuns(p)
        !           541: mnod *p;
        !           542: {      mnod *tmp, *asg, *new;
        !           543:        if(!sideffects(p->left->left))
        !           544:                return(0);
        !           545:        debugpr("#REWRITE fixuns");
        !           546:        tmp = tempnode(p->left->left, 0);
        !           547:        asg = gimmemnod();
        !           548:        asg->type = tmp->type;
        !           549:        asg->op = Asg;
        !           550:        asg->left = tmp;
        !           551:        asg->right = p->left->left;
        !           552:        new = gimmemnod();
        !           553:        *new = *p;
        !           554:        new->left->left = tmp;
        !           555:        p->op = Comop;
        !           556:        p->left = asg;
        !           557:        p->right = new;
        !           558:        return(1);
        !           559: }
        !           560: 
        !           561: stasgrewrite(p)
        !           562: mnod *p;
        !           563: {      mnod *qa, *qb, *n, *left, *right;
        !           564:        debugpr("#REWRITE starasgrewrite ");
        !           565:        totemp(p, RIGHT);
        !           566:        longjmp(back, 1);
        !           567: }

unix.superglobalmegacorp.com

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