Annotation of lucent/sys/src/alef/k/inst.c, revision 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.