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

1.1     ! root        1: #include "gencode.h"
        !             2: #define fieldbotch(p) if(p->left->op == Fld) {rewritefld(p); longjmp(back, 1);}
        !             3: jmp_buf back;
        !             4: int acnt, Pflag, bbcnt;
        !             5: NODE *svq;             /* just for printing at FAIL */
        !             6: 
        !             7: gencode(p)
        !             8: NODE *p;
        !             9: {      mnod *q;
        !            10:        ret s;
        !            11:        int svtemp, svregvar, i, svbb;
        !            12:        extern int bothdebug;
        !            13:        svtemp = tmpoff;
        !            14:        svregvar = regvar;
        !            15:        svbb = ++bbcnt;
        !            16:        svq = p;
        !            17:        if(setjmp(back)) {
        !            18:                pr("#\treg\t%d\n", ++acnt) /*,prtree(q), putchar('\n')*/;
        !            19:                if(acnt > 20) {
        !            20:                        prtree(q);
        !            21:                        outpr();
        !            22:                        tmpoff = svtemp;
        !            23:                        bbcnt = svbb;
        !            24:                        uerror("expression too complicated");
        !            25:                        return;
        !            26:                }
        !            27:        }
        !            28:        else
        !            29:                q = copytree(p);
        !            30:        buf = bufs[1];
        !            31:        prptr = prbuf;
        !            32:        if(Pflag && q->op != Init) {
        !            33:                pr("#\tincl\tlocprof+%d\n", 4*(svbb+3));
        !            34:        }
        !            35:        s = doit(q, 0, 0, REGMASK);
        !            36:        if(s.flag & FAIL)
        !            37:                uerror("codegen failed at top level");
        !            38:        acnt = ntree = 0;
        !            39:        if(Pflag && q->op != Init)
        !            40:                printx("#%d ", svbb), prtree(q), printx("\n");
        !            41:        outpr();
        !            42:        tmpoff = svtemp;
        !            43:        regvar = svregvar;
        !            44: }
        !            45: 
        !            46: ret
        !            47: doit(p, flag, dest, regmask)
        !            48: mnod *p;
        !            49: ret dest;
        !            50: {      ret s, t, x, y;
        !            51:        char *pp;
        !            52:        mnod snode, *q;
        !            53:        int i, j, svmask = regmask;
        !            54:        switch(p->op) {
        !            55:        default:
        !            56:                pr("#\tweird??? %d\n", p->op);
        !            57:                return(dest);
        !            58:        case Andeq:
        !            59:                fieldbotch(p)
        !            60:                if(dest.ans && p->left->op == Star)
        !            61:                        longjmp(back, mediumstar(p));
        !            62:                flag |= DESTISLEFT;
        !            63:                flag &= ~CC;
        !            64:        case And:
        !            65:                if((flag & CC)) {       /* short b; reg int *c; if(b & *c++); */
        !            66:                        if(p->left->op == Conv && incrsize(p->left->left) < 4)
        !            67:                                p->left = p->left->left;
        !            68:                        if(p->right->op == Conv
        !            69:                                && incrsize(p->right->left) < 4)
        !            70:                                p->right = p->right->left;
        !            71:                }
        !            72:                t = doit(p->left, VALUE|USED, 0, regmask);
        !            73:                if(t.flag & FAIL)
        !            74:                        return(t);
        !            75:                regmask &= ~t.regmask;
        !            76:                s = doit(p->right, VALUE|USED, 0, regmask);
        !            77:                if(s.flag & FAIL)
        !            78:                        goto binfail;
        !            79:                if(flag & CC) {
        !            80:                        if(incrsize(p->left) == incrsize(p->right))
        !            81:                                i = type(p->right);
        !            82:                        else if(incrsize(p->left) < incrsize(p->right)) {
        !            83:                                if(s.flag & INDEX) {
        !            84:                                        totemp(p, RIGHT);
        !            85:                                        longjmp(back, 1);
        !            86:                                }
        !            87:                                i = childtype(p);
        !            88:                        }
        !            89:                        else {
        !            90:                                if(t.flag & INDEX) {
        !            91:                                        totemp(p, LEFT);
        !            92:                                        longjmp(back, 1);
        !            93:                                }
        !            94:                                i = type(p->right);
        !            95:                        }
        !            96:                        pr("#\tbit%c\t%s,%s\n", i, str(s), str(t));
        !            97:                        dest.ans = 0;
        !            98:                        dest.flag = CC;
        !            99:                        dest.regmask = 0;
        !           100:                        return(dest);
        !           101:                }
        !           102:                regmask &= ~s.regmask;
        !           103:                /* p->right->op == Compl is a useful special case */
        !           104:                if((flag & DESTISLEFT) && dest.ans == 0)
        !           105:                        dest = x = t;
        !           106:                if(dest.ans == 0)
        !           107:                        if(s.flag & SCRATCH)
        !           108:                                dest = x = s;
        !           109:                        else if(t.flag & SCRATCH) {
        !           110:                                dest = t;
        !           111:                                x = allocreg(p, regmask);
        !           112:                        }
        !           113:                        else
        !           114:                                dest = x = allocreg(p, regmask);
        !           115:                else
        !           116:                        x = allocreg(p, regmask);
        !           117:                if(p->right->op == Icon) {
        !           118:                        x = tostack();  /* to get a buf */
        !           119:                        sprintx(str(x), "$%d", -p->right->lval - 1);
        !           120:                }
        !           121:                else
        !           122:                        pr("#\tmcom%c\t%s,%s\n", childtype(p), str(s), str(x));
        !           123:                if(strcmp(str(t), str(dest)) == 0)
        !           124:                        pr("#\tbic%c2\t%s,%s\n", childtype(p), str(x), str(dest));
        !           125:                else if(flag & DESTISLEFT) {
        !           126:                        pr("#\tbic%c2\t%s,%s\n", childtype(p), str(x), str(t));
        !           127:                        if(strcmp(str(t), str(dest))) {
        !           128:                                x = t;
        !           129:                                goto movexdest;
        !           130:                        }
        !           131:                }
        !           132:                else
        !           133:                        pr("#\tbic%c3\t%s,%s,%s\n", childtype(p), str(x),
        !           134:                                str(t), str(dest));
        !           135:                if(flag & ASADDR)
        !           136:                        goto toaddr;
        !           137:                dest.flag |= CC;
        !           138:                return(dest);
        !           139:        case Call:
        !           140: call:
        !           141:                s.flag = funargs(p->right, regmask);
        !           142:                if(s.flag & FAIL)
        !           143:                        return(s);
        !           144:                i = p->argsize/32;
        !           145:                if(i > 255)
        !           146:                        uerror("%d arguments is too many", i);
        !           147: called:
        !           148:                s = doit(p->left, VALUE|ASADDR|USED, 0, regmask);
        !           149:                pp = str(s);
        !           150: aftercall:
        !           151:                if(svmask != REGMASK) {
        !           152:                        debugpr("#FAIL aftercall ");
        !           153:                        s.flag = FAIL;
        !           154:                        return(s);
        !           155:                }
        !           156:                x = specialreg(p, regmask);
        !           157:                pr("#\tcalls\t$%d,%s\n", i, pp);
        !           158:                if(flag & ASADDR) {
        !           159:                        strcat(str(x), ")");
        !           160:                        strshift(str(x), 1);
        !           161:                        str(x)[0] = '(';
        !           162:                }
        !           163:                if(dest.ans == 0)
        !           164:                        if(flag & DESTISLEFT)
        !           165:                                dest = doit(p->left->op == Conv?
        !           166:                                        p->left->left:
        !           167:                                        p->left, 0/* ? */, 0, regmask & ~x.regmask);
        !           168:                        else
        !           169:                                return(x);
        !           170: movexdest:     /* type(p), not childtype, for a = a % b */
        !           171:                if(strcmp(str(x), str(dest)) == 0)
        !           172:                        return(x);
        !           173:                if((flag & TOSTACK) && incrsize(p) == 4)
        !           174:                        pr("#\tpush%c\t%s\n", type(p), str(x));
        !           175:                else if(x.flag & ICON0)
        !           176:                        pr("#\tclr%c\t%s\n", type(p), str(dest));
        !           177:                else if(isfloat(p) != isfloat(p->left)
        !           178:                        && p->op != Call && p->op != Ucall)
        !           179:                        pr("#\tcvt%c%c\t%s,%s\n", childtype(p), type(p), str(x), str(dest));
        !           180:                else if((flag & TOSTACK) && (incrsize(p) != 8))
        !           181:                        pr("#\tcvt%cl\t%s,-(sp)\n", type(p), str(x));
        !           182:                else {
        !           183:                        pr("#\tmov%c\t%s,%s\n", type(p), str(x), str(dest));
        !           184:                        dest = simpler(x, dest);
        !           185:                }
        !           186:                dest.flag |= CC;
        !           187:                return(dest);
        !           188:        case Cmp:
        !           189:                if(p->left->op == Conv && p->right->op == Conv
        !           190:                        && childtype(p->left) == childtype(p->right)
        !           191:                        && !isfloat(p->left->left)) {   /* bogus? */
        !           192:                        p->left = p->left->left;
        !           193:                        p->right = p->right->left;
        !           194:                }
        !           195:                else if(p->left->op == Conv && p->right->op == Icon
        !           196:                        && p->right->lval >= 0
        !           197:                        && ((incrsize(p->left->left) == 1
        !           198:                                && p->right->lval < 128)
        !           199:                        || (incrsize(p->left->left) == 2
        !           200:                                && p->right->lval < 32768)))
        !           201:                        p->left = p->left->left;
        !           202:                /* the above rewriting depends on childype being of p->left */
        !           203:                s = doit(p->left, VALUE|USED, 0, regmask);
        !           204:                if(s.flag & FAIL)
        !           205:                        return(s);
        !           206:                regmask &= ~s.regmask;
        !           207:                t = doit(p->right, VALUE|USED, 0, regmask);
        !           208:                if(t.flag & FAIL) {
        !           209:                        t = doit(p->right, VALUE|USED, 0, REGMASK);
        !           210:                        if(!(t.flag & FAIL) && svmask != REGMASK)
        !           211:                                return(t.flag = FAIL, t);
        !           212:                        totemp(p, LEFT);
        !           213:                        longjmp(back, 1);
        !           214:                }
        !           215:                pr("#\tcmp%c\t%s,%s\n", childtype(p), str(s), str(t));
        !           216:                dest.ans = dest.regmask = 0;
        !           217:                dest.flag = CC;
        !           218:                return(dest);
        !           219:        case Comop:     /* qnodes lurking underneath */
        !           220:                if(p->left->op == Genlab && hasqnode(p->right)) {
        !           221:                        if(dest.ans == 0) {
        !           222:                                dest = allocreg(p, regmask);
        !           223:                        }
        !           224:                        t = doit(p->left, VALUE|(flag & CC), dest, regmask);
        !           225:                }
        !           226:                else
        !           227:                        t = doit(p->left, 0, 0, regmask);
        !           228:                if(t.flag & FAIL)
        !           229:                        return(t);
        !           230:                s = doit(p->right, VALUE|(flag & (USED|CC)), dest, regmask);
        !           231:                if(s.flag & FAIL)
        !           232:                        return(s);
        !           233:                if(flag & ASADDR) {
        !           234:                        dest.ans = 0;
        !           235:                        i = (s.flag & (ISREG|CANINDIR|SCRATCH));
        !           236:                        j = s.regmask;
        !           237:                        buf = str(s);
        !           238:                        goto convbuf;
        !           239:                }
        !           240:                return(s);
        !           241:        case Compl:
        !           242:                s = doit(p->left, VALUE|USED, 0, regmask);
        !           243:                if(s.flag & FAIL)
        !           244:                        return(s);
        !           245:                if(dest.ans == 0)
        !           246:                        if(s.flag & SCRATCH)
        !           247:                                dest = s;
        !           248:                        else
        !           249:                                dest = allocreg(p, regmask & ~s.regmask);
        !           250:                pr("#\tmcom%c\t%s,%s\n", childtype(p), str(s), str(dest));
        !           251:                dest.flag |= CC;
        !           252:                return(dest);
        !           253:        case Conv:
        !           254:                if(p->left->op == Asg && p->left->left->op == Star) {
        !           255:                        if(dest.ans == 0) {
        !           256:                                dest = allocreg(p, regmask);
        !           257:                                s = doit(p->left, VALUE|USED, dest, regmask);
        !           258:                        }
        !           259:                        else {
        !           260:                                x = allocreg(p, regmask);
        !           261:                                s = doit(p->left, VALUE|USED, x, regmask & ~x.regmask);
        !           262:                        }
        !           263:                        if(s.flag & FAIL) {
        !           264:                                asgwrite(p->left);
        !           265:                                longjmp(back, 1);
        !           266:                        }
        !           267:                }
        !           268:                else
        !           269:                        s = doit(p->left, VALUE|USED, 0, regmask);
        !           270:                if(childtype(p) == type(p) && dest.ans == 0)
        !           271:                        return(s);
        !           272:                if(s.flag & FAIL)
        !           273:                        return(s);
        !           274:                if(dest.ans == 0)
        !           275:                        if(s.flag & SCRATCH)
        !           276:                                dest = checksize(p, s, regmask);
        !           277:                        else
        !           278:                                dest = allocreg(p, regmask);
        !           279:                if(isunsigned(p->left) && incrsize(p) > incrsize(p->left)) {
        !           280:                        if(type(p) != 'f' && type(p) != 'd')
        !           281:                                pp = "movz";
        !           282:                        else {  /* uns to float or double */
        !           283:                                rewriteconv(p);
        !           284:                                longjmp(back, 1);
        !           285:                        }
        !           286:                }
        !           287:                else
        !           288:                        pp = "cvt";
        !           289:                if(isfloat(p) != isfloat(p->left))
        !           290:                        goto cvtop;
        !           291:                if(incrsize(p) < incrsize(p->left)) {
        !           292:                        if(isfloat(p))
        !           293:                                goto cvtop;
        !           294:                        pr("#\tmov%c\t%s,%s\n", type(p), str(s), str(dest));
        !           295:                        dest = simpler(s, dest);
        !           296:                }
        !           297:                else if(incrsize(p) > incrsize(p->left))
        !           298: cvtop:
        !           299:                        pr("#\t%s%c%c\t%s,%s\n", pp, childtype(p), type(p), str(s), str(dest));
        !           300:                else {  /* types were the same, but dest.ans != 0 */
        !           301:                        pr("#\tmov%c\t%s,%s\n", type(p), str(s), str(dest));
        !           302:                        dest = simpler(s, dest);
        !           303:                }
        !           304:                dest.flag |= CC;
        !           305:                return(dest);
        !           306:        case Decr:
        !           307:                i = -1;
        !           308:                pp = "sub";
        !           309: incrop:
        !           310:                if(p->type == Tfloat)
        !           311:                        uerror("no float ++/--");
        !           312:                fieldbotch(p)
        !           313:                /* if the dest uses regs, it may be from a qnode, so that reg
        !           314:                 * shouldn't be used (i?*a->b++:x()) where b has offset > 0
        !           315:                 */
        !           316:                s = doit(p->left, USED, 0, dest.ans? regmask & ~dest.regmask: regmask);
        !           317:                if(s.flag & FAIL)
        !           318:                        return(s);
        !           319:                t = doit(p->right, 0, 0, 0);
        !           320:                if(flag & VALUE) {
        !           321:                        if(dest.ans == 0)
        !           322:                                dest = allocreg(p, regmask & ~s.regmask);
        !           323:                        pr("#\tmov%c\t%s,%s\n", childtype(p), str(s), str(dest));
        !           324:                        if(t.flag & ICON1) {
        !           325:                                if(i == 1)
        !           326:                                        pp = "inc";
        !           327:                                else
        !           328:                                        pp = "dec";
        !           329:                                pr("#\t%s%c\t%s\n", pp, childtype(p), str(s));
        !           330:                        }
        !           331:                        else
        !           332:                                pr("#\t%s%c2\t%s,%s\n", pp, childtype(p),
        !           333:                                        str(t), str(s));
        !           334: toaddr:
        !           335:                        if(flag & ASADDR) {
        !           336:                                if(dest.flag & ISREG) {
        !           337:                                        sprintx(buf, "(%s)", str(dest));
        !           338:                                        done(dest, CANINDIR, dest.regmask);
        !           339:                                }
        !           340:                                if(dest.flag & CANINDIR) {
        !           341:                                        sprintx(buf, "*%s", str(dest));
        !           342:                                        done(dest, 0, dest.regmask);
        !           343:                                }
        !           344:                                uerror("weird asaddr in incrop");
        !           345:                        }
        !           346:                        dest.flag &= ~CC;
        !           347:                        return(dest);
        !           348:                }
        !           349:                if(t.flag & ICON1) {
        !           350:                        if(i == 1)
        !           351:                                pp = "inc";
        !           352:                        else
        !           353:                                pp = "dec";
        !           354:                        pr("#\t%s%c\t%s\n", pp, childtype(p), str(s));
        !           355:                }
        !           356:                else
        !           357:                        pr("#\t%s%c2\t%s,%s\n", pp, childtype(p), str(t), str(s));
        !           358:                if(dest.ans) {
        !           359:                        x = s;
        !           360:                        goto movexdest;
        !           361:                }
        !           362:                s.flag &= ~CC;
        !           363:                return(s);
        !           364:        case Diveq:
        !           365:                fieldbotch(p)
        !           366:                if(rewriteasgop(p))
        !           367:                        goto assign;
        !           368:                flag |= DESTISLEFT;
        !           369:        case Div:
        !           370:                /* trees wrong: uns/=int and int/=uns */
        !           371:                if(!isunsigned(p->right) && !isunsigned(p->left)) {
        !           372:                        pp = "div";
        !           373:                        goto binop;
        !           374:                }
        !           375:                pp = "udiv";
        !           376: unsdiv:
        !           377:                /* *p++ /= uns is hard */
        !           378:                if(p->left->op == Star && fixuns(p))
        !           379:                        longjmp(back, 1);       /* *A op= B => (T=A, *T op= B) */
        !           380:                if(incrsize(p->right) != 4) {
        !           381:                        snode.op = Conv;
        !           382:                        snode.left = p->right;
        !           383:                        snode.type = Tulong;
        !           384:                        s = doit(&snode, VALUE|TOSTACK, tostack(), regmask);
        !           385:                }
        !           386:                else
        !           387:                        s = doit(p->right, TOSTACK, tostack(), regmask);
        !           388:                if(s.flag & FAIL)
        !           389:                        return(s);
        !           390:                regmask &= ~s.regmask;
        !           391:                if(incrsize(p->left) != 4) {            
        !           392:                        snode.op = Conv;
        !           393:                        snode.left = p->left;
        !           394:                        snode.type = Tulong;
        !           395:                        t = doit(&snode, VALUE|TOSTACK, tostack(), regmask);
        !           396:                }
        !           397:                else
        !           398:                        t = doit(p->left, VALUE|TOSTACK, tostack(), regmask);
        !           399:                if(t.flag & FAIL) {
        !           400:                        if(dest.ans || svmask != REGMASK) {
        !           401:                                t = doit(p->left, VALUE|TOSTACK, tostack(), svmask);
        !           402:                                if(t.flag & FAIL)
        !           403:                                        return(t);
        !           404:                        }
        !           405:                        totemp(p, RIGHT);
        !           406:                        longjmp(back, 1);
        !           407:                }
        !           408:                i = 2;
        !           409:                goto aftercall;
        !           410:        case Xoreq:
        !           411:                fieldbotch(p)
        !           412:                flag |= DESTISLEFT;
        !           413:        case Xor:
        !           414:                pp = "xor";
        !           415: binop:
        !           416:                if((flag & DESTISLEFT) && dest.ans && p->left->op == Star)
        !           417:                        longjmp(back, mediumstar(p));
        !           418:                t = doit(p->left, VALUE|USED, 0, regmask);
        !           419:                if(t.flag & FAIL) {
        !           420:                        return(t);
        !           421:                }
        !           422:                regmask &= ~t.regmask;
        !           423:                s = doit(p->right, VALUE|USED, 0, regmask);
        !           424:                if(s.flag & FAIL) {
        !           425: binfail:
        !           426:                        if(dest.ans || svmask != REGMASK) {
        !           427:                                s = doit(p->right, VALUE|USED, 0, svmask);
        !           428:                                if(s.flag & FAIL)
        !           429:                                        return(s);
        !           430:                        }
        !           431:                        /* *foo op= expr  requires care */
        !           432:                        if((flag & DESTISLEFT) && p->left->op == Star)
        !           433:                                totemp(p->left, LEFT);
        !           434:                        else
        !           435:                                totemp(p, LEFT);
        !           436:                        longjmp(back, 1);
        !           437:                }
        !           438:                if(type(p) != childtype(p)) {
        !           439:                        x = allocreg(p, regmask);
        !           440:                        pr("#\t%s%c3\t%s,%s,%s\n", pp, childtype(p), str(s),
        !           441:                                str(t), str(x));
        !           442:                        if(dest.ans == 0)
        !           443:                                if(flag & DESTISLEFT)
        !           444:                                        dest = t;
        !           445:                                else
        !           446:                                        dest = x;
        !           447:                        if(!isfloat(p) && !isfloat(p->left)
        !           448:                                && incrsize(p) < incrsize(p->left)) {
        !           449:                                pr("#\tmov%c\t%s,%s\n", type(p), str(x), str(dest));
        !           450:                                dest = simpler(x, dest);
        !           451:                        }
        !           452:                        else
        !           453:                                pr("#\tcvt%c%c\t%s,%s\n", childtype(p), type(p),
        !           454:                                        str(x), str(dest));
        !           455:                        dest.flag |= CC;
        !           456:                        return(dest);
        !           457:                }       
        !           458:                if(dest.ans == 0)
        !           459:                        if((t.flag & SCRATCH) || (flag & DESTISLEFT)) {
        !           460: twoop:
        !           461:                                dest = t;
        !           462:                                if(*pp == 'a' && (s.flag & ICON1))
        !           463:                                        pr("#\tinc%c\t%s\n", childtype(p), str(t));
        !           464:                                else if(*pp == 's' && (s.flag & ICON1))
        !           465:                                        pr("#\tdec%c\t%s\n", childtype(p), str(t));
        !           466:                                else
        !           467:                                        pr("#\t%s%c2\t%s,%s\n", pp, childtype(p),
        !           468:                                                str(s), str(t));
        !           469:                                if(flag & ASADDR)
        !           470:                                        goto binopaddr;
        !           471:                                if(flag & TOSTACK)
        !           472:                                        pr("#\tpush%c\t%s\n", type(p), str(t));
        !           473:                                dest.flag |= CC;
        !           474:                                return(dest);
        !           475:                        }
        !           476:                        else if(s.flag & SCRATCH)
        !           477:                                dest = s;
        !           478:                        else
        !           479:                                dest = allocreg(p, regmask);
        !           480:                if(dest.ans && (flag & DESTISLEFT)) {
        !           481:                        pr("#\t%s%c2\t%s,%s\n", pp, childtype(p), str(s), str(t));
        !           482:                        x = t;
        !           483:                        goto movexdest;
        !           484:                }
        !           485:                if(commutes(p->op) && strcmp(str(s), str(dest)) == 0) {
        !           486:                        dest = s;
        !           487:                        s = t;
        !           488:                        t = dest;
        !           489:                        goto twoop;
        !           490:                }
        !           491:                if(strcmp(str(t), str(dest)) == 0)
        !           492:                        goto twoop;
        !           493:                        
        !           494:                pr("#\t%s%c3\t%s,%s,%s\n", pp, childtype(p), str(s), str(t), str(dest));
        !           495: binopaddr:
        !           496:                if(flag & ASADDR) {
        !           497:                        if(dest.flag & ISREG) {
        !           498:                                strcat(str(dest), ")");
        !           499:                                strshift(str(dest), 1);
        !           500:                                str(dest)[0] = '(';
        !           501:                                return(dest);
        !           502:                        }
        !           503:                        if(dest.flag & CANINDIR) {
        !           504:                                strshift(str(dest), 1);
        !           505:                                str(dest)[0] = '*';
        !           506:                                dest.flag &= ~CANINDIR;
        !           507:                                return(dest);
        !           508:                        }
        !           509:                        debugpr("#FAIL doubtful ");
        !           510:                        dest.flag = FAIL;       /* doubtful */
        !           511:                        return(dest);
        !           512:                }
        !           513:                dest.flag |= CC;
        !           514:                return(dest);   
        !           515:        case Fld:
        !           516:                /* this is rvalues */
        !           517:                s = doit(p->left, USED, 0, regmask);
        !           518:                if(s.flag & FAIL)
        !           519:                        return(s);
        !           520:                if(dest.ans == 0)
        !           521:                        dest = allocreg(p, regmask);
        !           522:                if((s.flag & INDEX) && p->left->op == Star
        !           523:                        && incrsize(p->left) != 1) {
        !           524:                /* over-enthusiastic use of index mode */
        !           525:                        if(dest.flag & SCRATCH)
        !           526:                                x = dest;
        !           527:                        else
        !           528:                                x = allocreg(p, regmask);
        !           529:                        pr("#\tmov%c\t%s,%s\n", childtype(p), str(s), str(x));
        !           530:                        s = x;
        !           531:                }
        !           532:                pr("#\text%sv\t$%d,$%d,%s,%s\n", isunsigned(p->left)? "z": "",
        !           533:                        p->rval/64, p->rval%64, str(s), str(dest));
        !           534:                dest.flag |= CC;
        !           535:                return(dest);
        !           536:        case Genbr:
        !           537:                if(p->left->op == Conv)
        !           538:                        s = doit(p->left->left, CC|VALUE|USED, 0, regmask);
        !           539:                /*else if(p->left->op == And && pow2(p->left->right->lval) > 0) {
        !           540:                        s = doit(p->left->left, CC|VALUE, 0, regmask);
        !           541:                        pp = genjbc(p->lop);
        !           542:                        pr("#\t%s\t$%d,%s,L%d\n", pp, pow2(p->left->right->lval),
        !           543:                                str(s), p->label);
        !           544:                        goto genbr0;
        !           545:                } not a win on 8550 */
        !           546:                else
        !           547:                        s = doit(p->left, CC|VALUE|USED, 0, regmask);
        !           548:                pp = genjmp(p->lop);
        !           549:                if(s.flag & CC)
        !           550:                        if(p->left->op != Conv || p->left->type >= Tint)
        !           551:                                pr("#\t%s\t", pp);
        !           552:                        else
        !           553:                                pr("#\ttst%c\t%s\n\t%s\t", childtype(p),
        !           554:                                        str(s), pp);
        !           555:                else if(p->left->op == Conv)
        !           556:                        pr("#\ttst%c\t%s\n#\t%s\t", childtype(p->left), str(s), pp);
        !           557:                else
        !           558:                        pr("#\ttst%c\t%s\n#\t%s\t", childtype(p), str(s), pp);
        !           559:                pr("L%d\n", p->label);
        !           560: genbr0:
        !           561:                s.flag |= CC;   /* ?? */
        !           562:                if(Pflag) {
        !           563:                        ++bbcnt;
        !           564:                        pr("#\tincl\tlocprof+%d\n", 4*(bbcnt+3));
        !           565:                }
        !           566:                return(s);
        !           567:        case Genlab:
        !           568:                s = doit(p->left, flag, dest, regmask);
        !           569:                pr("#L%d:\n", p->label);
        !           570:                if(Pflag) {
        !           571:                        ++bbcnt;
        !           572:                        pr("#\tincl\tlocprof+%d\n", 4*(bbcnt+3));
        !           573:                }
        !           574:                return(s);
        !           575:        case Genubr:
        !           576:                s = doit(p->left, flag & CC, dest, regmask);
        !           577:                if((flag & CC) && !(s.flag & CC))
        !           578:                        pr("#\ttst%c\t%s\n", childtype(p), str(s));
        !           579:                pr("#\tjbr\tL%d\n", p->label);
        !           580:                return(s);
        !           581:        case Icon:
        !           582:                if(p->name)
        !           583:                        if(p->lval)
        !           584:                                sprintx(buf, "%s+%d", p->name, p->lval);
        !           585:                        else
        !           586:                                sprintx(buf, "%s", p->name);
        !           587:                else
        !           588:                        sprintx(buf, "%d", p->lval);
        !           589:                if(!(flag & ASADDR)) {
        !           590:                        strshift(buf, 1);;
        !           591:                        buf[0] = '$';
        !           592:                }
        !           593:                i = 0;
        !           594:                if(p->name == 0)
        !           595:                        if(p->lval == 0)
        !           596:                                i = ICON0;
        !           597:                        else if(p->lval == 1)
        !           598:                                i = ICON1;
        !           599:                j = 0;
        !           600: convbuf:       /* the cookie is in buf */
        !           601:                if(dest.ans == 0 && !(flag & TOSTACK)) {
        !           602:                        if(p->op == Icon || !(flag & ASADDR)) {
        !           603:                                done(s, i, j);
        !           604:                        }
        !           605:                        if(i & CANINDIR) {
        !           606:                                strshift(buf, 1);
        !           607:                                buf[0] = '*';
        !           608:                                done(s, i & ~CANINDIR, j);
        !           609:                        }
        !           610:                        if(i & ISREG) {
        !           611:                                strcat(buf, ")");
        !           612:                                strshift(buf, 1);
        !           613:                                buf[0] = '(';
        !           614:                                done(s, i, j);
        !           615:                        }
        !           616:                        pp = buf;
        !           617:                        buf += BUF;
        !           618:                        s = allocreg(p, regmask);
        !           619:                        pr("#\tmov%c\t%s,%s\n", type(p), pp, str(s));
        !           620:                        flag &= ~ASADDR;
        !           621:                        goto inreg;
        !           622:                }
        !           623:                if(flag & TOSTACK)
        !           624:                        if(incrsize(p) == 4)
        !           625:                                pr("#\tpushl\t%s\n", buf);
        !           626:                        else if(incrsize(p) == 8)
        !           627:                                pr("#\tmovd\t%s,%s\n", buf, str(dest));
        !           628:                        else
        !           629:                                pr("#\tcvt%cl\t%s,%s\n", type(p), buf, str(dest));
        !           630:                else if(i & ICON0)
        !           631:                        pr("#\tclr%c\t%s\n", type(p), str(dest));
        !           632:                else {  
        !           633:                        pr("#\tmov%c\t%s,%s\n", type(p), buf, str(dest));
        !           634:                        if(!(dest.flag & INDEX) || !index(str(dest), '+')
        !           635:                                && !index(str(dest), '-'))
        !           636:                                ;
        !           637:                        else if(!(i & INDEX) || !index(buf, '+')
        !           638:                                && !index(buf, '-')) {
        !           639:                                done(s, (i|CC), j);
        !           640:                        }
        !           641:                        else
        !           642:                                dest.flag |= USED;
        !           643:                }
        !           644:                dest.flag |= CC;
        !           645:                return(dest);
        !           646:        case Incr:
        !           647:                i = 1;
        !           648:                pp = "add";
        !           649:                goto incrop;
        !           650:        case Init:      /* knows it is ICON */
        !           651:                s = doit(p->left, ASADDR, 0, 0);
        !           652:                pr("#\t.long\t%s\n", str(s));
        !           653:                return(dest);
        !           654:        case Lseq:
        !           655:                if(incrsize(p) != 4)
        !           656:                        lsconv(p);
        !           657:                if(rewriteasgop(p))
        !           658:                        goto assign;
        !           659:                fieldbotch(p)
        !           660:                flag |= DESTISLEFT;
        !           661:                if(dest.ans && p->left->op == Star)
        !           662:                        longjmp(back, mediumstar(p));
        !           663:        case Ls:        /* stupid vax */
        !           664:                if(incrsize(p) != 4)
        !           665:                        lsconv(p);
        !           666:                s = doit(p->left, VALUE|USED, 0, regmask);
        !           667:                if(s.flag & FAIL)
        !           668:                        return(s);
        !           669:                regmask &= ~s.regmask;
        !           670:                t = doit(p->right, VALUE|USED, 0, regmask);
        !           671:                if(t.flag & FAIL)
        !           672:                        goto binfail;
        !           673:                if((t.flag & INDEX) && p->right->op == Star
        !           674:                        && incrsize(p->right) != 1) {
        !           675:                /* over-enthusiastic use of index mode */
        !           676:                        if(dest.flag & SCRATCH)
        !           677:                                x = dest;
        !           678:                        else
        !           679:                                x = allocreg(p, regmask);
        !           680:                        pr("#\tmov%c\t%s,%s\n", childtype(p), str(t), str(x));
        !           681:                        t = x;
        !           682:                }
        !           683:                if(dest.ans == 0)
        !           684:                        if((s.flag & SCRATCH) || (flag & DESTISLEFT))
        !           685:                                dest = s;
        !           686:                        else
        !           687:                                dest = allocreg(p, regmask);
        !           688:                if(incrsize(p) != 4) {  /* stupid vax */
        !           689:                        x = allocreg(p, regmask);
        !           690:                        pr("#\tashl\t%s,%s,%s\n", str(t), str(s), str(x));
        !           691:                        pr("#\tmov%c\t%s,%s\n", type(p), str(x), str(dest));
        !           692:                        if(flag & DESTISLEFT)
        !           693:                                pr("#\tmovl\t%s,%s\n", str(x), str(s));
        !           694:                        dest.flag |= CC;
        !           695:                        return(dest);
        !           696:                }
        !           697:                if(p->right->op == Icon && (i = p->right->lval) <= 4
        !           698:                        && (dest.flag & ISREG) && !(s.flag&AUTO)) {
        !           699:                        if(strcmp(str(s), str(dest))) {
        !           700:                                i--;
        !           701:                                pr("#\taddl3\t%s,%s,%s\n", str(s), str(s), str(dest));
        !           702:                        }
        !           703:                        while(i-- > 0)
        !           704:                                pr("#\taddl2\t%s,%s\n", str(dest), str(dest));
        !           705:                }
        !           706:                else if(flag & DESTISLEFT)
        !           707:                        pr("#\tashl\t%s,%s,%s\n", str(t), str(s), str(s));
        !           708:                else
        !           709:                        pr("#\tashl\t%s,%s,%s\n", str(t), str(s), str(dest));
        !           710:                if((flag & DESTISLEFT) && strcmp(str(dest), str(s)))
        !           711:                        pr("#\tmovl\t%s,%s\n", str(s), str(dest));
        !           712:                dest.flag |= CC;
        !           713:                return(dest);
        !           714:        case Minuseq:
        !           715:                fieldbotch(p)
        !           716:                if(rewriteasgop(p))
        !           717:                        goto assign;
        !           718:                flag |= DESTISLEFT;
        !           719:        case Minus:
        !           720:                pp = "sub";
        !           721:                /* you won't believe this: type x[], *y where type is shorter than
        !           722:                 * int, generates subx $_x,y which the assembler barfs on.
        !           723:                 * instead, generate crummy code (stupid assembler)
        !           724:                 */
        !           725:                if(incrsize(p) < 4) {
        !           726:                        if(p->left->op == Icon && p->left->name) {
        !           727:                                p->left->type = Tint;
        !           728:                                totemp(p, LEFT);
        !           729:                        }
        !           730:                        if(p->right->op == Icon && p->right->name) {
        !           731:                                p->right->type = Tint;
        !           732:                                totemp(p, RIGHT);
        !           733:                        }
        !           734:                }
        !           735:                goto binop;
        !           736:        case Modeq:
        !           737:                fieldbotch(p)
        !           738:                if(rewriteasgop(p))
        !           739:                        goto assign;
        !           740:                if(dest.ans && p->left->op == Star)
        !           741:                        longjmp(back, mediumstar(p));
        !           742:                flag |= DESTISLEFT;
        !           743:        case Mod:
        !           744:                if(isunsigned(p->right) || isunsigned(p->left)) {
        !           745:                        pp = "urem";
        !           746:                        goto unsdiv;
        !           747:                }
        !           748:                s = doit(p->left, VALUE|USED, 0, regmask);
        !           749:                if(s.flag & FAIL)
        !           750:                        return(s);
        !           751:                regmask &= ~s.regmask;
        !           752:                t = doit(p->right, VALUE|USED, 0, regmask);
        !           753:                if(t.flag & FAIL)
        !           754:                        goto binfail;
        !           755:                regmask &= ~t.regmask;
        !           756:                x = allocreg(p, regmask);
        !           757:                pr("#\tdiv%c3\t%s,%s,%s\n", childtype(p), str(t), str(s), str(x));
        !           758:                pr("#\tmul%c2\t%s,%s\n", childtype(p), str(t), str(x));
        !           759:                pr("#\tsub%c3\t%s,%s,%s\n", childtype(p), str(x), str(s), str(x));
        !           760:                if(dest.ans)
        !           761:                        goto movexdest;
        !           762:                if(flag & DESTISLEFT) {
        !           763:                        dest = s;
        !           764:                        goto movexdest;
        !           765:                }
        !           766:                x.flag |= CC;
        !           767:                return(x);
        !           768:        case Muleq:
        !           769:                fieldbotch(p)
        !           770:                if(rewriteasgop(p))
        !           771:                        goto assign;
        !           772:                flag |= DESTISLEFT;
        !           773:        case Mul:
        !           774:                pp = "mul";
        !           775:                goto binop;
        !           776:        case Name:      /* ASADDR? */
        !           777:                if(p->lval && p->name)
        !           778:                        sprintx(buf, "%s+%d", p->name, p->lval);
        !           779:                else if(p->name)
        !           780:                        sprintx(buf, "%s", p->name);
        !           781:                else if(p->lval)
        !           782:                        sprintf(buf, "%d", p->lval);
        !           783:                else
        !           784:                        sprintx(buf, "0");
        !           785:                j = 0;
        !           786:                i = CANINDIR;
        !           787:                goto convbuf;
        !           788:        case Oreq:
        !           789:                fieldbotch(p)
        !           790:                flag |= DESTISLEFT;
        !           791:        case Or:
        !           792:                pp = "bis";
        !           793:                goto binop;
        !           794:        case Pluseq:
        !           795:                fieldbotch(p)
        !           796:                if(rewriteasgop(p))
        !           797:                        goto assign;
        !           798:                flag |= DESTISLEFT;
        !           799:        case Plus:
        !           800:                pp = "add";
        !           801:                goto binop;
        !           802:        case Reg:
        !           803:                sprintx(buf, "%s", regnames[p->rval]);
        !           804:                j = 0;
        !           805:                i = ISREG;
        !           806:                if(p->lval == 1)
        !           807:                        i |= SCRATCH;
        !           808:                goto convbuf;
        !           809:        case Rnode: case Snode:
        !           810:                x = specialreg(p, 3);
        !           811:                x.regmask = 0;
        !           812:                if(dest.ans)
        !           813:                        goto movexdest;
        !           814:                return(x);
        !           815:        case Qnode:
        !           816:                return(specialreg(p, regmask));
        !           817:        case Rseq:
        !           818:                fieldbotch(p)
        !           819:                if(incrsize(p) != 4)
        !           820:                        lsconv(p);
        !           821:                if(rewriteasgop(p))
        !           822:                        goto assign;
        !           823:                flag |= DESTISLEFT;
        !           824:        case Rs:        /* all right shifts are unsigned */
        !           825:                if(incrsize(p->left) != 4)      /* shifting funny objects */
        !           826:                        lsconv(p);
        !           827:                s = doit(p->left, VALUE|USED, 0, regmask);
        !           828:                if(s.flag & FAIL)
        !           829:                        return(s);
        !           830:                if(p->left->op == Icon ||
        !           831:                        (s.flag & INDEX) && p->left->op == Star
        !           832:                        && incrsize(p->left) != 1 ||
        !           833:                        (s.flag & AUTO) && incrsize(p->left) != 1) {
        !           834:                /* over-enthusiastic use of index mode */
        !           835:                /* 12 >> i generates a byte immediate */
        !           836:                        if((s.flag & INDEX) && (flag & DESTISLEFT)) {/* *a++ >>= 1 */
        !           837:                                lsconv(p);      /* not best */
        !           838:                                longjmp(back, 1);
        !           839:                        }
        !           840:                        if((flag & DESTISLEFT) && dest.ans == 0) {
        !           841:                                dest = s;
        !           842:                                regmask &= ~s.regmask;
        !           843:                        }
        !           844:                        if(dest.flag & SCRATCH)
        !           845:                                x = dest;
        !           846:                        else
        !           847:                                x = allocreg(p, regmask);
        !           848:                        pr("#\tmovl\t%s,%s\n", str(s), str(x));
        !           849:                        s = x;
        !           850:                }
        !           851:                regmask &= ~s.regmask;
        !           852:                if(dest.ans == 0)
        !           853:                        if((flag & DESTISLEFT) || (s.flag & SCRATCH))
        !           854:                                dest = s;
        !           855:                        else
        !           856:                                dest = allocreg(p, regmask);
        !           857:                dest.flag |= CC;
        !           858:                regmask &= ~dest.regmask;
        !           859:                if(incrsize(p) != 4)
        !           860:                        x = allocreg(p, regmask);
        !           861:                else if(flag & DESTISLEFT)
        !           862:                        x = s;
        !           863:                else
        !           864:                        x = dest;
        !           865:                if(p->right->op == Icon && (i = p->right->lval) >= 0) {
        !           866:                        pr("#\textzv\t$%d,$%d,%s,%s\n", i, 32 - i, str(s), str(x));
        !           867:                        goto movexdest;
        !           868:                }
        !           869:                t = doit(p->right, VALUE|USED, 0, regmask);
        !           870:                if(t.flag & FAIL)
        !           871:                        goto binfail;
        !           872:                y = allocreg(p, regmask & ~t.regmask);
        !           873:                pr("#\tsubl3\t%s,$32,%s\n", str(t), str(y));
        !           874:                pr("#\textzv\t%s,%s,%s,%s\n", str(t), str(y), str(s), str(x));
        !           875:                goto movexdest;
        !           876:        case Star:
        !           877:                switch(p->left->op) {
        !           878:                case Icon:      /* as in foo((a, a)), where a is a struct */
        !           879:                        s = doit(p->left, VALUE, 0, regmask);
        !           880:                        sprintx(buf, "%s", str(s)+1);
        !           881:                        i = j = 0;
        !           882:                        goto convbuf;
        !           883:                case Auto:
        !           884:                case Param:
        !           885:                case Name:
        !           886:                        s = doit(p->left, VALUE, 0, regmask);
        !           887:                        sprintx(buf, "*%s", str(s));
        !           888:                        j = i = 0;
        !           889:                        goto convbuf;
        !           890:                case Reg:
        !           891:                        s = doit(p->left, VALUE, 0, regmask);
        !           892: inreg:
        !           893:                        if(s.flag & ISREG) {
        !           894:                                sprintx(buf, "(%s)", str(s));
        !           895:                                j = s.regmask;
        !           896:                                i = CANINDIR;
        !           897:                                goto convbuf;
        !           898:                        }
        !           899:                        else if(s.flag & CANINDIR) {
        !           900:                                sprintx(buf, "*%s", str(s));
        !           901:                                j = s.regmask;
        !           902:                                i = 0;
        !           903:                                goto convbuf;
        !           904:                        }
        !           905:                        else {
        !           906:                                debugpr("#FAIL STAR REG ");
        !           907:                                s.flag = FAIL;
        !           908:                                return(s);
        !           909:                        }
        !           910:                }
        !           911:                q = p->left;
        !           912:                if(q->op == Incr && !(flag & INDEX)
        !           913:                        && q->right->op == Icon && q->left->op == Reg
        !           914:                        && incrsize(p) == (int) q->right->lval) {
        !           915:                        s = doit(q->left, VALUE, 0, regmask);
        !           916:                        sprintx(buf, "(%s)+", str(s));
        !           917:                        i = INDEX|AUTO;
        !           918:                        j = s.regmask;
        !           919:                        goto convbuf;
        !           920:                }
        !           921:                if(q->op == Plus && q->left->op == Ls
        !           922:                        && !(flag & INDEX)
        !           923:                        && q->left->right->op == Icon
        !           924:                        && shiftsize(p) == (int) q->left->right->lval) {
        !           925:                        s = doit(q->left->left, VALUE|USED, 0, regmask);
        !           926:                        if(s.flag & FAIL)
        !           927:                                return(s);
        !           928:                        regmask &= ~s.regmask;
        !           929:                        if(!(s.flag & ISREG)) {
        !           930:                                x = allocreg(p, regmask);
        !           931:                                pr("#\tmov%c\t%s,%s\n", childtype(q), str(s), str(x));
        !           932:                                regmask |= s.regmask;
        !           933:                                regmask &= ~x.regmask;
        !           934:                                s = x;
        !           935:                                if(!(s.flag & ISREG)) {
        !           936:                                        debugpr("#FAIL a[b] ");
        !           937:                                        s.flag = FAIL;
        !           938:                                        return(s);
        !           939:                                }
        !           940:                        }
        !           941:                        t = doit(q->right, ASADDR|USED|VALUE, 0, regmask);
        !           942:                        if(t.flag & FAIL) {
        !           943:                                totemp(q, LEFT);
        !           944:                                longjmp(back, 1);
        !           945:                        }
        !           946:                        sprintx(buf, "%s[%s]", str(t), str(s));
        !           947:                        i = INDEX;
        !           948:                        j = s.regmask | t.regmask;
        !           949:                        goto convbuf;
        !           950:                }
        !           951:                if(q->op == Plus && q->right->op == Icon) {
        !           952:                        s = doit(q->left, VALUE|USED, 0, regmask);
        !           953:                        if(s.flag & FAIL)
        !           954:                                return(s);
        !           955:                        if(!(s.flag & ISREG)) {
        !           956:                                x = allocreg(p, regmask);
        !           957:                                pr("#\tmov%c\t%s,%s\n", childtype(q), str(s), str(x));
        !           958:                                s = x;
        !           959:                                if(!(s.flag & ISREG)) {
        !           960:                                        debugpr("#FAIL a(b) ");
        !           961:                                        s.flag = FAIL;
        !           962:                                        return(s);
        !           963:                                }
        !           964:                        }
        !           965:                        regmask &= ~s.regmask;
        !           966:                        t = doit(q->right, ASADDR|USED, 0, regmask);
        !           967:                        sprintx(buf, "%s(%s)", str(t), str(s));
        !           968:                        i = CANINDIR;
        !           969:                        j = s.regmask;
        !           970:                        goto convbuf;
        !           971:                }
        !           972:                if(q->op == Minus && q->right->op == Icon) {
        !           973:                        s = doit(q->left, VALUE|USED, 0, regmask);
        !           974:                        if(s.flag & FAIL)
        !           975:                                return(s);
        !           976:                        if(!(s.flag & ISREG)) {
        !           977:                                x = allocreg(p, regmask);
        !           978:                                pr("#\tmov%c\t%s,%s\n", childtype(q), str(s), str(x));
        !           979:                                s = x;
        !           980:                                if(!(s.flag & ISREG)) {
        !           981:                                        debugpr("#FAIL %d(a) ");
        !           982:                                        s.flag = FAIL;
        !           983:                                        return(s);
        !           984:                                }
        !           985:                        }
        !           986:                        regmask &= ~s.regmask;
        !           987:                        sprintx(buf, "%d(%s)", -q->right->lval, str(s));
        !           988:                        i = CANINDIR;
        !           989:                        j = s.regmask;
        !           990:                        goto convbuf;
        !           991:                }
        !           992:                if(q->op == Minuseq && !(flag & (INDEX|USED))
        !           993:                        && q->right->op == Icon && q->left->op == Reg
        !           994:                        && incrsize(p) == (int) q->right->lval) {
        !           995:                        s = doit(q->left, VALUE, 0, regmask);
        !           996:                        sprintx(buf, "-(%s)", str(s));
        !           997:                        i = INDEX|AUTO;
        !           998:                        j = s.regmask;
        !           999:                        goto convbuf;
        !          1000:                }
        !          1001:                if(q->op == Plus && q->left->op == Reg
        !          1002:                        && !(flag & INDEX) && q->right->op == Reg
        !          1003:                        && incrsize(p) == 1) {
        !          1004:                        sprintx(buf, "(r%d)[r%d]", q->right->rval,
        !          1005:                                q->left->rval);
        !          1006:                        i = INDEX;
        !          1007:                        j = 0;
        !          1008:                        goto convbuf;
        !          1009:                }
        !          1010:                s = doit(p->left, VALUE|USED, 0, regmask);
        !          1011:                if(s.flag & FAIL)
        !          1012:                        return(s);
        !          1013:                regmask &= ~s.regmask;
        !          1014:                if(s.flag & CANINDIR) {
        !          1015:                        sprintx(buf, "*%s", str(s));
        !          1016:                        i = 0;
        !          1017:                        j = s.regmask;
        !          1018:                        goto convbuf;
        !          1019:                }
        !          1020:                if(!(s.flag & ISREG)) {
        !          1021:                        x = allocreg(p, regmask);
        !          1022:                        pr("#\tmov%c\t%s,%s\n", type(q), str(s), str(x));
        !          1023:                        regmask |= s.regmask;
        !          1024:                        regmask &= ~x.regmask;
        !          1025:                        s = x;
        !          1026:                }
        !          1027:                if(!(s.flag & ISREG)) {
        !          1028:                        debugpr("#FAIL STAR ");
        !          1029:                        s.flag = FAIL;
        !          1030:                        return(s);
        !          1031:                }
        !          1032:                sprintx(buf, "(%s)", str(s));
        !          1033:                i = 0;
        !          1034:                j = s.regmask;
        !          1035:                goto convbuf;
        !          1036:        case Stasg:
        !          1037:                if(p->stsize/8 == 4) {
        !          1038:                        i = 'l';
        !          1039: stasg:
        !          1040:                        s = doit(p->left, VALUE|ASADDR|USED|FSTASG, 0, regmask);
        !          1041:                        if(s.flag & FAIL)
        !          1042:                                return(s);
        !          1043:                        regmask &= ~s.regmask;
        !          1044:                        t = doit(p->right, VALUE|ASADDR|USED|FSTASG, 0, regmask);
        !          1045:                        if(t.flag & FAIL) {
        !          1046:                                t = doit(p->right, VALUE|ASADDR|USED|FSTASG, 0, REGMASK);
        !          1047:                                if(!(t.flag & FAIL) && svmask != REGMASK)
        !          1048:                                        return(t.flag = FAIL, t);
        !          1049:                                totemp(p, LEFT);
        !          1050:                                longjmp(back, 1);
        !          1051:                        }
        !          1052:                        pr("#\tmov%c\t%s,%s\n", i, str(t), str(s));
        !          1053:                        if(!(flag & FSTASG))
        !          1054:                                s = addrsimp(s, t);
        !          1055:                        return(s);
        !          1056:                }
        !          1057:                else if(p->stsize/8 == 8) {
        !          1058:                        i = 'q';
        !          1059:                        goto stasg;
        !          1060:                }
        !          1061:                if(regmask != REGMASK) {
        !          1062:                        debugpr("#FAIL stasg ");
        !          1063:                        s.flag = FAIL;
        !          1064:                        return(s);
        !          1065:                }
        !          1066:                s = doit(p->right, VALUE|USED|FSTASG, 0, regmask);
        !          1067:                if(s.flag & INDEX) {
        !          1068:                /* over-enthusiastic use of index mode */
        !          1069:                        x = allocreg(p, regmask);
        !          1070:                        pr("#\tmovl\t%s,%s\n", str(s), str(x));
        !          1071:                        s = x;
        !          1072:                }
        !          1073:                regmask &= ~s.regmask;
        !          1074:                t = doit(p->left, VALUE|USED|FSTASG, 0, regmask);
        !          1075:                if(t.flag & FAIL) {
        !          1076:                        totemp(p, RIGHT);
        !          1077:                        longjmp(back, 1);
        !          1078:                }
        !          1079:                if(t.flag & INDEX) {
        !          1080:                /* over-enthusiastic use of index mode */
        !          1081:                        x = allocreg(p, regmask);
        !          1082:                        pr("#\tmovl\t%s,%s\n", str(t), str(x));
        !          1083:                        t = x;
        !          1084:                }
        !          1085:                t = indirit(t);
        !          1086:                if(t.flag & FAIL) {
        !          1087:                        if(p->left->op != Star)
        !          1088:                                cerror("codegen failure in struct asg");
        !          1089:                        totemp(p->left, LEFT);
        !          1090:                        longjmp(back, 1);
        !          1091:                }
        !          1092:                s = indirit(s);
        !          1093:                if(s.flag & FAIL) {
        !          1094:                        if(p->right->op != Star)
        !          1095:                                cerror("codgen fail in stasg");
        !          1096:                        totemp(p->right, LEFT);
        !          1097:                        longjmp(back, 1);
        !          1098:                }
        !          1099:                pr("#\tmovc3\t$%d,%s,%s\n", p->stsize/8, str(s), str(t));
        !          1100:                if(flag & USED) {
        !          1101:                        t = specialreg(p, REGMASK);
        !          1102:                        pr("#\tsubl3\t$%d,r3,r0\n", p->stsize/8);
        !          1103:                }
        !          1104:                else
        !          1105:                        t.flag = 0;
        !          1106:                return(t);
        !          1107:        case Stcall:
        !          1108:                goto call;
        !          1109:        case Auto:
        !          1110:                sprintx(buf, "%d(%s)", p->lval, frameptr);
        !          1111:                j = 0;
        !          1112:                i = CANINDIR;
        !          1113:                goto convbuf;
        !          1114:        case Param:
        !          1115:                sprintx(buf, "%d(%s)", p->lval, argptr);
        !          1116:                j = 0;
        !          1117:                i = CANINDIR;
        !          1118:                goto convbuf;
        !          1119:        case Addr:
        !          1120:                s = doit(p->left, USED, 0, regmask);
        !          1121:                if(s.flag & FAIL)
        !          1122:                        return(s);
        !          1123:                regmask &= ~s.regmask;
        !          1124:                if(dest.ans == 0) {
        !          1125:                        dest = allocreg(p, regmask);
        !          1126:                }
        !          1127:                if(s.flag & ISREG) {
        !          1128:                        x = alloctmp(p);
        !          1129:                        pr("#\tmov%c\t%s,%s\n", childtype(p), str(s), str(x));
        !          1130:                        s = x;
        !          1131:                }
        !          1132:                if(flag & TOSTACK)
        !          1133:                        pr("#\tpushal\t%s\n", str(s));
        !          1134:                else
        !          1135:                        pr("#\tmova%c\t%s,%s\n", type(p), str(s), str(dest));
        !          1136:                if(flag & ASADDR) {
        !          1137:                        if(dest.flag & ISREG) {
        !          1138:                                strcat(str(dest), ")");
        !          1139:                                strshift(str(dest), 1);
        !          1140:                                str(dest)[0] = '(';
        !          1141:                        }
        !          1142:                        else {
        !          1143:                                strshift(str(dest), 1);
        !          1144:                                str(dest)[0] = '*';
        !          1145:                        }
        !          1146:                }
        !          1147:                return(dest);
        !          1148:        case Ucall:
        !          1149:                i = 0;
        !          1150:                goto called;
        !          1151:        case Uminus:
        !          1152:                s = doit(p->left, VALUE|USED, 0, regmask);
        !          1153:                if(s.flag & FAIL)
        !          1154:                        return(s);
        !          1155:                if(dest.ans == 0)
        !          1156:                        if(s.flag & SCRATCH)
        !          1157:                                dest = s;
        !          1158:                        else
        !          1159:                                dest = allocreg(p, regmask & ~s.regmask);
        !          1160:                pr("#\tmneg%c\t%s,%s\n", childtype(p), str(s), str(dest));
        !          1161:                dest.flag |= CC;
        !          1162:                return(dest);
        !          1163:        case Ustcall:
        !          1164:                i = 0;
        !          1165:                goto called;
        !          1166:        case Asg:
        !          1167: assign:
        !          1168:                if(p->left->op == Qnode && dest.ans) {
        !          1169:                        s = doit(p->right, VALUE|(flag&USED? USED: 0),
        !          1170:                                dest, regmask);
        !          1171:                        return(s);
        !          1172:                }
        !          1173:                if(p->left->op == Rnode || p->left->op == Snode) {
        !          1174:                        s = doit(p->right, VALUE|(flag&USED? USED: 0),
        !          1175:                                dest, regmask);
        !          1176:                        if(s.flag & FAIL)
        !          1177:                                return(s);
        !          1178:                        x = s;
        !          1179:                        dest = doit(p->left, USED, 0, 0);
        !          1180:                        goto movexdest;
        !          1181:                }
        !          1182:                if(p->left->op == Fld) {
        !          1183:                        s = doit(p->left->left, INDEX, 0, regmask);
        !          1184:                        regmask &= ~s.regmask;
        !          1185:                        if(p->right->op == Asg) {
        !          1186:                                x = allocreg(p->right, regmask);
        !          1187:                                t = doit(p->right, VALUE|USED, x, regmask & ~x.regmask);
        !          1188:                        }
        !          1189:                        else
        !          1190:                                t = doit(p->right, VALUE|USED, 0, regmask);
        !          1191:                        if(t.flag & FAIL) {     /* was fldstar */
        !          1192:                                totemp(p->left->left, LEFT);
        !          1193:                                totemp(p, RIGHT);
        !          1194:                                longjmp(back, 1);
        !          1195:                        }
        !          1196:                        i = '$';
        !          1197:                        pr("#\tinsv\t%s,%c%d,%c%d,%s\n", str(t), i,
        !          1198:                                p->left->rval/64, i,
        !          1199:                                p->left->rval % 64, str(s));
        !          1200:                        if(dest.ans) {
        !          1201:                                pr("#\tmovl\t%s,%s\n", str(t), str(dest));
        !          1202:                                t.flag |= CC;
        !          1203:                        }
        !          1204:                        return(t);
        !          1205:                }
        !          1206:                if(dest.ans && p->left->op == Star) {
        !          1207:                        if(dest.flag & SCRATCH)
        !          1208:                                x = dest;
        !          1209:                        else
        !          1210:                                x = allocreg(p, regmask);
        !          1211:                        s = doit(p->right, VALUE|USED, x, regmask);
        !          1212:                        if(s.flag & FAIL)
        !          1213:                                return(s);
        !          1214:                        regmask &= ~s.regmask;
        !          1215:                        t = doit(p->left, USED, 0, regmask);
        !          1216:                        if(t.flag & FAIL) {
        !          1217:                        /* did we fail because of a dest, or was it us? */
        !          1218:                                if(dest.ans || svmask != REGMASK) {
        !          1219:                                        t = doit(p->left, USED, 0, svmask);
        !          1220:                                        if(t.flag & FAIL) {
        !          1221:                                                return(t);
        !          1222:                                        }
        !          1223:                                        starasg(p);
        !          1224:                                }
        !          1225:                                else
        !          1226:                                        asgwrite(p);
        !          1227:                                longjmp(back, 1);
        !          1228:                        }
        !          1229:                        pr("#\tmov%c\t%s,%s\n", type(p), str(x), str(t));
        !          1230:                        if(strcmp(str(x), str(dest)) == 0) {
        !          1231:                                dest.flag |= CC;
        !          1232:                                return(dest);
        !          1233:                        }
        !          1234:                        goto movexdest;
        !          1235:                }
        !          1236:                if(p->right->op == Fld && incrsize(p) != 4) {
        !          1237:                        /* ext sets whole word */
        !          1238:                        asgwrite(p);
        !          1239:                        p->left->type = isunsigned(p)? Tuint: Tint;
        !          1240:                        longjmp(back, 1);
        !          1241:                }
        !          1242:                t = doit(p->left, USED, 0, regmask);
        !          1243:                regmask &= ~t.regmask;
        !          1244:                if(p->right->op == Genlab || p->right->op == Comop)
        !          1245:                        extracheck(p);  /* slightly worse code in usual case */
        !          1246:                s = doit(p->right, VALUE, t, regmask);  /* VALUE is't right:
        !          1247:                        register char *a, *b; return((*a++ = *b++ | 40) != 3); */
        !          1248:                if(s.flag & NOGOOD) {
        !          1249:                /* did we fail because of a dest, or was it us? */
        !          1250:                        if(s.flag & FAIL) {
        !          1251:                                if(dest.ans || svmask != REGMASK) {
        !          1252:                                        s = doit(p->right, VALUE, t, svmask);
        !          1253:                                        if(s.flag & FAIL) {
        !          1254:                                                return(s);
        !          1255:                                        }
        !          1256:                                }
        !          1257:                                asgwrite(p);
        !          1258:                                longjmp(back, 1);
        !          1259:                        }
        !          1260:                        else if((flag & USED) && !((flag & CC) && (s.flag & CC))) {
        !          1261:                                /* presumably USED as in *p++=*q++ */
        !          1262:                                totemp(p, RIGHT);
        !          1263:                                longjmp(back, 1);
        !          1264:                        }
        !          1265:                }
        !          1266:                if(dest.ans) {
        !          1267:                        x = s;
        !          1268:                        goto movexdest;
        !          1269:                }
        !          1270:                else if(flag & ASADDR) {
        !          1271:                        i = (s.flag & (ISREG|CANINDIR|SCRATCH));
        !          1272:                        j = s.regmask;
        !          1273:                        buf = str(s);
        !          1274:                        goto convbuf;
        !          1275:                }
        !          1276:                return(s);
        !          1277:        }
        !          1278: }

unix.superglobalmegacorp.com

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