Annotation of researchv10no/cmd/ccom/vax/genaux.c, revision 1.1.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.