Annotation of lucent/sys/src/alef/k/inst.c, revision 1.1.1.1

1.1       root        1: #include <u.h>
                      2: #include <libc.h>
                      3: #include <bio.h>
                      4: #include <ctype.h>
                      5: #define Extern extern
                      6: #include "parl.h"
                      7: #include "globl.h"
                      8: 
                      9: /* These are machine specific convs which generate no code */
                     10: ulong
                     11: nopconv[Ntype] =
                     12: {
                     13:        0,                      /* TXXX */
                     14:        MINT|MUINT|MIND,        /* TINT */
                     15:        MINT|MUINT|MIND,        /* TUINT */
                     16:        MSINT|MSUINT,           /* TSINT */
                     17:        MSINT|MSUINT,           /* TSUINT */
                     18:        MCHAR,                  /* TCHAR */
                     19:        MFLOAT,                 /* TFLOAT */
                     20:        MINT|MUINT|MIND,        /* TIND */
                     21:        0,                      /* TCHANNEL */
                     22:        0,                      /* TARRAY */
                     23:        MAGGREGATE,             /* TAGGREGATE */
                     24:        MUNION,                 /* TUNION */
                     25:        0,                      /* TFUNC */
                     26:        0,                      /* TVOID */
                     27:        TADT,                   /* TADT */
                     28: };
                     29: 
                     30: Inst*
                     31: ai(void)
                     32: {
                     33:        Inst *i;
                     34: 
                     35:        i = malloc(sizeof(Inst));
                     36:        i->src1.type = A_NONE;
                     37:        i->dst.type = A_NONE;
                     38:        i->reg = Nreg;
                     39:        i->next = 0;
                     40:        i->lineno = iline;
                     41:        return i;
                     42: }
                     43: 
                     44: /* Emit an assembler instruction */
                     45: Inst*
                     46: instruction(int op, Node *s1, Node *s2, Node *dst)
                     47: {
                     48:        Inst *i;
                     49: 
                     50:        i = ai();
                     51:        i->op = op;
                     52:        i->pc = pc++;
                     53: 
                     54:        if(s1)
                     55:                mkaddr(s1, &i->src1, 1);
                     56: 
                     57:        if(s2 && s2 != dst) {
                     58:                switch(s2->type) {
                     59:                case OREGISTER:
                     60:                        break;
                     61:                case OCONST:
                     62:                        if(s2->ival == 0) {
                     63:                                s2->reg = 0;
                     64:                                break;
                     65:                        }
                     66:                        /* Fall */
                     67:                default:
                     68:                        fatal("inst %s %N,%N,%N", itab[op], s1, s2, dst);
                     69:                }
                     70:                if(s2->t->type == TFLOAT)
                     71:                        i->reg = s2->reg - Freg;
                     72:                else
                     73:                        i->reg = s2->reg;
                     74:        }
                     75: 
                     76:        if(dst) {
                     77:                mkaddr(dst, &i->dst, 1);
                     78:                if(i->dst.type == A_REG)
                     79:                if(i->reg == i->dst.reg)
                     80:                        i->reg = Nreg;
                     81:        }
                     82:        ilink(i);
                     83:        return ipc;
                     84: }
                     85: 
                     86: void
                     87: ilink(Inst *i)
                     88: {
                     89:        if(opt('c'))
                     90:                print("(%d)%i\n", i->lineno, i);
                     91: 
                     92:        if(proghead)
                     93:                ipc->next = i;
                     94:        else
                     95:                proghead = i;
                     96: 
                     97:        ipc = i;
                     98: }
                     99: 
                    100: /* Back patch a branch */
                    101: void
                    102: label(Inst *i, ulong pc)
                    103: {
                    104:        Adres *a;
                    105: 
                    106:        switch(i->op) {
                    107:        case ABA:
                    108:        case ABCC:
                    109:        case ABCS:
                    110:        case ABE:
                    111:        case ABG:
                    112:        case ABGE:
                    113:        case ABGU:
                    114:        case ABL:
                    115:        case ABLE:
                    116:        case ABLEU:
                    117:        case ABN:
                    118:        case ABNE:
                    119:        case ABNEG:
                    120:        case ABPOS:
                    121:        case ABVC:
                    122:        case ABVS:
                    123:        case AJMPL:
                    124:        case AJMP:
                    125:        case AFBA:
                    126:        case AFBE:
                    127:        case AFBG:
                    128:        case AFBGE:
                    129:        case AFBL:
                    130:        case AFBLE:
                    131:        case AFBLG:
                    132:        case AFBN:
                    133:        case AFBNE:
                    134:        case AFBO:
                    135:        case AFBU:
                    136:        case AFBUE:
                    137:        case AFBUG:
                    138:        case AFBUGE:
                    139:        case AFBUL:
                    140:        case AFBULE:
                    141:                break;
                    142: 
                    143:        default:
                    144:                fatal("label not branch");
                    145:        }
                    146:        a = &i->dst;
                    147:        a->type = A_BRANCH;
                    148:        a->ival = pc;
                    149: }
                    150: 
                    151: /* Select code for arithmetic operations */
                    152: void
                    153: codmop(Node *o, Node *l, Node *r, Node *dst)
                    154: {
                    155:        int op;
                    156: 
                    157:        op = AGOK;
                    158:        switch(o->type) {
                    159:        case OADD:
                    160:        case OADDEQ:
                    161:                switch(o->t->type) {
                    162:                default:
                    163:                        op = AADD;
                    164:                        break;
                    165:                case TFLOAT:
                    166:                        op = AFADDD;
                    167:                        break;
                    168:                }
                    169:                break;
                    170: 
                    171:        case OSUB:
                    172:        case OSUBEQ:
                    173:                switch(o->t->type) {
                    174:                default:
                    175:                        op = ASUB;
                    176:                        break;
                    177:                case TFLOAT:
                    178:                        op = AFSUBD;
                    179:                        break;
                    180:                }
                    181:                break;
                    182: 
                    183:        case OMUL:
                    184:        case OMULEQ:
                    185:                switch(o->t->type) {
                    186:                default:
                    187:                        op = AMUL;
                    188:                        break;
                    189:                case TFLOAT:
                    190:                        op = AFMULD;
                    191:                        break;
                    192:                }
                    193:                break;
                    194: 
                    195:        case ODIV:
                    196:        case ODIVEQ:    
                    197:                switch(o->t->type) {
                    198:                default:
                    199:                        op = ADIV;
                    200:                        break;
                    201:                case TUINT:
                    202:                case TSUINT:
                    203:                        op = ADIVL;
                    204:                        break;
                    205:                case TFLOAT:
                    206:                        op = AFDIVD;
                    207:                        break;
                    208:                }
                    209:                break;
                    210: 
                    211:        case OMOD:
                    212:        case OMODEQ:
                    213:                switch(o->t->type) {
                    214:                default:
                    215:                        op = AMOD;
                    216:                        break;
                    217:                case TUINT:
                    218:                case TSUINT:
                    219:                        op = AMODL;
                    220:                        break;
                    221:                }
                    222:                break;
                    223: 
                    224:        case OALSH:
                    225:        case OLSH:
                    226:        case OLSHEQ:
                    227:                op = ASLL;
                    228:                break;
                    229: 
                    230:        case ORSH:
                    231:        case ORSHEQ:
                    232:                op = ASRL;
                    233:                break;
                    234: 
                    235:        case OXOR:
                    236:        case OXOREQ:
                    237:                op = AXOR;
                    238:                break;
                    239: 
                    240:        case OLOR:
                    241:        case OOREQ:
                    242:                op = AOR;
                    243:                break;
                    244: 
                    245:        case OLAND:
                    246:        case OANDEQ:
                    247:                op = AAND;
                    248:                break;
                    249: 
                    250:        case OARSH:
                    251:                op = ASRA;
                    252:                break;
                    253:        }
                    254:        instruction(op, l, r, dst);
                    255: }
                    256: 
                    257: int
                    258: mulcon(Node *n, Node *nn)
                    259: {
                    260:        int o;
                    261:        long v;
                    262:        Multab *m;
                    263:        Node *l, *r, nod1, nod2, mop;
                    264:        char code[sizeof(m->code)+2], *p;
                    265: 
                    266:        if(n->t->type == TFLOAT)
                    267:                return 0;
                    268: 
                    269:        mop.t = n->t;
                    270:        l = n->left;
                    271:        r = n->right;
                    272:        if(l->type == OCONST) {
                    273:                l = r;
                    274:                r = n->left;
                    275:        }
                    276:        if(r->type != OCONST)
                    277:                return 0;
                    278: 
                    279:        v = r->ival;
                    280:        m = mulcon0(v);
                    281:        if(!m) {
                    282:                if(opt('M'))
                    283:                        print("%L multiply table: %lld\n", r->ival);
                    284:                return 0;
                    285:        }
                    286:        if(opt('M'))
                    287:                print("%L multiply: %ld\n", v);
                    288: 
                    289:        memmove(code, m->code, sizeof(m->code));
                    290:        code[sizeof(m->code)] = 0;
                    291: 
                    292:        p = code;
                    293:        if(p[1] == 'i')
                    294:                p += 2;
                    295:        reg(&nod1, n->t, nn);
                    296:        genexp(l, &nod1);
                    297:        if(v < 0) {
                    298:                mop.type = OSUB;
                    299:                codmop(&mop, &nod1, con(0), &nod1);
                    300:        }
                    301:        reg(&nod2, n->t, ZeroN);
                    302: 
                    303:        for(;;) {
                    304:                switch(*p) {
                    305:                case '\0':
                    306:                        regfree(&nod2);
                    307:                        assign(&nod1, nn);
                    308:                        regfree(&nod1);
                    309:                        return 1;
                    310:                case '+':
                    311:                        o = OADD;
                    312:                        goto addsub;
                    313:                case '-':
                    314:                        o = OSUB;
                    315:                addsub: /* number is r,n,l */
                    316:                        v = p[1] - '0';
                    317:                        r = &nod1;
                    318:                        if(v&4)
                    319:                                r = &nod2;
                    320:                        n = &nod1;
                    321:                        if(v&2)
                    322:                                n = &nod2;
                    323:                        l = &nod1;
                    324:                        if(v&1)
                    325:                                l = &nod2;
                    326:                        mop.type = o;
                    327:                        codmop(&mop, l, n, r);
                    328:                        break;
                    329:                default: /* op is shiftcount, number is r,l */
                    330:                        v = p[1] - '0';
                    331:                        r = &nod1;
                    332:                        if(v&2)
                    333:                                r = &nod2;
                    334:                        l = &nod1;
                    335:                        if(v&1)
                    336:                                l = &nod2;
                    337:                        v = *p - 'a';
                    338:                        if(v < 0 || v >= 32) {
                    339:                                diag(n, "mulcon unknown op: %c%c", p[0], p[1]);
                    340:                                break;
                    341:                        }
                    342:                        mop.type = OALSH;
                    343:                        codmop(&mop, con(v), l, r);
                    344:                        break;
                    345:                }
                    346:                p += 2;
                    347:        }
                    348:        return 0;
                    349: }
                    350: 
                    351: int
                    352: vconst(Node *n)
                    353: {
                    354:        int i;
                    355: 
                    356:        if(n == ZeroN || n->type != OCONST || n->t == ZeroT)
                    357:                return -159;
                    358: 
                    359:        switch(n->t->type) {
                    360:        case TFLOAT:
                    361:                i = 100;
                    362:                if(n->fval > i || n->fval < -i)
                    363:                        return -159;
                    364:                i = n->fval;
                    365:                if(i != n->fval)
                    366:                        return -159;
                    367:                return i;
                    368: 
                    369:        case TCHAR:
                    370:        case TSINT:
                    371:        case TSUINT:
                    372:        case TINT:
                    373:        case TUINT:
                    374:        case TIND:
                    375:                i = n->ival;
                    376:                if(i != n->ival)
                    377:                        return -159;
                    378:                return i;
                    379:        }
                    380: }
                    381: 
                    382: /* Select code for conditional operators */
                    383: void
                    384: codcond(int comp, Node *src1, Node *src2)
                    385: {
                    386:        int a, t;
                    387: 
                    388:        if(src1->type == OCONST)
                    389:        if(src1->ival == 0)
                    390:        if(src1->t->type != TFLOAT)
                    391:                src1 = regn(0);
                    392: 
                    393:        if(src2->type == OCONST)
                    394:        if(src2->ival == 0)
                    395:        if(src2->t->type != TFLOAT)
                    396:                src2 = regn(0);
                    397: 
                    398:        t = src1->t->type;
                    399:        switch(comp) {
                    400:        default:
                    401:                fatal("codcond: %N %s %N", src1, treeop[comp]+1, src2);
                    402: 
                    403:        case OEQ:
                    404:                a = ABE;
                    405:                if(t == TFLOAT)
                    406:                        a = AFBE;
                    407:                break;
                    408: 
                    409:        case ONEQ:
                    410:                a = ABNE;
                    411:                if(t == TFLOAT)
                    412:                        a = AFBNE;
                    413:                break;
                    414: 
                    415:        case OLT:
                    416:                a = ABL;
                    417:                if(t == TFLOAT)
                    418:                        a = AFBL;
                    419:                break;
                    420:                
                    421:        case OGT:
                    422:                a = ABG;
                    423:                if(t == TFLOAT)
                    424:                        a = AFBG;
                    425:                break;
                    426: 
                    427:        case OLEQ:
                    428:                a = ABLE;
                    429:                if(t == TFLOAT)
                    430:                        a = AFBLE;
                    431:                break;
                    432: 
                    433:        case OGEQ:
                    434:                a = ABGE;
                    435:                if(t == TFLOAT)
                    436:                        a = AFBGE;
                    437:                break;
                    438: 
                    439:        case OLO:
                    440:                a = ABCS;
                    441:                break;
                    442: 
                    443:        case OHI:
                    444:                a = ABGU;
                    445:                break;
                    446: 
                    447:        case OLOS:
                    448:                a = ABLEU;
                    449:                break;
                    450: 
                    451:        case OHIS:
                    452:                a = ABCC;
                    453:                break;
                    454:        }
                    455: 
                    456:        if(t == TFLOAT)
                    457:                instruction(AFCMPD,src1, ZeroN, src2);
                    458:        else
                    459:                instruction(ACMP, src1, ZeroN, src2);
                    460: 
                    461:        instruction(a, ZeroN, ZeroN, ZeroN);
                    462: }
                    463: 
                    464: void
                    465: mkdata(Node *n, int off, int size, Inst *i)
                    466: {
                    467:        Adres *a;
                    468: 
                    469:        if(n->type != ONAME)
                    470:                fatal("mkdata %N\n", n);
                    471: 
                    472:        a = &i->src1;
                    473: 
                    474:        a->reg = Nreg;
                    475:        a->ival = off;
                    476:        a->sym = n->sym;
                    477:        a->type = A_INDREG;
                    478:        a->class = n->t->class;
                    479:        a->etype = n->t->type;
                    480: 
                    481:        i->reg = size;
                    482: }
                    483: 
                    484: void
                    485: mkaddr(Node *n, Adres *a, int ur0)
                    486: {
                    487:        long o;
                    488:        Tinfo *ti;
                    489: 
                    490:        a->sym = ZeroS;
                    491:        a->reg = Nreg;
                    492: 
                    493:        switch(n->type) {
                    494:        default:
                    495:                fatal("mkaddr: %N\n", n);
                    496: 
                    497:        case ONAME:
                    498:                ti = n->ti;
                    499: 
                    500:                a->type = A_INDREG;
                    501:                a->etype = ti->t->type;
                    502:                a->ival = ti->offset;
                    503:                a->sym = n->sym;
                    504:                if(ti->class == Argument) {
                    505:                        a->reg = RegSP;
                    506:                        a->class = A_NONE;
                    507:                        break;
                    508:                }
                    509:                a->class = ti->class;
                    510:                break;
                    511: 
                    512:        case OCONST:
                    513:                switch(n->t->type) {
                    514:                default:
                    515:                        if(ur0 && n->ival == 0) {
                    516:                                a->type = A_REG;
                    517:                                a->reg = 0;
                    518:                                break;
                    519:                        }
                    520:                        a->type = A_CONST;
                    521:                        a->ival = n->ival;
                    522:                        break;
                    523:                case TFLOAT:
                    524:                        a->type = A_FCONST;
                    525:                        a->fval = n->fval;
                    526:                        break;
                    527:                }
                    528:                break;
                    529: 
                    530:        case OADD:
                    531:                if(n->left->type == OCONST) {
                    532:                        mkaddr(n->left, a, 0);
                    533:                        o = a->ival;
                    534:                        mkaddr(n->right, a, 1);
                    535:                }
                    536:                else {
                    537:                        mkaddr(n->right, a, 0);
                    538:                        o = a->ival;
                    539:                        mkaddr(n->left, a, 1);
                    540:                }
                    541:                a->ival += o;
                    542:                break;
                    543: 
                    544:        case OINDREG:
                    545:                a->type = A_INDREG;
                    546:                a->reg = n->reg;
                    547:                a->ival = n->ival;
                    548:                break;
                    549: 
                    550:        case OREGISTER:
                    551:                a->type = A_REG;
                    552:                switch(n->t->type) {
                    553:                default:
                    554:                        a->reg = n->reg;
                    555:                        break;
                    556:        
                    557:                case TFLOAT:
                    558:                        a->type = A_FREG;
                    559:                        if(n->reg == Retfreg)
                    560:                                a->reg = Retfregno;
                    561:                        else
                    562:                                a->reg = n->reg - Freg;
                    563:                        break;
                    564:                }
                    565:                break;
                    566: 
                    567:        case OIND:
                    568:                mkaddr(n->left, a, 1);
                    569:                if(a->type == A_REG || a->type == A_CONST)
                    570:                        a->type = A_INDREG;
                    571:                break;
                    572: 
                    573:        case OADDR:
                    574:                mkaddr(n->left, a, 1);
                    575:                a->type = A_CONST;
                    576:                a->ival += n->ival;
                    577:                break;
                    578:        }
                    579: }
                    580: 
                    581: /* Generate function preamble and assign parameter offsets */
                    582: void
                    583: preamble(Node *name)
                    584: {
                    585:        Inst *i;
                    586:        Node *n;
                    587: 
                    588:        i = ai();
                    589:        i->op = ATEXT;
                    590:        i->pc = pc++;
                    591:        i->lineno = name->srcline;
                    592: 
                    593:        n = an(0, ZeroN, ZeroN);
                    594:        *n = *name;
                    595:        n->type = ONAME;
                    596:        mkaddr(n, &i->src1, 0);
                    597:        mkaddr(con(0), &i->dst, 0);
                    598:        ilink(i);
                    599:        funentry = i;           /* To back patch arg space */
                    600:        becomentry = i;
                    601: }
                    602: 
                    603: /* Output accumulated string constants */
                    604: void
                    605: strop(void)
                    606: {
                    607:        String *s;
                    608:        int c, l;
                    609:        Inst *i;
                    610:        char *p;
                    611: 
                    612:        for(s = strdat; s; s = s->next) {
                    613:                i = ai();
                    614:                i->op = AGLOBL;
                    615:                mkaddr(&s->n, &i->src1, 0);
                    616:                mkaddr(con(s->len), &i->dst, 0);
                    617:                ilink(i);
                    618: 
                    619:                c = 0;
                    620:                p = s->string;
                    621:                while(s->len) {
                    622:                        l = s->len;
                    623:                        if(l > 8)
                    624:                                l = 8;
                    625: 
                    626:                        iline = s->n.srcline;
                    627:                        i = ai();
                    628:                        i->op = ADATA;
                    629:                        i->dst.type = A_STRING;
                    630:                        memset(i->dst.str, 0, sizeof(i->dst.str));
                    631:                        memmove(i->dst.str, p, l);
                    632:                        s->len -= l;
                    633:                        mkdata(&s->n, c, l, i);
                    634:                        p += l;
                    635:                        c += l;
                    636:                        ilink(i);
                    637:                }
                    638:        }
                    639: }

unix.superglobalmegacorp.com

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