Annotation of lucent/sys/src/alef/k/code.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: void
        !            10: gendata(Node *n)
        !            11: {
        !            12:        Type *t;
        !            13:        Inst *i;
        !            14:        ulong s;
        !            15: 
        !            16:        if(n == ZeroN)
        !            17:                return;
        !            18: 
        !            19:        switch(n->type) {
        !            20:        default:
        !            21:                gendata(n->left);
        !            22:                gendata(n->right);
        !            23:                break;
        !            24: 
        !            25:        case OAGDECL:
        !            26:        case OUNDECL:
        !            27:        case OADTDECL:
        !            28:        case OSETDECL:
        !            29:        case OFUNC:
        !            30:                break;
        !            31: 
        !            32:        case ONAME:
        !            33:                switch(n->t->class) {
        !            34:                case Internal:
        !            35:                case Global:
        !            36:                        iline = n->srcline;
        !            37:                        t = n->t;
        !            38:                        if(n->init)
        !            39:                                doinit(n, t, n->init, 0);
        !            40: 
        !            41:                        s = t->size;
        !            42:                        if(s == 0)
        !            43:                                break;
        !            44:                        if(s & (Align_data-1))
        !            45:                                s += Align_data-(s&(Align_data-1));
        !            46: 
        !            47:                        i = ai();
        !            48:                        i->op = AGLOBL;
        !            49:                        mkaddr(con(s), &i->dst, 0);
        !            50:                        mkaddr(n, &i->src1, 0);
        !            51:                        ilink(i);
        !            52:                        break;
        !            53:                }
        !            54:                break;
        !            55:        }
        !            56: }
        !            57: 
        !            58: /* Load/store instructions by type
        !            59: 
        !            60:                TXXX  TINT   TUINT  TSINT  TSUINT TCHAR  TFLOAT TIND 
        !            61:                TCHAN  TARY   TAGG   TUNI   TFUNC TVOID
        !            62: */
        !            63: int ostore[] ={ AGOK, AMOVW, AMOVW, AMOVH, AMOVH, AMOVB, AFMOVD, AMOVW, 
        !            64:                AMOVW, AGOK,  AGOK,  AGOK,  AGOK,  AGOK };
        !            65: 
        !            66: int oload[] = { AGOK, AMOVW, AMOVW, AMOVH, AMOVHU,AMOVBU,AFMOVD, AMOVW,
        !            67:                AMOVW,AGOK,  AGOK,  AGOK,  AGOK,  AGOK };
        !            68: 
        !            69: void
        !            70: load(Node *from, Node *to)
        !            71: {
        !            72:        Node n1;
        !            73:        int op;
        !            74: 
        !            75:        op = oload[from->t->type];
        !            76:        reg(&n1, from->t, to);
        !            77:        instruction(op, from, ZeroN, &n1);
        !            78:        assign(&n1, to);
        !            79:        regfree(&n1);
        !            80: }
        !            81: 
        !            82: void
        !            83: store(Node *from, Node *to)
        !            84: {
        !            85:        Node n1;
        !            86:        int op, t;
        !            87: 
        !            88:        op = ostore[to->t->type];
        !            89: 
        !            90:        t = from->t->type;
        !            91: 
        !            92:        if(t != TFLOAT)
        !            93:        if(vconst(from) == 0) {
        !            94:                instruction(op, from, ZeroN, to);
        !            95:                return;
        !            96:        }
        !            97:                
        !            98:        if(t == to->t->type)
        !            99:                reg(&n1, to->t, from);
        !           100:        else
        !           101:                reg(&n1, to->t, ZeroN);
        !           102: 
        !           103:        assign(from, &n1);
        !           104:        instruction(op, &n1, ZeroN, to);
        !           105:        regfree(&n1);
        !           106: }
        !           107: 
        !           108: void
        !           109: inttoflt(Node *s, Node *d)
        !           110: {
        !           111:        Inst *nofix;
        !           112:        Node n, *tmp;
        !           113: 
        !           114:        reg(&n, d->t, d);
        !           115:        tmp = stknode(d->t);
        !           116:        instruction(AMOVW, s, ZeroN, tmp);
        !           117:        instruction(AFMOVD, tmp, ZeroN, &n);
        !           118:        instruction(AFMOVWD, &n, ZeroN, d);
        !           119:        regfree(&n);
        !           120:        if(s->t->type == TUINT) {
        !           121:                instruction(ACMP, s, ZeroN, con(0));
        !           122:                instruction(ABGE, ZeroN, ZeroN, ZeroN);
        !           123:                nofix = ipc;
        !           124:                reg(&n, builtype[TFLOAT], ZeroN);
        !           125:                instruction(AFMOVD, conf(4294967296.), ZeroN, &n);
        !           126:                instruction(AFADDD, &n, ZeroN, d);
        !           127:                regfree(&n);
        !           128:                label(nofix, ipc->pc+1);
        !           129:        }
        !           130: }
        !           131: 
        !           132: /*
        !           133:  * Compile code for moves
        !           134:  */
        !           135: void
        !           136: assign(Node *src, Node *dst)
        !           137: {
        !           138:        Node n1, *tmp;
        !           139:        int op, dt;
        !           140: 
        !           141:        if(opt('a'))
        !           142:                print("assign: %N = %N\n", dst, src); 
        !           143: 
        !           144:        if(dst == ZeroN)
        !           145:                return;
        !           146: 
        !           147:        switch(src->type) {
        !           148:        case ONAME:
        !           149:        case OINDREG:
        !           150:        case OIND:
        !           151:                load(src, dst);
        !           152:                return;
        !           153:        }
        !           154: 
        !           155:        switch(dst->type) {
        !           156:        case ONAME:
        !           157:        case OINDREG:
        !           158:        case OIND:
        !           159:                store(src, dst);
        !           160:                return;
        !           161:        }
        !           162: 
        !           163:        /* delete register/register nop moves */
        !           164:        if(src->type == OREGISTER)
        !           165:        if(dst->type == OREGISTER)
        !           166:        if(dst->reg == src->reg)
        !           167:        if(dst->type == src->type)
        !           168:                return;
        !           169: 
        !           170:        op = AGOK;
        !           171:        dt = dst->t->type;
        !           172:        switch(src->t->type) {
        !           173:        case TINT:
        !           174:        case TUINT:
        !           175:        case TIND:
        !           176:        case TCHANNEL:
        !           177:                switch(dt) {
        !           178:                case TINT:
        !           179:                case TUINT:
        !           180:                case TCHAR:
        !           181:                case TSUINT:
        !           182:                case TSINT:
        !           183:                case TIND:
        !           184:                case TCHANNEL:
        !           185:                        op = AMOVW;
        !           186:                        break;
        !           187: 
        !           188:                case TFLOAT:
        !           189:                        inttoflt(src, dst);
        !           190:                        return;
        !           191:                }
        !           192:                break;
        !           193: 
        !           194:        case TSUINT:
        !           195:                switch(dt) {
        !           196:                case TINT:
        !           197:                case TUINT:
        !           198:                case TIND:
        !           199:                        op = AMOVHU;
        !           200:                        break;
        !           201: 
        !           202:                case TSUINT:
        !           203:                case TCHAR:
        !           204:                case TSINT:
        !           205:                        op = AMOVW;
        !           206:                        break;
        !           207: 
        !           208:                case TFLOAT:
        !           209:                        inttoflt(src, dst);
        !           210:                        return;
        !           211:                }
        !           212:                break;
        !           213: 
        !           214:        case TSINT:
        !           215:                switch(dt) {
        !           216:                case TINT:
        !           217:                case TUINT:
        !           218:                case TIND:
        !           219:                        op = AMOVH;
        !           220:                        break;
        !           221: 
        !           222:                case TSUINT:
        !           223:                case TCHAR:
        !           224:                case TSINT:
        !           225:                        op = AMOVW;
        !           226:                        break;
        !           227: 
        !           228:                case TFLOAT:
        !           229:                        inttoflt(src, dst);
        !           230:                        return;
        !           231:                }
        !           232:                break;
        !           233: 
        !           234:        case TFLOAT:
        !           235:                switch(dt) {
        !           236:                case TINT:
        !           237:                case TUINT:
        !           238:                case TIND:
        !           239:                case TCHAR:
        !           240:                case TSINT:
        !           241:                case TSUINT:
        !           242:                        reg(&n1, builtype[TFLOAT], ZeroN);
        !           243:                        tmp = stknode(builtype[TINT]);
        !           244:                        instruction(AFMOVDW, src, ZeroN, &n1);
        !           245:                        instruction(AFMOVD, &n1, ZeroN, tmp);
        !           246:                        regfree(&n1);
        !           247:                        instruction(AMOVW, tmp, ZeroN, dst);
        !           248:                        assign(dst, dst);
        !           249:                        return;
        !           250: 
        !           251:                case TFLOAT:
        !           252:                        op = AFMOVD;
        !           253:                        break;
        !           254:                }
        !           255:                break;
        !           256:        case TCHAR:
        !           257:                switch(dt) {
        !           258:                case TINT:
        !           259:                case TUINT:
        !           260:                case TIND:
        !           261:                        op = AMOVBU;
        !           262:                        break;
        !           263: 
        !           264:                case TSUINT:
        !           265:                case TSINT:
        !           266:                case TCHAR:
        !           267:                        op = AMOVW;
        !           268:                        break;
        !           269: 
        !           270:                case TFLOAT:
        !           271:                        inttoflt(src, dst);
        !           272:                        return;
        !           273:                }
        !           274:                break;
        !           275:        }
        !           276:        instruction(op, src, ZeroN, dst);
        !           277: }
        !           278: 
        !           279: /*
        !           280:  * Generate the address of an expression
        !           281:  */
        !           282: void
        !           283: genaddr(Node *expr, Node *dst)
        !           284: {
        !           285:        Node n, *tmp;
        !           286: 
        !           287:        if(opt('g'))
        !           288:                print("genaddr: %N\n", expr);
        !           289: 
        !           290:        if(expr->type == OIND) {
        !           291:                genexp(expr->left, dst);
        !           292:                return;
        !           293:        }
        !           294:        if(isaddr(expr) == 0) {
        !           295:                tmp = stknode(expr->t);
        !           296:                n.type = OASGN;
        !           297:                n.t = tmp->t;
        !           298:                n.left = tmp;
        !           299:                n.right = expr;
        !           300:                n.islval = 0;
        !           301:                genexp(&n, ZeroN);
        !           302:                expr = tmp;
        !           303:        }
        !           304:        n = *expr;
        !           305:        reg(&n, builtype[TIND], dst);
        !           306:        n.type = OADDR;
        !           307:        n.left = expr;
        !           308:        n.right = ZeroN;
        !           309:        n.t = builtype[TIND];
        !           310:        assign(&n, dst);
        !           311:        regfree(&n);
        !           312: }
        !           313: 
        !           314: /* 
        !           315:  * generate an l-value into a register
        !           316:  */
        !           317: void
        !           318: rgenaddr(Node *t, Node *rval, Node *lval)
        !           319: {
        !           320:        Node *r;
        !           321:        ulong v;
        !           322: 
        !           323:        *t = *rval;
        !           324:        t->t = builtype[TIND];
        !           325:        reg(t, t->t, lval);
        !           326:        if(rval->type == OIND) {
        !           327:                r = rval->left;
        !           328:                while(r->type == OADD)
        !           329:                        r = r->right;
        !           330:                if(immed(r)) {
        !           331:                        v = r->ival;
        !           332:                        r->ival = 0;
        !           333:                        genaddr(rval, t);
        !           334:                        t->ival += v;
        !           335:                        r->ival = v;
        !           336:                        t->type = OINDREG;
        !           337:                        t->t = rval->t;
        !           338:                        return;
        !           339:                }
        !           340:        }
        !           341:        genaddr(rval, t);
        !           342:        t->type = OINDREG;
        !           343:        t->t = rval->t;
        !           344: }
        !           345: 
        !           346: /*
        !           347:  * pre and post increment generation
        !           348:  */
        !           349: void
        !           350: postop(Node *rval, Node *lval)
        !           351: {
        !           352:        Node *l, *nconst;
        !           353:        Node n1, n2, n3, n4;
        !           354: 
        !           355:        l = rval->left;
        !           356:        nconst = con(1);
        !           357:        if(l->t->type == TIND)
        !           358:                nconst->ival = l->t->next->size;
        !           359: 
        !           360:        if(rval->type == OPDEC)
        !           361:                nconst->ival = -nconst->ival;
        !           362: 
        !           363:        if(l->islval < Sucompute)
        !           364:                rgenaddr(&n2, l, ZeroN);
        !           365:        else
        !           366:                n2 = *l;
        !           367: 
        !           368:        n3.type = OADD;
        !           369:        n3.t = builtype[TINT];
        !           370: 
        !           371:        /* Easy if we dont need the value after the inc */
        !           372:        if(lval == ZeroN) {
        !           373:                reg(&n1, l->t, lval);
        !           374:                assign(&n2, &n1);
        !           375: 
        !           376:                codmop(&n3, nconst, &n1, &n1);
        !           377: 
        !           378:                assign(&n1, &n2);
        !           379:                goto out;
        !           380:        }
        !           381: 
        !           382:        reg(&n4, l->t, lval);
        !           383:        assign(&n2, &n4);
        !           384:        reg(&n1, l->t, ZeroN);
        !           385:        /* Thank RISC for three address ! */
        !           386:        codmop(&n3, nconst, &n4, &n1);
        !           387:        assign(&n1, &n2);
        !           388: 
        !           389:        regfree(&n4);
        !           390: out:
        !           391:        regfree(&n1);
        !           392:        if(l->islval < Sucompute)
        !           393:                regfree(&n2);
        !           394: }
        !           395: 
        !           396: void
        !           397: preop(Node *rval, Node *lval)
        !           398: {
        !           399:        Node n1, n2, n3;
        !           400:        Node *l, *nconst;
        !           401: 
        !           402:        l = rval->left;
        !           403:        nconst = con(1);
        !           404:        if(l->t->type == TIND)
        !           405:                nconst->ival = l->t->next->size;
        !           406: 
        !           407:        if(rval->type == OEDEC)
        !           408:                nconst->ival = -nconst->ival;
        !           409: 
        !           410:        if(l->islval < Sucompute)
        !           411:                rgenaddr(&n2, l, ZeroN);
        !           412:        else
        !           413:                n2 = *l;
        !           414: 
        !           415:        reg(&n1, l->t, lval);
        !           416:        assign(&n2, &n1);
        !           417: 
        !           418:        n3.type = OADD;
        !           419:        n3.t = builtype[TINT];
        !           420:        codmop(&n3, nconst, &n1, &n1);
        !           421: 
        !           422:        assign(&n1, &n2);
        !           423: 
        !           424:        regfree(&n1);
        !           425:        if(l->islval < Sucompute)
        !           426:                regfree(&n2);
        !           427: }
        !           428: 
        !           429: void
        !           430: docall(Node *n)
        !           431: {
        !           432:        Node *rsp;
        !           433: 
        !           434:        if(atv == ZeroN) {
        !           435:                instruction(AJMPL, ZeroN, ZeroN, n);
        !           436:                return;
        !           437:        }
        !           438: 
        !           439:        /*
        !           440:         * if calling through an activation, link
        !           441:         * to the new stack
        !           442:         */
        !           443:        ratv.ival = atv->atvsafe;
        !           444:        rsp = regn(RegSP);
        !           445:        instruction(AMOVW, rsp, ZeroN, &ratv);
        !           446:        ratv.type = OREGISTER;
        !           447:        assign(&ratv, rsp);
        !           448:        instruction(AJMPL, ZeroN, ZeroN, n);
        !           449:        rsp->type = OINDREG;
        !           450:        rsp->ival = atv->atvsafe;
        !           451:        instruction(AMOVW, rsp, ZeroN, regn(RegSP));
        !           452:        regfree(&ratv);
        !           453: }
        !           454: 
        !           455: void
        !           456: become(Node *rval)
        !           457: {
        !           458:        Node nl;
        !           459:        Node *l, *r, *ns, *tmp;
        !           460: 
        !           461:        tmp = rval->left;
        !           462:        r = tmp->right;
        !           463:        l = tmp->left;
        !           464: 
        !           465:        if(opt('b')) {
        !           466:                print("BECOME:\n");
        !           467:                ptree(rval, 0);
        !           468:        }
        !           469: 
        !           470:        tmp = ZeroN;
        !           471:        if(!isaddr(l)) {
        !           472:                tmp = stknode(builtype[TIND]);
        !           473:                genaddr(l, tmp);
        !           474:        }
        !           475: 
        !           476:        /* Generate the alias saves */
        !           477:        genelist(rval->right);
        !           478: 
        !           479:        evalarg(r, 0);
        !           480: 
        !           481:        /*
        !           482:         * Write out tail recursion
        !           483:         */
        !           484:        if(l->type == ONAME && curfunc->sym == l->sym) {
        !           485:                tip = block[Scope];
        !           486:                evalarg(r, 4);
        !           487:                instruction(AJMP, ZeroN, ZeroN, ZeroN);
        !           488:                label(ipc, becomentry->pc+1);
        !           489:                return;
        !           490:        }
        !           491: 
        !           492:        ns = an(ONAME, ZeroN, ZeroN);
        !           493:        ns->sym = malloc(sizeof(Sym));
        !           494:        ns->sym->name = ".xframe";
        !           495:        ns->ti = ati(builtype[TADT], Parameter);
        !           496:        ns->ti->offset = 0;
        !           497:        ns->t = builtype[TINT];
        !           498:        ns = an(OADDR, ns, nil);
        !           499:        sucalc(ns);
        !           500: 
        !           501:        reg(&ratv, builtype[TIND], ZeroN);
        !           502:        ratv.ival = Parambase;
        !           503:        genexp(ns, &ratv);
        !           504:        evalarg(r, 3);
        !           505:        regfree(&ratv);
        !           506: 
        !           507:        /* Restore the complex pointer */
        !           508:        switch(curfunc->t->next->type) {
        !           509:        case TADT:
        !           510:        case TUNION:
        !           511:        case TAGGREGATE:
        !           512:                assign(rnode, regn(Regspass));
        !           513:                break;
        !           514:        }
        !           515: 
        !           516:        if(tmp) {
        !           517:                reg(&nl, builtype[TIND], ZeroN);
        !           518:                assign(tmp, &nl);
        !           519:                nl.type = OINDREG;
        !           520:                nl.ival = 0;
        !           521:                instruction(ARETURN, con(ratv.ival), ZeroN, &nl);
        !           522:                regfree(&nl);
        !           523:        }
        !           524:        else
        !           525:                instruction(ARETURN, con(ratv.ival), ZeroN, l);
        !           526: }
        !           527: 
        !           528: /*
        !           529:  * Compile code expressions
        !           530:  */
        !           531: void
        !           532: genexp(Node *rval, Node *lval)
        !           533: {
        !           534:        Node nl, nr, nspare;
        !           535:        Node *l, *r, *nstack;
        !           536: 
        !           537:        l = rval->left;
        !           538:        r = rval->right;
        !           539: 
        !           540:        if(opt('v'))
        !           541:                print("%L R %N L %N\n", rval->srcline, rval, lval);
        !           542: 
        !           543:        if(rval->t)
        !           544:        switch(rval->t->type) {
        !           545:        case TADT:
        !           546:        case TUNION:
        !           547:        case TAGGREGATE:
        !           548:                gencomplex(rval, lval);
        !           549:                return;
        !           550:        }
        !           551: 
        !           552:        /* addressable */
        !           553:        if(isaddr(rval)) {
        !           554:                assign(rval, lval);
        !           555:                return;
        !           556:        }
        !           557: 
        !           558:        /* Follow function call evaluations into stack temporary */
        !           559:        if(rval->sun >= Sucall)
        !           560:        if(l->sun >= Sucall)
        !           561:        if(r && r->sun >= Sucall)
        !           562:        switch(rval->type) {
        !           563:        case OFUNC:
        !           564:        case OLAND:
        !           565:        case OLOR:
        !           566:                break;
        !           567: 
        !           568:        default:
        !           569:                regret(&nspare, r->t);
        !           570:                genexp(r, &nspare);
        !           571:                nstack = stknode(r->t);
        !           572:                assign(&nspare, nstack);
        !           573:                regfree(&nspare);
        !           574:                nspare = *rval;
        !           575:                nspare.right = nstack;
        !           576:                genexp(&nspare, lval);
        !           577:                return;
        !           578:        }
        !           579: 
        !           580:        switch(rval->type) {
        !           581:        default:
        !           582:                fatal("genexp: %N", rval);
        !           583:                break;
        !           584: 
        !           585:        case OBLOCK:
        !           586:                bstmnt(l);
        !           587:                genexp(r, lval);
        !           588:                break;
        !           589: 
        !           590:        case OBECOME:
        !           591:                become(rval);
        !           592:                break;
        !           593: 
        !           594:        case ODOT:
        !           595:                nstack = stknode(l->t);
        !           596:                genexp(l, nstack);
        !           597:                if(rval == ZeroN)
        !           598:                        break;
        !           599: 
        !           600:                rgenaddr(&nspare, nstack, ZeroN);
        !           601:                nspare.ival = r->ival;
        !           602:                nspare.t = rval->t;
        !           603:                genexp(&nspare, lval);
        !           604:                regfree(&nspare);
        !           605:                break;
        !           606: 
        !           607:        case OCONV:
        !           608:                if(lval == ZeroN) {
        !           609:                        warn(rval, "result ignored");
        !           610:                        break;
        !           611:                }
        !           612: 
        !           613:                if(convisnop(l->t, rval->t) && convisnop(rval->t, lval->t)) {
        !           614:                        genexp(l, lval);
        !           615:                        break;
        !           616:                }
        !           617:                reg(&nl, l->t, lval);
        !           618:                genexp(l, &nl);
        !           619:                reg(&nr, rval->t, &nl);
        !           620:                assign(&nl, &nr);
        !           621:                assign(&nr, lval);
        !           622:                regfree(&nr);
        !           623:                regfree(&nl);
        !           624:                break;
        !           625: 
        !           626:        case OASGN:
        !           627:                oasgn(rval, lval);
        !           628:                break;
        !           629: 
        !           630:        case OADDR:
        !           631:                if(lval == ZeroN) {
        !           632:                        warn(rval, "result ignored");
        !           633:                        break;
        !           634:                }
        !           635: 
        !           636:                genaddr(l, lval);
        !           637:                break;
        !           638: 
        !           639:        case OIND:
        !           640:                if(lval == ZeroN) {
        !           641:                        warn(rval, "result ignored");
        !           642:                        break;
        !           643:                }
        !           644:                reg(&nr, builtype[TIND], lval);
        !           645:                if(l->type == OADD && l->right->type == OCONST) {
        !           646:                        nr.ival = l->right->ival;
        !           647:                        genexp(l->left, &nr);
        !           648:                }
        !           649:                else {
        !           650:                        genexp(l, &nr);
        !           651:                        nr.ival = 0;
        !           652:                }
        !           653:                nr.type = OINDREG;
        !           654:                nr.t = rval->t;
        !           655:                assign(&nr, lval);
        !           656:                regfree(&nr);
        !           657:                break;
        !           658: 
        !           659:        case OCAND:
        !           660:        case OCOR:
        !           661:        case OEQ:
        !           662:        case OLEQ:
        !           663:        case ONEQ:
        !           664:        case OLT:
        !           665:        case OGEQ:
        !           666:        case OGT:
        !           667:        case OHI:
        !           668:        case OLO:
        !           669:        case OLOS:
        !           670:        case OHIS:
        !           671:                if(lval == ZeroN)
        !           672:                        break;
        !           673: 
        !           674:                gencond(rval, lval, True);
        !           675:                break;
        !           676: 
        !           677:        case ONOT:
        !           678:                gencond(l, lval, False);
        !           679:                break;
        !           680: 
        !           681:        case OADDEQ:
        !           682:        case OSUBEQ:
        !           683:        case ORSHEQ:
        !           684:        case OLSHEQ:
        !           685:        case OANDEQ:
        !           686:        case OOREQ:
        !           687:        case OXOREQ:
        !           688:                while(l->type == OCONV)
        !           689:                        l = l->left;
        !           690: 
        !           691:                /* Peel off the instructions with immediate operands */
        !           692:                if(r->t->type != TFLOAT)
        !           693:                if(r->type == OCONST) {
        !           694:                        if(l->islval < Sucompute)
        !           695:                                rgenaddr(&nspare, l, ZeroN);
        !           696:                        else
        !           697:                                nspare = *l;
        !           698:                        reg(&nl, r->t, lval);
        !           699:                        assign(&nspare, &nl);
        !           700:                        codmop(rval, r, &nl, &nl);
        !           701:                        assign(&nl, &nspare);
        !           702:        
        !           703:                        regfree(&nl);
        !           704:                        if(l->islval < Sucompute)
        !           705:                                regfree(&nspare);
        !           706:                        break;
        !           707:                }
        !           708: 
        !           709:                /* Fall through */
        !           710:        case OMULEQ:
        !           711:        case ODIVEQ:
        !           712:        case OMODEQ:
        !           713:                while(l->type == OCONV)
        !           714:                        l = l->left;
        !           715: 
        !           716:                if(l->sun >= r->sun) {
        !           717:                        if(l->islval < Sucompute)
        !           718:                                rgenaddr(&nspare, l, ZeroN);
        !           719:                        else
        !           720:                                nspare = *l;
        !           721:                        reg(&nr, r->t, ZeroN);
        !           722:                        genexp(r, &nr);
        !           723:                } else {
        !           724:                        reg(&nr, r->t, ZeroN);
        !           725:                        genexp(r, &nr);
        !           726:                        if(l->islval < Sucompute)
        !           727:                                rgenaddr(&nspare, l, ZeroN);
        !           728:                        else
        !           729:                                nspare = *l;
        !           730:                }
        !           731: 
        !           732:                reg(&nl, rval->t, lval);
        !           733:                assign(&nspare, &nl);
        !           734:                codmop(rval, &nr, ZeroN, &nl);
        !           735:                assign(&nl, &nspare);
        !           736:                assign(&nl, lval);
        !           737:                regfree(&nl);
        !           738:                regfree(&nr);
        !           739:                if(l->islval < Sucompute)
        !           740:                        regfree(&nspare);
        !           741:                break;
        !           742:                
        !           743:        case OADD:
        !           744:        case OSUB:
        !           745:        case OLAND:
        !           746:        case OLOR:
        !           747:        case OXOR:
        !           748:        case OLSH:
        !           749:        case ORSH:
        !           750:        case OALSH:
        !           751:        case OARSH:
        !           752:                if(lval == ZeroN)
        !           753:                        break;
        !           754: 
        !           755:                /* Peel off the instructions with immediate operands */
        !           756:                if(r->t->type != TFLOAT)
        !           757:                if(r->type == OCONST) {
        !           758:                        genexp(l, lval);
        !           759:                        if(r->ival == 0)
        !           760:                        if(rval->type != OLAND)
        !           761:                                break;
        !           762:                        codmop(rval, r, lval, lval);
        !           763:                        break;
        !           764:                }
        !           765:                
        !           766:                /* Fall through */
        !           767:        case OMUL:
        !           768:        case ODIV:
        !           769:        case OMOD:
        !           770:                if(lval == ZeroN) {
        !           771:                        warn(rval, "result ignored");
        !           772:                        break;
        !           773:                }
        !           774: 
        !           775:                if(rval->type == OMUL && mulcon(rval, lval))
        !           776:                        break;
        !           777: 
        !           778:                if(l->sun >= r->sun) {
        !           779:                        reg(&nl, l->t, lval);
        !           780:                        genexp(l, &nl);
        !           781:                        reg(&nr, r->t, ZeroN);
        !           782:                        genexp(r, &nr);
        !           783:                        codmop(rval, &nr, &nl, &nl);
        !           784:                }
        !           785:                else {
        !           786:                        reg(&nr, r->t, ZeroN);
        !           787:                        genexp(r, &nr);
        !           788:                        reg(&nl, l->t, lval);
        !           789:                        genexp(l, &nl);
        !           790:                        codmop(rval, &nr, &nl, &nl);
        !           791:                }
        !           792:                regfree(&nr);
        !           793:                assign(&nl, lval);
        !           794:                regfree(&nl);
        !           795:                break;
        !           796: 
        !           797:        case OPINC:
        !           798:        case OPDEC:
        !           799:                postop(rval, lval);
        !           800:                break;
        !           801: 
        !           802:        case OEINC:
        !           803:        case OEDEC:
        !           804:                preop(rval, lval);
        !           805:                break;
        !           806: 
        !           807:        case OSEND:
        !           808:                genexp(l, lval);
        !           809:                break;
        !           810: 
        !           811:        case ORECV:
        !           812:        case OCALL:
        !           813:                if(l->sun >= Sucall) {
        !           814:                        reg(&nr, builtype[TIND], ZeroN);
        !           815:                        genaddr(l, &nr);
        !           816:                        if(nr.type != OREGISTER)
        !           817:                                fatal("genexp: call %N", &nr);
        !           818: 
        !           819:                        nstack = stknode(builtype[TIND]);
        !           820:                        assign(&nr, nstack);
        !           821:                        regfree(&nr);
        !           822: 
        !           823:                        genarg(r);
        !           824: 
        !           825:                        reg(&nr, builtype[TIND], ZeroN);
        !           826:                        assign(nstack, &nr);
        !           827:                        nr.type = OINDREG;
        !           828:                        nr.ival = 0;
        !           829:                        docall(&nr);
        !           830:                        regfree(&nr);
        !           831:                        break;
        !           832:                }
        !           833: 
        !           834:                genarg(r);
        !           835: 
        !           836:                if(!isaddr(l)) {
        !           837:                        reg(&nr, builtype[TIND], ZeroN);
        !           838:                        genaddr(l, &nr);
        !           839:                        if(nr.type != OREGISTER)
        !           840:                                fatal("genexp: call %N", &nr);
        !           841:                        nr.type = OINDREG;
        !           842:                        nr.ival = 0;
        !           843:                        docall(&nr);
        !           844:                        regfree(&nr);
        !           845:                }
        !           846:                else
        !           847:                        docall(l);
        !           848: 
        !           849:                /* Return value */
        !           850:                if(lval) {
        !           851:                        regret(&nr, rval->t);
        !           852:                        assign(&nr, lval);
        !           853:                        regfree(&nr);
        !           854:                }
        !           855:                break;
        !           856:        
        !           857:        }
        !           858: }
        !           859: 
        !           860: /*
        !           861:  * Compile assignment operator
        !           862:  */
        !           863: void
        !           864: oasgn(Node *rval, Node *lval)
        !           865: {
        !           866:        Node n1, n2;
        !           867:        Node *l, *r;
        !           868: 
        !           869:        r = rval->right;
        !           870:        l = rval->left;
        !           871: 
        !           872:        if(opt('q')) {
        !           873:                print("OASGN r");
        !           874:                ptree(rval, 0);
        !           875:                print("OASGN l");
        !           876:                ptree(lval,0);
        !           877:                print("*\n");
        !           878:        }
        !           879: 
        !           880:        if(l->islval >= Sucompute)
        !           881:        if(l->sun < Sucall) {
        !           882:                if(lval != ZeroN || r->islval < Sucompute) {
        !           883:                        reg(&n1, r->t, lval);
        !           884:                        genexp(r, &n1);
        !           885:                        assign(&n1, l);
        !           886:                        regfree(&n1);
        !           887:                } else
        !           888:                        assign(r, l);
        !           889:                return;
        !           890:        }
        !           891: 
        !           892:        if(l->sun >= r->sun) {
        !           893:                rgenaddr(&n2, l, ZeroN);
        !           894:                if(r->islval >= Sucompute) {
        !           895:                        assign(r, &n2);
        !           896:                        assign(r, lval);
        !           897:                        regfree(&n2);
        !           898:                        return;
        !           899:                }
        !           900:                reg(&n1, r->t, lval);
        !           901:                genexp(r, &n1);
        !           902:        } else {
        !           903:                reg(&n1, r->t, lval);
        !           904:                genexp(r, &n1);
        !           905:                rgenaddr(&n2, l, ZeroN);
        !           906:        }
        !           907:        assign(&n1, &n2);
        !           908:        regfree(&n1);
        !           909:        regfree(&n2);
        !           910: }
        !           911: 
        !           912: void
        !           913: evalarg(Node *n, int pass)
        !           914: {
        !           915:        Node *tmp, n1;
        !           916: 
        !           917:        if(n == ZeroN)
        !           918:                return;
        !           919: 
        !           920:        switch(n->type) {
        !           921:        case OLIST:
        !           922:                evalarg(n->left, pass);
        !           923:                evalarg(n->right, pass);
        !           924:                break;
        !           925: 
        !           926:        default:
        !           927:                switch(pass) {
        !           928:                case 0:
        !           929:                        if(n->type == OBLOCK) {
        !           930:                                stmnt(n->left);
        !           931:                                *n = *n->right;
        !           932:                                break;
        !           933:                        }
        !           934:                        if(n->sun < Sucall)
        !           935:                                break;
        !           936: 
        !           937:                        tmp = stknode(n->t);
        !           938:                        n1.type = OASGN;
        !           939:                        n1.left = tmp;
        !           940:                        n1.right = n;
        !           941:                        n1.t = n->t;
        !           942:                        sucalc(&n1);
        !           943:                        genexp(&n1, ZeroN);
        !           944:                        *n = *tmp;
        !           945:                        break;
        !           946: 
        !           947:                case 1:
        !           948:                        if(atv)
        !           949:                                tmp = atvnode(n->t);
        !           950:                        else
        !           951:                                tmp = argnode(n->t);
        !           952:                compute:
        !           953:                        switch(n->t->type) {
        !           954:                        default:
        !           955:                                fatal("evalarg %T",  n->t);
        !           956:                        case TADT:
        !           957:                        case TUNION:
        !           958:                        case TAGGREGATE:
        !           959:                                gencomplex(n, tmp);
        !           960:                                break;
        !           961: 
        !           962:                        case TSINT:
        !           963:                        case TSUINT:
        !           964:                        case TCHAR:
        !           965:                        case TINT:
        !           966:                        case TUINT:
        !           967:                        case TIND:
        !           968:                        case TFLOAT:
        !           969:                        case TCHANNEL:
        !           970:                                n1.type = OASGN;
        !           971:                                n1.left = tmp;
        !           972:                                n1.right = n;
        !           973:                                n1.t = n->t;
        !           974:                                sucalc(&n1);
        !           975:                                genexp(&n1, ZeroN);
        !           976:                                break;
        !           977:                        }
        !           978:                        break;
        !           979:                case 3:
        !           980:                        /*
        !           981:                         * Second pass becoming somebody else
        !           982:                         */
        !           983:                        tmp = atvnode(n->t);
        !           984:                        if(n->type == ONAME)
        !           985:                        if(n->ti->class == Parameter)
        !           986:                        if(n->ti->offset == tmp->left->right->ival)
        !           987:                                break;
        !           988:                        goto compute;
        !           989:                case 4:
        !           990:                        /*
        !           991:                         * Second pass becoming myself
        !           992:                         */
        !           993:                        tmp = paramnode(n->t);
        !           994:                        if(tmp->type == ONAME)
        !           995:                        if(tmp->sym == n->sym)
        !           996:                        if(tmp->ti->class == n->ti->class)
        !           997:                                break;
        !           998:                        goto compute;
        !           999:                }
        !          1000:        }       
        !          1001: }
        !          1002: 
        !          1003: /*
        !          1004:  * genarg - Push function arguments onto the stack
        !          1005:  */
        !          1006: void
        !          1007: genarg(Node *n)
        !          1008: {
        !          1009:        evalarg(n, 0);
        !          1010: 
        !          1011:        args = Argbase;
        !          1012:        if(atv) {
        !          1013:                reg(&ratv, builtype[TIND], 0);
        !          1014:                assign(atv, &ratv);
        !          1015:                ratv.type = OINDREG;
        !          1016:                ratv.ival = Argbase;
        !          1017:                evalarg(n, 1);
        !          1018:                return; 
        !          1019:        }
        !          1020: 
        !          1021:        evalarg(n, 1);
        !          1022:        if(args > maxframe)
        !          1023:                maxframe = args;
        !          1024: }
        !          1025: 
        !          1026: /*
        !          1027:  * Compute the frame size of function arguments
        !          1028:  */
        !          1029: void
        !          1030: framesize(Node *n)
        !          1031: {
        !          1032:        if(n == ZeroN)
        !          1033:                return;
        !          1034: 
        !          1035:        switch(n->type) {
        !          1036:        case OLIST:
        !          1037:                framesize(n->left);
        !          1038:                framesize(n->right);
        !          1039:                break;
        !          1040: 
        !          1041:        default:
        !          1042:                frsize = align(frsize, builtype[TINT]);
        !          1043:                frsize += n->t->size;
        !          1044:        }
        !          1045: }
        !          1046: 
        !          1047: void
        !          1048: setcond(Node *lval)
        !          1049: {
        !          1050:        Inst *true, *false;
        !          1051: 
        !          1052:        if(lval == ZeroN)
        !          1053:                return;
        !          1054: 
        !          1055:        true = ipc;
        !          1056:        assign(con(1), lval);
        !          1057:        instruction(AJMP, ZeroN, ZeroN, ZeroN); 
        !          1058:        false = ipc;
        !          1059:        label(true, ipc->pc+1);
        !          1060:        assign(con(0), lval);
        !          1061:        label(false, ipc->pc+1);
        !          1062: }
        !          1063: 
        !          1064: void
        !          1065: andand(Node *l, Node *r, int bool)
        !          1066: {
        !          1067:        Inst *true, *false;
        !          1068: 
        !          1069:        if(l->t == ZeroT)
        !          1070:                instruction(AJMP, ZeroN, ZeroN, ZeroN);
        !          1071:        else
        !          1072:                gencond(l, ZeroN, bool);
        !          1073:        
        !          1074:        false = ipc;
        !          1075: 
        !          1076:        if(r->t == ZeroT)
        !          1077:                instruction(AJMP, ZeroN, ZeroN, ZeroN);
        !          1078:        else
        !          1079:                gencond(r, ZeroN, !bool);
        !          1080: 
        !          1081:        true = ipc;
        !          1082: 
        !          1083:        label(false, ipc->pc+1);
        !          1084:        instruction(AJMP, ZeroN, ZeroN, ZeroN);
        !          1085:        label(true, ipc->pc+1);
        !          1086: 
        !          1087: }
        !          1088: 
        !          1089: void
        !          1090: oror(Node *l, Node *r, int bool)
        !          1091: {
        !          1092:        Inst *false1, *false2;
        !          1093: 
        !          1094:        if(l->t == ZeroT)
        !          1095:                instruction(AJMP, ZeroN, ZeroN, ZeroN);
        !          1096:        else
        !          1097:                gencond(l, ZeroN, !bool);
        !          1098:        
        !          1099:        false1 = ipc;
        !          1100: 
        !          1101:        if(r->t == ZeroT)
        !          1102:                instruction(AJMP, ZeroN, ZeroN, ZeroN);
        !          1103:        else
        !          1104:                gencond(r, ZeroN, !bool);
        !          1105: 
        !          1106:        false2 = ipc;
        !          1107: 
        !          1108:        instruction(AJMP, ZeroN, ZeroN, ZeroN);
        !          1109:        label(false1, ipc->pc+1);
        !          1110:        label(false2, ipc->pc+1);
        !          1111: }
        !          1112: 
        !          1113: /*
        !          1114:  * Generate for boolean conditionals
        !          1115:  */
        !          1116: void
        !          1117: gencond(Node *rval, Node *lval, int bool)
        !          1118: {
        !          1119:        int op;
        !          1120:        Node n1, n2;
        !          1121:        Node *l, *r, *nstack;
        !          1122: 
        !          1123:        l = rval->left;
        !          1124:        r = rval->right;
        !          1125: 
        !          1126:        op = rval->type;
        !          1127:        switch(op) {
        !          1128:        default:
        !          1129:                reg(&n1, rval->t, lval);
        !          1130:                genexp(rval, &n1);
        !          1131:                if(bool)
        !          1132:                        op = OEQ;
        !          1133:                else
        !          1134:                        op = ONEQ;
        !          1135:                codcond(op, &n1, con(0));
        !          1136:                setcond(lval);
        !          1137:                regfree(&n1);
        !          1138:                return;
        !          1139: 
        !          1140:        case OCAND:
        !          1141:                if(bool == False)
        !          1142:                        oror(l, r, bool);
        !          1143:                else
        !          1144:                        andand(l, r, bool);
        !          1145:                break;
        !          1146: 
        !          1147:        case OCOR:
        !          1148:                if(bool == False)
        !          1149:                        andand(l, r, bool);
        !          1150:                else
        !          1151:                        oror(l, r, bool);
        !          1152:                break;
        !          1153: 
        !          1154:        case ONOT:
        !          1155:                gencond(rval->left, lval, !bool);
        !          1156:                break;
        !          1157: 
        !          1158:        case OHI:
        !          1159:        case OLO:
        !          1160:        case OLOS:
        !          1161:        case OHIS:
        !          1162:        case OEQ:
        !          1163:        case OLEQ:
        !          1164:        case ONEQ:
        !          1165:        case OLT:
        !          1166:        case OGEQ:
        !          1167:        case OGT:
        !          1168:                if(r->sun >= Sucall && l->sun >= Sucall) {
        !          1169:                        nstack = stknode(l->t);
        !          1170:                        genexp(l, nstack);
        !          1171:                        rval->left = nstack;
        !          1172:                        gencond(rval, lval, bool);
        !          1173:                        return;                         
        !          1174:                }
        !          1175: 
        !          1176:                if(bool)
        !          1177:                        op = not[op];
        !          1178: 
        !          1179:                if(immed(r)) {
        !          1180:                        reg(&n1, l->t, lval);
        !          1181:                        genexp(l, &n1);
        !          1182:                        codcond(op, &n1, r);
        !          1183:                        regfree(&n1);
        !          1184:                        setcond(lval);
        !          1185:                        return;
        !          1186:                }
        !          1187:                if(l->sun >= r->sun) {
        !          1188:                        reg(&n1, l->t, lval);
        !          1189:                        genexp(l, &n1);
        !          1190:                        reg(&n2, r->t, ZeroN);
        !          1191:                        genexp(r, &n2);
        !          1192:                }
        !          1193:                else {
        !          1194:                        reg(&n2, r->t, lval);
        !          1195:                        genexp(r, &n2);
        !          1196:                        reg(&n1, l->t, ZeroN);
        !          1197:                        genexp(l, &n1);
        !          1198:                }
        !          1199:                codcond(op, &n1, &n2);
        !          1200:                regfree(&n1);
        !          1201:                regfree(&n2);
        !          1202:        }
        !          1203:        setcond(lval);
        !          1204: }
        !          1205: 
        !          1206: void
        !          1207: genelist(Node *n)
        !          1208: {
        !          1209:        if(n == ZeroN)
        !          1210:                return;
        !          1211: 
        !          1212:        switch(n->type) {
        !          1213:        case OLIST:
        !          1214:                genelist(n->left);
        !          1215:                genelist(n->right);
        !          1216:                break;
        !          1217:        default:
        !          1218:                genexp(n, ZeroN);
        !          1219:                break;
        !          1220:        }
        !          1221: }
        !          1222: 
        !          1223: void
        !          1224: gensubreg(Node *n, Node *reg)
        !          1225: {
        !          1226:        if(n == ZeroN)
        !          1227:                return;
        !          1228: 
        !          1229:        switch(n->type) {
        !          1230:        default:
        !          1231:                gensubreg(n->left, reg);
        !          1232:                gensubreg(n->right, reg);
        !          1233:                break;
        !          1234:        case OREGISTER:
        !          1235:                *n = *reg;
        !          1236:                break;
        !          1237:        }
        !          1238: }
        !          1239: 
        !          1240: void
        !          1241: genmove(Node *rval, Type *rt, Node *lval, int o)
        !          1242: {
        !          1243:        Type *t;
        !          1244:        Node *l, *r;
        !          1245: 
        !          1246:        for(t = rt->next; t; t = t->member) {
        !          1247:                switch(t->type) {
        !          1248:                case TFUNC:
        !          1249:                        break;
        !          1250:                case TADT:
        !          1251:                case TAGGREGATE:
        !          1252:                        genmove(rval, t, lval, t->offset);
        !          1253:                        break;
        !          1254:                default:
        !          1255:                        r = an(OADDR, rval, ZeroN);
        !          1256:                        r->t = at(TIND, t);
        !          1257:                        r = an(OADD, r, con(o+t->offset));
        !          1258:                        r->t = r->left->t;
        !          1259:                        r = an(OIND, r, ZeroN);
        !          1260:                        r->t = t;
        !          1261:                        l = an(OADDR, lval, ZeroN);
        !          1262:                        l->t = at(TIND, t);
        !          1263:                        l = an(OADD, l, con(o+t->offset));
        !          1264:                        l->t = l->left->t;
        !          1265:                        l = an(OIND, l, ZeroN);
        !          1266:                        l->t = t;
        !          1267:                        sucalc(r);
        !          1268:                        sucalc(l);
        !          1269:                        genexp(r, l);
        !          1270:                }
        !          1271:        }
        !          1272: }
        !          1273: 
        !          1274: int
        !          1275: bitmove(Node *rval, Node *lval)
        !          1276: {
        !          1277:        if(!isaddr(rval))
        !          1278:                return 0;
        !          1279: 
        !          1280:        if(!isaddr(lval))
        !          1281:                return 0;
        !          1282: 
        !          1283:        genmove(rval, rval->t, lval, 0);
        !          1284:        return 1;
        !          1285: }
        !          1286: 
        !          1287: /*
        !          1288:  * generate moves for complex types
        !          1289:  */
        !          1290: void
        !          1291: gencomplex(Node *rval, Node *lval)
        !          1292: {
        !          1293:        Type *t;
        !          1294:        Inst *back;
        !          1295:        int size, w, i, o;
        !          1296:        Node *l, *r, *tmp, *ptr;
        !          1297:        Node n1, n2, treg, loop;
        !          1298: 
        !          1299:        if(opt('x')) {
        !          1300:                print("GENCOM r\n");
        !          1301:                ptree(rval, 0);
        !          1302:                print("*\nGENCOM l\n");
        !          1303:                ptree(lval, 0);
        !          1304:        }
        !          1305: 
        !          1306:        r = rval->right;
        !          1307:        l = rval->left;
        !          1308: 
        !          1309:        switch(rval->type) {
        !          1310:        case OBLOCK:
        !          1311:                bstmnt(l);
        !          1312:                gencomplex(r, lval);
        !          1313:                break;
        !          1314: 
        !          1315:        case ODOT:
        !          1316:                tmp = stknode(l->t);
        !          1317:                genexp(l, tmp);
        !          1318:                if(rval == ZeroN)
        !          1319:                        break;
        !          1320: 
        !          1321:                tmp->ival = r->ival;
        !          1322:                tmp->t = rval->t;
        !          1323:                genexp(tmp, lval);
        !          1324:                break;
        !          1325: 
        !          1326:        case OASGN:
        !          1327:                if(l->type == OILIST) {
        !          1328:                        if(!isaddr(r) || lval != 0) {
        !          1329:                                tmp = stknode(r->t);
        !          1330:                                gencomplex(r, tmp);
        !          1331:                        }
        !          1332:                        else
        !          1333:                                tmp = r;
        !          1334: 
        !          1335:                        reg(&treg, builtype[TIND], ZeroN);
        !          1336:                        genaddr(tmp, &treg);
        !          1337:                        ptr = stknode(builtype[TIND]);
        !          1338:                        assign(&treg, ptr);
        !          1339:                        regfree(&treg);
        !          1340: 
        !          1341:                        gensubreg(l->left, ptr);
        !          1342:                        genelist(l->left);
        !          1343:                        if(lval)
        !          1344:                                gencomplex(tmp, lval);
        !          1345:                        break;
        !          1346:                }
        !          1347:                if(lval == ZeroN) {
        !          1348:                        if(rval->islval < Sucompute)
        !          1349:                                gencomplex(r, l);
        !          1350:                        break;
        !          1351:                }
        !          1352:                tmp = stknode(rval->t);
        !          1353:                gencomplex(r, tmp);
        !          1354:                gencomplex(tmp, l);
        !          1355:                gencomplex(tmp, lval);
        !          1356:                break;
        !          1357: 
        !          1358:        case ORECV:
        !          1359:        case OCALL:
        !          1360:                if(lval == ZeroN) {
        !          1361:                        tmp = stknode(rval->t);
        !          1362:                        gencomplex(rval, tmp);
        !          1363:                        break;
        !          1364:                }
        !          1365: 
        !          1366:                if(l->sun >= Sucall) {
        !          1367:                        reg(&treg, builtype[TIND], ZeroN);
        !          1368:                        genaddr(l, &treg);
        !          1369:                        if(treg.type != OREGISTER)
        !          1370:                                fatal("gencomplex: call %N", &treg);
        !          1371: 
        !          1372:                        l = stknode(builtype[TIND]);
        !          1373:                        l = an(OIND, l, ZeroN);
        !          1374:                        l->t = builtype[TIND];
        !          1375:                        assign(&treg, l);
        !          1376:                        regfree(&treg);
        !          1377:                }
        !          1378:                genarg(r);
        !          1379: 
        !          1380:                t = at(TIND, lval->t);
        !          1381:                regret(&n1, t);
        !          1382:                if(isaddr(lval)) {
        !          1383:                        lval = an(OADDR, lval, ZeroN);
        !          1384:                        lval->t = t;
        !          1385:                        genexp(lval, &n1);
        !          1386:                        tmp = ZeroN;
        !          1387:                }
        !          1388:                else {
        !          1389:                        tmp = stknode(lval->t);
        !          1390:                        n2.type = OADDR;
        !          1391:                        n2.ival = 0;
        !          1392:                        n2.t = t;
        !          1393:                        n2.left = tmp;
        !          1394:                        n2.right = ZeroN;
        !          1395:                        genexp(&n2, &n1);
        !          1396:                }
        !          1397: 
        !          1398:                if(!isaddr(l)) {
        !          1399:                        reg(&treg, builtype[TIND], ZeroN);
        !          1400:                        genaddr(l, &treg);
        !          1401:                        if(treg.type != OREGISTER)
        !          1402:                                fatal("gencomplex: call %N", &treg);
        !          1403: 
        !          1404:                        treg.type = OINDREG;
        !          1405:                        treg.ival = 0;
        !          1406:                        docall(&treg);
        !          1407:                        regfree(&treg);
        !          1408:                }
        !          1409:                else
        !          1410:                        docall(l);
        !          1411: 
        !          1412:                regfree(&n1);
        !          1413: 
        !          1414:                if(tmp)
        !          1415:                        gencomplex(tmp, lval);
        !          1416: 
        !          1417:                break;
        !          1418: 
        !          1419:        case OILIST:
        !          1420:                if(lval == ZeroN) {
        !          1421:                        warn(rval, "result ignored");
        !          1422:                        break;
        !          1423:                }
        !          1424: 
        !          1425:                t = lval->t;
        !          1426:                lval->t = builtype[TINT];
        !          1427:                rgenaddr(&n2, lval, ZeroN);
        !          1428:                if(t->type == TPOLY)
        !          1429:                        lval->t = polyshape;
        !          1430:                else
        !          1431:                        lval->t = t;
        !          1432:                o = n2.ival;
        !          1433:                n2.ival = 0;
        !          1434:                cominit(&n2, lval->t, rval, o);
        !          1435:                regfree(&n2);
        !          1436:                break;
        !          1437: 
        !          1438:        default:
        !          1439:                if(lval == ZeroN) {
        !          1440:                        warn(rval, "result ignored");
        !          1441:                        break;
        !          1442:                }
        !          1443:        
        !          1444:                size = rval->t->size;
        !          1445:                w = builtype[TINT]->size;
        !          1446:                size /= w;
        !          1447:                if(size < 6 && notunion(rval->t) && bitmove(rval, lval))
        !          1448:                        break;
        !          1449:        
        !          1450:                if(rval->sun > lval->sun) {
        !          1451:                        t = rval->t;
        !          1452:                        rval->t = builtype[TINT];
        !          1453:                        rgenaddr(&n1, rval, ZeroN);
        !          1454:                        rval->t = t;
        !          1455:        
        !          1456:                        t = lval->t;
        !          1457:                        lval->t = builtype[TINT];
        !          1458:                        rgenaddr(&n2, lval, ZeroN);
        !          1459:                        lval->t = t;
        !          1460:                }
        !          1461:                else {
        !          1462:                        t = lval->t;
        !          1463:                        lval->t = builtype[TINT];
        !          1464:                        rgenaddr(&n2, lval, ZeroN);
        !          1465:                        lval->t = t;
        !          1466:        
        !          1467:                        t = rval->t;
        !          1468:                        rval->t = builtype[TINT];
        !          1469:                        rgenaddr(&n1, rval, ZeroN);
        !          1470:                        rval->t = t;
        !          1471:                }
        !          1472:        
        !          1473:                reg(&treg, builtype[TINT], ZeroN);
        !          1474:                if(size < 6) {
        !          1475:                        for(i = 0; i < size; i++) {
        !          1476:                                instruction(AMOVW, &n1, ZeroN, &treg);
        !          1477:                                instruction(AMOVW, &treg, ZeroN, &n2);
        !          1478:                                n1.ival += w;
        !          1479:                                n2.ival += w;
        !          1480:                        }
        !          1481:                }
        !          1482:                else {
        !          1483:                        reg(&loop, builtype[TINT], ZeroN);
        !          1484: 
        !          1485:                        instruction(AMOVW, con(size), ZeroN, &loop);
        !          1486:                        instruction(AMOVW, &n1, ZeroN, &treg);
        !          1487:                        back = ipc;
        !          1488:                        instruction(AMOVW, &treg, ZeroN, &n2);
        !          1489:                        n1.type = OREGISTER;
        !          1490:                        n2.type = OREGISTER;
        !          1491:                        instruction(AADD, con(w), ZeroN, &n1);
        !          1492:                        instruction(AADD, con(w), ZeroN, &n2);
        !          1493:                        instruction(ASUBCC, con(1), ZeroN, &loop);
        !          1494:                        instruction(ABNE, ZeroN,  ZeroN, ZeroN);
        !          1495:                        label(ipc, back->pc);
        !          1496:                        regfree(&loop);
        !          1497:                }
        !          1498:                regfree(&treg);
        !          1499:                regfree(&n1);
        !          1500:                regfree(&n2);
        !          1501:        }
        !          1502: }

unix.superglobalmegacorp.com

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