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

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

unix.superglobalmegacorp.com

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